Example #1
0
 /**
  * Converts a property file into a yaml file
  * @param array $transform an array of transformation rules such as eg. 'sourcetag' => 'desttag' (desttag can be empty for tag removal or an array for tag expansion)
  * @todo move to a separate class to slim down base class?
  * @todo make it capable to remove complete $ext.version.alias property
  */
 static function convertPropertyFileToYamlFile($infile, $outfile = '', $transform = array(), $prepend = '')
 {
     if ($outfile == '') {
         $outfile = self::getOptionsDir() . '/options.yaml';
     }
     $current = array();
     $out = array();
     foreach (file($infile) as $line) {
         $line = trim($line);
         if ($line == '') {
             $out[] = '';
         } else {
             if (strpos($line, '<!--') === 0) {
                 $out[] .= preg_replace('/^<!-- *(.*) *-->$/', '# $1', $line);
             } else {
                 if (strpos($line, '=') != 0) {
                     $line = explode('=', $line, 2);
                     $path = explode('.', trim($line[0]));
                     foreach ($transform as $src => $dst) {
                         foreach ($path as $i => $element) {
                             if ($element == $src) {
                                 if ($dst == '') {
                                     unset($path[$i]);
                                 } else {
                                     if (is_array($dst)) {
                                         array_splice($path, $i - 1, 1, $dst);
                                     } else {
                                         $path[$i] = $dst;
                                     }
                                 }
                             }
                         }
                     }
                     // elements index can have holes here, cannot trust them => reorder
                     $path = array_values($path);
                     $value = $line[1];
                     $token = array_pop($path);
                     if ($path != $current) {
                         $skip = 0;
                         foreach ($path as $j => $element) {
                             if ($element == @$current[$j]) {
                                 $skip++;
                             } else {
                                 break;
                             }
                         }
                         for ($j = $skip; $j < count($path); $j++) {
                             $line = '';
                             for ($i = 0; $i < $j; $i++) {
                                 $line .= '    ';
                             }
                             $line .= $path[$j] . ':';
                             $out[] = $line;
                         }
                     }
                     $line = '';
                     for ($i = 0; $i < count($path); $i++) {
                         $line .= '    ';
                     }
                     $line .= $token . ': ' . $value;
                     $out[] = $line;
                     $current = $path;
                 } else {
                     /// @todo log warning?
                 }
             }
         }
     }
     pake_mkdirs('pake');
     // ask confirmation if file exists
     $ok = !file_exists($outfile) || pake_input("Destionation file {$outfile} exists. Overwrite? [y/n]", 'n') == 'y';
     if ($ok) {
         file_put_contents($outfile, $prepend . implode($out, "\n"));
         pake_echo_action('file+', $outfile);
     }
 }
Example #2
0
/**
 * Demo-task
 *
 * @param string $task
 * @param string $args
 * @return bool
 * @author Alexey Zakhlestin
 */
function run_foo($task, $args)
{
    $age = pake_input('How old are you?');
    pake_echo_comment("You are " . $age);
    // throw new Exception('test');
}
 /**
  * Converts an existing ant properties file in its corresponding yaml version
  *
  * Converts the .properties files used to hold configuration settings for old
  * versions of ezextensionbuilder (the ones based on ant) to a .yaml configuration
  * file that is suitable for this version of the script.
  * It is recommended to inspect by hand the generated .yaml file after executing
  * the conversion.
  */
 static function run_convert_configuration($task = null, $args = array(), $cliopts = array())
 {
     self::setConfigDir($cliopts);
     $extname = @$args[0];
     if ($extname == '') {
         $extname = dirname(__FILE__);
     }
     while (!is_file("ant/{$extname}.properties")) {
         $extname = pake_input('What is the name of the current extension?');
         if (!is_file("ant/{$extname}.properties")) {
             pake_echo("File ant/{$extname}.properties not found");
         }
     }
     self::convertPropertyFileToYamlFile("ant/{$extname}.properties", self::getConfigDir() . "/options-{$extname}.yaml", array($extname => '', 'external' => 'dependencies', 'dependency' => 'extensions', 'repository' => array('svn', 'url')), "extension:\n    name: {$extname}\n\n");
     foreach (array('files.to.parse.txt' => 'to_parse', 'files.to.exclude.txt' => 'to_exclude') as $file => $option) {
         $src = "ant/{$file}";
         if (file_exists($src)) {
             //$ok = !file_exists( $dst ) || ( pake_input( "Destionation file $dst exists. Overwrite? [y/n]", 'n' ) == 'y' );
             //$ok && pake_copy( $src, $dst, array( 'override' => true ) );
             if (count($in = file($src, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES))) {
                 $in = "\n\nfiles:\n    {$option}: [" . implode(', ', $in) . "]\n";
                 file_put_contents(self::getConfigDir() . "options-{$extname}.yaml", $in, FILE_APPEND);
             }
         }
     }
 }
