diff --git a/README.md b/README.md index 7ca12bf..157d588 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,9 @@ The `extra.downloads` section contains a list of files to download. Each extra-f * `archive`: The `url` references a zip or tarball which should be extracted at the given `path`. (Default for URLs involving `*.zip`, `*.tar.gz`, or `*.tgz`.) * `file`: The `url` should be downloaded to the given `path`. (Default for all other URLs.) * `phar`: The `url` references a PHP executable which should be installed at the given `path`. + * `git`: The `url` references a git repository address and commit, tag or branch (separated by an @ sign) which should be checked out at the given `path`. (E.g. `https://git.me.org/foo/bar@123abc`.) -* `ignore`: (*Optional*) A list of a files that should be omited from the extracted folder. (This supports a subset of `.gitignore` notation.) +* `ignore`: (*Optional*) A list of a files that should be omited from the extracted folder. (This supports a subset of `.gitignore` notation.) The `ignore` property is ignored when using the `git` type. * `version`: (*Optional*) A version number for the downloaded artifact. This has no functional impact on the lifecycle of the artifact, but it can affect the console output, and it can be optionally used as a variable when setting `url` or `path`. diff --git a/src/DownloadsParser.php b/src/DownloadsParser.php index 614882e..12ad738 100644 --- a/src/DownloadsParser.php +++ b/src/DownloadsParser.php @@ -16,6 +16,7 @@ use LastCall\DownloadsPlugin\Handler\BaseHandler; use LastCall\DownloadsPlugin\Handler\FileHandler; use LastCall\DownloadsPlugin\Handler\PharHandler; +use LastCall\DownloadsPlugin\Handler\GitHandler; class DownloadsParser { @@ -62,6 +63,7 @@ public function pickClass($extraFile) 'archive' => ArchiveHandler::CLASS, 'file' => FileHandler::CLASS, 'phar' => PharHandler::CLASS, + 'git' => GitHandler::CLASS, ]; if (isset($extraFile['type'], $types[$extraFile['type']])) { return $types[$extraFile['type']]; diff --git a/src/Handler/GitHandler.php b/src/Handler/GitHandler.php new file mode 100644 index 0000000..af502a0 --- /dev/null +++ b/src/Handler/GitHandler.php @@ -0,0 +1,66 @@ +setDistType('git'); + return $pkg; + } + + public function getTrackingFile() + { + $file = basename($this->extraFile['id']) . '-' . md5($this->extraFile['id']) . '.json'; + return + dirname($this->getTargetPath()) . + DIRECTORY_SEPARATOR . self::DOT_DIR . + DIRECTORY_SEPARATOR . $file; + } + + /** + * @param Composer $composer + * @param IOInterface $io + */ + public function download(Composer $composer, IOInterface $io) { + $urlAndVersion = $this->getSubpackage()->getDistUrl(); + $config = $composer->getConfig(); + $wd = $this->getTargetPath(); + $process = new ProcessExecutor($io); + $cfs = new Filesystem(); + $git = new Git($io, $config, $process, $cfs); + if (file_exists($wd)) { + $cfs->removeDirectory($wd); + } + // Make the directory recursively. + $cfs->ensureDirectoryExists($wd); + $gitCallable = static function ($urlAndVersion): string { + $parts = explode('@', $urlAndVersion); + $url = $parts[0]; + if (count($parts) > 1) { + $version = $parts[1]; + } + else { + $version = 'master'; + } + return sprintf('git init && git fetch %s "+refs/heads/*:refs/remotes/origin/*" && git checkout %s', + ProcessExecutor::escape($url), + ProcessExecutor::escape($version) + ); + }; + $git->runCommand($gitCallable, $urlAndVersion, $wd); + } + +} diff --git a/tests/SniffTest.php b/tests/SniffTest.php index f78c7f2..d123ba0 100644 --- a/tests/SniffTest.php +++ b/tests/SniffTest.php @@ -45,6 +45,11 @@ public static function getComposerJson() { 'url' => 'https://download.civicrm.org/cv/cv.phar-2019-08-20-14fe9da8', 'path' => 'bin/cv', ], + 'org.civicrm.sms.twilio' => [ + 'type' => 'git', + 'url' => 'https://github.com/civicrm/org.civicrm.sms.twilio@494728cf13bb65c228429665c158d899cd7e6dc1', + 'path' => 'web/sites/default/files/civicrm/ext/org.civicrm.sms.twilio', + ], ], ], 'config' => [ @@ -69,7 +74,8 @@ public function getExampleChecksums() { ['extern/jquery-full', 'extern/jquery-full/Gruntfile.js', '3508ff74f8ef106a80f25f28f44a20c47a2b67d84396bb141928ff978ba4012e'], ['extern/jquery-lesser', 'extern/jquery-lesser/dist/jquery.js', '5f2caf09052782caf67e1772c0abce31747ffbc7a1c50690e331b99c7d9ea8dc'], ['extern/jquery-lesser', 'extern/jquery-lesser/Gruntfile.js', NULL], - ['bin/cv', 'bin/cv', 'bf162d5d7dd0bef087d7dd07f474039b2e25c4bcca328a2b2097958ac6294476'] + ['bin/cv', 'bin/cv', 'bf162d5d7dd0bef087d7dd07f474039b2e25c4bcca328a2b2097958ac6294476'], + ['web/sites/default/files/civicrm/ext/org.civicrm.sms.twilio', 'web/sites/default/files/civicrm/ext/org.civicrm.sms.twilio/info.xml', 'fce6bbd3af2315b4357393b3fc76b52ebc6ab3c27290c82ce7545f0bf2928109'], ]; } @@ -92,7 +98,7 @@ public function testDownloadAndRedownload($path, $file, $sha256) { else { unlink($path); } - $this->assertFileNotExists($file); + $this->assertFileDoesNotExist($file); $composer_path = self::getComposerPath(); PH::runOk("$composer_path install -v"); @@ -102,7 +108,7 @@ public function testDownloadAndRedownload($path, $file, $sha256) { public function assertFileChecksum($file, $sha256, $message = NULL) { if ($sha256 === NULL) { - $this->assertFileNotExists($file, "($message) File should not exist"); + $this->assertFileDoesNotExist($file, "($message) File should not exist"); } else { $this->assertFileExists($file, "($message) File should exist");