Merge branch '3.4' into 4.0
* 3.4: [HttpKernel] Fixed invalid REMOTE_ADDR in inline subrequest when configuring trusted proxy with subnet [FrameworkBundle] fixed guard event names for transitions [DI] Improve class named servics error message [HttpFoundation] fixed using _method parameter with invalid type [Intl] Replace svn with git in the icu data update script [HttpFoundation] Fix Cookie::isCleared
This commit is contained in:
commit
e0ce427aef
|
@ -525,7 +525,9 @@ class FrameworkExtension extends Extension
|
|||
$guard = new Definition(Workflow\EventListener\GuardListener::class);
|
||||
$guard->setPrivate(true);
|
||||
$configuration = array();
|
||||
foreach ($workflow['transitions'] as $transitionName => $config) {
|
||||
foreach ($workflow['transitions'] as $config) {
|
||||
$transitionName = $config['name'];
|
||||
|
||||
if (!isset($config['guard'])) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,15 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
|
|||
throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id));
|
||||
}
|
||||
if (class_exists($id) || interface_exists($id, false)) {
|
||||
if (0 === strpos($id, '\\') && 1 < substr_count($id, '\\')) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'The definition for "%s" has no class attribute, and appears to reference a class or interface. '
|
||||
.'Please specify the class attribute explicitly or remove the leading backslash by renaming '
|
||||
.'the service to "%s" to get rid of this error.',
|
||||
$id, substr($id, 1)
|
||||
));
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf(
|
||||
'The definition for "%s" has no class attribute, and appears to reference a '
|
||||
.'class or interface in the global namespace. Leaving out the "class" attribute '
|
||||
|
|
|
@ -1238,6 +1238,30 @@ class ContainerBuilderTest extends TestCase
|
|||
$container->compile();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionMessage The definition for "\DateTime" has no class attribute, and appears to reference a class or interface in the global namespace.
|
||||
*/
|
||||
public function testNoClassFromGlobalNamespaceClassIdWithLeadingSlash()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('\\'.\DateTime::class);
|
||||
$container->compile();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionMessage The definition for "\Symfony\Component\DependencyInjection\Tests\FooClass" has no class attribute, and appears to reference a class or interface. Please specify the class attribute explicitly or remove the leading backslash by renaming the service to "Symfony\Component\DependencyInjection\Tests\FooClass" to get rid of this error.
|
||||
*/
|
||||
public function testNoClassFromNamespaceClassIdWithLeadingSlash()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container->register('\\'.FooClass::class);
|
||||
$container->compile();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
* @expectedExceptionMessage The definition for "123_abc" has no class.
|
||||
|
|
|
@ -266,7 +266,7 @@ class Cookie
|
|||
*/
|
||||
public function isCleared()
|
||||
{
|
||||
return $this->expire < time();
|
||||
return 0 !== $this->expire && $this->expire < time();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1221,7 +1221,10 @@ class Request
|
|||
if ($method = $this->headers->get('X-HTTP-METHOD-OVERRIDE')) {
|
||||
$this->method = strtoupper($method);
|
||||
} elseif (self::$httpMethodParameterOverride) {
|
||||
$this->method = strtoupper($this->request->get('_method', $this->query->get('_method', 'POST')));
|
||||
$method = $this->request->get('_method', $this->query->get('_method', 'POST'));
|
||||
if (\is_string($method)) {
|
||||
$this->method = strtoupper($method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,6 +154,18 @@ class CookieTest extends TestCase
|
|||
$cookie = new Cookie('foo', 'bar', time() - 20);
|
||||
|
||||
$this->assertTrue($cookie->isCleared(), '->isCleared() returns true if the cookie has expired');
|
||||
|
||||
$cookie = new Cookie('foo', 'bar');
|
||||
|
||||
$this->assertFalse($cookie->isCleared());
|
||||
|
||||
$cookie = new Cookie('foo', 'bar', 0);
|
||||
|
||||
$this->assertFalse($cookie->isCleared());
|
||||
|
||||
$cookie = new Cookie('foo', 'bar', -1);
|
||||
|
||||
$this->assertFalse($cookie->isCleared());
|
||||
}
|
||||
|
||||
public function testToString()
|
||||
|
|
|
@ -848,6 +848,11 @@ class RequestTest extends TestCase
|
|||
$request->setMethod('POST');
|
||||
$request->headers->set('X-HTTP-METHOD-OVERRIDE', 'delete');
|
||||
$this->assertEquals('DELETE', $request->getMethod(), '->getMethod() returns the method from X-HTTP-Method-Override if defined and POST');
|
||||
|
||||
$request = new Request();
|
||||
$request->setMethod('POST');
|
||||
$request->query->set('_method', array('delete', 'patch'));
|
||||
$this->assertSame('POST', $request->getMethod(), '->getMethod() returns the request method if invalid type is defined in query');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -115,8 +115,7 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
|
|||
$server['HTTP_X_FORWARDED_FOR'] = ($currentXForwardedFor ? $currentXForwardedFor.', ' : '').$request->getClientIp();
|
||||
}
|
||||
|
||||
$trustedProxies = Request::getTrustedProxies();
|
||||
$server['REMOTE_ADDR'] = $trustedProxies ? reset($trustedProxies) : '127.0.0.1';
|
||||
$server['REMOTE_ADDR'] = $this->resolveTrustedProxy();
|
||||
|
||||
unset($server['HTTP_IF_MODIFIED_SINCE']);
|
||||
unset($server['HTTP_IF_NONE_MATCH']);
|
||||
|
@ -133,6 +132,17 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
|
|||
return $subRequest;
|
||||
}
|
||||
|
||||
private function resolveTrustedProxy()
|
||||
{
|
||||
if (!$trustedProxies = Request::getTrustedProxies()) {
|
||||
return '127.0.0.1';
|
||||
}
|
||||
|
||||
$firstTrustedProxy = reset($trustedProxies);
|
||||
|
||||
return false !== ($i = strpos($firstTrustedProxy, '/')) ? substr($firstTrustedProxy, 0, $i) : $firstTrustedProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -195,6 +195,25 @@ class InlineFragmentRendererTest extends TestCase
|
|||
Request::setTrustedProxies(array(), -1);
|
||||
}
|
||||
|
||||
public function testIpAddressOfRangedTrustedProxyIsSetAsRemote()
|
||||
{
|
||||
$expectedSubRequest = Request::create('/');
|
||||
$expectedSubRequest->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
|
||||
$expectedSubRequest->server->set('REMOTE_ADDR', '1.1.1.1');
|
||||
$expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
|
||||
$expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
|
||||
|
||||
Request::setTrustedProxies(array('1.1.1.1/24'), -1);
|
||||
|
||||
$strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->headers->set('Surrogate-Capability', 'abc="ESI/1.0"');
|
||||
$strategy->render('/', $request);
|
||||
|
||||
Request::setTrustedProxies(array(), -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Kernel expecting a request equals to $request
|
||||
* Allows delta in comparison in case REQUEST_TIME changed by 1 second.
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
; ICU data source URLs
|
||||
; We use always the latest release of a major version.
|
||||
4.0 = http://source.icu-project.org/repos/icu/icu/tags/release-4-0-1/source
|
||||
4.2 = http://source.icu-project.org/repos/icu/icu/tags/release-4-2-1/source
|
||||
4.4 = http://source.icu-project.org/repos/icu/icu/tags/release-4-4-2/source
|
||||
4.6 = http://source.icu-project.org/repos/icu/icu/tags/release-4-6-1/source
|
||||
4.8 = http://source.icu-project.org/repos/icu/icu/tags/release-4-8-1-1/source
|
||||
49 = http://source.icu-project.org/repos/icu/icu/tags/release-49-1-2/source
|
||||
50 = http://source.icu-project.org/repos/icu/icu/tags/release-50-1-2/source
|
||||
51 = http://source.icu-project.org/repos/icu/icu/tags/release-51-2/source
|
||||
52 = http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source
|
||||
53 = http://source.icu-project.org/repos/icu/icu/tags/release-53-1/source
|
||||
54 = http://source.icu-project.org/repos/icu/icu/tags/release-54-1/source
|
||||
55 = http://source.icu-project.org/repos/icu/icu/tags/release-55-1/source
|
||||
57 = http://source.icu-project.org/repos/icu/icu/tags/release-57-1/source
|
||||
58 = http://source.icu-project.org/repos/icu/tags/release-58-2/icu4c/source
|
||||
59 = http://source.icu-project.org/repos/icu/tags/release-59-1/icu4c/source
|
||||
60 = http://source.icu-project.org/repos/icu/tags/release-60-2/icu4c/source
|
||||
61 = http://source.icu-project.org/repos/icu/tags/release-61-1/icu4c/source
|
||||
62 = http://source.icu-project.org/repos/icu/tags/release-62-1/icu4c/source
|
|
@ -25,8 +25,7 @@ use Symfony\Component\Intl\Data\Provider\RegionDataProvider;
|
|||
use Symfony\Component\Intl\Data\Provider\ScriptDataProvider;
|
||||
use Symfony\Component\Intl\Intl;
|
||||
use Symfony\Component\Intl\Locale;
|
||||
use Symfony\Component\Intl\Util\IcuVersion;
|
||||
use Symfony\Component\Intl\Util\SvnRepository;
|
||||
use Symfony\Component\Intl\Util\GitRepository;
|
||||
|
||||
require_once __DIR__.'/common.php';
|
||||
require_once __DIR__.'/autoload.php';
|
||||
|
@ -40,7 +39,7 @@ Usage: php update-data.php <path/to/icu/source> <path/to/icu/build>
|
|||
|
||||
Updates the ICU data for Symfony to the latest version of ICU.
|
||||
|
||||
If you downloaded the SVN repository before, you can pass the path to the
|
||||
If you downloaded the git repository before, you can pass the path to the
|
||||
repository source in the first optional argument.
|
||||
|
||||
If you also built the repository before, you can pass the directory where that
|
||||
|
@ -64,37 +63,31 @@ if (!Intl::isExtensionLoaded()) {
|
|||
bailout('The intl extension for PHP is not installed.');
|
||||
}
|
||||
|
||||
$filesystem = new Filesystem();
|
||||
$urls = parse_ini_file(__DIR__.'/icu.ini');
|
||||
|
||||
echo "icu.ini parsed. Available versions:\n";
|
||||
|
||||
$maxVersion = 0;
|
||||
|
||||
foreach ($urls as $urlVersion => $url) {
|
||||
$maxVersion = IcuVersion::compare($maxVersion, $urlVersion, '<')
|
||||
? $urlVersion
|
||||
: $maxVersion;
|
||||
|
||||
echo " $urlVersion\n";
|
||||
}
|
||||
|
||||
$shortIcuVersion = strip_minor_versions($maxVersion);
|
||||
|
||||
if ($argc >= 2) {
|
||||
$sourceDir = $argv[1];
|
||||
$svn = new SvnRepository($sourceDir);
|
||||
$repoDir = $argv[1];
|
||||
$git = new GitRepository($repoDir);
|
||||
|
||||
echo "Using existing SVN repository at {$sourceDir}.\n";
|
||||
echo "Using the existing git repository at {$repoDir}.\n";
|
||||
} else {
|
||||
echo "Starting SVN checkout for version $shortIcuVersion. This may take a while...\n";
|
||||
echo "Starting git clone. This may take a while...\n";
|
||||
|
||||
$sourceDir = sys_get_temp_dir().'/icu-data/'.$shortIcuVersion.'/source';
|
||||
$svn = SvnRepository::download($urls[$shortIcuVersion], $sourceDir);
|
||||
$repoDir = sys_get_temp_dir().'/icu-data';
|
||||
$git = GitRepository::download('https://github.com/unicode-org/icu.git', $repoDir);
|
||||
|
||||
echo "SVN checkout to {$sourceDir} complete.\n";
|
||||
echo "Git clone to {$repoDir} complete.\n";
|
||||
}
|
||||
|
||||
$gitTag = $git->getLastTag(function ($tag) {
|
||||
return preg_match('#^release-[0-9]{1,}-[0-9]{1}$#', $tag);
|
||||
});
|
||||
$shortIcuVersion = strip_minor_versions(preg_replace('#release-([0-9]{1,})-([0-9]{1,})#', '$1.$2', $gitTag));
|
||||
|
||||
echo "Checking out `{$gitTag}` for version `{$shortIcuVersion}`...\n";
|
||||
$git->checkout('tags/'.$gitTag);
|
||||
|
||||
$filesystem = new Filesystem();
|
||||
$sourceDir = $repoDir.'/icu4c/source';
|
||||
|
||||
if ($argc >= 3) {
|
||||
$buildDir = $argv[2];
|
||||
} else {
|
||||
|
@ -265,23 +258,23 @@ $generator->generateData($config);
|
|||
|
||||
echo "Resource bundle compilation complete.\n";
|
||||
|
||||
$svnInfo = <<<SVN_INFO
|
||||
SVN information
|
||||
$gitInfo = <<<GIT_INFO
|
||||
Git information
|
||||
===============
|
||||
|
||||
URL: {$svn->getUrl()}
|
||||
Revision: {$svn->getLastCommit()->getRevision()}
|
||||
Author: {$svn->getLastCommit()->getAuthor()}
|
||||
Date: {$svn->getLastCommit()->getDate()}
|
||||
URL: {$git->getUrl()}
|
||||
Revision: {$git->getLastCommitHash()}
|
||||
Author: {$git->getLastAuthor()}
|
||||
Date: {$git->getLastAuthoredDate()->format('c')}
|
||||
|
||||
SVN_INFO;
|
||||
GIT_INFO;
|
||||
|
||||
foreach ($targetDirs as $targetDir) {
|
||||
$svnInfoFile = $targetDir.'/svn-info.txt';
|
||||
$gitInfoFile = $targetDir.'/git-info.txt';
|
||||
|
||||
file_put_contents($svnInfoFile, $svnInfo);
|
||||
file_put_contents($gitInfoFile, $gitInfo);
|
||||
|
||||
echo "Wrote $svnInfoFile.\n";
|
||||
echo "Wrote $gitInfoFile.\n";
|
||||
|
||||
$versionFile = $targetDir.'/version.txt';
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
Git information
|
||||
===============
|
||||
|
||||
URL: https://github.com/unicode-org/icu.git
|
||||
Revision: 4a3ba8eee90ea1414d4f7ee36563e6c9b28fda96
|
||||
Author: Yoshito Umaoka
|
||||
Date: 2018-06-20T05:34:56+00:00
|
|
@ -1,7 +0,0 @@
|
|||
SVN information
|
||||
===============
|
||||
|
||||
URL: http://source.icu-project.org/repos/icu/tags/release-62-1/icu4c/source
|
||||
Revision: 41542
|
||||
Author: yoshito
|
||||
Date: 2018-06-20T05:34:56.496986Z
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Tests\Util;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Intl\Util\GitRepository;
|
||||
|
||||
/**
|
||||
* @group intl-data
|
||||
*/
|
||||
class GitRepositoryTest extends TestCase
|
||||
{
|
||||
private $targetDir;
|
||||
|
||||
const REPO_URL = 'https://github.com/symfony/intl.git';
|
||||
|
||||
/**
|
||||
* @before
|
||||
* @after
|
||||
*/
|
||||
protected function cleanup()
|
||||
{
|
||||
$this->targetDir = sys_get_temp_dir().'/GitRepositoryTest/source';
|
||||
|
||||
$fs = new Filesystem();
|
||||
$fs->remove($this->targetDir);
|
||||
}
|
||||
|
||||
public function testItThrowsAnExceptionIfInitialisedWithNonGitDirectory()
|
||||
{
|
||||
$this->expectException('Symfony\Component\Intl\Exception\RuntimeException');
|
||||
|
||||
@mkdir($this->targetDir, '0777', true);
|
||||
|
||||
new GitRepository($this->targetDir);
|
||||
}
|
||||
|
||||
public function testItClonesTheRepository()
|
||||
{
|
||||
$git = GitRepository::download(self::REPO_URL, $this->targetDir);
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Intl\Util\GitRepository', $git);
|
||||
$this->assertDirectoryExists($this->targetDir.'/.git');
|
||||
$this->assertSame($this->targetDir, $git->getPath());
|
||||
$this->assertSame(self::REPO_URL, $git->getUrl());
|
||||
$this->assertRegExp('#^[0-9a-z]{40}$#', $git->getLastCommitHash());
|
||||
$this->assertNotEmpty($git->getLastAuthor());
|
||||
$this->assertInstanceOf('DateTime', $git->getLastAuthoredDate());
|
||||
$this->assertStringMatchesFormat('v%s', $git->getLastTag());
|
||||
$this->assertStringMatchesFormat('v3%s', $git->getLastTag(function ($tag) { return 0 === strpos($tag, 'v3'); }));
|
||||
}
|
||||
|
||||
public function testItCheckoutsToTheLastTag()
|
||||
{
|
||||
$git = GitRepository::download(self::REPO_URL, $this->targetDir);
|
||||
$lastCommitHash = $git->getLastCommitHash();
|
||||
$lastV3Tag = $git->getLastTag(function ($tag) { return 0 === strpos($tag, 'v3'); });
|
||||
|
||||
$git->checkout($lastV3Tag);
|
||||
|
||||
$this->assertNotEquals($lastCommitHash, $git->getLastCommitHash());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Util;
|
||||
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class GitRepository
|
||||
{
|
||||
private $path;
|
||||
|
||||
public function __construct(string $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
|
||||
$this->getUrl();
|
||||
}
|
||||
|
||||
public static function download(string $remote, string $targetDir): self
|
||||
{
|
||||
self::exec('which git', 'The command "git" is not installed.');
|
||||
|
||||
$filesystem = new Filesystem();
|
||||
|
||||
if (!$filesystem->exists($targetDir.'/.git')) {
|
||||
$filesystem->remove($targetDir);
|
||||
$filesystem->mkdir($targetDir);
|
||||
|
||||
self::exec(sprintf('git clone %s %s', escapeshellarg($remote), escapeshellarg($targetDir)));
|
||||
}
|
||||
|
||||
return new self(realpath($targetDir));
|
||||
}
|
||||
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->getLastLine($this->execInPath('git config --get remote.origin.url'));
|
||||
}
|
||||
|
||||
public function getLastCommitHash()
|
||||
{
|
||||
return $this->getLastLine($this->execInPath('git log -1 --format="%H"'));
|
||||
}
|
||||
|
||||
public function getLastAuthor()
|
||||
{
|
||||
return $this->getLastLine($this->execInPath('git log -1 --format="%an"'));
|
||||
}
|
||||
|
||||
public function getLastAuthoredDate()
|
||||
{
|
||||
return new \DateTime($this->getLastLine($this->execInPath('git log -1 --format="%ai"')));
|
||||
}
|
||||
|
||||
public function getLastTag(callable $filter = null)
|
||||
{
|
||||
$tags = $this->execInPath('git tag -l --sort=v:refname');
|
||||
|
||||
if (null !== $filter) {
|
||||
$tags = array_filter($tags, $filter);
|
||||
}
|
||||
|
||||
return $this->getLastLine($tags);
|
||||
}
|
||||
|
||||
public function checkout($branch)
|
||||
{
|
||||
$this->execInPath(sprintf('git checkout %s', escapeshellarg($branch)));
|
||||
}
|
||||
|
||||
private function execInPath($command)
|
||||
{
|
||||
return self::exec(sprintf('cd %s && %s', escapeshellarg($this->path), $command));
|
||||
}
|
||||
|
||||
private static function exec($command, $customErrorMessage = null)
|
||||
{
|
||||
exec(sprintf('%s 2>&1', $command), $output, $result);
|
||||
|
||||
if (0 !== $result) {
|
||||
throw new RuntimeException(null !== $customErrorMessage ? $customErrorMessage : sprintf('The `%s` command failed.', $command));
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
private function getLastLine(array $output)
|
||||
{
|
||||
return array_pop($output);
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Util;
|
||||
|
||||
/**
|
||||
* An SVN commit.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class SvnCommit
|
||||
{
|
||||
private $svnInfo;
|
||||
|
||||
/**
|
||||
* Creates a commit from the given "svn info" data.
|
||||
*
|
||||
* @param \SimpleXMLElement $svnInfo the XML result from the "svn info" command
|
||||
*/
|
||||
public function __construct(\SimpleXMLElement $svnInfo)
|
||||
{
|
||||
$this->svnInfo = $svnInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the revision of the commit.
|
||||
*
|
||||
* @return string The revision of the commit
|
||||
*/
|
||||
public function getRevision()
|
||||
{
|
||||
return (string) $this->svnInfo['revision'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the author of the commit.
|
||||
*
|
||||
* @return string The author name
|
||||
*/
|
||||
public function getAuthor()
|
||||
{
|
||||
return (string) $this->svnInfo->author;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date of the commit.
|
||||
*
|
||||
* @return string The commit date
|
||||
*/
|
||||
public function getDate()
|
||||
{
|
||||
return (string) $this->svnInfo->date;
|
||||
}
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Intl\Util;
|
||||
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Intl\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* A SVN repository containing ICU data.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class SvnRepository
|
||||
{
|
||||
/**
|
||||
* @var string The path to the repository
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* @var \SimpleXMLElement
|
||||
*/
|
||||
private $svnInfo;
|
||||
|
||||
/**
|
||||
* @var SvnCommit
|
||||
*/
|
||||
private $lastCommit;
|
||||
|
||||
/**
|
||||
* Downloads the ICU data for the given version.
|
||||
*
|
||||
* @param string $url The URL to download from
|
||||
* @param string $targetDir The directory in which to store the repository
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @throws RuntimeException if an error occurs during the download
|
||||
*/
|
||||
public static function download($url, $targetDir)
|
||||
{
|
||||
exec('which svn', $output, $result);
|
||||
|
||||
if (0 !== $result) {
|
||||
throw new RuntimeException('The command "svn" is not installed.');
|
||||
}
|
||||
|
||||
$filesystem = new Filesystem();
|
||||
|
||||
if (!$filesystem->exists($targetDir.'/.svn')) {
|
||||
$filesystem->remove($targetDir);
|
||||
$filesystem->mkdir($targetDir);
|
||||
|
||||
exec('svn checkout '.$url.' '.$targetDir, $output, $result);
|
||||
|
||||
if (0 !== $result) {
|
||||
throw new RuntimeException('The SVN checkout of '.$url.'failed.');
|
||||
}
|
||||
}
|
||||
|
||||
return new static(realpath($targetDir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the SVN repository at the given path.
|
||||
*
|
||||
* @param string $path The path to the repository
|
||||
*/
|
||||
public function __construct(string $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the repository.
|
||||
*
|
||||
* @return string The path to the repository
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the repository.
|
||||
*
|
||||
* @return string The URL of the repository
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return (string) $this->getSvnInfo()->entry->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last commit of the repository.
|
||||
*
|
||||
* @return SvnCommit The last commit
|
||||
*/
|
||||
public function getLastCommit()
|
||||
{
|
||||
if (null === $this->lastCommit) {
|
||||
$this->lastCommit = new SvnCommit($this->getSvnInfo()->entry->commit);
|
||||
}
|
||||
|
||||
return $this->lastCommit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the SVN repository.
|
||||
*
|
||||
* @return \SimpleXMLElement The XML result from the "svn info" command
|
||||
*
|
||||
* @throws RuntimeException if the "svn info" command failed
|
||||
*/
|
||||
private function getSvnInfo()
|
||||
{
|
||||
if (null === $this->svnInfo) {
|
||||
exec('svn info --xml '.$this->path, $output, $result);
|
||||
|
||||
$svnInfo = simplexml_load_string(implode("\n", $output));
|
||||
|
||||
if (0 !== $result) {
|
||||
throw new RuntimeException('svn info failed');
|
||||
}
|
||||
|
||||
$this->svnInfo = $svnInfo;
|
||||
}
|
||||
|
||||
return $this->svnInfo;
|
||||
}
|
||||
}
|
Reference in New Issue