Skip to content

Commit 2d13833

Browse files
committed
Fix handling one-letter git refs in lockfile paths
Add regression tests for Windows absolute base lock paths and one-letter ref:path syntax.
1 parent a86957e commit 2d13833

2 files changed

Lines changed: 60 additions & 2 deletions

File tree

src/PackageDiff.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,11 @@ private function getFileContents($path, $lockFile = true)
213213
return file_get_contents($localPath);
214214
}
215215

216-
if ($lockFile && false === strpos($originalPath, self::GIT_SEPARATOR) && $this->looksLikeComposerLockFile($localPath)) {
216+
if ($lockFile && !$this->containsGitSeparator($originalPath) && $this->looksLikeComposerLockFile($localPath)) {
217217
return '{}';
218218
}
219219

220-
if (false === strpos($originalPath, self::GIT_SEPARATOR)) {
220+
if (!$this->containsGitSeparator($originalPath)) {
221221
$path .= self::GIT_SEPARATOR.self::COMPOSER.($lockFile ? self::EXTENSION_LOCK : self::EXTENSION_JSON);
222222
}
223223

@@ -265,6 +265,29 @@ private function isMissingFileError($gitOutput)
265265
return false !== stripos($gitOutput, 'does not exist in') || false !== stripos($gitOutput, 'exists on disk, but not in');
266266
}
267267

268+
/**
269+
* @param string $path
270+
*
271+
* @return bool
272+
*/
273+
private function containsGitSeparator($path)
274+
{
275+
$pos = strpos($path, self::GIT_SEPARATOR);
276+
277+
if (false === $pos) {
278+
return false;
279+
}
280+
281+
// Ignore Windows absolute drive paths (e.g. "C:\path" or "C:/path").
282+
if (1 === $pos && ctype_alpha($path[0])) {
283+
if (isset($path[2]) && ('\\' === $path[2] || '/' === $path[2])) {
284+
return false;
285+
}
286+
}
287+
288+
return true;
289+
}
290+
268291
/**
269292
* @param string $path
270293
*

tests/PackageDiffTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,41 @@ public function testDiffAgainstMissingGitLockFilePath()
189189
}
190190
}
191191

192+
public function testDiffAgainstMissingWindowsAbsoluteBaseLockFile()
193+
{
194+
$diff = new PackageDiff();
195+
196+
$prodOperations = $diff->getPackageDiff(
197+
'C:\\tmp\\missing\\composer.lock',
198+
__DIR__.'/fixtures/empty-target/composer.lock',
199+
false,
200+
false
201+
);
202+
$devOperations = $diff->getPackageDiff(
203+
'C:\\tmp\\missing\\composer.lock',
204+
__DIR__.'/fixtures/empty-target/composer.lock',
205+
true,
206+
false
207+
);
208+
209+
$this->assertSame(array(
210+
'install example/package 1.2.3',
211+
), array_map(array($this, 'entryToString'), $prodOperations->getArrayCopy()));
212+
$this->assertSame(array(
213+
'install example/dev-package 2.3.4',
214+
), array_map(array($this, 'entryToString'), $devOperations->getArrayCopy()));
215+
}
216+
217+
public function testOneLetterGitRefPath()
218+
{
219+
$diff = new PackageDiff();
220+
$this->prepareGit();
221+
exec('git branch -f z');
222+
$operations = $diff->getPackageDiff('z:composer.lock', '', false, false);
223+
224+
$this->assertNotEmpty($operations);
225+
}
226+
192227
public function diffOperationsProvider()
193228
{
194229
return array(

0 commit comments

Comments
 (0)