Merge pull request #20150 from MegaphoneJon/backoffice-xfer
[civicrm-core.git] / tools / bin / scripts / set-version.php
CommitLineData
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 13if (!(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__)));
18chdir($civicrm_root);
19
20/* *********************************************************************** */
21/* Parse inputs -- $oldVersion, $newVersion, $doCommit */
22
23$oldVersion = (string) simplexml_load_file("xml/version.xml")->version_no;
24if (!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
31extract(parseArgs($argv));
32
545fc9df
TO
33if (!isVersionValid($newVersion)) {
34 fatal("failed to read new version\n");
35}
36
545fc9df
TO
37/* *********************************************************************** */
38/* Main */
39
337dc87a
TO
40echo "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.
53if ($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
59updateFile("xml/version.xml", function ($content) use ($newVersion, $oldVersion) {
60 return str_replace($oldVersion, $newVersion, $content);
61});
62
653b713e
C
63if (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
69updateFile("sql/civicrm_generated.mysql", function ($content) use ($newVersion, $oldVersion) {
70 return str_replace($oldVersion, $newVersion, $content);
71});
72
d071a643
SL
73updateFile("sql/test_data_second_domain.mysql", function ($content) use ($newVersion, $oldVersion) {
74 return str_replace($oldVersion, $newVersion, $content);
75});
76
545fc9df 77if ($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
97function 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 */
113function 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 */
133function 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
139function isVersionValid($v) {
140 return $v && preg_match('/^[0-9a-z\.\-]+$/', $v);
141}
142
143/**
144 * @param $error
145 */
146function 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 */
166function 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}