示例#1
0
 /**
  * Updates information in package.xml file used by packaged extensions
  */
 static function run_update_package_xml($task = null, $args = array(), $cliopts = array())
 {
     /// @todo replace hostname, build time
     $opts = self::getOpts(@$args[0], @$args[1], $cliopts);
     if (!SharedLock::acquire($opts['extension']['name'], LOCK_EX, $opts)) {
         throw new PakeException("Source code locked by another process");
     }
     $destdir = $opts['build']['dir'];
     $files = pakeFinder::type('file')->name('package.xml')->maxdepth(0);
     if (count($files) == 1) {
         // original format
         pake_replace_regexp($files, $destdir, array('#^( *\\074name\\076)(.*)(\\074/name\\076\\r?\\n?)$#m' => '${1}' . $opts['extension']['name'] . '_extension' . '$3', '#^( *\\074version\\076)(.*)(\\074/version\\076\\r?\\n?)$#m' => '${1}' . $opts['ezp']['version']['major'] . '.' . $opts['ezp']['version']['minor'] . '.' . $opts['ezp']['version']['release'] . '$3', '#^( *\\074named-version\\076)(.*)(\\074/named-version\\076\\r?\\n?)$#m' => '${1}' . $opts['ezp']['version']['major'] . '.' . $opts['ezp']['version']['minor'] . '$3', '#^( *\\074number\\076)(.*)(\\074/number\\076\\r?\\n?)$#m' => '${1}' . $opts['version']['alias'] . '$3', '#^( *\\074release\\076)(.*)(\\074/release\\076\\r?\\n?)$#m' => '${1}' . $opts['version']['release'] . '$3', '#^( *\\074timestamp\\076)(.*)(\\074/timestamp\\076\\r?\\n?)$#m' => '${1}' . time() . '$3', '#^( *\\074host\\076)(.*)(\\074/host\\076\\r?\\n?)$#m' => '${1}' . gethostname() . '$3', '#^( *\\074licence\\076)(.*)(\\074/licence\\076\\r?\\n?)$#m' => '${1}' . $opts['version']['license'] . '$3'));
         // replacing a token based on its value instead of its location (text immediately before and after,
         // as done above) has a disadvantage: we cannot execute the substitution many
         // times on the same text, as the 1st substitution will remove the token's
         // value. This means we have to reinit the build to get a 100% updated
         // package file. Unfortunately hunting for xml attributes not based on
         // token values needs a real xml parser, simplistic regexps are not enough...
         pake_replace_tokens($files, $destdir, '{', '}', array('$name' => $opts['extension']['name'], '$version' => $opts['version']['alias'], '$ezp_version' => $opts['ezp']['version']['major'] . '.' . $opts['ezp']['version']['minor'] . '.' . $opts['ezp']['version']['release']));
     }
     SharedLock::release($opts['extension']['name'], LOCK_EX, $opts);
 }
