Exemple #1
0
 /**
  * {@inheritDoc}
  */
 public function initialize()
 {
     if (Filesystem::isLocalPath($this->url)) {
         $this->url = preg_replace('{[\\/]\\.git/?$}', '', $this->url);
         $this->repoDir = $this->url;
         $cacheUrl = realpath($this->url);
     } else {
         $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
         GitUtil::cleanEnv();
         $fs = new Filesystem();
         $fs->ensureDirectoryExists(dirname($this->repoDir));
         if (!is_writable(dirname($this->repoDir))) {
             throw new \RuntimeException('Can not clone ' . $this->url . ' to access package information. The "' . dirname($this->repoDir) . '" directory is not writable by the current user.');
         }
         if (preg_match('{^ssh://[^@]+@[^:]+:[^0-9]+}', $this->url)) {
             throw new \InvalidArgumentException('The source URL ' . $this->url . ' is invalid, ssh URLs should have a port number after ":".' . "\n" . 'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
         }
         $gitUtil = new GitUtil($this->io, $this->config, $this->process, $fs);
         if (!$gitUtil->syncMirror($this->url, $this->repoDir)) {
             $this->io->writeError('<error>Failed to update ' . $this->url . ', package information from this repository may be outdated</error>');
         }
         $cacheUrl = $this->url;
     }
     $this->getTags();
     $this->getBranches();
     $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $cacheUrl));
 }
