!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache/2.4.68 (Linux) PHP/7.4.33. PHP/7.4.33 

uname -a: Linux bjb2293782.nichost.ru 6.6.151-1.el8.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Aug 10
11:16:02 MSK 2026 x86_64
 

uid=12584(bjb2293782) gid=12584(bjb2293782) groups=12584(bjb2293782)  

Safe-mode: OFF (not secure)

/usr/share/php/Composer/Package/Version/   drwxr-xr-x
Free 60.59 GB of 99.95 GB (60.62%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     VersionGuesser.php (16.67 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php declare(strict_types=1);

/*
 * This file is part of Composer.
 *
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Package\Version;

use 
Composer\Config;
use 
Composer\Pcre\Preg;
use 
Composer\Repository\Vcs\HgDriver;
use 
Composer\IO\NullIO;
use 
Composer\Semver\VersionParser as SemverVersionParser;
use 
Composer\Util\Git as GitUtil;
use 
Composer\Util\HttpDownloader;
use 
Composer\Util\Platform;
use 
Composer\Util\ProcessExecutor;
use 
Composer\Util\Svn as SvnUtil;
use 
React\Promise\CancellablePromiseInterface;
use 
Symfony\Component\Process\Process;

/**
 * Try to guess the current version number based on different VCS configuration.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @author Samuel Roze <samuel.roze@gmail.com>
 *
 * @phpstan-type Version array{version: string, commit: string|null, pretty_version: string|null}|array{version: string, commit: string|null, pretty_version: string|null, feature_version: string|null, feature_pretty_version: string|null}
 */
class VersionGuesser
{
    
/**
     * @var Config
     */
    
private $config;

    
/**
     * @var ProcessExecutor
     */
    
private $process;

    
/**
     * @var SemverVersionParser
     */
    
private $versionParser;

    public function 
__construct(Config $configProcessExecutor $processSemverVersionParser $versionParser)
    {
        
$this->config $config;
        
$this->process $process;
        
$this->versionParser $versionParser;
    }

    
/**
     * @param array<string, mixed> $packageConfig
     * @param string               $path Path to guess into
     *
     * @phpstan-return Version|null
     */
    
public function guessVersion(array $packageConfigstring $path): ?array
    {
        if (!
function_exists('proc_open')) {
            return 
null;
        }

        
// bypass version guessing in bash completions as it takes time to create
        // new processes and the root version is usually not that important
        
if (Platform::isInputCompletionProcess()) {
            return 
null;
        }

        
$versionData $this->guessGitVersion($packageConfig$path);
        if (
null !== $versionData['version']) {
            return 
$this->postprocess($versionData);
        }

        
$versionData $this->guessHgVersion($packageConfig$path);
        if (
null !== $versionData && null !== $versionData['version']) {
            return 
$this->postprocess($versionData);
        }

        
$versionData $this->guessFossilVersion($path);
        if (
null !== $versionData['version']) {
            return 
$this->postprocess($versionData);
        }

        
$versionData $this->guessSvnVersion($packageConfig$path);
        if (
null !== $versionData && null !== $versionData['version']) {
            return 
$this->postprocess($versionData);
        }

        return 
null;
    }

    
/**
     * @phpstan-param Version $versionData
     *
     * @phpstan-return Version
     */
    
private function postprocess(array $versionData): array
    {
        if (!empty(
$versionData['feature_version']) && $versionData['feature_version'] === $versionData['version'] && $versionData['feature_pretty_version'] === $versionData['pretty_version']) {
            unset(
$versionData['feature_version'], $versionData['feature_pretty_version']);
        }

        if (
'-dev' === substr($versionData['version'], -4) && Preg::isMatch('{\.9{7}}'$versionData['version'])) {
            
$versionData['pretty_version'] = Preg::replace('{(\.9{7})+}''.x'$versionData['version']);
        }

        if (!empty(
$versionData['feature_version']) && '-dev' === substr($versionData['feature_version'], -4) && Preg::isMatch('{\.9{7}}'$versionData['feature_version'])) {
            
$versionData['feature_pretty_version'] = Preg::replace('{(\.9{7})+}''.x'$versionData['feature_version']);
        }

        return 
$versionData;
    }

    
/**
     * @param array<string, mixed> $packageConfig
     *
     * @return array{version: string|null, commit: string|null, pretty_version: string|null, feature_version?: string|null, feature_pretty_version?: string|null}
     */
    
private function guessGitVersion(array $packageConfigstring $path): array
    {
        
GitUtil::cleanEnv();
        
$commit null;
        
$version null;
        
$prettyVersion null;
        
$featureVersion null;
        
$featurePrettyVersion null;
        
$isDetached false;

        
// try to fetch current version from git branch
        
if (=== $this->process->execute(['git''branch''-a''--no-color''--no-abbrev''-v'], $output$path)) {
            
$branches = [];
            
$isFeatureBranch false;

            
// find current branch and collect all branch names
            
foreach ($this->process->splitLines($output) as $branch) {
                if (
$branch && Preg::isMatchStrictGroups('{^(?:\* ) *(\(no branch\)|\(detached from \S+\)|\(HEAD detached at \S+\)|\S+) *([a-f0-9]+) .*$}'$branch$match)) {
                    if (
                        
$match[1] === '(no branch)'
                        
|| strpos($match[1], '(detached ') === 0
                        
|| strpos($match[1], '(HEAD detached at') === 0
                    
) {
                        
$version 'dev-' $match[2];
                        
$prettyVersion $version;
                        
$isFeatureBranch true;
                        
$isDetached true;
                    } else {
                        
$version $this->versionParser->normalizeBranch($match[1]);
                        
$prettyVersion 'dev-' $match[1];
                        
$isFeatureBranch $this->isFeatureBranch($packageConfig$match[1]);
                    }

                    
$commit $match[2];
                }

                if (
$branch && !Preg::isMatchStrictGroups('{^ *.+/HEAD }'$branch)) {
                    if (
Preg::isMatchStrictGroups('{^(?:\* )? *((?:remotes/(?:origin|upstream)/)?[^\s/]+) *([a-f0-9]+) .*$}'$branch$match)) {
                        
$branches[] = $match[1];
                    }
                }
            }

            if (
$isFeatureBranch) {
                
$featureVersion $version;
                
$featurePrettyVersion $prettyVersion;

                
// try to find the best (nearest) version branch to assume this feature's version
                
$result $this->guessFeatureVersion($packageConfig$version$branches'git rev-list %candidate%..%branch%'$path);
                
$version $result['version'];
                
$prettyVersion $result['pretty_version'];
            }
        }

        if (!
$version || $isDetached) {
            
$result $this->versionFromGitTags($path);
            if (
$result) {
                
$version $result['version'];
                
$prettyVersion $result['pretty_version'];
                
$featureVersion null;
                
$featurePrettyVersion null;
            }
        }

        if (
null === $commit) {
            
$command 'git log --pretty="%H" -n1 HEAD'.GitUtil::getNoShowSignatureFlag($this->process);
            if (
=== $this->process->execute($command$output$path)) {
                
$commit trim($output) ?: null;
            }
        }

        if (
$featureVersion) {
            return [
'version' => $version'commit' => $commit'pretty_version' => $prettyVersion'feature_version' => $featureVersion'feature_pretty_version' => $featurePrettyVersion];
        }

        return [
'version' => $version'commit' => $commit'pretty_version' => $prettyVersion];
    }

    
/**
     * @return array{version: string, pretty_version: string}|null
     */
    
private function versionFromGitTags(string $path): ?array
    {
        
// try to fetch current version from git tags
        
if (=== $this->process->execute('git describe --exact-match --tags'$output$path)) {
            try {
                
$version $this->versionParser->normalize(trim($output));

                return [
'version' => $version'pretty_version' => trim($output)];
            } catch (\
Exception $e) {
            }
        }

        return 
null;
    }

    
/**
     * @param array<string, mixed> $packageConfig
     *
     * @return array{version: string|null, commit: ''|null, pretty_version: string|null, feature_version?: string|null, feature_pretty_version?: string|null}|null
     */
    
private function guessHgVersion(array $packageConfigstring $path): ?array
    {
        
// try to fetch current version from hg branch
        
if (=== $this->process->execute('hg branch'$output$path)) {
            
$branch trim($output);
            
$version $this->versionParser->normalizeBranch($branch);
            
$isFeatureBranch === strpos($version'dev-');

            if (
VersionParser::DEFAULT_BRANCH_ALIAS === $version) {
                return [
'version' => $version'commit' => null'pretty_version' => 'dev-'.$branch];
            }

            if (!
$isFeatureBranch) {
                return [
'version' => $version'commit' => null'pretty_version' => $version];
            }

            
// re-use the HgDriver to fetch branches (this properly includes bookmarks)
            
$io = new NullIO();
            
$driver = new HgDriver(['url' => $path], $io$this->config, new HttpDownloader($io$this->config), $this->process);
            
$branches array_map('strval'array_keys($driver->getBranches()));

            
// try to find the best (nearest) version branch to assume this feature's version
            
$result $this->guessFeatureVersion($packageConfig$version$branches'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"'$path);
            
$result['commit'] = '';
            
$result['feature_version'] = $version;
            
$result['feature_pretty_version'] = $version;

            return 
$result;
        }

        return 
null;
    }

    
/**
     * @param array<string, mixed>     $packageConfig
     * @param string[]                 $branches
     *
     * @phpstan-param non-empty-string $scmCmdline
     *
     * @return array{version: string|null, pretty_version: string|null}
     */
    
private function guessFeatureVersion(array $packageConfig, ?string $version, array $branchesstring $scmCmdlinestring $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, main is picked
            // and sort using natural sort so that 1.10 will appear before 1.9
            
usort($branches, static function ($a$b): int {
                
$aRemote === strpos($a'remotes/');
                
$bRemote === strpos($b'remotes/');

                if (
$aRemote !== $bRemote) {
                    return 
$aRemote : -1;
                }

                return 
strnatcasecmp($b$a);
            });

            
$promises = [];
            
$this->process->setMaxJobs(30);
            try {
                foreach (
$branches as $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 str_replace(['%candidate%''%branch%'], [$candidate$branch], $scmCmdline);
                    
$promises[] = $this->process->executeAsync($cmdLine$path)->then(function (Process $process) use (&$length, &$version, &$prettyVersion$candidateVersion, &$promises): void {
                        if (!
$process->isSuccessful()) {
                            return;
                        }

                        
$output $process->getOutput();
                        if (
strlen($output) < $length) {
                            
$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];
    }

    
/**
     * @param array<string, mixed> $packageConfig
     */
    
private function isFeatureBranch(array $packageConfig, ?string $branchName): bool
    
{
        
$nonFeatureBranches '';
        if (!empty(
$packageConfig['non-feature-branches'])) {
            
$nonFeatureBranches implode('|'$packageConfig['non-feature-branches']);
        }

        return !
Preg::isMatch('{^(' $nonFeatureBranches '|master|main|latest|next|current|support|tip|trunk|default|develop|\d+\..+)$}'$branchName$match);
    }

    
/**
     * @return array{version: string|null, commit: '', pretty_version: string|null}
     */
    
private function guessFossilVersion(string $path): array
    {
        
$version null;
        
$prettyVersion null;

        
// try to fetch current version from fossil
        
if (=== $this->process->execute('fossil branch list'$output$path)) {
            
$branch trim($output);
            
$version $this->versionParser->normalizeBranch($branch);
            
$prettyVersion 'dev-' $branch;
        }

        
// try to fetch current version from fossil tags
        
if (=== $this->process->execute('fossil tag list'$output$path)) {
            try {
                
$version $this->versionParser->normalize(trim($output));
                
$prettyVersion trim($output);
            } catch (\
Exception $e) {
            }
        }

        return [
'version' => $version'commit' => '''pretty_version' => $prettyVersion];
    }

    
/**
     * @param array<string, mixed> $packageConfig
     *
     * @return array{version: string, commit: '', pretty_version: string}|null
     */
    
private function guessSvnVersion(array $packageConfigstring $path): ?array
    {
        
SvnUtil::cleanEnv();

        
// try to fetch current version from svn
        
if (=== $this->process->execute('svn info --xml'$output$path)) {
            
$trunkPath = isset($packageConfig['trunk-path']) ? preg_quote($packageConfig['trunk-path'], '#') : 'trunk';
            
$branchesPath = isset($packageConfig['branches-path']) ? preg_quote($packageConfig['branches-path'], '#') : 'branches';
            
$tagsPath = isset($packageConfig['tags-path']) ? preg_quote($packageConfig['tags-path'], '#') : 'tags';

            
$urlPattern '#<url>.*/(' $trunkPath '|(' $branchesPath '|' $tagsPath ')/(.*))</url>#';

            if (
Preg::isMatch($urlPattern$output$matches)) {
                if (isset(
$matches[2], $matches[3]) && ($branchesPath === $matches[2] || $tagsPath === $matches[2])) {
                    
// we are in a branches path
                    
$version $this->versionParser->normalizeBranch($matches[3]);
                    
$prettyVersion 'dev-' $matches[3];

                    return [
'version' => $version'commit' => '''pretty_version' => $prettyVersion];
                }

                
assert(is_string($matches[1]));
                
$prettyVersion trim($matches[1]);
                if (
$prettyVersion === 'trunk') {
                    
$version 'dev-trunk';
                } else {
                    
$version $this->versionParser->normalize($prettyVersion);
                }

                return [
'version' => $version'commit' => '''pretty_version' => $prettyVersion];
            }
        }

        return 
null;
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0056 ]--