From 72a66ad9d2a3a8407052f4f9c1ed2eba6779f104 Mon Sep 17 00:00:00 2001 From: kthbit Date: Sat, 12 Aug 2017 08:39:35 -0500 Subject: [PATCH 1/3] Do not assume we are on Linux and have head, tail, and awk commands available. Instead, parse the output in PHP. --- src/Composer/Repository/Vcs/FossilDriver.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Composer/Repository/Vcs/FossilDriver.php b/src/Composer/Repository/Vcs/FossilDriver.php index e0abd10fc..961e696bf 100644 --- a/src/Composer/Repository/Vcs/FossilDriver.php +++ b/src/Composer/Repository/Vcs/FossilDriver.php @@ -140,9 +140,10 @@ class FossilDriver extends VcsDriver */ public function getChangeDate($identifier) { - $this->process->execute(sprintf('fossil finfo composer.json | head -n 2 | tail -n 1 | awk \'{print $1}\''), $output, $this->checkoutDir); - - return new \DateTime(trim($output), new \DateTimeZone('UTC')); + $this->process->execute('fossil finfo -b -n 1 composer.json', $output, $this->checkoutDir); + list($ckout, $date, $message) = explode(' ', trim($output), 3); + + return new \DateTime($date, new \DateTimeZone('UTC')); } /** From 927d3dda89d5005647989c3d4719111300cc3a16 Mon Sep 17 00:00:00 2001 From: kthbit Date: Sat, 12 Aug 2017 11:31:57 -0500 Subject: [PATCH 2/3] Teach FossilDriver to work with urls pointing to local repository.fossil files, and not just the local checkout directories. --- src/Composer/Repository/Vcs/FossilDriver.php | 104 +++++++++++-------- 1 file changed, 62 insertions(+), 42 deletions(-) diff --git a/src/Composer/Repository/Vcs/FossilDriver.php b/src/Composer/Repository/Vcs/FossilDriver.php index 961e696bf..0479c70a6 100644 --- a/src/Composer/Repository/Vcs/FossilDriver.php +++ b/src/Composer/Repository/Vcs/FossilDriver.php @@ -34,56 +34,76 @@ class FossilDriver extends VcsDriver */ public function initialize() { - if (Filesystem::isLocalPath($this->url)) { + // Make sure fossil is installed and reachable. + $this->checkFossil(); + + // Ensure we are allowed to use this URL by config. + $this->config->prohibitUrlByConfig($this->url, $this->io); + + // Only if url points to a locally accessible directory, assume it's the checkout directory. + // Otherwise, it should be something fossil can clone from. + if (Filesystem::isLocalPath($this->url) && is_dir($this->url)) { $this->checkoutDir = $this->url; } else { - $this->repoFile = $this->config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9]}i', '-', $this->url) . '.fossil'; - $this->checkoutDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9]}i', '-', $this->url) . '/'; - - $fs = new Filesystem(); - $fs->ensureDirectoryExists($this->checkoutDir); - - if (!is_writable(dirname($this->checkoutDir))) { - throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.$this->checkoutDir.'" directory is not writable by the current user.'); - } - - // Ensure we are allowed to use this URL by config - $this->config->prohibitUrlByConfig($this->url, $this->io); - - // update the repo if it is a valid fossil repository - if (is_file($this->repoFile) && is_dir($this->checkoutDir) && 0 === $this->process->execute('fossil info', $output, $this->checkoutDir)) { - if (0 !== $this->process->execute('fossil pull', $output, $this->checkoutDir)) { - $this->io->writeError('Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')'); - } - } else { - // clean up directory and do a fresh clone into it - $fs->removeDirectory($this->checkoutDir); - $fs->remove($this->repoFile); - - $fs->ensureDirectoryExists($this->checkoutDir); - - if (0 !== $this->process->execute(sprintf('fossil clone %s %s', ProcessExecutor::escape($this->url), ProcessExecutor::escape($this->repoFile)), $output)) { - $output = $this->process->getErrorOutput(); - - if (0 !== $this->process->execute('fossil version', $ignoredOutput)) { - throw new \RuntimeException('Failed to clone '.$this->url.', fossil was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput()); - } - - throw new \RuntimeException('Failed to clone '.$this->url.' to repository ' . $this->repoFile . "\n\n" .$output); - } - - if (0 !== $this->process->execute(sprintf('fossil open %s', ProcessExecutor::escape($this->repoFile)), $output, $this->checkoutDir)) { - $output = $this->process->getErrorOutput(); - - throw new \RuntimeException('Failed to open repository '.$this->repoFile.' in ' . $this->checkoutDir . "\n\n" .$output); - } - } + $localName = preg_replace('{[^a-z0-9]}i', '-', $this->url); + $this->repoFile = $this->config->get('cache-repo-dir') . '/' . $localName . '.fossil'; + $this->checkoutDir = $this->config->get('cache-vcs-dir') . '/' . $localName . '/'; } + $this->updateLocalRepo(); + $this->getTags(); $this->getBranches(); } + /** + * Check that fossil can be invoked via command line. + */ + protected function checkFossil() + { + if (0 !== $this->process->execute('fossil version', $ignoredOutput)) { + throw new \RuntimeException("fossil was not found, check that it is installed and in your PATH env.\n\n" . $this->process->getErrorOutput()); + } + } + + /** + * Clone or update existing local fossil repository. + */ + protected function updateLocalRepo() + { + $fs = new Filesystem(); + $fs->ensureDirectoryExists($this->checkoutDir); + + if (!is_writable(dirname($this->checkoutDir))) { + throw new \RuntimeException('Can not clone '.$this->url.' to access package information. The "'.$this->checkoutDir.'" directory is not writable by the current user.'); + } + + // update the repo if it is a valid fossil repository + if (is_file($this->repoFile) && is_dir($this->checkoutDir) && 0 === $this->process->execute('fossil info', $output, $this->checkoutDir)) { + if (0 !== $this->process->execute('fossil pull', $output, $this->checkoutDir)) { + $this->io->writeError('Failed to update '.$this->url.', package information from this repository may be outdated ('.$this->process->getErrorOutput().')'); + } + } else { + // clean up directory and do a fresh clone into it + $fs->removeDirectory($this->checkoutDir); + $fs->remove($this->repoFile); + + $fs->ensureDirectoryExists($this->checkoutDir); + + if (0 !== $this->process->execute(sprintf('fossil clone %s %s', ProcessExecutor::escape($this->url), ProcessExecutor::escape($this->repoFile)), $output)) { + $output = $this->process->getErrorOutput(); + + throw new \RuntimeException('Failed to clone '.$this->url.' to repository ' . $this->repoFile . "\n\n" .$output); + } + + if (0 !== $this->process->execute(sprintf('fossil open %s', ProcessExecutor::escape($this->repoFile)), $output, $this->checkoutDir)) { + $output = $this->process->getErrorOutput(); + + throw new \RuntimeException('Failed to open repository '.$this->repoFile.' in ' . $this->checkoutDir . "\n\n" .$output); + } + } + } + /** * {@inheritDoc} */ From 1a30e3fbc1e717b44d10b776fea61b3a5362d320 Mon Sep 17 00:00:00 2001 From: kthbit Date: Mon, 14 Aug 2017 10:56:02 -0500 Subject: [PATCH 3/3] Don't update local checkout directory if url is pointing to it. Only update the checkout directory if it is controlled by composer. --- src/Composer/Repository/Vcs/FossilDriver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Composer/Repository/Vcs/FossilDriver.php b/src/Composer/Repository/Vcs/FossilDriver.php index 0479c70a6..3874e56c5 100644 --- a/src/Composer/Repository/Vcs/FossilDriver.php +++ b/src/Composer/Repository/Vcs/FossilDriver.php @@ -48,9 +48,9 @@ class FossilDriver extends VcsDriver $localName = preg_replace('{[^a-z0-9]}i', '-', $this->url); $this->repoFile = $this->config->get('cache-repo-dir') . '/' . $localName . '.fossil'; $this->checkoutDir = $this->config->get('cache-vcs-dir') . '/' . $localName . '/'; - } - $this->updateLocalRepo(); + $this->updateLocalRepo(); + } $this->getTags(); $this->getBranches();