Commit | Line | Data |
---|---|---|
545fc9df TO |
1 | #!/usr/bin/env php |
2 | <?php | |
3 | ||
4 | // Update the data-files within this repo to reflect a new version number. | |
5 | // Example usage: | |
6 | // git checkout origin/master -b master-4.7.29 | |
7 | // ./tools/bin/scripts/set-version.php 4.7.29 --commit | |
8 | // git commit -m "Update to version 4.7.29" | |
9 | // git push origin master | |
10 | ||
11 | /* *********************************************************************** */ | |
12 | /* Boot */ | |
5c5ed6db | 13 | if (!(php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0))) { |
a9f3bf65 SL |
14 | header("HTTP/1.0 404 Not Found"); |
15 | return; | |
16 | } | |
545fc9df TO |
17 | $civicrm_root = dirname(dirname(dirname(__DIR__))); |
18 | chdir($civicrm_root); | |
19 | ||
20 | /* *********************************************************************** */ | |
21 | /* Parse inputs -- $oldVersion, $newVersion, $doCommit */ | |
22 | ||
23 | $oldVersion = (string) simplexml_load_file("xml/version.xml")->version_no; | |
24 | if (!isVersionValid($oldVersion)) { | |
25 | fatal("failed to read old version from \"xml/version.xml\"\n"); | |
26 | } | |
27 | ||
b43bfb44 TO |
28 | /** @var string $newVersion */ |
29 | /** @var bool $doCommit */ | |
bd9556c5 | 30 | /** @var bool $doSql */ |
b43bfb44 TO |
31 | extract(parseArgs($argv)); |
32 | ||
545fc9df TO |
33 | if (!isVersionValid($newVersion)) { |
34 | fatal("failed to read new version\n"); | |
35 | } | |
36 | ||
545fc9df TO |
37 | /* *********************************************************************** */ |
38 | /* Main */ | |
39 | ||
337dc87a TO |
40 | echo "Changing version from $oldVersion to $newVersion...\n"; |
41 | ||
42 | $verName = makeVerName($newVersion); | |
b7c0a88f | 43 | $phpFile = initFile("CRM/Upgrade/Incremental/php/{$verName}.php", function () use ($verName) { |
337dc87a TO |
44 | ob_start(); |
45 | global $camelNumber; | |
46 | $camelNumber = $verName; | |
47 | require 'CRM/Upgrade/Incremental/php/Template.php'; | |
48 | unset($camelNumber); | |
49 | return ob_get_clean(); | |
50 | }); | |
51 | ||
bd9556c5 TO |
52 | // It is typical for `*.alpha` to need SQL file -- and for `*.beta1` and `*.0` to NOT need a SQL file. |
53 | if ($doSql === TRUE || ($doSql === 'auto' && preg_match(';alpha;', $newVersion))) { | |
54 | $sqlFile = initFile("CRM/Upgrade/Incremental/sql/{$newVersion}.mysql.tpl", function () use ($newVersion) { | |
55 | return "{* file to handle db changes in $newVersion during upgrade *}\n"; | |
56 | }); | |
57 | } | |
545fc9df TO |
58 | |
59 | updateFile("xml/version.xml", function ($content) use ($newVersion, $oldVersion) { | |
60 | return str_replace($oldVersion, $newVersion, $content); | |
61 | }); | |
62 | ||
653b713e C |
63 | if (file_exists("civicrm-version.php")) { |
64 | updateFile("civicrm-version.php", function ($content) use ($newVersion, $oldVersion) { | |
65 | return str_replace($oldVersion, $newVersion, $content); | |
66 | }); | |
67 | } | |
4d4f529c | 68 | |
545fc9df TO |
69 | updateFile("sql/civicrm_generated.mysql", function ($content) use ($newVersion, $oldVersion) { |
70 | return str_replace($oldVersion, $newVersion, $content); | |
71 | }); | |
72 | ||
d071a643 SL |
73 | updateFile("sql/test_data_second_domain.mysql", function ($content) use ($newVersion, $oldVersion) { |
74 | return str_replace($oldVersion, $newVersion, $content); | |
75 | }); | |
76 | ||
545fc9df | 77 | if ($doCommit) { |
bd9556c5 TO |
78 | $files = array_filter( |
79 | ['xml/version.xml', 'sql/civicrm_generated.mysql', 'sql/test_data_second_domain.mysql', $phpFile, @$sqlFile], | |
80 | 'file_exists' | |
81 | ); | |
82 | $filesEsc = implode(' ', array_map('escapeshellarg', $files)); | |
83 | passthru("git add $filesEsc"); | |
84 | passthru("git commit $filesEsc -m " . escapeshellarg("Set version to $newVersion")); | |
545fc9df TO |
85 | } |
86 | ||
87 | /* *********************************************************************** */ | |
88 | /* Helper functions */ | |
89 | ||
337dc87a TO |
90 | /** |
91 | * Update the content of a file. | |
92 | * | |
93 | * @param string $file | |
94 | * @param callable $callback | |
95 | * Function(string $originalContent) => string $newContent. | |
96 | */ | |
545fc9df TO |
97 | function updateFile($file, $callback) { |
98 | if (!file_exists($file)) { | |
99 | die("File does not exist: $file\n"); | |
100 | } | |
101 | echo "Update \"$file\"\n"; | |
102 | $content = file_get_contents($file); | |
103 | $content = $callback($content); | |
104 | file_put_contents($file, $content); | |
105 | } | |
106 | ||
337dc87a TO |
107 | /** |
108 | * Initialize a file (if it doesn't already exist). | |
109 | * @param string $file | |
110 | * @param callable $callback | |
111 | * Function() => string $newContent. | |
112 | */ | |
113 | function initFile($file, $callback) { | |
114 | if (file_exists($file)) { | |
115 | echo "File \"$file\" already exists.\n"; | |
116 | } | |
117 | else { | |
118 | echo "Initialize \"$file\"\n"; | |
119 | $content = $callback(); | |
120 | file_put_contents($file, $content); | |
121 | } | |
122 | return $file; | |
123 | } | |
124 | ||
125 | /** | |
126 | * Render a pretty string for a major/minor version number. | |
127 | * | |
128 | * @param string $version | |
129 | * Ex: '5.10.alpha1' | |
130 | * @return string | |
131 | * Ex: 'FiveTen'. | |
132 | */ | |
133 | function makeVerName($version) { | |
b43bfb44 | 134 | [$a, $b] = explode('.', $version); |
337dc87a TO |
135 | require_once 'CRM/Utils/EnglishNumber.php'; |
136 | return CRM_Utils_EnglishNumber::toCamelCase($a) . CRM_Utils_EnglishNumber::toCamelCase($b); | |
137 | } | |
138 | ||
545fc9df TO |
139 | function isVersionValid($v) { |
140 | return $v && preg_match('/^[0-9a-z\.\-]+$/', $v); | |
141 | } | |
142 | ||
143 | /** | |
144 | * @param $error | |
145 | */ | |
146 | function fatal($error) { | |
147 | echo $error; | |
bd9556c5 TO |
148 | echo "usage: set-version.php <new-version> [--sql|--no-sql] [--commit|--no-commit]\n"; |
149 | echo " --sql A placeholder *.sql file will be created.\n"; | |
150 | echo " --no-sql A placeholder *.sql file will not be created.\n"; | |
151 | echo " --commit Any changes will be committed automatically the current git branch.\n"; | |
152 | echo " --no-commit Any changes will be left uncommitted.\n"; | |
153 | echo "\n"; | |
154 | echo "If the SQL style is not specified, it will decide automatically. (Alpha versions get SQL files.)\n"; | |
155 | echo "\n"; | |
156 | echo "You MUST indicate whether to commit.\n"; | |
545fc9df TO |
157 | exit(1); |
158 | } | |
b43bfb44 TO |
159 | |
160 | /** | |
161 | * @param array $argv | |
162 | * Ex: ['myscript.php', '--no-commit', '5.6.7'] | |
163 | * @return array | |
164 | * Ex: ['scriptFile' => 'myscript.php', 'doCommit' => FALSE, 'newVersion' => '5.6.7'] | |
165 | */ | |
166 | function parseArgs($argv) { | |
167 | $parsed = []; | |
bd9556c5 | 168 | $parsed['doSql'] = 'auto'; |
b43bfb44 TO |
169 | $positions = ['scriptFile', 'newVersion']; |
170 | $positional = []; | |
171 | ||
172 | foreach ($argv as $arg) { | |
173 | switch ($arg) { | |
174 | case '--commit': | |
175 | $parsed['doCommit'] = TRUE; | |
176 | break; | |
177 | ||
178 | case '--no-commit': | |
179 | $parsed['doCommit'] = FALSE; | |
180 | break; | |
181 | ||
bd9556c5 TO |
182 | case '--sql': |
183 | $parsed['doSql'] = TRUE; | |
184 | break; | |
185 | ||
186 | case '--no-sql': | |
187 | $parsed['doSql'] = FALSE; | |
188 | break; | |
189 | ||
b43bfb44 TO |
190 | default: |
191 | if ($arg[0] !== '-') { | |
192 | $positional[] = $arg; | |
193 | } | |
194 | else { | |
195 | fatal("Unrecognized argument: $arg\n"); | |
196 | } | |
197 | break; | |
198 | } | |
199 | } | |
200 | ||
201 | foreach ($positional as $offset => $value) { | |
202 | $name = $positions[$offset] ?? "unknown_$offset"; | |
203 | $parsed[$name] = $value; | |
204 | } | |
205 | ||
206 | if (!isset($parsed['doCommit'])) { | |
207 | fatal("Must specify --commit or --no-commit\n"); | |
208 | } | |
209 | ||
210 | return $parsed; | |
211 | } |