Example #4
0
 /**
  * Creates a tarball of the built extension.
  *
  * Depending on configuration options, different versions of the extenion tarball
  * are generated by this task: .tar.gz, .zip, .ezpkg
  */
 static function run_dist($task = null, $args = array(), $cliopts = array())
 {
     $opts = self::getOpts(@$args[0], @$args[1], $cliopts);
     if ($opts['create']['tarball'] || $opts['create']['zip'] || $opts['create']['ezpackage'] || $opts['create']['pearpackage']) {
         if (!SharedLock::acquire($opts['extension']['name'], LOCK_SH, $opts)) {
             throw new PakeException("Source code locked by another process");
         }
         pake_mkdirs($opts['dist']['dir']);
         $rootpath = self::getBuildDir($opts) . '/' . $opts['extension']['name'];
         if ($opts['create']['tarball']) {
             $target = $opts['dist']['dir'] . '/' . $opts['extension']['name'] . '-' . $opts['version']['alias'] . '.' . $opts['version']['release'] . '.tar.gz';
             self::archiveDir($rootpath, $target);
         }
         if ($opts['create']['zip']) {
             $target = $opts['dist']['dir'] . '/' . $opts['extension']['name'] . '-' . $opts['version']['alias'] . '.' . $opts['version']['release'] . '.zip';
             self::archiveDir($rootpath, $target);
         }
         if ($opts['create']['ezpackage'] || $opts['create']['pearpackage']) {
             $toppath = $opts['build']['dir'];
             // check if package.xml file is there
             $file = pakeFinder::type('file')->name('package.xml')->maxdepth(0)->in($toppath);
             if (!count($file)) {
                 pake_echo_error("File 'package.xml' missing in build dir {$rootpath}. Cannot create package(s)");
                 return;
             }
             // cleanup if extra files/dirs found
             $dirs = array();
             $dirs = pakeFinder::type('directory')->not_name(array('documents', 'ezextension'))->maxdepth(0)->in($toppath);
             $dirs = array_merge($dirs, pakeFinder::type('directory')->in($toppath . '/documents'));
             $dirs = array_merge($dirs, pakeFinder::type('directory')->not_name($opts['extension']['name'])->maxdepth(0)->in($toppath . '/ezextension'));
             $files = pakeFinder::type('file')->not_name('package.xml')->maxdepth(0)->in($toppath);
             $files = array_merge($files, pakeFinder::type('file')->in($toppath . '/documents'));
             $files = array_merge($files, pakeFinder::type('file')->not_name('extension-' . $opts['extension']['name'] . '.xml')->maxdepth(0)->in($toppath . '/ezextension'));
             if (count($dirs) || count($files)) {
                 pake_echo("Extra files/dirs found in build dir. Must remove them to continue:\n  " . implode("\n  ", $dirs) . "  " . implode("\n  ", $files));
                 $ok = pake_input("Do you want to delete them? [y/n]", 'n');
                 if ($ok != 'y') {
                     return;
                 }
                 foreach ($files as $file) {
                     pake_remove($file, '');
                 }
                 foreach ($dirs as $dir) {
                     pake_remove_dir($dir);
                 }
             }
             // prepare missing folders/files
             /// @todo we should not blindly copy LICENSE and README, but inspect actual package.xml file
             ///       and copy any files mentioned there
             pake_copy($rootpath . '/' . $opts['files']['gnu_dir'] . '/LICENSE', $toppath . '/documents/LICENSE');
             pake_copy($rootpath . '/' . $opts['files']['gnu_dir'] . '/README', $toppath . '/documents/README');
             $target = $opts['dist']['dir'] . '/' . $opts['extension']['name'] . '_extension.ezpkg';
             self::archiveDir($toppath, $target, true);
             if ($opts['create']['pearpackage']) {
                 /// @todo ...
                 pake_echo_error("PEAR package creation not yet implemented");
             }
         }
         SharedLock::release($opts['extension']['name'], LOCK_SH, $opts);
     }
 }
Example #5
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']}");
 }