From 7b777c70e87b1cec508e4d74570ae710d99fc7c8 Mon Sep 17 00:00:00 2001 From: Hamish Friedlander Date: Thu, 3 Feb 2011 17:36:03 +1300 Subject: [PATCH] ENHANCEMENT: Add first version of tools for pulling in modules, now that we cant just use svn externals --- tools/lib/new-project.php | 100 ++++++++++++++++++++++++++++ tools/lib/sources.php | 119 +++++++++++++++++++++++++++++++++ tools/lib/template.php | 30 +++++++++ tools/lib/tools.php | 136 ++++++++++++++++++++++++++++++++++++++ tools/new-project | 3 + tools/new-project.bat | 2 + tools/versions.php | 3 + 7 files changed, 393 insertions(+) create mode 100644 tools/lib/new-project.php create mode 100644 tools/lib/sources.php create mode 100644 tools/lib/template.php create mode 100644 tools/lib/tools.php create mode 100755 tools/new-project create mode 100644 tools/new-project.bat create mode 100644 tools/versions.php diff --git a/tools/lib/new-project.php b/tools/lib/new-project.php new file mode 100644 index 0000000..f4ce832 --- /dev/null +++ b/tools/lib/new-project.php @@ -0,0 +1,100 @@ + $source) { + if ($mode == 'flat') $errors = array_merge($errors, (array)$source->canExport()); + elseif ($mode == 'piston') $errors = array_merge($errors, (array)$source->canPiston()); + elseif ($mode == 'contribute') $errors = array_merge($errors, (array)$source->canCheckout()); + } + + $errors = array_unique($errors); + if ($errors) { + echo "\nRequirements were not met for mode $mode:\n "; + echo implode("\n ", $errors); + echo "\n\nEither correct the requirements or try a different mode\n\n"; + $mode = null; + } +} + +if (($mode != 'piston' && $mode != 'flat' && $mode != 'contribute') || !$templatefile || isset($opts['h']) || isset($opts['help'])) { + echo "Usage: new-project [-m | --mode piston | flat | contribute] [-t | --template template.php] [-h | --help]\n"; + echo "\n"; + echo " piston is the default mode, and uses the piston tool to add the core modules\n"; + echo " It allows pulling down core module updates later while maintaining your changes.\n"; + echo " It does not provide any tools for contributing your changes back upstream, though a third-party tool for git is available\n"; + echo " It requires the external piston tool and all it's dependancies to be installed.\n"; + echo " It only works on svn and git managed repositories.\n"; + echo "\n"; + echo " flat copies the core module code without using any tools or version control\n"; + echo " It does not provide any tools for pulling down core modules updates later, or contributing changes back upstream\n"; + echo " It requires only php with the zip and curl extensions\n"; + echo " It works regardless of version control system\n"; + echo "\n"; + echo " contribute sets up the core as separate modules, allowing you to contribute any changes back upstream\n"; + echo " It allows pulling down core module updates later while maintaining your changes.\n"; + echo " It allows contributing your changes back upstream\n"; + echo " It requires git and all it's dependancies to be installed.\n"; + echo " It only works on git managed repositories.\n"; + die; +} + +// Check we're not being re-called before we do anything +$alreadyexists = false; +foreach ($template as $dest => $source) { + if (file_exists($dest)) { + echo "ERROR: Module $dest already exists. This script can not be called multiple times, or upgrade existing modules.\n"; + $alreadyexists = true; + } +} +if ($alreadyexists) die; + +if ($mode == 'piston') { + echo "Now running piston to add modules. Piston is quite noisy, and can sometimes list errors as fatal that can be ignored.\n"; + echo "If errors are shown, please check result before assuming failure\n\n"; +} + +foreach ($template as $dest => $source) { + if ($mode == 'contribute') { + GIT::ignore($dest); + $source->checkout($dest); + } + else if ($mode == 'piston') $source->piston($dest); + else $source->export($dest); +} + +if ($mode == 'piston' && GIT::isGITRepo()) { + echo "\n\nNow commit the changes with something like \"git commit -m 'Import core SilverStripe modules'\"\n"; +} + diff --git a/tools/lib/sources.php b/tools/lib/sources.php new file mode 100644 index 0000000..6ffde9d --- /dev/null +++ b/tools/lib/sources.php @@ -0,0 +1,119 @@ +data = $data; + } + + function repoURL() { + return $this->data['repo']; + } + + function export($out) { + throw new Exception('Dont know how to do this yet'); + } + + function canExport() { + return array('Cant currently use flat mode with git source repositories'); + } + + function piston($out) { + $data = $this->data; + Piston::import($this->repoURL(), $data['branch'], $out); + } + + function canPiston() { + $errors = array(); + if (!GIT::available()) $errors = "Git is not available."; + if (!Piston::available()) $errors[] = "Piston is not available."; + if (!SVN::isSVNRepo() && !GIT::isGITRepo()) $errors[] = "Piston only works on svn working copies and git repositories."; + return $errors; + } + + function checkout($out) { + $data = $this->data; + GIT::checkout($this->repoURL(), $data['branch'], $out); + } + + function canCheckout() { + $errors = array(); + if (!GIT::available()) $errors = "Git is not available."; + return $errors; + } +} + +class Github extends GitRepo { + protected $data; + + function __construct($data) { + $this->data = $data; + } + + function repoURL() { + $data = $this->data; + return "git://github.com/{$data['user']}/{$data['project']}.git"; + } + + function export($out) { + $data = $this->data; + + $tmp = tempnam(sys_get_temp_dir(), 'phpinstaller-') . '.zip'; + + HTTP::get("https://github.com/{$data['user']}/{$data['project']}/zipball/{$data['branch']}", $tmp); + Zip::import($tmp, $out, 1); + } + + function canExport() { + $errors = array(); + if (!HTTP::available()) $errors[] = "The curl module is not available"; + if (!Zip::available()) $errors[] = "The zip module is not available"; + return $errors; + } +} + +class SvnRepo { + function __construct($data) { + $this->data = $data; + } + + function repoURL() { + $data = $this->data; + return "{$data['repo']}/{$data['branch']}" . (isset($data['subdir']) ? "/{$data['subdir']}" : ''); + } + + function export($out) { + SVN::export($this->repoURL(), $out); + } + + function canExport() { + $errors = array(); + if (!SVN::available()) $errors[] = "Subversion is not available."; + return $errors; + } + + function piston($out) { + Piston::import($this->repoURL(), null, $out); + } + + function canPiston() { + $errors = array(); + if (!SVN::available()) $errors[] = "Subversion is not available."; + if (!Piston::available()) $errors[] = "Piston is not available."; + if (!SVN::isSVNRepo() && !GIT::isGITRepo()) $errors[] = "Piston only works on svn working copies and git repositories."; + return $errors; + } + + function checkout($out) { + SVN::checkout($this->repoURL(), $out); + } + + function canCheckout() { + $errors = array(); + if (!SVN::available()) $errors[] = "Subversion is not available."; + return $errors; + } +} \ No newline at end of file diff --git a/tools/lib/template.php b/tools/lib/template.php new file mode 100644 index 0000000..9627483 --- /dev/null +++ b/tools/lib/template.php @@ -0,0 +1,30 @@ + new Github(array( + 'user' => 'silverstripe', + 'project' => 'sapphire', + 'branch' => SAPPHIRE_CURRENT_BRANCH + )), + 'cms' => new Github(array( + 'user' => 'silverstripe', + 'project' => 'silverstripe-cms', + 'branch' => SAPPHIRE_CURRENT_BRANCH + )), + 'themes/blackcandy' => new SvnRepo(array( + 'repo' => 'http://svn.silverstripe.com/open/themes/blackcandy', + 'branch' => 'trunk', + 'subdir' => 'blackcandy' + )), + 'themes/blackcandy_blog' => new SvnRepo(array( + 'repo' => 'http://svn.silverstripe.com/open/themes/blackcandy', + 'branch' => 'trunk', + 'subdir' => 'blackcandy_blog' + )) +); + diff --git a/tools/lib/tools.php b/tools/lib/tools.php new file mode 100644 index 0000000..14e3c3f --- /dev/null +++ b/tools/lib/tools.php @@ -0,0 +1,136 @@ +open($src); + if ($res === TRUE) { + + if ($skipdirs) { + $tmpdir = tempnam(sys_get_temp_dir(), 'phpinstaller-') . '.ext'; + mkdir($tmpdir, 0700); + + mkdir($dest); + + $zip->extractTo($tmpdir); + + for($i = 0; $i < $zip->numFiles; $i++){ + $name = $srcname = $zip->getNameIndex($i); + $parts = array(); + + while ($name && $name != '.' && $name != '/') { + array_unshift($parts, basename($name)); + $name = dirname($name); + } + + // We only need to move the very next level after the skipdirs level + if (count($parts) != $skipdirs+1) continue; + + $dstname = $parts[$skipdirs]; + rename($tmpdir.'/'.$srcname, $dest.'/'.$dstname); + } + } + else { + $zip->extractTo($dest); + } + + $zip->close(); + } else { + throw new Exception('Could not extract zip at '.$src.' to '.$dest); + } + } +} + diff --git a/tools/new-project b/tools/new-project new file mode 100755 index 0000000..99f8cd2 --- /dev/null +++ b/tools/new-project @@ -0,0 +1,3 @@ +#!/bin/bash +base=`dirname $0` +php $base/lib/new-project.php "$@" \ No newline at end of file diff --git a/tools/new-project.bat b/tools/new-project.bat new file mode 100644 index 0000000..b705a18 --- /dev/null +++ b/tools/new-project.bat @@ -0,0 +1,2 @@ +@echo off +php %~dp0\lib\new-project.php %* \ No newline at end of file diff --git a/tools/versions.php b/tools/versions.php new file mode 100644 index 0000000..e49319c --- /dev/null +++ b/tools/versions.php @@ -0,0 +1,3 @@ +