Skip to content
Snippets Groups Projects
Commit 8edd74c2 authored by Jared Hancock's avatar Jared Hancock
Browse files

deploy: Use `git ls-files` for deployment source

As an option, this will allow preventing deployment of files not tracked
with git. It's also about twice as fast as the PHP version.
parent c12f06ae
No related branches found
No related tags found
No related merge requests found
...@@ -24,6 +24,10 @@ class Deployment extends Unpacker { ...@@ -24,6 +24,10 @@ class Deployment extends Unpacker {
'action'=>'store_true', 'action'=>'store_true',
'help'=>'Remove files from the destination that are no longer 'help'=>'Remove files from the destination that are no longer
included in this repository'); included in this repository');
$this->options['git'] = array('-g','--git',
'action'=>'store_true',
'help'=>'Use `git ls-files -s` as files source. Eliminates
possibility of deploying untracked files');
# super(*args); # super(*args);
call_user_func_array(array('parent', '__construct'), func_get_args()); call_user_func_array(array('parent', '__construct'), func_get_args());
} }
...@@ -142,36 +146,41 @@ class Deployment extends Unpacker { ...@@ -142,36 +146,41 @@ class Deployment extends Unpacker {
return $source; return $source;
} }
function copyFile($source, $dest, $hash=false) { function copyFile($source, $dest, $hash=false, $mode=0644) {
$contents = $this->getEditedContents($source); $contents = $this->getEditedContents($source);
if ($contents === false) if ($contents === false)
// Regular file // Regular file
return parent::copyFile($source, $dest, $hash); return parent::copyFile($source, $dest, $hash, $mode);
if (!file_put_contents($dest, $contents)) if (!file_put_contents($dest, $contents))
$this->fail($dest.": Unable to apply rewrite rules"); $this->fail($dest.": Unable to apply rewrite rules");
return true; $this->updateManifest($source, $hash);
return chmod($dest, $mode);
} }
function unpackage($folder, $destination, $recurse=0, $exclude=false) { function unpackage($folder, $destination, $recurse=0, $exclude=false) {
return parent::unpackage($folder, $destination, $recurse, $exclude); $use_git = $this->getOption('git', false);
if (!$use_git)
return parent::unpackage($folder, $destination, $recurse, $exclude);
// TODO: Consider using `git ls-files` for deployment // Attempt to read from git using `git ls-files` for deployment
if (substr($destination, -1) !== '/') if (substr($destination, -1) !== '/')
$destination .= '/'; $destination .= '/';
$source = $this->source; $source = $this->source;
if (substr($source, -1) != '/') if (substr($source, -1) != '/')
$source .= '/'; $source .= '/';
$local = str_replace(array($source, '{,.}*'), array('',''), $folder);
$pipes = array(); $pipes = array();
$patterns = array(); $patterns = array();
foreach ((array) $exclude as $x) { foreach ((array) $exclude as $x) {
$patterns[] = str_replace($source, '', $x); $patterns[] = str_replace($source, '', $x);
} }
$exclude = implode(' --exclude-per-directory=', $patterns); $X = implode(' --exclude-per-directory=', $patterns);
chdir($source.$local);
if (!($files = proc_open( if (!($files = proc_open(
"git ls-files -s --exclude-standard --exclude-per-directory=$exclude $folder", "git ls-files -s --full-name --exclude-standard --exclude-per-directory=$X -- .",
array(1 => array('pipe', 'w')), array(1 => array('pipe', 'w')),
$pipes $pipes
))) { ))) {
...@@ -183,17 +192,18 @@ class Deployment extends Unpacker { ...@@ -183,17 +192,18 @@ class Deployment extends Unpacker {
while ($line = stream_get_line($pipes[1], 255, PHP_EOL)) { while ($line = stream_get_line($pipes[1], 255, PHP_EOL)) {
list($mode, $hash, , $path) = preg_split('/\s+/', $line); list($mode, $hash, , $path) = preg_split('/\s+/', $line);
$src = $source.$path; $src = $source.$path;
$dst = $destination.$path; if ($this->exclude($exclude, $src))
if (!$this->isChanged($src, false, $hash))
continue; continue;
if (!$this->isChanged($src, $hash))
continue;
$dst = $destination.$path;
if ($verbose) if ($verbose)
$this->stdout->write($dst."\n"); $this->stdout->write($dst."\n");
if ($dryrun) if ($dryrun)
continue; continue;
if (!is_dir(dirname($dst))) if (!is_dir(dirname($dst)))
mkdir(dirname($dst), 0751, true); mkdir(dirname($dst), 0751, true);
// TODO: Consider the MODE value $this->copyFile($src, $dst, $hash, octdec($mode));
$this->copyFile($src, $dst, $hash);
} }
} }
...@@ -222,10 +232,10 @@ class Deployment extends Unpacker { ...@@ -222,10 +232,10 @@ class Deployment extends Unpacker {
# Prime the manifest system # Prime the manifest system
$this->readManifest($this->destination.'/.MANIFEST'); $this->readManifest($this->destination.'/.MANIFEST');
$exclusions = array("$rootPattern/include", "$rootPattern/.git*", $exclusions = array("$rootPattern/include/*", "$rootPattern/.git*",
"*.sw[a-z]","*.md", "*.txt"); "*.sw[a-z]","*.md", "*.txt");
if (!$options['setup']) if (!$options['setup'])
$exclusions[] = "$rootPattern/setup"; $exclusions[] = "$rootPattern/setup/*";
# Unpack everything but the include/ folder # Unpack everything but the include/ folder
$this->unpackage("$root/{,.}*", $this->destination, -1, $this->unpackage("$root/{,.}*", $this->destination, -1,
......
...@@ -135,9 +135,9 @@ class Unpacker extends Module { ...@@ -135,9 +135,9 @@ class Unpacker extends Module {
$this->manifest[$local] = $hash; $this->manifest[$local] = $hash;
} }
function copyFile($src, $dest, $hash=false) { function copyFile($src, $dest, $hash=false, $mode=0644) {
$this->updateManifest($src, $hash); $this->updateManifest($src, $hash);
return copy($src, $dest); return copy($src, $dest) && chmod($dest, $mode);
} }
/** /**
...@@ -174,7 +174,7 @@ class Unpacker extends Module { ...@@ -174,7 +174,7 @@ class Unpacker extends Module {
continue; continue;
if (!is_dir($destination)) if (!is_dir($destination))
mkdir($destination, 0751, true); mkdir($destination, 0751, true);
$this->copyFile($file, $target); $this->copyFile($file, $target, $hash);
} }
} }
if ($recurse) { if ($recurse) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment