Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge feature/36-clone #80

Merged
merged 3 commits into from
Dec 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed bin/.files/cache/.gitkeep
Empty file.
13 changes: 12 additions & 1 deletion src/Joomlatools/Console/Command/Site/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ protected function configure()
null,
InputOption::VALUE_REQUIRED,
"A YAML file consisting of serialized parameters to override JConfig."
)
->addOption(
'clone',
null,
InputOption::VALUE_OPTIONAL,
'Clone the Git repository instead of creating a copy in the target directory. Use --clone=shallow for a shallow clone or leave empty.',
true
);
}

Expand Down Expand Up @@ -192,11 +199,15 @@ public function download(InputInterface $input, OutputInterface $output)
$arguments = array(
'site:download',
'site' => $this->site,
'--release' => $input->getOption('release'),
'--release' => $input->getOption('release'),
'--clear-cache' => $input->getOption('clear-cache'),
'--www' => $this->www
);

if ($input->hasParameterOption('--clone')) {
$arguments['--clone'] = $input->getOption('clone');
}

$repo = $input->getOption('repo');
if (!empty($repo)) {
$arguments['--repo'] = $repo;
Expand Down
173 changes: 121 additions & 52 deletions src/Joomlatools/Console/Command/Site/Download.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ class Download extends AbstractSite
*/
protected $output = null;

/**
* @var InputInterface
*/
protected $input = null;

protected function configure()
{
parent::configure();
Expand Down Expand Up @@ -67,12 +72,20 @@ protected function configure()
InputOption::VALUE_REQUIRED,
'Alternative Git repository to clone. Also accepts a gzipped tar archive instead of a Git repository. To use joomlatools/platform, use --repo=platform. For Kodekit Platform, use --repo=kodekit-platform.'
)
->addOption(
'clone',
null,
InputOption::VALUE_OPTIONAL,
'Clone the Git repository instead of creating a copy in the target directory. Use --clone=shallow for a shallow clone or leave empty.',
true
);
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$this->output = $output;
$this->input = $input;

parent::execute($input, $output);

Expand All @@ -98,39 +111,24 @@ protected function execute(InputInterface $input, OutputInterface $output)

$this->setVersion($input->getOption('release'));

if ($this->version != 'none')
{
$tarball = $this->_getTarball($output);

if (!$this->_isValidTarball($tarball))
{
if (file_exists($tarball)) {
unlink($tarball);
}

throw new \RuntimeException(sprintf('Downloaded tar archive "%s" could not be verified. A common cause is an interrupted download: check your internet connection and try again.', basename($tarball)));
}

if (!file_exists($this->target_dir)) {
`mkdir -p $this->target_dir`;
}

`cd $this->target_dir; tar xzf $tarball --strip 1`;
if (strtolower($this->version) == 'none') {
return;
}

if ($this->versions->isBranch($this->version)) {
unlink($tarball);
}
if ($input->hasParameterOption('--clone')) {
$this->_setupClone();
}
else $this->_setupCopy();

$isPlatform = Util::isPlatform($this->target_dir);
$isPlatform = Util::isPlatform($this->target_dir);

$directory = $this->target_dir. ($isPlatform ? '/web' : '');
if (file_exists($directory.'/htaccess.txt')) {
`cp $directory/htaccess.txt $directory/.htaccess`;
}
$directory = $this->target_dir. ($isPlatform ? '/web' : '');
if (file_exists($directory.'/htaccess.txt')) {
`cp $directory/htaccess.txt $directory/.htaccess`;
}

if ($isPlatform || Util::isKodekitPlatform($this->target_dir)) {
`cd $this->target_dir; composer --no-interaction install -q`;
}
if ($isPlatform || Util::isKodekitPlatform($this->target_dir)) {
`cd $this->target_dir; composer --no-interaction install -q`;
}
}

Expand Down Expand Up @@ -200,7 +198,40 @@ public function setVersion($version)
$this->version = $result;
}

protected function _getTarball(OutputInterface $output)
protected function _setupCopy()
{
$tarball = $this->_getTarball();

if (!$this->_isValidTarball($tarball))
{
if (file_exists($tarball)) {
unlink($tarball);
}

throw new \RuntimeException(sprintf('Downloaded tar archive "%s" could not be verified. A common cause is an interrupted download: check your internet connection and try again.', basename($tarball)));
}

if (!file_exists($this->target_dir)) {
`mkdir -p $this->target_dir`;
}

`cd $this->target_dir; tar xzf $tarball --strip 1`;

if ($this->versions->isBranch($this->version)) {
unlink($tarball);
}
}

