Merge remote-tracking branch 'xrstf/mercurial-support'
commit
5bac9ffaaa
|
@ -160,9 +160,21 @@ class RootPackageLoader extends ArrayLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
private function guessVersion(array $config)
|
private function guessVersion(array $config)
|
||||||
|
{
|
||||||
|
if (function_exists('proc_open')) {
|
||||||
|
$version = $this->guessGitVersion($config);
|
||||||
|
if (null !== $version) {
|
||||||
|
return $version;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->guessHgVersion($config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function guessGitVersion(array $config)
|
||||||
{
|
{
|
||||||
// try to fetch current version from git branch
|
// try to fetch current version from git branch
|
||||||
if (function_exists('proc_open') && 0 === $this->process->execute('git branch --no-color --no-abbrev -v', $output)) {
|
if (0 === $this->process->execute('git branch --no-color --no-abbrev -v', $output)) {
|
||||||
$branches = array();
|
$branches = array();
|
||||||
$isFeatureBranch = false;
|
$isFeatureBranch = false;
|
||||||
$version = null;
|
$version = null;
|
||||||
|
@ -193,32 +205,71 @@ class RootPackageLoader extends ArrayLoader
|
||||||
return $version;
|
return $version;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore feature branches if they have no branch-alias or self.version is used
|
// try to find the best (nearest) version branch to assume this feature's version
|
||||||
// and find the branch they came from to use as a version instead
|
$version = $this->guessFeatureVersion($config, $version, $branches, 'git rev-list %candidate%..%branch%');
|
||||||
if ((isset($config['extra']['branch-alias']) && !isset($config['extra']['branch-alias'][$version]))
|
|
||||||
|| strpos(json_encode($config), '"self.version"')
|
|
||||||
) {
|
|
||||||
$branch = preg_replace('{^dev-}', '', $version);
|
|
||||||
$length = PHP_INT_MAX;
|
|
||||||
foreach ($branches as $candidate) {
|
|
||||||
// do not compare against other feature branches
|
|
||||||
if ($candidate === $branch || !preg_match('{^(master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (0 !== $this->process->execute('git rev-list '.$candidate.'..'.$branch, $output)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (strlen($output) < $length) {
|
|
||||||
$length = strlen($output);
|
|
||||||
$version = $this->versionParser->normalizeBranch($candidate);
|
|
||||||
if ('9999999-dev' === $version) {
|
|
||||||
$version = 'dev-'.$match[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $version;
|
return $version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function guessHgVersion(array $config)
|
||||||
|
{
|
||||||
|
// try to fetch current version from hg branch
|
||||||
|
if (0 === $this->process->execute('hg branch', $output)) {
|
||||||
|
$branch = trim($output);
|
||||||
|
$version = $this->versionParser->normalizeBranch($branch);
|
||||||
|
$isFeatureBranch = 0 === strpos($version, 'dev-');
|
||||||
|
|
||||||
|
if ('9999999-dev' === $version) {
|
||||||
|
$version = 'dev-'.$branch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$isFeatureBranch) {
|
||||||
|
return $version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-use the HgDriver to fetch branches (this properly includes bookmarks)
|
||||||
|
$config = array('url' => getcwd());
|
||||||
|
$driver = new HgDriver($config, new NullIO(), $this->config, $this->process);
|
||||||
|
$branches = array_keys($driver->getBranches());
|
||||||
|
|
||||||
|
// try to find the best (nearest) version branch to assume this feature's version
|
||||||
|
$version = $this->guessFeatureVersion($config, $version, $branches, 'hg log -r "not ancestors(\'%candidate%\') and ancestors(\'%branch%\')" --template "{node}\\n"');
|
||||||
|
|
||||||
|
return $version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function guessFeatureVersion(array $config, $version, array $branches, $scmCmdline)
|
||||||
|
{
|
||||||
|
// 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($config['extra']['branch-alias']) && !isset($config['extra']['branch-alias'][$version]))
|
||||||
|
|| strpos(json_encode($config), '"self.version"')
|
||||||
|
) {
|
||||||
|
$branch = preg_replace('{^dev-}', '', $version);
|
||||||
|
$length = PHP_INT_MAX;
|
||||||
|
foreach ($branches as $candidate) {
|
||||||
|
// do not compare against other feature branches
|
||||||
|
if ($candidate === $branch || !preg_match('{^(master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cmdLine = str_replace(array('%candidate%', '%branch%'), array($candidate, $branch), $scmCmdline);
|
||||||
|
if (0 !== $this->process->execute($cmdLine, $output)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen($output) < $length) {
|
||||||
|
$length = strlen($output);
|
||||||
|
$version = $this->versionParser->normalizeBranch($candidate);
|
||||||
|
if ('9999999-dev' === $version) {
|
||||||
|
$version = 'dev-'.$match[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $version;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,13 +288,9 @@ class Locker
|
||||||
unset($spec['version_normalized']);
|
unset($spec['version_normalized']);
|
||||||
|
|
||||||
if ($package->isDev()) {
|
if ($package->isDev()) {
|
||||||
if (function_exists('proc_open') && 'git' === $package->getSourceType() && ($path = $this->installationManager->getInstallPath($package))) {
|
$time = $this->getPackageTime($package);
|
||||||
$sourceRef = $package->getSourceReference() ?: $package->getDistReference();
|
if (null !== $time) {
|
||||||
$process = new ProcessExecutor();
|
$spec['time'] = $time;
|
||||||
if (0 === $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'));
|
|
||||||
$spec['time'] = $datetime->format('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,4 +312,42 @@ class Locker
|
||||||
|
|
||||||
return $locked;
|
return $locked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 = $this->installationManager->getInstallPath($package);
|
||||||
|
$sourceType = $package->getSourceType();
|
||||||
|
$datetime = null;
|
||||||
|
|
||||||
|
if ($path && in_array($sourceType, array('git', 'hg'))) {
|
||||||
|
$sourceRef = $package->getSourceReference() ?: $package->getDistReference();
|
||||||
|
$process = new ProcessExecutor();
|
||||||
|
|
||||||
|
switch ($sourceType) {
|
||||||
|
case 'git':
|
||||||
|
if (0 === $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 === $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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue