Skip to content

Commit 1d7c65b

Browse files
committed
fix: handle missing composer.lock paths as empty
1 parent a4085e9 commit 1d7c65b

3 files changed

Lines changed: 66 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ composer diff --help # Display detailed usage instructions
8383
```shell script
8484
composer diff master # Compare current composer.lock with the one on master branch
8585
composer diff master:composer.lock develop:composer.lock -p # Compare master and develop branches, including platform dependencies
86-
composer diff /path/to/empty/composer.lock composer.lock # Compare a new lock file against an empty base
86+
composer diff /path/to/missing/composer.lock composer.lock # Compare a new lock file against a non-existing base lock file
8787
composer diff --no-dev # ignore dev dependencies
8888
composer diff -p # include platform dependencies
8989
composer diff -f json # Output as JSON instead of table

src/PackageDiff.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ private function getFileContents($path, $lockFile = true)
213213
return $this->normalizeFileContents(file_get_contents($localPath));
214214
}
215215

216+
if ($lockFile && false === strpos($originalPath, self::GIT_SEPARATOR) && $this->looksLikeComposerLockFile($localPath)) {
217+
return '{}';
218+
}
219+
216220
if (false === strpos($originalPath, self::GIT_SEPARATOR)) {
217221
$path .= self::GIT_SEPARATOR.self::COMPOSER.($lockFile ? self::EXTENSION_LOCK : self::EXTENSION_JSON);
218222
}
@@ -226,6 +230,10 @@ private function getFileContents($path, $lockFile = true)
226230
$outputString = implode("\n", $output);
227231

228232
if (0 !== $exit) {
233+
if ($lockFile && $this->isMissingFileError($outputString)) {
234+
return '{}';
235+
}
236+
229237
if ($lockFile) {
230238
throw new \RuntimeException(sprintf('Could not open file %s or find it in git as %s: %s', $originalPath, $path, $outputString));
231239
}
@@ -237,6 +245,26 @@ private function getFileContents($path, $lockFile = true)
237245
return $this->normalizeFileContents($outputString);
238246
}
239247

248+
/**
249+
* @param string $path
250+
*
251+
* @return bool
252+
*/
253+
private function looksLikeComposerLockFile($path)
254+
{
255+
return self::EXTENSION_LOCK === substr($path, -strlen(self::EXTENSION_LOCK));
256+
}
257+
258+
/**
259+
* @param string $gitOutput
260+
*
261+
* @return bool
262+
*/
263+
private function isMissingFileError($gitOutput)
264+
{
265+
return false !== stripos($gitOutput, 'does not exist in') || false !== stripos($gitOutput, 'exists on disk, but not in');
266+
}
267+
240268
/**
241269
* @param string $contents
242270
*

tests/PackageDiffTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,43 @@ public function testDiffAgainstEmptyBaseLockFile()
177177
), array_map(array($this, 'entryToString'), $devOperations->getArrayCopy()));
178178
}
179179

180+
public function testDiffAgainstMissingBaseLockFile()
181+
{
182+
$diff = new PackageDiff();
183+
184+
$prodOperations = $diff->getPackageDiff(
185+
__DIR__.'/fixtures/missing/composer.lock',
186+
__DIR__.'/fixtures/empty-target/composer.lock',
187+
false,
188+
false
189+
);
190+
$devOperations = $diff->getPackageDiff(
191+
__DIR__.'/fixtures/missing/composer.lock',
192+
__DIR__.'/fixtures/empty-target/composer.lock',
193+
true,
194+
false
195+
);
196+
197+
$this->assertSame(array(
198+
'install example/package 1.2.3',
199+
), array_map(array($this, 'entryToString'), $prodOperations->getArrayCopy()));
200+
$this->assertSame(array(
201+
'install example/dev-package 2.3.4',
202+
), array_map(array($this, 'entryToString'), $devOperations->getArrayCopy()));
203+
}
204+
205+
public function testDiffAgainstMissingGitLockFilePath()
206+
{
207+
$diff = new PackageDiff();
208+
$this->prepareGit();
209+
$operations = $diff->getPackageDiff('HEAD:missing/composer.lock', '', false, false);
210+
211+
$this->assertNotEmpty($operations);
212+
foreach ($operations as $entry) {
213+
$this->assertInstanceOf('Composer\DependencyResolver\Operation\InstallOperation', $entry->getOperation());
214+
}
215+
}
216+
180217
public function diffOperationsProvider()
181218
{
182219
return array(

0 commit comments

Comments
 (0)