protected function _setupClone()
{
if (!$this->versions->isGitRepository()) {
throw new \RuntimeException(sprintf('The --clone flag requires a valid Git repository'));
}

$this->_clone($this->target_dir, $this->version);
}

protected function _getTarball()
{
$tar = $this->version.'.tar.gz';
// Replace forward slashes with a dash, otherwise the path looks like it contains more subdirectories
Expand All @@ -223,7 +254,14 @@ protected function _getTarball(OutputInterface $output)
if (in_array($scheme, array('http', 'https')) && $isGitHub && $extension != '.git') {
$result = $this->_downloadFromGitHub($cache);
}
else $result = $this->_clone($cache);
else
{
$directory = $this->versions->getCacheDirectory() . '/source';

if ($this->_clone($directory)) {
$result = $this->_archive($directory, $cache);
}
}
}
else $result = $this->_download($cache);

Expand Down Expand Up @@ -274,61 +312,92 @@ protected function _download($target)
}

/**
* Clone Git repository and create tarball
* Clone Git repository to $target directory
*
* @param $target
* @param $target Target directory
* @param $tag Tag or branch to check out
* @return bool
*/
protected function _clone($target)
protected function _clone($directory, $tag = false)
{
if (substr($target, -3) == '.gz') {
$target = substr($target, 0, -3);
}

$clone = $this->versions->getCacheDirectory() . '/source';
$repository = $this->versions->getRepository();

if (!file_exists($clone))
if (!file_exists($directory))
{
$this->output->writeln("<info>Cloning $repository - this could take a few minutes ..</info>");

`git clone --recursive "$repository" "$clone"`;
$option = strtolower($this->input->getOption('clone'));
$args = $option == 'shallow' ? '--depth 1' : '';

if (is_string($tag)) {
$args .= sprintf(' --branch %s', escapeshellarg($tag));
}

$command = sprintf("git clone %s --recursive %s %s", $args, escapeshellarg($repository), escapeshellarg($directory));

exec($command, $result, $exit_code);

if ($exit_code > 0) {
return false;
}
}

if ($this->versions->isBranch($this->version))
{
$this->output->writeln("<info>Fetching latest changes from $repository - this could take a few minutes ..</info>");

`git --git-dir "$clone/.git" fetch`;
exec(sprintf("git --git-dir %s fetch", escapeshellarg("$directory/.git")), $result, $exit_code);

if ($exit_code > 0) {
return false;
}
}

return true;
}

/**
* Create tarball from cloned Git repository.
*
* @param $source Git repository
* @param $filename Output filename
* @return bool
*/
protected function _archive($source, $filename)
{
$repository = $this->versions->getRepository();

$this->output->writeln("<info>Creating $this->version archive for $repository ..</info>");

`git --git-dir "$clone/.git" archive --prefix=base/ $this->version >"$target"`;
if (substr($filename, -3) == '.gz') {
$filename = substr($filename, 0, -3);
}

`git --git-dir "$source/.git" archive --prefix=base/ $this->version >"$filename"`;

// Make sure to include submodules
if (file_exists("$clone/.gitmodules"))
if (file_exists("$source/.gitmodules"))
{
exec("cd $clone && (git submodule foreach) | while read entering path; do echo \$path; done", $output, $return_var);
exec("cd $source && (git submodule foreach) | while read entering path; do echo \$path; done", $result, $return_var);

if (is_array($output))
if (is_array($result))
{
foreach ($output as $module)
foreach ($result as $module)
{
$module = trim($module, "'");
$path = "$clone/$module";
$path = "$source/$module";

$cmd = "cd $path && git archive --prefix=base/$module/ HEAD > /tmp/$module.tar && tar --concatenate --file=\"$target\" /tmp/$module.tar";
$cmd = "cd $path && git archive --prefix=base/$module/ HEAD > /tmp/$module.tar && tar --concatenate --file=\"$filename\" /tmp/$module.tar";
exec($cmd);

@unlink("/tmp/$module.tar");
}
}
}

`gzip $target`;
`gzip $filename`;

return (bool) @filesize("$target.gz");
return (bool) @filesize("$filename.gz");
}

/**
Expand All @@ -350,7 +419,7 @@ protected function _isValidTarball($file)

foreach ($commands as $command)
{
exec($command, $output, $returnVal);
exec($command, $result, $returnVal);

if ($returnVal != 0) {
return false;
Expand Down