parent
261d93aacf
commit
995bf5a932
|
@ -469,7 +469,7 @@ class GitHubDriver extends VcsDriver
|
|||
}
|
||||
}
|
||||
|
||||
$rateLimited = $gitHubUtil->isRateLimited($e->getHeaders());
|
||||
$rateLimited = $gitHubUtil->isRateLimited((array) $e->getHeaders());
|
||||
|
||||
if (!$this->io->hasAuthentication($this->originUrl)) {
|
||||
if (!$this->io->isInteractive()) {
|
||||
|
@ -575,7 +575,7 @@ class GitHubDriver extends VcsDriver
|
|||
protected function getNextPage(Response $response)
|
||||
{
|
||||
$header = $response->getHeader('link');
|
||||
|
||||
|
||||
if (!$header) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ class AuthHelper
|
|||
/**
|
||||
* @param string $origin
|
||||
* @param string|bool $storeAuth
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function storeAuth($origin, $storeAuth)
|
||||
{
|
||||
|
@ -192,10 +194,11 @@ class AuthHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
* @param string $origin
|
||||
* @param string $url
|
||||
* @return array updated headers array
|
||||
* @param string[] $headers
|
||||
* @param string $origin
|
||||
* @param string $url
|
||||
*
|
||||
* @return string[] updated headers array
|
||||
*/
|
||||
public function addAuthenticationHeader(array $headers, $origin, $url)
|
||||
{
|
||||
|
|
|
@ -211,16 +211,17 @@ class Bitbucket
|
|||
throw new \LogicException('Failed to initialize token above');
|
||||
}
|
||||
|
||||
// side effect above caused this, https://github.com/phpstan/phpstan/issues/5129
|
||||
// @phpstan-ignore-next-line
|
||||
return $this->token['access_token'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the new/updated credentials to the configuration
|
||||
*
|
||||
* @param string $originUrl
|
||||
* @param string $consumerKey
|
||||
* @param string $consumerSecret
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function storeInAuthConfig($originUrl, $consumerKey, $consumerSecret)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,16 @@ namespace Composer\Util;
|
|||
*/
|
||||
class ComposerMirror
|
||||
{
|
||||
/**
|
||||
* @param string $mirrorUrl
|
||||
* @param string $packageName
|
||||
* @param string $version
|
||||
* @param string|null $reference
|
||||
* @param string|null $type
|
||||
* @param string|null $prettyVersion
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function processUrl($mirrorUrl, $packageName, $version, $reference, $type, $prettyVersion = null)
|
||||
{
|
||||
if ($reference) {
|
||||
|
@ -36,6 +46,14 @@ class ComposerMirror
|
|||
return str_replace($from, $to, $mirrorUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mirrorUrl
|
||||
* @param string $packageName
|
||||
* @param string $url
|
||||
* @param string|null $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function processGitUrl($mirrorUrl, $packageName, $url, $type)
|
||||
{
|
||||
if (preg_match('#^(?:(?:https?|git)://github\.com/|git@github\.com:)([^/]+)/(.+?)(?:\.git)?$#', $url, $match)) {
|
||||
|
@ -53,6 +71,14 @@ class ComposerMirror
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mirrorUrl
|
||||
* @param string $packageName
|
||||
* @param string $url
|
||||
* @param string $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function processHgUrl($mirrorUrl, $packageName, $url, $type)
|
||||
{
|
||||
return self::processGitUrl($mirrorUrl, $packageName, $url, $type);
|
||||
|
|
|
@ -45,7 +45,7 @@ class ConfigValidator
|
|||
* @param int $arrayLoaderValidationFlags Flags for ArrayLoader validation
|
||||
* @param int $flags Flags for validation
|
||||
*
|
||||
* @return array a triple containing the errors, publishable errors, and warnings
|
||||
* @return array{list<string>, list<string>, list<string>} a triple containing the errors, publishable errors, and warnings
|
||||
*/
|
||||
public function validate($file, $arrayLoaderValidationFlags = ValidatingArrayLoader::CHECK_ALL, $flags = self::CHECK_VERSION)
|
||||
{
|
||||
|
|
|
@ -82,6 +82,8 @@ class ErrorHandler
|
|||
* Register error handler.
|
||||
*
|
||||
* @param IOInterface|null $io
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function register(IOInterface $io = null)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,11 @@ class Filesystem
|
|||
$this->processExecutor = $executor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function remove($file)
|
||||
{
|
||||
if (is_dir($file)) {
|
||||
|
@ -62,6 +67,12 @@ class Filesystem
|
|||
return \count($finder) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
* @param bool $ensureDirectoryExists
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function emptyDirectory($dir, $ensureDirectoryExists = true)
|
||||
{
|
||||
if (is_link($dir) && file_exists($dir)) {
|
||||
|
@ -163,6 +174,7 @@ class Filesystem
|
|||
|
||||
/**
|
||||
* @param string $directory
|
||||
* @param bool $fallbackToPhp
|
||||
*
|
||||
* @return bool|null Returns null, when no edge case was hit. Otherwise a bool whether removal was successfull
|
||||
*/
|
||||
|
@ -240,6 +252,11 @@ class Filesystem
|
|||
return $this->rmdir($directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $directory
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ensureDirectoryExists($directory)
|
||||
{
|
||||
if (!is_dir($directory)) {
|
||||
|
@ -326,6 +343,8 @@ class Filesystem
|
|||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function copyThenRemove($source, $target)
|
||||
{
|
||||
|
@ -370,6 +389,12 @@ class Filesystem
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rename($source, $target)
|
||||
{
|
||||
if (true === @rename($source, $target)) {
|
||||
|
@ -605,13 +630,18 @@ class Filesystem
|
|||
return (bool) preg_match('{^(file://(?!//)|/(?!/)|/?[a-z]:[\\\\/]|\.\.[\\\\/]|[a-z0-9_.-]+[\\\\/])}i', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getPlatformPath($path)
|
||||
{
|
||||
if (Platform::isWindows()) {
|
||||
$path = preg_replace('{^(?:file:///([a-z]):?/)}i', 'file://$1:/', $path);
|
||||
}
|
||||
|
||||
return preg_replace('{^file://}i', '', $path);
|
||||
return (string) preg_replace('{^file://}i', '', $path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -641,6 +671,11 @@ class Filesystem
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $directory
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function directorySize($directory)
|
||||
{
|
||||
$it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
|
@ -767,6 +802,8 @@ class Filesystem
|
|||
*
|
||||
* @param string $target
|
||||
* @param string $junction
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function junction($target, $junction)
|
||||
{
|
||||
|
@ -845,6 +882,12 @@ class Filesystem
|
|||
return $this->rmdir($junction);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $content
|
||||
*
|
||||
* @return int|false
|
||||
*/
|
||||
public function filePutContentsIfModified($path, $content)
|
||||
{
|
||||
$currentContent = @file_get_contents($path);
|
||||
|
@ -860,6 +903,8 @@ class Filesystem
|
|||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function safeCopy($source, $target)
|
||||
{
|
||||
|
@ -876,6 +921,11 @@ class Filesystem
|
|||
/**
|
||||
* compare 2 files
|
||||
* https://stackoverflow.com/questions/3060125/can-i-use-file-get-contents-to-compare-two-files
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function filesAreEqual($a, $b)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,14 @@ class Git
|
|||
$this->filesystem = $fs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $commandCallable
|
||||
* @param string $url
|
||||
* @param string|null $cwd
|
||||
* @param bool $initialClone
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function runCommand($commandCallable, $url, $cwd, $initialClone = false)
|
||||
{
|
||||
// Ensure we are allowed to use this URL by config
|
||||
|
@ -257,6 +265,12 @@ class Git
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $dir
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function syncMirror($url, $dir)
|
||||
{
|
||||
if (getenv('COMPOSER_DISABLE_NETWORK') && getenv('COMPOSER_DISABLE_NETWORK') !== 'prime') {
|
||||
|
@ -295,6 +309,13 @@ class Git
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $dir
|
||||
* @param string $ref
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function fetchRefOrSyncMirror($url, $dir, $ref)
|
||||
{
|
||||
if ($this->checkRefIsInMirror($dir, $ref)) {
|
||||
|
@ -308,6 +329,9 @@ class Git
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getNoShowSignatureFlag(ProcessExecutor $process)
|
||||
{
|
||||
$gitVersion = self::getVersion($process);
|
||||
|
@ -318,6 +342,12 @@ class Git
|
|||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
* @param string $ref
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkRefIsInMirror($dir, $ref)
|
||||
{
|
||||
if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
|
||||
|
@ -331,6 +361,12 @@ class Git
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string[] $match
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isAuthenticationFailure($url, &$match)
|
||||
{
|
||||
if (!preg_match('{^(https?://)([^/]+)(.*)$}i', $url, $match)) {
|
||||
|
@ -355,6 +391,9 @@ class Git
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function cleanEnv()
|
||||
{
|
||||
if (PHP_VERSION_ID < 50400 && ini_get('safe_mode') && false === strpos(ini_get('safe_mode_allowed_env_vars'), 'GIT_ASKPASS')) {
|
||||
|
@ -383,16 +422,28 @@ class Git
|
|||
Platform::clearEnv('DYLD_LIBRARY_PATH');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public static function getGitHubDomainsRegex(Config $config)
|
||||
{
|
||||
return '(' . implode('|', array_map('preg_quote', $config->get('github-domains'))) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public static function getGitLabDomainsRegex(Config $config)
|
||||
{
|
||||
return '(' . implode('|', array_map('preg_quote', $config->get('gitlab-domains'))) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $message
|
||||
* @param string $url
|
||||
*
|
||||
* @return never
|
||||
*/
|
||||
private function throwException($message, $url)
|
||||
{
|
||||
// git might delete a directory when it fails and php will not know
|
||||
|
|
|
@ -132,11 +132,11 @@ class GitHub
|
|||
}
|
||||
|
||||
/**
|
||||
* Extract ratelimit from response.
|
||||
* Extract rate limit from response.
|
||||
*
|
||||
* @param array $headers Headers from Composer\Downloader\TransportException.
|
||||
* @param string[] $headers Headers from Composer\Downloader\TransportException.
|
||||
*
|
||||
* @return array Associative array with the keys limit and reset.
|
||||
* @return array{limit: int|'?', reset: string}
|
||||
*/
|
||||
public function getRateLimit(array $headers)
|
||||
{
|
||||
|
@ -167,7 +167,7 @@ class GitHub
|
|||
/**
|
||||
* Finds whether a request failed due to rate limiting
|
||||
*
|
||||
* @param array $headers Headers from Composer\Downloader\TransportException.
|
||||
* @param string[] $headers Headers from Composer\Downloader\TransportException.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
|
|
@ -160,6 +160,14 @@ class GitLab
|
|||
throw new \RuntimeException('Invalid GitLab credentials 5 times in a row, aborting.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scheme
|
||||
* @param string $originUrl
|
||||
*
|
||||
* @return array{access_token: non-empty-string, token_type: non-empty-string, expires_in: positive-int}
|
||||
*
|
||||
* @see https://docs.gitlab.com/ee/api/oauth2.html#resource-owner-password-credentials-flow
|
||||
*/
|
||||
private function createToken($scheme, $originUrl)
|
||||
{
|
||||
$username = $this->io->ask('Username: ');
|
||||
|
|
|
@ -45,6 +45,13 @@ class Hg
|
|||
$this->process = $process;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $commandCallable
|
||||
* @param string $url
|
||||
* @param string|null $cwd
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function runCommand($commandCallable, $url, $cwd)
|
||||
{
|
||||
$this->config->prohibitUrlByConfig($url, $this->io);
|
||||
|
@ -75,6 +82,12 @@ class Hg
|
|||
$this->throwException('Failed to clone ' . $url . ', ' . "\n\n" . $error, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $message
|
||||
* @param string $url
|
||||
*
|
||||
* @return never
|
||||
*/
|
||||
private function throwException($message, $url)
|
||||
{
|
||||
if (null === self::getVersion($this->process)) {
|
||||
|
|
|
@ -23,8 +23,9 @@ class ProxyHelper
|
|||
/**
|
||||
* Returns proxy environment values
|
||||
*
|
||||
* @return array{string|null, string|null, string|null} httpProxy, httpsProxy, noProxy values
|
||||
*
|
||||
* @throws \RuntimeException on malformed url
|
||||
* @return array httpProxy, httpsProxy, noProxy values
|
||||
*/
|
||||
public static function getProxyData()
|
||||
{
|
||||
|
@ -59,8 +60,9 @@ class ProxyHelper
|
|||
/**
|
||||
* Returns http context options for the proxy url
|
||||
*
|
||||
* @param string $proxyUrl
|
||||
* @return array
|
||||
* @param string $proxyUrl
|
||||
*
|
||||
* @return array{http: array{proxy: string, header?: string}}
|
||||
*/
|
||||
public static function getContextOptions($proxyUrl)
|
||||
{
|
||||
|
@ -90,8 +92,10 @@ class ProxyHelper
|
|||
/**
|
||||
* Sets/unsets request_fulluri value in http context options array
|
||||
*
|
||||
* @param string $requestUrl
|
||||
* @param array $options Set by method
|
||||
* @param string $requestUrl
|
||||
* @param mixed[] $options Set by method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setRequestFullUri($requestUrl, array &$options)
|
||||
{
|
||||
|
@ -105,8 +109,9 @@ class ProxyHelper
|
|||
/**
|
||||
* Searches $_SERVER for case-sensitive values
|
||||
*
|
||||
* @param array $names Names to search for
|
||||
* @param mixed $name Name of any found value
|
||||
* @param string[] $names Names to search for
|
||||
* @param string|null $name Name of any found value
|
||||
*
|
||||
* @return string|null The found value
|
||||
*/
|
||||
private static function getProxyEnv(array $names, &$name)
|
||||
|
@ -151,8 +156,9 @@ class ProxyHelper
|
|||
/**
|
||||
* Formats a url from its component parts
|
||||
*
|
||||
* @param array $proxy Values from parse_url
|
||||
* @param bool $includeAuth Whether to include authorization values
|
||||
* @param array{scheme: string, host: string, port?: int, user?: string, pass?: string} $proxy
|
||||
* @param bool $includeAuth
|
||||
*
|
||||
* @return string The formatted value
|
||||
*/
|
||||
private static function formatParsedUrl(array $proxy, $includeAuth)
|
||||
|
|
|
@ -71,6 +71,8 @@ class ProxyManager
|
|||
|
||||
/**
|
||||
* Clears the persistent instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
|
@ -130,6 +132,8 @@ class ProxyManager
|
|||
|
||||
/**
|
||||
* Initializes proxy values from the environment
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function initProxyData()
|
||||
{
|
||||
|
@ -160,8 +164,10 @@ class ProxyManager
|
|||
/**
|
||||
* Sets initial data
|
||||
*
|
||||
* @param string $url Proxy url
|
||||
* @param 'http'|'https' $scheme Environment variable scheme
|
||||
* @param non-empty-string $url Proxy url
|
||||
* @param 'http'|'https' $scheme Environment variable scheme
|
||||
*
|
||||
* @return non-empty-string
|
||||
*/
|
||||
private function setData($url, $scheme)
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@ use Symfony\Component\Process\Process;
|
|||
|
||||
/**
|
||||
* @author Matt Whittom <Matt.Whittom@veteransunited.com>
|
||||
*
|
||||
* @phpstan-type RepoConfig array{unique_perforce_client_name?: string, depot?: string, branch?: string, p4user?: string, p4password?: string}
|
||||
*/
|
||||
class Perforce
|
||||
{
|
||||
|
@ -30,7 +32,7 @@ class Perforce
|
|||
protected $p4User;
|
||||
/** @var ?string */
|
||||
protected $p4Password;
|
||||
/** @var int */
|
||||
/** @var string */
|
||||
protected $p4Port;
|
||||
/** @var string */
|
||||
protected $p4Stream;
|
||||
|
@ -55,6 +57,14 @@ class Perforce
|
|||
/** @var Filesystem */
|
||||
protected $filesystem;
|
||||
|
||||
/**
|
||||
* @phpstan-param RepoConfig $repoConfig
|
||||
* @param string $port
|
||||
* @param string $path
|
||||
* @param ProcessExecutor $process
|
||||
* @param bool $isWindows
|
||||
* @param IOInterface $io
|
||||
*/
|
||||
public function __construct($repoConfig, $port, $path, ProcessExecutor $process, $isWindows, IOInterface $io)
|
||||
{
|
||||
$this->windowsFlag = $isWindows;
|
||||
|
@ -65,11 +75,26 @@ class Perforce
|
|||
$this->io = $io;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param RepoConfig $repoConfig
|
||||
* @param string $port
|
||||
* @param string $path
|
||||
* @param ProcessExecutor $process
|
||||
* @param IOInterface $io
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function create($repoConfig, $port, $path, ProcessExecutor $process, IOInterface $io)
|
||||
{
|
||||
return new Perforce($repoConfig, $port, $path, $process, Platform::isWindows(), $io);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param ProcessExecutor $processExecutor
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkServerExists($url, ProcessExecutor $processExecutor)
|
||||
{
|
||||
$output = null;
|
||||
|
@ -77,6 +102,11 @@ class Perforce
|
|||
return 0 === $processExecutor->execute('p4 -p ' . ProcessExecutor::escape($url) . ' info -s', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param RepoConfig $repoConfig
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initialize($repoConfig)
|
||||
{
|
||||
$this->uniquePerforceClientName = $this->generateUniquePerforceClientName();
|
||||
|
@ -103,6 +133,12 @@ class Perforce
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $depot
|
||||
* @param string|null $branch
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeDepotAndBranch($depot, $branch)
|
||||
{
|
||||
if (isset($depot)) {
|
||||
|
@ -113,11 +149,17 @@ class Perforce
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function generateUniquePerforceClientName()
|
||||
{
|
||||
return gethostname() . "_" . time();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function cleanupClientSpec()
|
||||
{
|
||||
$client = $this->getClient();
|
||||
|
@ -130,6 +172,11 @@ class Perforce
|
|||
$fileSystem->remove($clientSpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $command
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function executeCommand($command)
|
||||
{
|
||||
$this->commandResult = '';
|
||||
|
@ -137,6 +184,9 @@ class Perforce
|
|||
return $this->process->execute($command, $this->commandResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getClient()
|
||||
{
|
||||
if (!isset($this->p4Client)) {
|
||||
|
@ -147,11 +197,19 @@ class Perforce
|
|||
return $this->p4Client;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializePath($path)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
@ -159,11 +217,19 @@ class Perforce
|
|||
$fs->ensureDirectoryExists($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getPort()
|
||||
{
|
||||
return $this->p4Port;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stream
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setStream($stream)
|
||||
{
|
||||
$this->p4Stream = $stream;
|
||||
|
@ -174,11 +240,17 @@ class Perforce
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isStream()
|
||||
{
|
||||
return is_string($this->p4DepotType) && (strcmp($this->p4DepotType, 'stream') === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
if (!isset($this->p4Stream)) {
|
||||
|
@ -192,6 +264,11 @@ class Perforce
|
|||
return $this->p4Stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stream
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStreamWithoutLabel($stream)
|
||||
{
|
||||
$index = strpos($stream, '@');
|
||||
|
@ -202,21 +279,35 @@ class Perforce
|
|||
return substr($stream, 0, $index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function getP4ClientSpec()
|
||||
{
|
||||
return $this->path . '/' . $this->getClient() . '.p4.spec';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
return $this->p4User;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUser($user)
|
||||
{
|
||||
$this->p4User = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function queryP4User()
|
||||
{
|
||||
$this->getUser();
|
||||
|
@ -272,6 +363,9 @@ class Perforce
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function queryP4Password()
|
||||
{
|
||||
if (isset($this->p4Password)) {
|
||||
|
@ -286,6 +380,12 @@ class Perforce
|
|||
return $password;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $command
|
||||
* @param bool $useClient
|
||||
*
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function generateP4Command($command, $useClient = true)
|
||||
{
|
||||
$p4Command = 'p4 ';
|
||||
|
@ -298,6 +398,9 @@ class Perforce
|
|||
return $p4Command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isLoggedIn()
|
||||
{
|
||||
$command = $this->generateP4Command('login -s', false);
|
||||
|
@ -318,6 +421,9 @@ class Perforce
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function connectClient()
|
||||
{
|
||||
$p4CreateClientCommand = $this->generateP4Command(
|
||||
|
@ -326,6 +432,11 @@ class Perforce
|
|||
$this->executeCommand($p4CreateClientCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $sourceReference
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function syncCodeBase($sourceReference)
|
||||
{
|
||||
$prevDir = getcwd();
|
||||
|
@ -338,6 +449,11 @@ class Perforce
|
|||
chdir($prevDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource|false $spec
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function writeClientSpecToFile($spec)
|
||||
{
|
||||
fwrite($spec, 'Client: ' . $this->getClient() . PHP_EOL . PHP_EOL);
|
||||
|
@ -361,6 +477,9 @@ class Perforce
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function writeP4ClientSpec()
|
||||
{
|
||||
$clientSpec = $this->getP4ClientSpec();
|
||||
|
@ -374,6 +493,12 @@ class Perforce
|
|||
fclose($spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resource $pipe
|
||||
* @param mixed $name
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function read($pipe, $name)
|
||||
{
|
||||
if (feof($pipe)) {
|
||||
|
@ -385,6 +510,11 @@ class Perforce
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $password
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function windowsLogin($password)
|
||||
{
|
||||
$command = $this->generateP4Command(' login -a');
|
||||
|
@ -393,12 +523,16 @@ class Perforce
|
|||
if (method_exists('Symfony\Component\Process\Process', 'fromShellCommandline')) {
|
||||
$process = Process::fromShellCommandline($command, null, null, $password);
|
||||
} else {
|
||||
// @phpstan-ignore-next-line
|
||||
$process = new Process($command, null, null, $password);
|
||||
}
|
||||
|
||||
return $process->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function p4Login()
|
||||
{
|
||||
$this->queryP4User();
|
||||
|
@ -416,6 +550,11 @@ class Perforce
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function getComposerInformation($identifier)
|
||||
{
|
||||
$composerFileContent = $this->getFileContent('composer.json', $identifier);
|
||||
|
@ -427,6 +566,12 @@ class Perforce
|
|||
return json_decode($composerFileContent, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFileContent($file, $identifier)
|
||||
{
|
||||
$path = $this->getFilePath($file, $identifier);
|
||||
|
@ -442,6 +587,12 @@ class Perforce
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param string $identifier
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFilePath($file, $identifier)
|
||||
{
|
||||
$index = strpos($identifier, '@');
|
||||
|
@ -467,6 +618,9 @@ class Perforce
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{master: string}
|
||||
*/
|
||||
public function getBranches()
|
||||
{
|
||||
$possibleBranches = array();
|
||||
|
@ -496,6 +650,9 @@ class Perforce
|
|||
return array('master' => $possibleBranches[$this->p4Branch] . '@'. $lastCommitNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
$command = $this->generateP4Command('labels');
|
||||
|
@ -513,6 +670,9 @@ class Perforce
|
|||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function checkStream()
|
||||
{
|
||||
$command = $this->generateP4Command('depots', false);
|
||||
|
@ -578,6 +738,9 @@ class Perforce
|
|||
return $this->commandResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Filesystem
|
||||
*/
|
||||
public function getFilesystem()
|
||||
{
|
||||
if (empty($this->filesystem)) {
|
||||
|
@ -587,6 +750,9 @@ class Perforce
|
|||
return $this->filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFilesystem(Filesystem $fs)
|
||||
{
|
||||
$this->filesystem = $fs;
|
||||
|
|
|
@ -555,6 +555,7 @@ class RemoteFilesystem
|
|||
* @param string $originUrl The origin URL
|
||||
* @param string $fileUrl The file URL
|
||||
* @param resource $context The stream context
|
||||
* @param string[] $responseHeaders
|
||||
* @param int $maxFileSize The maximum allowed file size
|
||||
*
|
||||
* @return string|false The response contents or false on failure
|
||||
|
@ -592,12 +593,15 @@ class RemoteFilesystem
|
|||
/**
|
||||
* Get notification action.
|
||||
*
|
||||
* @param int $notificationCode The notification code
|
||||
* @param int $severity The severity level
|
||||
* @param string $message The message
|
||||
* @param int $messageCode The message code
|
||||
* @param int $bytesTransferred The loaded size
|
||||
* @param int $bytesMax The total size
|
||||
* @param int $notificationCode The notification code
|
||||
* @param int $severity The severity level
|
||||
* @param string $message The message
|
||||
* @param int $messageCode The message code
|
||||
* @param int $bytesTransferred The loaded size
|
||||
* @param int $bytesMax The total size
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws TransportException
|
||||
*/
|
||||
protected function callbackGet($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax)
|
||||
|
@ -631,6 +635,13 @@ class RemoteFilesystem
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param positive-int $httpStatus
|
||||
* @param string|null $reason
|
||||
* @param string[] $headers
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function promptAuthAndRetry($httpStatus, $reason = null, $headers = array())
|
||||
{
|
||||
$result = $this->authHelper->promptAuthIfNeeded($this->fileUrl, $this->originUrl, $httpStatus, $reason, $headers);
|
||||
|
@ -643,6 +654,12 @@ class RemoteFilesystem
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $originUrl
|
||||
* @param mixed[] $additionalOptions
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getOptionsForUrl($originUrl, $additionalOptions)
|
||||
{
|
||||
$tlsOptions = array();
|
||||
|
@ -714,6 +731,13 @@ class RemoteFilesystem
|
|||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $http_response_header
|
||||
* @param mixed[] $additionalOptions
|
||||
* @param string|false $result
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
private function handleRedirect(array $http_response_header, array $additionalOptions, $result)
|
||||
{
|
||||
if ($locationHeader = Response::findHeaderValue($http_response_header, 'location')) {
|
||||
|
@ -763,6 +787,9 @@ class RemoteFilesystem
|
|||
*
|
||||
* @todo Remove when PHP 5.6 is minimum supported version.
|
||||
*
|
||||
* @param string $url
|
||||
* @param mixed[] $options
|
||||
*
|
||||
* @return ?array{cn: string, fp: string}
|
||||
*/
|
||||
private function getCertificateCnAndFp($url, $options)
|
||||
|
@ -807,6 +834,11 @@ class RemoteFilesystem
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getUrlAuthority($url)
|
||||
{
|
||||
$defaultPorts = array(
|
||||
|
@ -832,6 +864,12 @@ class RemoteFilesystem
|
|||
return parse_url($url, PHP_URL_HOST).':'.$port;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|false $result
|
||||
* @param string[] $http_response_header
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
private function decodeResult($result, $http_response_header)
|
||||
{
|
||||
// decode gzip
|
||||
|
|
Loading…
Reference in New Issue