Skip to content

Commit

Permalink
API Add cow;archive command
Browse files Browse the repository at this point in the history
API Failed calls to Step::runCommand now trigger exceptions
  • Loading branch information
Damian Mooyman committed Oct 2, 2015
1 parent d1ba595 commit 4f0789b
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ protected function getDefaultCommands()
$commands[] = new Commands\Release\Changelog();
$commands[] = new Commands\Release\Tag();
$commands[] = new Commands\Release\Push();
$commands[] = new Commands\Release\Archive();
$commands[] = new Commands\Release\Upload();

// Base release commands
Expand Down
31 changes: 31 additions & 0 deletions src/Commands/Release/Archive.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace SilverStripe\Cow\Commands\Release;

use SilverStripe\Cow\Steps\Release\BuildArchive;

/**
* Create archives
*
* @author dmooyman
*/
class Archive extends Release {

/**
*
* @var string
*/
protected $name = 'release:archive';

protected $description = 'Create archives for the release in tar.gz and zip formats';

protected function fire() {
// Get arguments
$version = $this->getInputVersion();
$directory = $this->getInputDirectory($version);

// Steps
$step = new BuildArchive($this, $version, $directory);
$step->run($this->input, $this->output);
}
}
5 changes: 3 additions & 2 deletions src/Commands/Release/Publish.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace SilverStripe\Cow\Commands\Release;