Exemple #2
0
 /**
  * {@inheritDoc}
  */
 public function initialize()
 {
     if (static::isLocalUrl($this->url)) {
         $this->repoDir = str_replace('file://', '', $this->url);
     } else {
         $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
         $util = new GitUtil();
         $util->cleanEnv();
         $fs = new Filesystem();
         $fs->ensureDirectoryExists(dirname($this->repoDir));
         if (!is_writable(dirname($this->repoDir))) {
             throw new \RuntimeException('Can not clone ' . $this->url . ' to access package information. The "' . dirname($this->repoDir) . '" directory is not writable by the current user.');
         }
         if (preg_match('{^ssh://[^@]+@[^:]+:[^0-9]+}', $this->url)) {
             throw new \InvalidArgumentException('The source URL ' . $this->url . ' is invalid, ssh URLs should have a port number after ":".' . "\n" . 'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
         }
         // update the repo if it is a valid git repository
         if (is_dir($this->repoDir) && 0 === $this->process->execute('git remote', $output, $this->repoDir)) {
             if (0 !== $this->process->execute('git remote update --prune origin', $output, $this->repoDir)) {
                 $this->io->write('<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->repoDir);
             $command = sprintf('git clone --mirror %s %s', escapeshellarg($this->url), escapeshellarg($this->repoDir));
             if (0 !== $this->process->execute($command, $output)) {
                 $output = $this->process->getErrorOutput();
                 if (0 !== $this->process->execute('git --version', $ignoredOutput)) {
                     throw new \RuntimeException('Failed to clone ' . $this->url . ', git was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput());
                 }
                 if ($this->io->isInteractive() && preg_match('{(https?://)([^/]+)(.*)$}i', $this->url, $match) && strpos($output, 'fatal: Authentication failed') !== false) {
                     if ($this->io->hasAuthentication($match[2])) {
                         $auth = $this->io->getAuthentication($match[2]);
                     } else {
                         $this->io->write($this->url . ' requires Authentication');
                         $auth = array('username' => $this->io->ask('Username: '******'password' => $this->io->askAndHideAnswer('Password: '******'username']) . ':' . rawurlencode($auth['password']) . '@' . $match[2] . $match[3];
                     $command = sprintf('git clone --mirror %s %s', escapeshellarg($url), escapeshellarg($this->repoDir));
                     if (0 === $this->process->execute($command, $output)) {
                         $this->io->setAuthentication($match[2], $auth['username'], $auth['password']);
                     } else {
                         $output = $this->process->getErrorOutput();
                         throw new \RuntimeException('Failed to clone ' . $this->url . ', could not read packages from it' . "\n\n" . $output);
                     }
                 } else {
                     throw new \RuntimeException('Failed to clone ' . $this->url . ', could not read packages from it' . "\n\n" . $output);
                 }
             }
         }
     }
     $this->getTags();
     $this->getBranches();
     $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url));
 }
Exemple #3
0
 private function guessGitVersion(array $packageConfig, $path)
 {
     GitUtil::cleanEnv();
     $commit = null;
     $version = null;
     $prettyVersion = null;
     // try to fetch current version from git branch
     if (0 === $this->process->execute('git branch --no-color --no-abbrev -v', $output, $path)) {
         $branches = array();
         $isFeatureBranch = false;
         // find current branch and collect all branch names
         foreach ($this->process->splitLines($output) as $branch) {
             if ($branch && preg_match('{^(?:\\* ) *(\\(no branch\\)|\\(detached from \\S+\\)|\\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
                 if ($match[1] === '(no branch)' || substr($match[1], 0, 10) === '(detached ') {
                     $version = 'dev-' . $match[2];
                     $prettyVersion = $version;
                     $isFeatureBranch = true;
                 } else {
                     $version = $this->versionParser->normalizeBranch($match[1]);
                     $prettyVersion = 'dev-' . $match[1];
                     $isFeatureBranch = 0 === strpos($version, 'dev-');
                     if ('9999999-dev' === $version) {
                         $version = $prettyVersion;
                     }
                 }
                 if ($match[2]) {
                     $commit = $match[2];
                 }
             }
             if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) {
                 if (preg_match('{^(?:\\* )? *(\\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
                     $branches[] = $match[1];
                 }
             }
         }
         if ($isFeatureBranch) {
             // 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) {
         $result = $this->versionFromGitTags($path);
         if ($result) {
             $version = $result['version'];
             $prettyVersion = $result['pretty_version'];
         }
     }
     if (!$commit) {
         $command = 'git log --pretty="%H" -n1 HEAD';
         if (0 === $this->process->execute($command, $output, $path)) {
             $commit = trim($output) ?: null;
         }
     }
     return array('version' => $version, 'commit' => $commit, 'pretty_version' => $prettyVersion);
 }
 /**
  * {@inheritDoc}
  */
 public function initialize()
 {
     if (Filesystem::isLocalPath($this->url)) {
         $this->url = preg_replace('{[\\/]\\.git/?$}', '', $this->url);
         $this->repoDir = $this->url;
         $cacheUrl = realpath($this->url);
     } else {
         $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
         GitUtil::cleanEnv();
         $fs = new Filesystem();
         $fs->ensureDirectoryExists(dirname($this->repoDir));
         if (!is_writable(dirname($this->repoDir))) {
             throw new \RuntimeException('Can not clone ' . $this->url . ' to access package information. The "' . dirname($this->repoDir) . '" directory is not writable by the current user.');
         }
         if (preg_match('{^ssh://[^@]+@[^:]+:[^0-9]+}', $this->url)) {
             throw new \InvalidArgumentException('The source URL ' . $this->url . ' is invalid, ssh URLs should have a port number after ":".' . "\n" . 'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
         }
         $gitUtil = new GitUtil($this->io, $this->config, $this->process, $fs);
         // update the repo if it is a valid git repository
         if (is_dir($this->repoDir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $this->repoDir) && trim($output) === '.') {
             try {
                 $commandCallable = function ($url) {
                     return sprintf('git remote set-url origin %s && git remote update --prune origin', ProcessExecutor::escape($url));
                 };
                 $gitUtil->runCommand($commandCallable, $this->url, $this->repoDir);
             } catch (\Exception $e) {
                 $this->io->writeError('<error>Failed to update ' . $this->url . ', package information from this repository may be outdated (' . $e->getMessage() . ')</error>');
             }
         } else {
             // clean up directory and do a fresh clone into it
             $fs->removeDirectory($this->repoDir);
             $repoDir = $this->repoDir;
             $commandCallable = function ($url) use($repoDir) {
                 return sprintf('git clone --mirror %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($repoDir));
             };
             $gitUtil->runCommand($commandCallable, $this->url, $this->repoDir, true);
         }
         $cacheUrl = $this->url;
     }
     $this->getTags();
     $this->getBranches();
     $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $cacheUrl));
 }
 /**
  * Clone repository
  *
  * @param PackageInterface $package
  * @param string $path
  * @param string $url
  * @return $this
  */
 protected function cloneRepository(PackageInterface $package, $path, $url)
 {
     $command = $this->getCloneCommand();
     $this->io->write("    Cloning " . $package->getSourceReference());
     $commandCallable = $this->getCloneCommandCallback($path, $package->getSourceReference(), $command);
     $this->gitUtil->runCommand($commandCallable, $url, $path, true);
     if ($url !== $package->getSourceUrl()) {
         $url = $package->getSourceUrl();
         $this->process->execute(sprintf('git remote set-url origin %s', ProcessExecutor::escape($url)), $output, $path);
     }
     $this->setPushUrl($path, $url);
     return $this;
 }
Exemple #6
0
 public function initialize()
 {
     if (static::isLocalUrl($this->url)) {
         $this->repoDir = str_replace('file://', '', $this->url);
     } else {
         $this->repoDir = $this->config->get('cache-vcs-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url) . '/';
         $util = new GitUtil();
         $util->cleanEnv();
         $fs = new Filesystem();
         $fs->ensureDirectoryExists(dirname($this->repoDir));
         if (!is_writable(dirname($this->repoDir))) {
             throw new \RuntimeException('Can not clone ' . $this->url . ' to access package information. The "' . dirname($this->repoDir) . '" directory is not writable by the current user.');
         }
         if (preg_match('{^ssh://[^@]+@[^:]+:[^0-9]+}', $this->url)) {
             throw new \InvalidArgumentException('The source URL ' . $this->url . ' is invalid, ssh URLs should have a port number after ":".' . "\n" . 'Use ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.');
         }
         if (is_dir($this->repoDir) && 0 === $this->process->execute('git remote', $output, $this->repoDir)) {
             if (0 !== $this->process->execute('git remote update --prune origin', $output, $this->repoDir)) {
                 $this->io->write('<error>Failed to update ' . $this->url . ', package information from this repository may be outdated (' . $this->process->getErrorOutput() . ')</error>');
             }
         } else {
             $fs->removeDirectory($this->repoDir);
             $command = sprintf('git clone --mirror %s %s', escapeshellarg($this->url), escapeshellarg($this->repoDir));
             if (0 !== $this->process->execute($command, $output)) {
                 $output = $this->process->getErrorOutput();
                 if (0 !== $this->process->execute('git --version', $ignoredOutput)) {
                     throw new \RuntimeException('Failed to clone ' . $this->url . ', git 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 . ', could not read packages from it' . "\n\n" . $output);
             }
         }
     }
     $this->getTags();
     $this->getBranches();
     $this->cache = new Cache($this->io, $this->config->get('cache-repo-dir') . '/' . preg_replace('{[^a-z0-9.]}i', '-', $this->url));
 }
Exemple #7
0
 private function guessGitVersion(array $packageConfig, $path)
 {
     GitUtil::cleanEnv();
     // try to fetch current version from git tags
     if (0 === $this->process->execute('git describe --exact-match --tags', $output, $path)) {
         try {
             return $this->versionParser->normalize(trim($output));
         } catch (\Exception $e) {
         }
     }
     // try to fetch current version from git branch
     if (0 === $this->process->execute('git branch --no-color --no-abbrev -v', $output, $path)) {
         $branches = array();
         $isFeatureBranch = false;
         $version = null;
         // find current branch and collect all branch names
         foreach ($this->process->splitLines($output) as $branch) {
             if ($branch && preg_match('{^(?:\\* ) *(\\(no branch\\)|\\(detached from \\S+\\)|\\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
                 if ($match[1] === '(no branch)' || substr($match[1], 0, 10) === '(detached ') {
                     $version = 'dev-' . $match[2];
                     $isFeatureBranch = true;
                 } else {
                     $version = $this->versionParser->normalizeBranch($match[1]);
                     $isFeatureBranch = 0 === strpos($version, 'dev-');
                     if ('9999999-dev' === $version) {
                         $version = 'dev-' . $match[1];
                     }
                 }
             }
             if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) {
                 if (preg_match('{^(?:\\* )? *(\\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
                     $branches[] = $match[1];
                 }
             }
         }
         if (!$isFeatureBranch) {
             return $version;
         }
         // try to find the best (nearest) version branch to assume this feature's version
         $version = $this->guessFeatureVersion($packageConfig, $version, $branches, 'git rev-list %candidate%..%branch%', $path);
         return $version;
     }
 }
 protected function setPushUrl($path, $url)
 {
     // set push url for github projects
     if (preg_match('{^(?:https?|git)://' . GitUtil::getGitHubDomainsRegex($this->config) . '/([^/]+)/([^/]+?)(?:\\.git)?$}', $url, $match)) {
         $protocols = $this->config->get('github-protocols');
         $pushUrl = 'git@' . $match[1] . ':' . $match[2] . '/' . $match[3] . '.git';
         if (!in_array('ssh', $protocols, true)) {
             $pushUrl = 'https://' . $match[1] . '/' . $match[2] . '/' . $match[3] . '.git';
         }
         $cmd = sprintf('git remote set-url --push origin %s', ProcessExecutor::escape($pushUrl));
         $this->process->execute($cmd, $ignoredOutput, $path);
     }
 }
 private function guessGitVersion(array $config)
 {
     $util = new GitUtil();
     $util->cleanEnv();
     if (0 === $this->process->execute('git describe --exact-match --tags', $output)) {
         try {
             return $this->versionParser->normalize(trim($output));
         } catch (\Exception $e) {
         }
     }
     if (0 === $this->process->execute('git branch --no-color --no-abbrev -v', $output)) {
         $branches = array();
         $isFeatureBranch = false;
         $version = null;
         foreach ($this->process->splitLines($output) as $branch) {
             if ($branch && preg_match('{^(?:\\* ) *(\\(no branch\\)|\\(detached from [a-f0-9]+\\)|\\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
                 if ($match[1] === '(no branch)' || substr($match[1], 0, 10) === '(detached ') {
                     $version = 'dev-' . $match[2];
                     $isFeatureBranch = true;
                 } else {
                     $version = $this->versionParser->normalizeBranch($match[1]);
                     $isFeatureBranch = 0 === strpos($version, 'dev-');
                     if ('9999999-dev' === $version) {
                         $version = 'dev-' . $match[1];
                     }
                 }
             }
             if ($branch && !preg_match('{^ *[^/]+/HEAD }', $branch)) {
                 if (preg_match('{^(?:\\* )? *(\\S+) *([a-f0-9]+) .*$}', $branch, $match)) {
                     $branches[] = $match[1];
                 }
             }
         }
         if (!$isFeatureBranch) {
             return $version;
         }
         $version = $this->guessFeatureVersion($config, $version, $branches, 'git rev-list %candidate%..%branch%');
         return $version;
     }
 }
Exemple #10
0
 /**
  * Returns the packages's datetime for its source reference.
  *
  * @param  PackageInterface $package The package to scan.
  * @return string|null      The formatted datetime or null if none was found.
  */
 private function getPackageTime(PackageInterface $package)
 {
     if (!function_exists('proc_open')) {
         return null;
     }
     $path = realpath($this->installationManager->getInstallPath($package));
     $sourceType = $package->getSourceType();
     $datetime = null;
     if ($path && in_array($sourceType, array('git', 'hg'))) {
         $sourceRef = $package->getSourceReference() ?: $package->getDistReference();
         switch ($sourceType) {
             case 'git':
                 $util = new GitUtil();
                 $util->cleanEnv();
                 if (0 === $this->process->execute('git log -n1 --pretty=%ct ' . escapeshellarg($sourceRef), $output, $path) && preg_match('{^\\s*\\d+\\s*$}', $output)) {
                     $datetime = new \DateTime('@' . trim($output), new \DateTimeZone('UTC'));
                 }
                 break;
             case 'hg':
                 if (0 === $this->process->execute('hg log --template "{date|hgdate}" -r ' . escapeshellarg($sourceRef), $output, $path) && preg_match('{^\\s*(\\d+)\\s*}', $output, $match)) {
                     $datetime = new \DateTime('@' . $match[1], new \DateTimeZone('UTC'));
                 }
                 break;
         }
     }
     return $datetime ? $datetime->format('Y-m-d H:i:s') : null;
 }
Exemple #11
0
 protected function cleanEnv()
 {
     $util = new GitUtil();
     $util->cleanEnv();
 }