示例#2
0
 /**
  * Commits changelog to the "ci" git repo and updates in there other files holding version-related infos; options: skip-update-ci-repo-source
  * As part of this task, the local copy of the "ci" git repo is updated from upstream.
  *
  * The "ci" repo is used by the standard eZ Publish build process, driven by Jenkins.
  * It holds, amongs other things, patch files that are applied in order to build the
  * CP version instead of the Enterprise one
  */
 public static function run_update_ci_repo($task = null, $args = array(), $cliopts = array())
 {
     $opts = self::getOpts($args, $cliopts);
     $rootpath = self::getSourceDir($opts, 'legacy');
     // start work on the ci repo:
     $cipath = self::getSourceDir($opts, 'ci-repo');
     $git = self::getTool('git', $opts);
     // 1. update ci repo - moved to a separate task
     // dirty, dirty hack
     $originp = @$GLOBALS['originp'];
     $repo = new pakeGit($cipath);
     if ($opts['git']['ci-repo']['path'] != '') {
         $cipath .= '/' . $opts['git']['ci-repo']['path'];
         $localcipath = $opts['git']['ci-repo']['path'] . '/';
     } else {
         $localcipath = '';
     }
     // 1b. check that there is no spurious stuff in changelog dir, or step 3 later will create bad patch files.
     //     we do this here to avoid adding ANY file to local copy of CI git repo and abort asap
     $changelogdir = 'doc/changelogs/Community_Project-' . $opts['version']['major'];
     $files = pakeFinder::type('file')->maxdepth(0)->relative()->in(self::getSourceDir($opts, 'legacy') . '/' . $changelogdir);
     if (count($files) != 1) {
         throw new pakeException("More than one changelog file (or none) found in directory {$changelogdir}, can not generate patch file for CI repo");
     }
     // 2. update 0002_2011_11_patch_fix_version.diff file
     $files1 = pakeFinder::type('file')->name('0002_2011_11_patch_fix_version.diff')->maxdepth(0)->relative()->in($cipath . '/patches');
     $files2 = pakeFinder::type('file')->name('0003_2011_11_patch_fix_package_repository.diff')->maxdepth(0)->relative()->in($cipath . '/patches');
     /// @todo what if those files are gone?
     $patchfile1 = $cipath . '/patches/' . $files1[0];
     $patchfile2 = $cipath . '/patches/' . $files2[0];
     // if a new major version has been released, the '0002_2011_11_patch_fix_version.diff' patch will not apply,
     // and the '0003_2011_11_patch_fix_package_repository.diff' file will have to be altered as well
     // we need thus to regenerate them (more details: https://docs.google.com/a/ez.no/document/d/1h5n3aZdXbyo9_iJoDjoDs9a6GdFZ2G-db9ToK7J1Gck/edit?hl=en_GB)
     // 1st, we test that the current patch file will apply cleanly (if it does, we assume no new EE release)
     $patch = self::getTool('patch', $opts);
     $patcherror = false;
     try {
         $patchResult = pake_sh(self::getCdCmd($rootpath) . " && {$patch} --dry-run -p0 < " . $patchfile1);
     } catch (Exception $e) {
         $patcherror = $e->getMessage();
     }
     // then, we (try to) recover version info from existing patch files
     $patch1 = file_get_contents($patchfile1);
     $patch2 = file_get_contents($patchfile2);
     if (preg_match('/^\\- +const +VERSION_MAJOR += +(\\d+);/m', $patch1, $m1) && preg_match('/^\\- +const +VERSION_MINOR += +(\\d+);/m', $patch1, $m2) && preg_match('/^\\+RemotePackagesIndexURL=http:\\/\\/packages.ez.no\\/ezpublish\\/[^\\/]+\\/(.+)$/m', $patch2, $m3)) {
         $oldNextVersionMajor = $m1[1];
         $oldNextVersionMinor = $m2[1];
         $currentVersion = $m3[1];
         // give some information to user
         pake_echo("\nPackages available during setup wizard execution for this CP build will be the ones from eZP {$currentVersion}");
         pake_echo("The next build of eZ Publish EE is expected to be {$oldNextVersionMajor}.{$oldNextVersionMinor}\n");
         // last, we try automated fixing or abort
         if ($patcherror) {
             // try to gather enough information to fix automatically the patch files
             $currfile = file_get_contents($rootpath . '/lib/version.php');
             if (preg_match('/^\\ +const +VERSION_MAJOR += +(\\d+);/m', $currfile, $m1) && preg_match('/^\\ +const +VERSION_MINOR += +(\\d+);/m', $currfile, $m2)) {
                 $newNextVersionMajor = $m1[1];
                 $newNextVersionMinor = $m2[1];
                 if ($newNextVersionMajor == $oldNextVersionMajor && $newNextVersionMinor == $oldNextVersionMinor) {
                     // patch does not apply but version number was not changed. Abort
                     throw new pakeException("The diff file {$patchfile1} does not apply correctly, build will fail. Please fix it, commit and push.\n Also check to fix if needed the url to packages repo in 0003_2011_11_patch_fix_package_repository.diff.\nError details:\n" . $patcherror);
                 }
                 pake_echo("It seems that EE version {$oldNextVersionMajor}.{$oldNextVersionMinor} was released, next expected EE version is currently {$newNextVersionMajor}.{$newNextVersionMinor}");
                 pake_echo("This means that the diff file {$patchfile1} does not apply correctly, the build will fail.");
                 pake_echo("The script can fix this automatically, or you will have to fix patch files by hand (at least 2 of them)");
                 pake_echo("Proposed changes:");
                 pake_echo("Packages available during setup wizard execution for this CP build will be the ones from eZP {$oldNextVersionMajor}.{$oldNextVersionMinor}.0");
                 $ok = pake_input("Do you want to continue with automatic fixing? [y/n]", 'n');
                 if ($ok != 'y') {
                     throw new pakeException("Please fix patch file by hand, commit and push.\nAlso remember to fix the url to packages repo in 0003_2011_11_patch_fix_package_repository.diff");
                 } else {
                     pake_replace_regexp($files1, $cipath . '/patches', array('/^- +const +VERSION_MAJOR += +\\d+;/m' => "+    const VERSION_MAJOR = {$newNextVersionMajor};", '/^- +const +VERSION_MINOR += +\\d+;/m' => "+    const VERSION_MINOR = {$newNextVersionMinor};"));
                     pake_replace_regexp($files2, $cipath . '/patches', array('/^\\+RemotePackagesIndexURL=http:\\/\\/packages.ez.no\\/ezpublish\\/([^\\/]+)\\/.*$/m' => "+RemotePackagesIndexURL=http://packages.ez.no/ezpublish/{$oldNextVersionMajor}.{$oldNextVersionMinor}/{$oldNextVersionMajor}.{$oldNextVersionMinor}.0"));
                 }
             } else {
                 throw new pakeException("The diff file {$patchfile1} does not apply correctly, build will fail. Please fix it, commit and push.\n Also remember to fix the url to packages repo in 0003_2011_11_patch_fix_package_repository.diff.\nError details:\n" . $patcherror);
             }
         }
     } else {
         if ($patcherror) {
             throw new pakeException("The diff file {$patchfile1} does not apply correctly, build will fail. Please fix it, commit and push.\n Also remember to fix the url to packages repo in 0003_2011_11_patch_fix_package_repository.diff.\nError details:\n" . $patcherror);
         } else {
             /// @todo waht to do here? warn user and give him a chance to abort...
         }
     }
     // finally, the changes which apply every time
     pake_replace_regexp($files1, $cipath . '/patches', array('/^\\+ +const +VERSION_MAJOR += +\\d+;/m' => "+    const VERSION_MAJOR = {$opts['version']['major']};", '/^\\+ +const +VERSION_MINOR += +\\d+;/m' => "+    const VERSION_MINOR = {$opts['version']['minor']};"));
     $repo->add(array($localcipath . 'patches/0002_2011_11_patch_fix_version.diff'));
     // 3. generate changelog diff
     // get absolute path to build dir
     $absrootpath = pakeFinder::type('directory')->name(self::getProjName())->in($opts['build']['dir'] . '/source');
     $absrootpath = dirname($absrootpath[0]);
     $difffile = $absrootpath . '/' . $opts['version']['alias'] . '_patch_fix_changelog.diff';
     pake_sh(self::getCdCmd($rootpath) . " && {$git} add " . escapeshellarg($changelogdir));
     pake_sh(self::getCdCmd($rootpath) . " && {$git} diff --no-prefix --staged -- " . escapeshellarg($changelogdir) . " > " . escapeshellarg($difffile));
     /// unstage the file
     pake_sh(self::getCdCmd($rootpath) . " && {$git} reset HEAD --");
     // 4. add new changelog file
     /// calculate sequence nr.
     $max = 0;
     $files = pakeFinder::type('file')->maxdepth(0)->in($cipath . '/patches');
     foreach ($files as $file) {
         $nr = (int) substr(basename($file), 0, 4);
         if ($nr > $max) {
             $max = $nr;
         }
     }
     $seqnr = str_pad($max + 1, 4, '0', STR_PAD_LEFT);
     $newdifffile = $seqnr . '_' . str_replace('.', '_', $opts['version']['alias']) . '_patch_fix_changelog.diff';
     // what if there is already a patch file in the ci repo which creates the changelog we are adding a patch file for?
     if (preg_match_all('/^\\+\\+\\+ (.*)$/m', file_get_contents($difffile), $matches)) {
         $added = $matches[1];
         //echo "adding: "; var_dump( $added );
         $patchfiles = pakeFinder::type('file')->name('*.diff')->maxdepth(0)->in($cipath . '/patches');
         foreach ($patchfiles as $patchfile) {
             if (preg_match_all('/^\\+\\+\\+ (.*)$/m', file_get_contents($patchfile), $matches)) {
                 //echo "already added: "; var_dump( $matches[1] );
                 if (array_intersect($added, $matches[1])) {
                     $cont = pake_select_input("The patch file\n  {$patchfile}\nseems to already create the same files wew want to create using a new patch file:\n  {$newdifffile}\n" . "This is a sign of a probable error somewhere. Press '1' to continue the build task anyway. Otherwise press '2' to exit.", array('Continue', 'Stop'), 1);
                     if ($cont != 'Y') {
                         exit;
                     }
                 }
             }
         }
     }
     pake_copy($difffile, $cipath . '/patches/' . $newdifffile, array('override' => true));
     $repo->add(array($localcipath . 'patches/' . $newdifffile));
     // 5. update ezpublish-gpl.properties
     $files = pakeFinder::type('file')->name('ezpublish-gpl.properties')->maxdepth(0)->relative()->in($cipath . '/properties');
     pake_replace_regexp($files, $cipath . '/properties', array('/^ezp\\.cp\\.version\\.major += +.+$/m' => "ezp.cp.version.major = {$opts['version']['major']}", '/^ezp\\.cp\\.version\\.minor += +.+$/m' => "ezp.cp.version.minor = {$opts['version']['minor']}"));
     $repo->add(array($localcipath . 'properties/ezpublish-gpl.properties'));
     // 5. commit changes and push to upstream
     $repo->commit('Prepare files for build of CP ' . $opts['version']['alias']);
     /// @todo allow the user to specify this on the command line
     if ($originp == '') {
         pake_echo("WARNING: Using \"origin\" as name of upstream repo as actual name not found");
         $originp = "origin";
     }
     pake_sh(self::getCdCmd($cipath) . " && {$git} push {$originp} {$opts['git']['ci-repo']['branch']}:{$opts['git']['ci-repo']['branch']}");
 }