use SilverStripe\Cow\Steps\Release\BuildArchive;
use SilverStripe\Cow\Steps\Release\PushRelease;
use SilverStripe\Cow\Steps\Release\TagModules;
use SilverStripe\Cow\Steps\Release\UploadArchive;
Expand Down Expand Up @@ -37,13 +38,13 @@ protected function fire() {
$tag = new TagModules($this, $version, $directory, $modules);
$tag->run($this->input, $this->output);


// Push tag & branch
$push = new PushRelease($this, $directory, $modules);
$push->run($this->input, $this->output);

// Create packages
// @todo
$package = new BuildArchive($this, $version, $directory);
$package->run($this->input, $this->output);

// Upload
$upload = new UploadArchive($this, $version, $directory, $awsProfile);
Expand Down
235 changes: 235 additions & 0 deletions src/Steps/Release/BuildArchive.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
<?php

namespace SilverStripe\Cow\Steps\Release;

use SilverStripe\Cow\Commands\Command;
use SilverStripe\Cow\Model\Project;
use SilverStripe\Cow\Model\ReleaseVersion;
use SilverStripe\Cow\Steps\Step;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Generate a new archive file for cms, framework in tar.gz and zip formats
*
* @author dmooyman
*/
class BuildArchive extends Step {

/**
* @var ReleaseVersion
*/
protected $version;

/**
* @var Project
*/
protected $project;

/**
* Build archives
*
* @param Command $command
* @param ReleaseVersion $version
* @param string $directory Where to translate
* @param string $awsProfile Name of aws profile to use
*/
public function __construct(Command $command, ReleaseVersion $version, $directory = '.') {
parent::__construct($command);

$this->version = $version;
$this->project = new Project($directory);
}

/**
* @return Project
*/
public function getProject() {
return $this->project;
}

/**
* @return ReleaseVersion
*/
public function getVersion() {
return $this->version;
}

public function getStepName() {
return 'archive';
}

public function run(InputInterface $input, OutputInterface $output) {
$this->log($output, "Generating new archive files");
$path = $this->createProject($output);
$this->buildFiles($output, $path);
$this->log($output, 'Upload complete');
}

/**
* Remove a directory and all subdirectories and files.
*
* @param string $folder Absolute folder path
*/
protected function unlink($folder) {
if(!file_exists($folder)) {
return;
}

// remove a file encountered by a recursive call.
if(is_file($folder) || is_link($folder)) {
unlink($folder);
return;
}

// Remove folder
$dir = opendir($folder);
while($file = readdir($dir)) {
if($file == '.' || $file == '..') {
continue;
}
$this->unlink($folder . '/' . $file);
}
closedir($dir);
rmdir($folder);
}

/**
* Copy file
*
* @param string $from
* @param string $to
* @throws \Exception
*/
protected function copy($from, $to) {
$this->unlink($to);

// Copy file if not a folder
if(!is_dir($from)) {
if(copy($from, $to) === false) {
throw new \Exception("Could not copy from {$from} to {$to}");
}
return;
}

// Create destination
if(mkdir($to) === false) {
throw new \Exception("Could not create destination folder {$to}");
}

// Iterate files
$dir = opendir($from);
while(false !== ( $file = readdir($dir)) ) {
if ($file == '.' || $file === '..' ) {
continue;
}
$this->copy("{$from}/{$file}", "{$to}/{$file}");
}
closedir($dir);
}

/**
* Write content to file
*
* @param string $path
* @param string $content
* @throws \Exception
*/
protected function write($path, $content) {
$result = file_put_contents($path, $content);
if($result === false) {
throw new \Exception("Could not write to {$path}");
}
}

/**
* Build a project of the given version in a temporary folder, and return the path to this
*
* @param OutputInterface $output
* @return string Path to temporary project
*/
protected function createProject(OutputInterface $output) {
// Get files
$version = $this->getVersion()->getValue();
$cmsArchive = "SilverStripe-cms-v{$version}";
$frameworkArchive = "SilverStripe-framework-v{$version}";

// Check path exists and is empty
$path = sys_get_temp_dir() . '/archiveTask';
$this->log($output, "Creating temporary project at {$path}");
$this->unlink($path);
mkdir($path);

// Copy composer.phar
$this->log($output, "Getting composer.phar");
$this->copy('http://getcomposer.org/composer.phar', "{$path}/composer.phar");

// Install to this location
$version = $this->version->getValue();
$this->log($output, "Installing version {$version}");
$pathArg = escapeshellarg($path);
$this->runCommand(
$output,
"cd {$pathArg} && php composer.phar create-project silverstripe/installer ./{$cmsArchive} {$version} --prefer-dist --no-dev",
"Could not install version {$version} from composer"
);

// Copy composer.phar to the project
// Write version info to the core folders (shouldn't be in version control)
$this->log($output, "Copying additional files");
$this->copy("{$path}/composer.phar", "{$path}/{$cmsArchive}/composer.phar");
$this->write("{$path}/{$cmsArchive}/framework/silverstripe_version", $version);
$this->write("{$path}/{$cmsArchive}/cms/silverstripe_version", $version);

// Copy to framework folder
$this->log($output, "Create framework-only project");
$this->copy("{$path}/{$cmsArchive}/", "{$path}/{$frameworkArchive}/");
$pathArg = escapeshellarg("{$path}/{$frameworkArchive}");
$this->runCommand(
$output,
"cd {$pathArg} && php composer.phar remove silverstripe/cms silverstripe/siteconfig silverstripe/reports --update-no-dev",
"Could not generate framework only version"
);

// Remove development files not needed in the archive package
$this->log($output, "Remove development files");
foreach(array("{$path}/{$cmsArchive}", "{$path}/{$frameworkArchive}") as $archivePath) {
$this->unlink("{$archivePath}/cms/tests/");
$this->unlink("{$archivePath}/framework/tests/");
$this->unlink("{$archivePath}/framework/admin/tests/");
$this->unlink("{$archivePath}/reports/tests/");
$this->unlink("{$archivePath}/siteconfig/tests/");
$this->unlink("{$archivePath}/framework/docs/");
}

// Remove Page.php from framework-only module
$this->unlink("{$path}/{$frameworkArchive}/mysite/code/Page.php");

// Done
return $path;
}

/**
* Generate archives in each of the specified types from the temporary folder
*
* @param OutputInterface $output
* @param string $path Location of project to archive
*/
protected function buildFiles(OutputInterface $output, $path) {
/*
$version = $this->getVersion()->getValue();
$cmsArchive = "SilverStripe-cms-v{$version}";
$frameworkArchive = "SilverStripe-framework-v{$version}";
$destination = $this->getProject()->getDirectory();
// Build tar files
$phar = new PharData($destination . '/' . $cmsArchive);
foreach($this->getVersion()->getReleaseFilenames() as $filename) {
// Build paths
$this->log($output, "Uploading <info>{$filename}</info>");
$from = $this->getProject()->getDirectory() . '/' . $filename;
}*/
}
}
10 changes: 4 additions & 6 deletions src/Steps/Release/CreateProject.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,15 @@ public function run(InputInterface $input, OutputInterface $output) {
* @return array
*/
protected function getAvailableVersions(OutputInterface $output) {
$output = $this->runCommand($output, array("composer", "show", $this->package));
$error = "Could not parse available versions from command \"composer show {$this->package}\"";
$output = $this->runCommand($output, array("composer", "show", $this->package), $error);

// Parse output
if($output && preg_match('/^versions\s*:\s*(?<versions>(\S.+\S))\s*$/m', $output, $matches)) {
return preg_split('/\s*,\s*/', $matches['versions']);
}

throw new Exception("Could not parse available versions from command \"composer show {$this->package}\"");
throw new Exception($error);
}

/**
Expand All @@ -90,10 +91,7 @@ protected function installVersion(OutputInterface $output, $version) {
$command = array(
"composer", "create-project", "--prefer-source", "--keep-vcs", $this->package, $this->directory, $version
);
$result = $this->runCommand($output, $command);
if($result === false) {
throw new Exception("Could not create project with version {$version}");
}
$this->runCommand($output, $command, "Could not create project with version {$version}");
}

/**
Expand Down
5 changes: 1 addition & 4 deletions src/Steps/Release/RunTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ public function getStepName() {
public function run(InputInterface $input, OutputInterface $output) {
$directory = $this->project->getDirectory();
$this->log($output, "Running unit tests in <info>{$directory}</info>");
$result = $this->runCommand($output, "cd $directory && vendor/bin/phpunit");
if($result === false) {
throw new Exception("Tests failed!");
}
$this->runCommand($output, "cd $directory && vendor/bin/phpunit", "Tests failed!");
}
}
13 changes: 5 additions & 8 deletions src/Steps/Release/UpdateTranslations.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,10 @@ public function run(InputInterface $input, OutputInterface $output) {
* @throws InvalidArgumentException
*/
protected function checkVersion(OutputInterface $output) {
$result = $this->runCommand($output, array("tx", "--version"));
$error = "translate requires transifex {$this->txVersion} at least. Run 'pip install transifex-client==0.11b3' to update.";
$result = $this->runCommand($output, array("tx", "--version"), $error);
if(!version_compare($result, $this->txVersion, '<')) {
throw new InvalidArgumentException(
"translate requires transifex {$this->txVersion} at least. "
."Run 'pip install transifex-client==0.11b3' to update. "
."Current version: ".$result
);
throw new InvalidArgumentException($error ." Current version: ".$result);
}

$this->log($output, "Using transifex CLI version: $result");
Expand Down Expand Up @@ -144,7 +141,7 @@ protected function collectStrings(OutputInterface $output, $modules) {
$this->getProject()->getDirectory(),
implode(',', $dirs)
);
$this->runCommand($output, $sakeCommand);
$this->runCommand($output, $sakeCommand, "Error encountered running i18nTextCollectorTask");
}

/**
Expand Down Expand Up @@ -235,7 +232,7 @@ public function pushSource(OutputInterface $output, $modules) {
'(cd %s && tx push -s)',
$module->getDirectory()
);
$this->runCommand($output, $pushCommand);
$this->runCommand($output, $pushCommand, "Error pushing module {$module} to origin");
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/Steps/Release/UploadArchive.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ public function run(InputInterface $input, OutputInterface $output) {
// Run this
$this->runCommand(
$output,
array("aws", "s3", "cp", $from, $to, "--acl", "public-read", "--profile", $awsProfile)
array("aws", "s3", "cp", $from, $to, "--acl", "public-read", "--profile", $awsProfile),
"Error copying release {$filename} to s3"
);
}
$this->log($output, 'Upload complete');
Expand Down
Loading

0 comments on commit 4f0789b

Please sign in to comment.