Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. FossilDriver.php

class FossilDriver

@author BohwaZ <http://bohwaz.net/&gt;

Hierarchy

  • class \Composer\Repository\Vcs\VcsDriver implements \Composer\Repository\Vcs\VcsDriverInterface
    • class \Composer\Repository\Vcs\FossilDriver extends \Composer\Repository\Vcs\VcsDriver

Expanded class hierarchy of FossilDriver

File

vendor/composer/composer/src/Composer/Repository/Vcs/FossilDriver.php, line 25

Namespace

Composer\Repository\Vcs
View source
class FossilDriver extends VcsDriver {
    
    /** @var array<int|string, string> Map of tag name to identifier */
    protected $tags;
    
    /** @var array<int|string, string> Map of branch name to identifier */
    protected $branches;
    
    /** @var ?string */
    protected $rootIdentifier = null;
    
    /** @var ?string */
    protected $repoFile = null;
    
    /** @var string */
    protected $checkoutDir;
    
    /**
     * @inheritDoc
     */
    public function initialize() : void {
        // 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 {
            if (!Cache::isUsable($this->config
                ->get('cache-repo-dir')) || !Cache::isUsable($this->config
                ->get('cache-vcs-dir'))) {
                throw new \RuntimeException('FossilDriver requires a usable cache directory, and it looks like you set it to be disabled');
            }
            $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() : void {
        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() : void {
        assert($this->repoFile !== null);
        $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('<error>Failed to update ' . $this->url . ', package information from this repository may be outdated (' . $this->process
                    ->getErrorOutput() . ')</error>');
            }
        }
        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([
                'fossil',
                'clone',
                '--',
                $this->url,
                $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([
                'fossil',
                'open',
                '--nested',
                '--',
                $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
     */
    public function getRootIdentifier() : string {
        if (null === $this->rootIdentifier) {
            $this->rootIdentifier = 'trunk';
        }
        return $this->rootIdentifier;
    }
    
    /**
     * @inheritDoc
     */
    public function getUrl() : string {
        return $this->url;
    }
    
    /**
     * @inheritDoc
     */
    public function getSource(string $identifier) : array {
        return [
            'type' => 'fossil',
            'url' => $this->getUrl(),
            'reference' => $identifier,
        ];
    }
    
    /**
     * @inheritDoc
     */
    public function getDist(string $identifier) : ?array {
        return null;
    }
    
    /**
     * @inheritDoc
     */
    public function getFileContent(string $file, string $identifier) : ?string {
        $this->process
            ->execute([
            'fossil',
            'cat',
            '-r',
            $identifier,
            '--',
            $file,
        ], $content, $this->checkoutDir);
        if ('' === trim($content)) {
            return null;
        }
        return $content;
    }
    
    /**
     * @inheritDoc
     */
    public function getChangeDate(string $identifier) : ?\DateTimeImmutable {
        $this->process
            ->execute([
            'fossil',
            'finfo',
            '-b',
            '-n',
            '1',
            'composer.json',
        ], $output, $this->checkoutDir);
        [
            ,
            $date,
        ] = explode(' ', trim($output), 3);
        return new \DateTimeImmutable($date, new \DateTimeZone('UTC'));
    }
    
    /**
     * @inheritDoc
     */
    public function getTags() : array {
        if (null === $this->tags) {
            $tags = [];
            $this->process
                ->execute([
                'fossil',
                'tag',
                'list',
            ], $output, $this->checkoutDir);
            foreach ($this->process
                ->splitLines($output) as $tag) {
                $tags[$tag] = $tag;
            }
            $this->tags = $tags;
        }
        return $this->tags;
    }
    
    /**
     * @inheritDoc
     */
    public function getBranches() : array {
        if (null === $this->branches) {
            $branches = [];
            $this->process
                ->execute([
                'fossil',
                'branch',
                'list',
            ], $output, $this->checkoutDir);
            foreach ($this->process
                ->splitLines($output) as $branch) {
                $branch = trim(Preg::replace('/^\\*/', '', trim($branch)));
                $branches[$branch] = $branch;
            }
            $this->branches = $branches;
        }
        return $this->branches;
    }
    
    /**
     * @inheritDoc
     */
    public static function supports(IOInterface $io, Config $config, string $url, bool $deep = false) : bool {
        if (Preg::isMatch('#(^(?:https?|ssh)://(?:[^@]@)?(?:chiselapp\\.com|fossil\\.))#i', $url)) {
            return true;
        }
        if (Preg::isMatch('!/fossil/|\\.fossil!', $url)) {
            return true;
        }
        // local filesystem
        if (Filesystem::isLocalPath($url)) {
            $url = Filesystem::getPlatformPath($url);
            if (!is_dir($url)) {
                return false;
            }
            $process = new ProcessExecutor($io);
            // check whether there is a fossil repo in that path
            if ($process->execute([
                'fossil',
                'info',
            ], $output, $url) === 0) {
                return true;
            }
        }
        return false;
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
FossilDriver::$branches protected property @var array&lt;int|string, string&gt; Map of branch name to identifier
FossilDriver::$checkoutDir protected property @var string
FossilDriver::$repoFile protected property @var ?string
FossilDriver::$rootIdentifier protected property @var ?string
FossilDriver::$tags protected property @var array&lt;int|string, string&gt; Map of tag name to identifier
FossilDriver::checkFossil protected function Check that fossil can be invoked via command line.
FossilDriver::getBranches public function @inheritDoc Overrides VcsDriverInterface::getBranches
FossilDriver::getChangeDate public function @inheritDoc Overrides VcsDriverInterface::getChangeDate
FossilDriver::getDist public function @inheritDoc Overrides VcsDriverInterface::getDist
FossilDriver::getFileContent public function @inheritDoc Overrides VcsDriverInterface::getFileContent
FossilDriver::getRootIdentifier public function @inheritDoc Overrides VcsDriverInterface::getRootIdentifier
FossilDriver::getSource public function @inheritDoc Overrides VcsDriverInterface::getSource
FossilDriver::getTags public function @inheritDoc Overrides VcsDriverInterface::getTags
FossilDriver::getUrl public function @inheritDoc Overrides VcsDriverInterface::getUrl
FossilDriver::initialize public function @inheritDoc Overrides VcsDriverInterface::initialize
FossilDriver::supports public static function @inheritDoc Overrides VcsDriverInterface::supports
FossilDriver::updateLocalRepo protected function Clone or update existing local fossil repository.
VcsDriver::$cache protected property @var ?Cache
VcsDriver::$config protected property @var Config
VcsDriver::$httpDownloader protected property @var HttpDownloader
VcsDriver::$infoCache protected property @var array&lt;int|string, mixed&gt;
VcsDriver::$io protected property @var IOInterface
VcsDriver::$originUrl protected property @var string
VcsDriver::$process protected property @var ProcessExecutor
VcsDriver::$repoConfig protected property @var array&lt;string, mixed&gt;
VcsDriver::$url protected property @var string
VcsDriver::cleanup public function @inheritDoc Overrides VcsDriverInterface::cleanup 1
VcsDriver::getBaseComposerInformation protected function
VcsDriver::getComposerInformation public function @inheritDoc Overrides VcsDriverInterface::getComposerInformation 4
VcsDriver::getContents protected function Get the remote content. 3
VcsDriver::getScheme protected function Get the https or http protocol depending on SSL support.
VcsDriver::hasComposerFile public function @inheritDoc Overrides VcsDriverInterface::hasComposerFile 1
VcsDriver::shouldCache protected function Returns whether or not the given $identifier should be cached or not. 1
VcsDriver::__construct final public function Constructor.

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal