Merge pull request #174 from Seldaek/lockdetect
Detect lock file changes and warn users on install, fixes #75pull/188/merge
commit
35c62f67be
|
@ -85,7 +85,7 @@ EOT
|
|||
// creating requirements request
|
||||
$request = new Request($pool);
|
||||
if ($update) {
|
||||
$output->writeln('<info>Updating dependencies.</info>');
|
||||
$output->writeln('<info>Updating dependencies</info>');
|
||||
$installedPackages = $installedRepo->getPackages();
|
||||
$links = $this->collectLinks($input, $composer->getPackage());
|
||||
|
||||
|
@ -100,7 +100,11 @@ EOT
|
|||
$request->install($link->getTarget(), $link->getConstraint());
|
||||
}
|
||||
} elseif ($composer->getLocker()->isLocked()) {
|
||||
$output->writeln('<info>Installing from lockfile.</info> (Run "composer update" to add or update packages)');
|
||||
$output->writeln('<info>Installing from lock file</info>');
|
||||
|
||||
if (!$composer->getLocker()->isFresh()) {
|
||||
$output->writeln('<warning>Your lock file is out of sync with your composer.json, run "composer.phar update" to update dependencies</warning>');
|
||||
}
|
||||
|
||||
foreach ($composer->getLocker()->getLockedPackages() as $package) {
|
||||
$constraint = new VersionConstraint('=', $package->getVersion());
|
||||
|
@ -150,6 +154,9 @@ EOT
|
|||
}
|
||||
|
||||
// execute operations
|
||||
if (!$operations) {
|
||||
$output->writeln('<info>Nothing to install/update</info>');
|
||||
}
|
||||
foreach ($operations as $operation) {
|
||||
if ($verbose) {
|
||||
$output->writeln((string) $operation);
|
||||
|
@ -162,7 +169,7 @@ EOT
|
|||
if (!$dryRun) {
|
||||
if ($update || !$composer->getLocker()->isLocked()) {
|
||||
$composer->getLocker()->lockPackages($localRepo->getPackages());
|
||||
$output->writeln('<info>Locked</info>');
|
||||
$output->writeln('<info>Writing lock file</info>');
|
||||
}
|
||||
|
||||
$localRepo->write();
|
||||
|
@ -171,8 +178,6 @@ EOT
|
|||
$generator = new AutoloadGenerator;
|
||||
$generator->dump($localRepo, $composer->getPackage(), $installationManager, $installationManager->getVendorPath().'/.composer');
|
||||
}
|
||||
|
||||
$output->writeln('<info>Done</info>');
|
||||
}
|
||||
|
||||
private function collectLinks(InputInterface $input, PackageInterface $package)
|
||||
|
|
|
@ -49,6 +49,7 @@ class Application extends BaseApplication
|
|||
{
|
||||
if (null === $output) {
|
||||
$styles['highlight'] = new OutputFormatterStyle('red');
|
||||
$styles['warning'] = new OutputFormatterStyle('black', 'yellow');
|
||||
$formatter = new OutputFormatter(null, $styles);
|
||||
$output = new ConsoleOutput(ConsoleOutput::VERBOSITY_NORMAL, null, $formatter);
|
||||
}
|
||||
|
@ -152,7 +153,7 @@ class Application extends BaseApplication
|
|||
|
||||
// init locker
|
||||
$lockFile = substr($composerFile, -5) === '.json' ? substr($composerFile, 0, -4).'lock' : $composerFile . '.lock';
|
||||
$locker = new Package\Locker(new JsonFile($lockFile), $rm);
|
||||
$locker = new Package\Locker(new JsonFile($lockFile), $rm, md5_file($composerFile));
|
||||
|
||||
// initialize composer
|
||||
$composer = new Composer();
|
||||
|
|
|
@ -24,33 +24,48 @@ class Locker
|
|||
{
|
||||
private $lockFile;
|
||||
private $repositoryManager;
|
||||
private $hash;
|
||||
|
||||
/**
|
||||
* Initializes packages locker.
|
||||
*
|
||||
* @param JsonFile $lockFile lockfile loader
|
||||
* @param RepositoryManager $repositoryManager repository manager instance
|
||||
* @param JsonFile $lockFile lockfile loader
|
||||
* @param RepositoryManager $repositoryManager repository manager instance
|
||||
* @param string $hash unique hash of the current composer configuration
|
||||
*/
|
||||
public function __construct(JsonFile $lockFile, RepositoryManager $repositoryManager)
|
||||
public function __construct(JsonFile $lockFile, RepositoryManager $repositoryManager, $hash)
|
||||
{
|
||||
$this->lockFile = $lockFile;
|
||||
$this->repositoryManager = $repositoryManager;
|
||||
$this->hash = $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether locker were been locked (lockfile found).
|
||||
*
|
||||
* @return Boolean
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isLocked()
|
||||
{
|
||||
return $this->lockFile->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the lock file is still up to date with the current hash
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isFresh()
|
||||
{
|
||||
$lock = $this->lockFile->read();
|
||||
|
||||
return $this->hash === $lock['hash'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches and returns an array of locked packages, retrieved from registered repositories.
|
||||
*
|
||||
* @return array
|
||||
* @return array
|
||||
*/
|
||||
public function getLockedPackages()
|
||||
{
|
||||
|
@ -60,7 +75,7 @@ class Locker
|
|||
|
||||
$lockList = $this->lockFile->read();
|
||||
$packages = array();
|
||||
foreach ($lockList as $info) {
|
||||
foreach ($lockList['packages'] as $info) {
|
||||
$package = $this->repositoryManager->getLocalRepository()->findPackage($info['package'], $info['version']);
|
||||
|
||||
if (!$package) {
|
||||
|
@ -83,11 +98,14 @@ class Locker
|
|||
/**
|
||||
* Locks provided packages into lockfile.
|
||||
*
|
||||
* @param array $packages array of packages
|
||||
* @param array $packages array of packages
|
||||
*/
|
||||
public function lockPackages(array $packages)
|
||||
{
|
||||
$hash = array();
|
||||
$lock = array(
|
||||
'hash' => $this->hash,
|
||||
'packages' => array(),
|
||||
);
|
||||
foreach ($packages as $package) {
|
||||
$name = $package->getPrettyName();
|
||||
$version = $package->getPrettyVersion();
|
||||
|
@ -98,9 +116,9 @@ class Locker
|
|||
));
|
||||
}
|
||||
|
||||
$hash[] = array('package' => $name, 'version' => $version);
|
||||
$lock['packages'][] = array('package' => $name, 'version' => $version);
|
||||
}
|
||||
|
||||
$this->lockFile->write($hash);
|
||||
$this->lockFile->write($lock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
public function testIsLocked()
|
||||
{
|
||||
$json = $this->createJsonFileMock();
|
||||
$locker = new Locker($json, $this->createRepositoryManagerMock());
|
||||
$locker = new Locker($json, $this->createRepositoryManagerMock(), 'md5');
|
||||
|
||||
$json
|
||||
->expects($this->once())
|
||||
|
@ -34,7 +34,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
$json = $this->createJsonFileMock();
|
||||
$repo = $this->createRepositoryManagerMock();
|
||||
|
||||
$locker = new Locker($json, $repo);
|
||||
$locker = new Locker($json, $repo, 'md5');
|
||||
|
||||
$json
|
||||
->expects($this->once())
|
||||
|
@ -51,7 +51,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
$json = $this->createJsonFileMock();
|
||||
$repo = $this->createRepositoryManagerMock();
|
||||
|
||||
$locker = new Locker($json, $repo);
|
||||
$locker = new Locker($json, $repo, 'md5');
|
||||
|
||||
$json
|
||||
->expects($this->once())
|
||||
|
@ -61,8 +61,10 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
->expects($this->once())
|
||||
->method('read')
|
||||
->will($this->returnValue(array(
|
||||
array('package' => 'pkg1', 'version' => '1.0.0-beta'),
|
||||
array('package' => 'pkg2', 'version' => '0.1.10')
|
||||
'packages' => array(
|
||||
array('package' => 'pkg1', 'version' => '1.0.0-beta'),
|
||||
array('package' => 'pkg2', 'version' => '0.1.10')
|
||||
)
|
||||
)));
|
||||
|
||||
$package1 = $this->createPackageMock();
|
||||
|
@ -82,7 +84,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
$json = $this->createJsonFileMock();
|
||||
$repo = $this->createRepositoryManagerMock();
|
||||
|
||||
$locker = new Locker($json, $repo);
|
||||
$locker = new Locker($json, $repo, 'md5');
|
||||
|
||||
$json
|
||||
->expects($this->once())
|
||||
|
@ -92,8 +94,10 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
->expects($this->once())
|
||||
->method('read')
|
||||
->will($this->returnValue(array(
|
||||
array('package' => 'pkg1', 'version' => '1.0.0-beta'),
|
||||
array('package' => 'pkg2', 'version' => '0.1.10')
|
||||
'packages' => array(
|
||||
array('package' => 'pkg1', 'version' => '1.0.0-beta'),
|
||||
array('package' => 'pkg2', 'version' => '0.1.10')
|
||||
)
|
||||
)));
|
||||
|
||||
$package1 = $this->createPackageMock();
|
||||
|
@ -115,7 +119,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
$json = $this->createJsonFileMock();
|
||||
$repo = $this->createRepositoryManagerMock();
|
||||
|
||||
$locker = new Locker($json, $repo);
|
||||
$locker = new Locker($json, $repo, 'md5');
|
||||
|
||||
$package1 = $this->createPackageMock();
|
||||
$package2 = $this->createPackageMock();
|
||||
|
@ -142,8 +146,11 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
->expects($this->once())
|
||||
->method('write')
|
||||
->with(array(
|
||||
array('package' => 'pkg1', 'version' => '1.0.0-beta'),
|
||||
array('package' => 'pkg2', 'version' => '0.1.10')
|
||||
'hash' => 'md5',
|
||||
'packages' => array(
|
||||
array('package' => 'pkg1', 'version' => '1.0.0-beta'),
|
||||
array('package' => 'pkg2', 'version' => '0.1.10')
|
||||
),
|
||||
));
|
||||
|
||||
$locker->lockPackages(array($package1, $package2));
|
||||
|
@ -154,7 +161,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
$json = $this->createJsonFileMock();
|
||||
$repo = $this->createRepositoryManagerMock();
|
||||
|
||||
$locker = new Locker($json, $repo);
|
||||
$locker = new Locker($json, $repo, 'md5');
|
||||
|
||||
$package1 = $this->createPackageMock();
|
||||
$package1
|
||||
|
@ -167,6 +174,36 @@ class LockerTest extends \PHPUnit_Framework_TestCase
|
|||
$locker->lockPackages(array($package1));
|
||||
}
|
||||
|
||||
public function testIsFresh()
|
||||
{
|
||||
$json = $this->createJsonFileMock();
|
||||
$repo = $this->createRepositoryManagerMock();
|
||||
|
||||
$locker = new Locker($json, $repo, 'md5');
|
||||
|
||||
$json
|
||||
->expects($this->once())
|
||||
->method('read')
|
||||
->will($this->returnValue(array('hash' => 'md5')));
|
||||
|
||||
$this->assertTrue($locker->isFresh());
|
||||
}
|
||||
|
||||
public function testIsFreshFalse()
|
||||
{
|
||||
$json = $this->createJsonFileMock();
|
||||
$repo = $this->createRepositoryManagerMock();
|
||||
|
||||
$locker = new Locker($json, $repo, 'md5');
|
||||
|
||||
$json
|
||||
->expects($this->once())
|
||||
->method('read')
|
||||
->will($this->returnValue(array('hash' => 'oldmd5')));
|
||||
|
||||
$this->assertFalse($locker->isFresh());
|
||||
}
|
||||
|
||||
private function createJsonFileMock()
|
||||
{
|
||||
return $this->getMockBuilder('Composer\Json\JsonFile')
|
||||
|
|
Loading…
Reference in New Issue