-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRoboFile.php
272 lines (245 loc) · 8.75 KB
/
RoboFile.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
<?php
use Robo\ResultData;
use Robo\Tasks;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Custom RoboFile commands for this project.
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @class RoboFile
*/
class RoboFile extends Tasks
{
/**
* Placeholder for your own project's commands.
*
* @command drupal-project:custom-command
*
* @return void
*
* @throws \Exception
*/
public function customCommand(InputInterface $input, OutputInterface $output): void
{
$io = new SymfonyStyle($input, $output);
$io->comment('This is just a placeholder command, please add your own custom commands here. Please edit : ' . __FILE__);
}
/**
* Generate a static site from Drupal with Tome.
*
* @command drupal-project:static
*
* @aliases static
*
* @param bool $incremental
* (Default false) If only content changes have happened, you can set this to 1 to make
* this command faster.
* @param bool $start_server
* (Default true) Start an HTTP server with node.
*
* @return \Robo\ResultData
*/
public function static(
InputInterface $input,
OutputInterface $output,
bool $incremental = FALSE,
bool $start_server = TRUE,
): ResultData
{
$io = new SymfonyStyle($input, $output);
if (!$incremental && is_dir("html")) {
$io->info('Removing pre-existing static site.');
$this->_cleanDir("html");
} else {
$io->info('Doing an incremental update');
}
$this->_exec('./drush.sh tome:static');
if ($start_server) {
$this->_exec('npm install && npx http-server html');
}
return new ResultData();
}
/**
* Export default content.
*
* @command drupal-project:export-content
*
* @aliases export-content
*
* @return \Robo\ResultData
*
* @throws \Exception
*/
public function exportContent(
InputInterface $input,
OutputInterface $output,
array $opts = [
'path' => 'modules/custom/default_content_config',
'entities' => [
'node',
'menu_link_content',
'media',
'redirect',
'user',
'config_pages',
'taxonomy_term',
],
]
): ResultData
{
$path = $opts['path'];
$entities = $opts['entities'];
$io = new SymfonyStyle($input, $output);
if (is_dir("web/$path/content")) {
$io->info('Removing existing default content exported.');
$this->_cleanDir("web/$path/content");
}
foreach ($entities as $entity) {
$io->info("Exporting $entity as default content");
$this->_exec("./drush.sh default-content:export-references $entity --folder=$path/content");
}
$io->info("Finished exporting default content to $path/content");
return new ResultData();
}
/**
* Shared functionality to help create and re-tag a release.
*
* @param string $hotfix_or_release
* Either 'hotfix' or 'release'.
* @param string $semantic_version
* A semantic version number in the form x.y.z. Release must end in 0.
*
* @return array
* An indexed array of [$tag_description, $new_branch_name, $source_branch].
*
* @throws \Exception
*/
protected function getVariablesForRelease(string $hotfix_or_release, string $semantic_version): array
{
if (!in_array($hotfix_or_release, ['hotfix', 'release'])) {
throw new InvalidArgumentException("hotfix_or_release must be either 'hotfix' or 'release', '$hotfix_or_release' given.");
}
// @see https://regex101.com/r/Ly7O1x/3/.
if ($hotfix_or_release === 'hotfix') {
if (!preg_match('/^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>[1-9]\d*)$/', $semantic_version)) {
throw new InvalidArgumentException("semantic_version must be in the form x.y.z, where z is greater than 0, '$semantic_version' given.");
}
} else if (!preg_match('/^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0)$/', $semantic_version)) {
throw new InvalidArgumentException("semantic_version must be in the form x.y.z, where z is 0, '$semantic_version' given.");
}
$this->_exec('git status');
if (`git status --porcelain`) {
throw new \Exception('Your "git status" must be clean of any changes or untracked files before continuing. Please see the output of "git status" above.');
}
if ($hotfix_or_release === 'hotfix') {
$source_branch = 'main';
$tag_description = "Hotfix version $semantic_version";
} else {
$source_branch = 'develop';
$tag_description = "Release version $semantic_version";
}
$new_branch_name = "$hotfix_or_release/$semantic_version";
return [$tag_description, $new_branch_name, $source_branch];
}
/**
* Create a release.
*
* @command drupal-project:create-release
*
* @aliases create-release
*
* @param string $hotfix_or_release
* Either 'hotfix' or 'release'.
* @param string $semantic_version
* A semantic version number in the form x.y.z. Release must end in 0.
*
* @return \Robo\ResultData
*
* @throws \Exception
*/
public function createRelease(
InputInterface $input,
OutputInterface $output,
string $hotfix_or_release,
string $semantic_version,
): ResultData
{
[$tag_description, $new_branch_name, $source_branch] = $this->getVariablesForRelease($hotfix_or_release, $semantic_version);
`git fetch`;
// Checkout the branch that the release will be created from.
$this->taskGitStack()
->stopOnFail()
->checkout($source_branch)
->run();
// If you trying to test this function, you will need to temp change
// $source_branch to whatever branch you are working in, otherwise,
// your changes will get wiped out.
// You will also want to comment the following line out, since it will
// also wipe out your changes.
`git reset --hard origin/$source_branch`;
// Create the new release branch.
`git checkout -b $new_branch_name`;
// Create a new release tag and push the release branch and tag.
$this->taskGitStack()
->stopOnFail()
->push('origin', $new_branch_name)
->tag("v$semantic_version", $tag_description)
->push('origin', "v$semantic_version")
->run();
return new ResultData();
}
/**
* Re-creates the tag for a release after updates have been pushed.
*
* The release branch will already be up to date because a feature branch
* should have been pushed to it, but the initial tag will be out of date
* now. This checks out the current version of the release, deletes the tag
* then pushes back up the tag.
*
* @command drupal-project:re-tag-release
*
* @aliases re-tag
*
* @param string $hotfix_or_release
* Either 'hotfix' or 'release'.
* @param string $semantic_version
* A semantic version number in the form x.y.z. Release must end in 0.
*
* @return \Robo\ResultData
*
* @throws \Exception
*/
public function reTagRelease(
InputInterface $input,
OutputInterface $output,
string $hotfix_or_release,
string $semantic_version,
): ResultData
{
[$tag_description, $new_branch_name] = $this->getVariablesForRelease($hotfix_or_release, $semantic_version);
`git fetch`;
// Check back out the release branch that has been updated by a feature
// request and is ahead of the source branch.
$this->taskGitStack()
->stopOnFail()
->checkout($new_branch_name)
->run();
// Ensure that the release is at the latest.
`git reset --hard origin/$new_branch_name`;
// Delete the old tag locally and remotely.
`git tag --delete v$semantic_version`;
`git push origin --delete v$semantic_version`;
// Create a new tag of the same named based on the updated release
// branch.
$this->taskGitStack()
->stopOnFail()
->tag("v$semantic_version", $tag_description)
->push('origin', "v$semantic_version")
->run();
return new ResultData();
}
}