Source for file EVSVersion.php

Documentation is available at EVSVersion.php


1 <?php
2 // EVS: Easy Versioning System
3 // Copyright (C) 2003 Lukas Feiler
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 /**This file is part of EVS - Easy Versioning System.
20 *
21 * @author Lukas Feiler <lukas.feiler@chello.at>
22 * @version 0.1.9
23 * @copyright Lukas Feiler 2003
24 * @package EVS
25 * @filesource
26 */
27
28 /**Is required for some string validation.
29 */
30 require_once('RSValidation/RSValidation.php');
31
32 /**The method loadConfig creates an instance of RSDEngine to get the config.
33 */
34 require_once('RSDEngine/RSDEngine.php');
35
36 /**Implements the possibility of updating a version and creating releases from it.
37 *
38 * @author Lukas Feiler <lukas.feiler@chello.at>
39 * @version 0.1.9
40 * @copyright Lukas Feiler 2003
41 * @package EVS
42 */
43 class EVSVersion {
44 /**An instance of EVSProject. Gets set inside the costructor method.
45 * @var EVSProject
46 */
47 var $project = null;
48
49 /**An instance of EVS. Gets set inside the costructor method.
50 * @var EVS
51 */
52 var $evs = null;
53
54 /**The version number or an empty string if the project was not created with versioning support. Gets set inside the costructor method.
55 * @var String
56 */
57 var $version;
58
59 /**The absolute path to the directory where the version is stored. Gets set inside the costructor method.
60 * @var String
61 */
62 var $projectDirectory = '';
63
64 /**Whether it is a release or a current version. See the tutorial for details. Gets set inside the costructor method.
65 * @var boolean
66 */
67 var $isRelease = false;
68
69 /**Whether it is current version or a release. See the tutorial for details. Gets set inside the costructor method.
70 * @var boolean
71 */
72 var $isCurrentVersion = false;
73
74 /**Whether it is a current stable version or not. See the tutorial for details. Gets set inside the costructor method.
75 * @var boolean
76 */
77 var $isStableVersion = false;
78
79 /**Whether it is a current development version or not. See the tutorial for details. Gets set inside the costructor method.
80 * @var boolean
81 */
82 var $isDevelopmentVersion = false;
83
84 /**The major version number. Gets set inside the costructor method.
85 * @var int
86 */
87 var $major = null;
88
89 /**The minor version number. Gets set inside the costructor method.
90 * @var int
91 */
92 var $minor = null;
93
94 /**The patchlevel version number. Gets set inside the costructor method.
95 * @var int
96 */
97 var $patchlevel = null;
98
99 /**The next major version number. Gets set inside the costructor method.
100 * @var int
101 */
102 var $nextMajor = null;
103
104 /**The next minor version number. Gets set inside the costructor method.
105 * @var int
106 */
107 var $nextMinor = null;
108
109 /**The next patchlevel version number. Gets set inside the costructor method.
110 * @var int
111 */
112 var $nextPatchlevel = null;
113
114 /**The complete version number of the next major release. Gets set inside the costructor method.
115 * @var int
116 */
117 var $nextMajorReleaseNumber = null;
118
119 /**The complete version number of the next minor release. Gets set inside the costructor method.
120 * @var int
121 */
122 var $nextMinorReleaseNumber = null;
123
124 /**The complete version number of the next patchlevel release. Gets set inside the costructor method.
125 * @var int
126 */
127 var $nextPatchlevelReleaseNumber = null;
128
129 /**Whether it is the latest current development version. See the tutorial for details. Gets set in the method init.
130 * @see init
131 * @var boolean
132 */
133 var $isLatestCurrentDevelopmentVersion = false;
134
135 /**Whether it is the latest current version. See the tutorial for details. Gets set in the method init.
136 * @see init
137 * @var boolean
138 */
139 var $isLatestCurrentVersion = false;
140
141 /**Whether it is the latest development release. See the tutorial for details. Gets set in the method init.
142 * @see init
143 * @var boolean
144 */
145 var $isLatestDevelopmentRelease = false;
146
147 /**Whether it is the latest stable release. See the tutorial for details. Gets set in the method init.
148 * @see init
149 * @var boolean
150 */
151 var $isLatestStableRelease = false;
152
153 /**Stores the configuration information from config.ini, README, AUTHORS, RELEASE, INSTALL, FAQ and ddl.sql.
154 * Gets filled by loadConfig.
155 * @see loadConfig
156 * @var Array
157 */
158 var $config = array();
159
160
161 /**Constructor method that sets most of the properties.
162 * @param EVSProject $project An instance of EVSProject passed by reference. This is the project this version is part of.
163 * @param String $version The version number or an empty string if the project was not created with versioning support.
164 */
165 function EVSVersion(&$project, $version)
166 {
167 $this->project =& $project;
168 $this->evs =& $this->project->evs;
169 $this->version = $version;
170 if (!$this->version) {
171 $this->versionDirectory = $this->project->projectDirectory;
172 } else {
173 $this->versionDirectory = $this->project->projectDirectory . "/$this->version";
174 $this->isRelease = !RSValidation::endsWith($version, '.current');
175 $this->isCurrentVersion = RSValidation::endsWith($version, '.current');
176 $this->isStableVersion = $this->_extractMinorVersion($version) % 2 == 0;
177 $this->isDevelopmentVersion = $this->_extractMinorVersion($version) % 2 == 1;
178
179 $this->major = $this->_extractMajorVersion($version) * 1;
180 $this->minor = $this->_extractMinorVersion($version) * 1;
181 $this->patchlevel = $this->_extractPatchlevelVersion($version) * 1;
182 $this->nextMajor = $this->major + 1;
183 $this->nextMinor = $this->minor + 1;
184
185 $this->nextMajorReleaseNumber = "$this->nextMajor.0.0";
186 $this->nextMinorReleaseNumber = "$this->major.$this->nextMinor.0";
187 }
188 }
189
190 /**Sets the properties isLatestCurrentVersion, isLatestCurrentDevelopmentVersion, isLatestDevelopmentRelease, isLatestStableRelease.
191 *
192 * Calling this method only makes sense after having loaded all versions of the project.
193 * @see isLatestCurrentDevelopmentVersion
194 * @see isLatestDevelopmentRelease
195 * @see isLatestStableRelease
196 */
197 function init()
198 {
199 if (!$this->version) {
200 return false;
201 }
202
203 $latestPatchlevel = $this->project->getLatestPatchlevelVersion($this->major, $this->minor);
204 if (is_object($latestPatchlevel)) {
205 $this->nextPatchlevel = $latestPatchlevel->patchlevel + 1;
206 } else {
207 $this->nextPatchlevel = 0;
208 }
209 $this->nextPatchlevelReleaseNumber = "$this->major.$this->minor.$this->nextPatchlevel";
210
211 $latestCurrentVersion = $this->project->getLatestCurrentVersion();
212 $this->isLatestCurrentVersion = $this->version == $latestCurrentVersion->version;
213
214 $latestCurrentDevelopmentVersion = $this->project->getLatestCurrentDevelopmentVersion();
215 $this->isLatestCurrentDevelopmentVersion = $this->version == $latestCurrentDevelopmentVersion->version;
216
217 $latestDevelopmentRelease = $this->project->getLatestDevelopmentRelease();
218 $this->isLatestDevelopmentRelease = $this->version == $latestDevelopmentRelease->version;
219
220 $latestStableRelease = $this->project->getLatestStableRelease();
221 $this->isLatestStableRelease = $this->version == $latestStableRelease->version;
222 }
223
224 /**Returns the major version number from the version number passed as argument.
225 * @access private
226 * @param String $version A version number in the format of "$major.$minor.$patchlevel".
227 * @return String The major version number.
228 */
229 function _extractMajorVersion($version)
230 {
231 $version = split('\.',$version);
232 return $version[0];
233 }
234
235 /**Returns the minor version number from the version number passed as argument.
236 * @access private
237 * @param String $version A version number in the format of "$major.$minor.$patchlevel".
238 * @return String The minor version number.
239 */
240 function _extractMinorVersion($version)
241 {
242 $version = split('\.',$version);
243 return $version[1];
244 }
245
246 /**Returns the patchlevel version number from the version number passed as argument.
247 * @access private
248 * @param String $version A version number in the format of "$major.$minor.$patchlevel".
249 * @return String The patchlevel version number.
250 */
251 function _extractPatchlevelVersion($version)
252 {
253 $version = split('\.',$version);
254 return $version[2];
255 }
256
257 /**Makes a new major release based on this version.
258 *
259 * Making new major releases is only possible from the latest current version. See the tutorial for details.
260 * @see isLatestCurrentVersion
261 *
262 * @param String $releaseInfo The release information to be used in the ChangeLog.
263 * @return boolean True on success false on failure (if the project was not created with versioning support or is is not the latest current version).
264 */
265 function makeMajorRelease($releaseInfo)
266 {
267 if (!$this->version) {
268 return false;
269 }
270 if (!$this->isLatestCurrentVersion) {
271 return false;
272 }
273
274 RSIO::copyDirectory(
275 $this->project->projectDirectory . "/$this->version/",
276 $this->project->projectDirectory . "/$this->nextMajor.0.0/"
277 );
278 RSIO::copyDirectory(
279 $this->project->projectDirectory . "/$this->version/",
280 $this->project->projectDirectory . "/$this->nextMajor.0.current/"
281 );
282
283 $newMajor = new EVSVersion($this->project,"$this->nextMajor.0.0");
284
285 $latestPatchlevelVersion = $this->project->getLatestPatchlevelVersion($this->major,$this->minor);
286 if (is_object($latestPatchlevelVersion)) {
287 $newMajor->setPreviousVersion($latestPatchlevelVersion->version);
288 } else {
289 $version = $this->getPreviousVersion();
290 if ($version != "") {
291 $newMajor->setPreviousVersion($version);
292 }
293 }
294
295 $newMajor->loadConfig();
296 $newMajor->config['release'] = "------- $newMajor->version released on " .
297 date("l dS of F Y H:i:s") . " -------\n$releaseInfo";
298 $newMajor->saveConfig();
299
300 copy(
301 $this->project->projectDirectory . "/$this->nextMajor.0.0/PREVIOUS_RELEASE",
302 $this->project->projectDirectory . "/$this->nextMajor.0.current/PREVIOUS_RELEASE"
303 );
304
305 $newMajor->updateChangelog();
306 $newMajor->updateVersionTags();
307 return true;
308 }
309
310 /**Makes a new minor release based on this version.
311 *
312 * Making new minor releases is only possible from the latest current version. See the tutorial for details.
313 * @see isLatestCurrentVersion
314 *
315 * @param String $releaseInfo The release information to be used in the ChangeLog.
316 * @return boolean True on success false on failure (if the project was not created with versioning support or is is not the latest current version).
317 */
318 function makeMinorRelease($releaseInfo)
319 {
320 if (!$this->version) {
321 return false;
322 }
323 if (!$this->isLatestCurrentVersion) {
324 return false;
325 }
326
327 RSIO::copyDirectory(
328 $this->project->projectDirectory . "/$this->version/",
329 $this->project->projectDirectory . "/$this->major.$this->nextMinor.0/"
330 );
331 RSIO::copyDirectory(
332 $this->project->projectDirectory . "/$this->version/",
333 $this->project->projectDirectory . "/$this->major.$this->nextMinor.current/"
334 );
335
336
337 $newMinor = new EVSVersion($this->project,"$this->major.$this->nextMinor.0");
338
339 $latestPatchlevelVersion = $this->project->getLatestPatchlevelVersion($this->major,$this->minor);
340 if (is_object($latestPatchlevelVersion)) {
341 $newMinor->setPreviousVersion($latestPatchlevelVersion->version);
342 } else {
343 $version = $this->getPreviousVersion();
344 if ($version != "") {
345 $newMinor->setPreviousVersion($version);
346 }
347 }
348
349 $newMinor->loadConfig();
350 $newMinor->config['release'] = "------- $newMinor->version released on " .
351 date("l dS of F Y H:i:s") . " -------\n$releaseInfo";
352 $newMinor->saveConfig();
353
354 $newMinor->updateChangelog();
355 $newMinor->updateVersionTags();
356 }
357
358 /**Makes a new minor release based on this version.
359 *
360 * Making new patchlevel releases is only possible from a current versions. See the tutorial for details.
361 * @see isCurrentVersion
362 *
363 * @param String $releaseInfo The release information to be used in the ChangeLog.
364 * @return boolean True on success false on failure (if the project was not created with versioning support or is is not current version).
365 */
366 function makePatchlevelRelease($releaseInfo)
367 {
368 if (!$this->version) {
369 return false;
370 }
371 if (!$this->isCurrentVersion) {
372 return false;
373 }
374 RSIO::copyDirectory(
375 $this->project->projectDirectory . "/$this->version/",
376 $this->project->projectDirectory . "/$this->nextPatchlevelReleaseNumber/"
377 );
378 $newPatchlevel = new EVSVersion($this->project,$this->nextPatchlevelReleaseNumber);
379
380 $latestPatchlevelVersion = $this->project->getLatestPatchlevelVersion($this->major,$this->minor);
381 if (is_object($latestPatchlevelVersion)) {
382 $newPatchlevel->setPreviousVersion($latestPatchlevelVersion->version);
383 } else {
384 $version = $this->getPreviousVersion();
385 if ($version != "") {
386 $newPatchlevel->setPreviousVersion($version);
387 }
388 }
389 $newPatchlevel->loadConfig();
390 $newPatchlevel->config['release'] = "------- $newPatchlevel->version released on " .
391 date("l dS of F Y H:i:s") . " -------\n$releaseInfo";
392 $newPatchlevel->saveConfig();
393 $newPatchlevel->updateChangelog();
394 $newPatchlevel->updateVersionTags();
395
396 }
397
398 /**Updates all @version tags found in any file under $this->versionDirectory.
399 */
400 function updateVersionTags()
401 {
402 if ($this->config['updateVersionAfterRelease']) {
403 $snr = new File_SearchReplace("", "", array(), array("$this->versionDirectory/"));
404 $snr->setSearchFunction('preg');
405 $snr->setFind("/^\*\ @version[^\n]*/m");
406 $snr->setReplace("* @version $this->version");
407 $snr->doSearch();
408 }
409 }
410
411 /**Returns a string containing the ChangeLog for this version.
412 *
413 * This method reads in the file VERSION_ROOT/code/RELEASE and appends the return value of getChangelog called on the privious version.
414 * To determine which is the previous verison $this->getPreviousVersion() is called.
415 * @see getPreviousVersion
416 * @return String The ChangeLog
417 */
418 function getChangelog()
419 {
420 $data = RSIO::getFileContents("$this->versionDirectory/code/RELEASE");
421 if (PEAR::isError($data)) {
422 $data = "";
423 }
424 $version = $this->getPreviousVersion();
425 if ($version != "") {
426 $previousVersion = $this->project->getVersion($version);
427 $data .= "\n\n\n" . $previousVersion->getChangelog();
428 }
429 return $data;
430 }
431
432 /**Writes the result of $this->getChangeLog() to the file VERSION_ROOT/code/CHANGELOG
433 */
434 function updateChangelog()
435 {
436 $data = $this->getChangeLog();
437 File::write("$this->versionDirectory/code/CHANGELOG", $data, FILE_MODE_WRITE);
438 }
439
440
441
442 /**Saves the version number of the previous release in the file VERSION_ROOT/PREVIOUS_RELEASE.
443 * @param String $version The version number of the previous release.
444 */
445 function setPreviousVersion($version)
446 {
447 $data = $version;
448 File::write("$this->versionDirectory/PREVIOUS_RELEASE", $data, FILE_MODE_WRITE);
449 }
450
451 /**Reads and returns the version number of the previous release from the file VERSION_ROOT/PREVIOUS_RELEASE.
452 * @return String The contents of VERSION_ROOT/PREVIOUS_RELEASE or an empty string if nonexisting.
453 */
454 function getPreviousVersion()
455 {
456 $data = RSIO::getFileContents("$this->versionDirectory/PREVIOUS_RELEASE");
457 return PEAR::isError($data) ? "" : $data;
458 }
459
460 /**Loads the configuration information of this version into the associative array $this->config.
461 *
462 * Acutally a new instance of RSDEngine is created with $this->versionDirectory as argument.
463 * This new instance is used to get the configuration information.
464 */
465 function loadConfig()
466 {
467 $rsdEngine = new RSDEngine($this->versionDirectory);
468 $rsdEngine->loadConfig();
469 $this->config = $rsdEngine->config;
470 }
471
472 /**Saves the configuration information of this version.
473 *
474 * Acutally a new instance of RSDEngine is created with $this->versionDirectory as argument.
475 * This new instance is used to save the configuration information by calling saveConfig.
476 *
477 * @param mixed $config An associative array that will be passed to $rsdEngine->saveConfig or false if you wish
478 * the configuration stored in $this->config to be saved. This argument is optional. The default is false.
479 */
480 function saveConfig($config = false)
481 {
482 if ($config === false) {
483 $config = $this->config;
484 }
485 $rsdEngine = new RSDEngine($this->versionDirectory);
486 $rsdEngine->saveConfig($config);
487 }
488 }
489 ?>

Documentation generated on Mon, 8 Dec 2003 13:10:35 +0100 by phpDocumentor 1.2.3