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

Breadcrumb

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

function VersionGuesser::guessFeatureVersion

Parameters

array<string, mixed> $packageConfig:

list<string> $branches:

list<string> $scmCmdline:

Return value

array{version: string|null, pretty_version: string|null}

2 calls to VersionGuesser::guessFeatureVersion()
VersionGuesser::guessGitVersion in vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php
VersionGuesser::guessHgVersion in vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php

File

vendor/composer/composer/src/Composer/Package/Version/VersionGuesser.php, line 277

Class

VersionGuesser
Try to guess the current version number based on different VCS configuration.

Namespace

Composer\Package\Version

Code

private function guessFeatureVersion(array $packageConfig, ?string $version, array $branches, array $scmCmdline, string $path) : array {
    $prettyVersion = $version;
    // ignore feature branches if they have no branch-alias or self.version is used
    // and find the branch they came from to use as a version instead
    if (!isset($packageConfig['extra']['branch-alias'][$version]) || strpos(json_encode($packageConfig), '"self.version"')) {
        $branch = Preg::replace('{^dev-}', '', $version);
        $length = PHP_INT_MAX;
        // return directly, if branch is configured to be non-feature branch
        if (!$this->isFeatureBranch($packageConfig, $branch)) {
            return [
                'version' => $version,
                'pretty_version' => $prettyVersion,
            ];
        }
        // sort local branches first then remote ones
        // and sort numeric branches below named ones, to make sure if the branch has the same distance from main and 1.10 and 1.9 for example, 1.9 is picked
        // and sort using natural sort so that 1.10 will appear before 1.9
        usort($branches, static function ($a, $b) : int {
            $aRemote = 0 === strpos($a, 'remotes/');
            $bRemote = 0 === strpos($b, 'remotes/');
            if ($aRemote !== $bRemote) {
                return $aRemote ? 1 : -1;
            }
            return strnatcasecmp($b, $a);
        });
        $promises = [];
        $this->process
            ->setMaxJobs(30);
        try {
            $lastIndex = -1;
            foreach ($branches as $index => $candidate) {
                $candidateVersion = Preg::replace('{^remotes/\\S+/}', '', $candidate);
                // do not compare against itself or other feature branches
                if ($candidate === $branch || $this->isFeatureBranch($packageConfig, $candidateVersion)) {
                    continue;
                }
                $cmdLine = array_map(static function (string $component) use ($candidate, $branch) {
                    return str_replace([
                        '%candidate%',
                        '%branch%',
                    ], [
                        $candidate,
                        $branch,
                    ], $component);
                }, $scmCmdline);
                $promises[] = $this->process
                    ->executeAsync($cmdLine, $path)
                    ->then(function (Process $process) use (&$lastIndex, $index, &$length, &$version, &$prettyVersion, $candidateVersion, &$promises) : void {
                    if (!$process->isSuccessful()) {
                        return;
                    }
                    $output = $process->getOutput();
                    // overwrite existing if we have a shorter diff, or we have an equal diff and an index that comes later in the array (i.e. older version)
                    // as newer versions typically have more commits, if the feature branch is based on a newer branch it should have a longer diff to the old version
                    // but if it doesn't and they have equal diffs, then it probably is based on the old version
                    if (strlen($output) < $length || strlen($output) === $length && $lastIndex < $index) {
                        $lastIndex = $index;
                        $length = strlen($output);
                        $version = $this->versionParser
                            ->normalizeBranch($candidateVersion);
                        $prettyVersion = 'dev-' . $candidateVersion;
                        if ($length === 0) {
                            foreach ($promises as $promise) {
                                // to support react/promise 2.x we wrap the promise in a resolve() call for safety
                                \React\Promise\resolve($promise)->cancel();
                            }
                        }
                    }
                });
            }
            $this->process
                ->wait();
        } finally {
            $this->process
                ->resetMaxJobs();
        }
    }
    return [
        'version' => $version,
        'pretty_version' => $prettyVersion,
    ];
}
RSS feed
Powered by Drupal