Skip to content

Commit 1444dd5

Browse files
authored
Merge pull request #10 from InvisibleSmiley/Issue-9
Fix splitting version strings with userinfo in URL
2 parents 8f2dbe7 + c2e5432 commit 1444dd5

File tree

2 files changed

+66
-21
lines changed

2 files changed

+66
-21
lines changed

src/Parser.php

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -216,20 +216,21 @@ function ($e) {
216216
}
217217

218218
/**
219-
* To avoid splitting on scoped package-names, every but the last @ are considered
220-
* package name.
221-
*
222219
* @param string $versionString
223-
*
224-
* @return string[]
220+
* @return array{string, string}
221+
* @throws ParserException
225222
*/
226223
public static function splitVersionString($versionString)
227224
{
228-
$parts = explode('@', $versionString);
229-
$version = array_pop($parts);
230-
return [
231-
implode('@', $parts),
232-
$version
233-
];
225+
// Scoped package names start with an "@" → skip the first character.
226+
// Note: $versionString may contain even more than two "@" if version is "protocol://user@host..."
227+
$location = strpos($versionString, '@', 1);
228+
if ($location > 0) {
229+
$name = substr($versionString, 0, $location);
230+
$version = substr($versionString, $location + 1);
231+
return [$name, $version];
232+
}
233+
234+
throw new ParserException('Invalid version string: ' . $versionString, 1729855362);
234235
}
235236
}

tests/src/Unit/ParserTest.php

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -218,21 +218,65 @@ public function testYarnExampleArray()
218218
}
219219

220220
/**
221-
* Scoped packages names should not be split at the first '@'
221+
* The parser should split the package name and version parts
222+
*
223+
* Scoped packages names (prefixed with @) and Git version references should be detected properly.
224+
*
225+
* @param string $versionString
226+
* @param array{string, string} $expectedResult
227+
* @dataProvider provideVersionsForSplitting
228+
* @return void
222229
*/
223-
public function testVersionSplitting()
230+
public function testVersionSplitting($versionString, array $expectedResult)
224231
{
225-
static::assertSame(
226-
['gulp-sourcemaps', '2.6.4'],
227-
Parser::splitVersionString('[email protected]')
228-
);
232+
self::assertSame($expectedResult, Parser::splitVersionString($versionString));
233+
}
229234

230-
static::assertSame(
231-
['@gulp-sourcemaps/identity-map', '1.X'],
232-
Parser::splitVersionString('@gulp-sourcemaps/[email protected]')
233-
);
235+
/**
236+
* @return array<string, array{
237+
* versionString: string,
238+
* expectedResult: array{string, string}
239+
* }>
240+
*/
241+
public static function provideVersionsForSplitting(): array
242+
{
243+
return [
244+
'simple package, simple version' => [
245+
'versionString' => '[email protected]',
246+
'expectedResult' => ['gulp-sourcemaps', '2.6.4'],
247+
],
248+
'namespaced package, simple version' => [
249+
'versionString' => '@gulp-sourcemaps/[email protected]',
250+
'expectedResult' => ['@gulp-sourcemaps/identity-map', '1.X'],
251+
],
252+
'simple package, Git semver reference' => [
253+
'versionString' => 'foo-bar@git+ssh://user@host:1234/foo/bar#semver:^1.2.3',
254+
'expectedResult' => ['foo-bar', 'git+ssh://user@host:1234/foo/bar#semver:^1.2.3'],
255+
],
256+
'namespaced package, Git semver reference' => [
257+
'versionString' => '@foo/bar@git+ssh://user@host:1234/foo/bar#semver:^1.2.3',
258+
'expectedResult' => ['@foo/bar', 'git+ssh://user@host:1234/foo/bar#semver:^1.2.3'],
259+
],
260+
'simple package, Git tag reference' => [
261+
'versionString' => 'foo-bar@git://user@host/foo/bar.git#v1.2.3',
262+
'expectedResult' => ['foo-bar', 'git://user@host/foo/bar.git#v1.2.3'],
263+
],
264+
'namespaced package, Git tag reference' => [
265+
'versionString' => '@foo/bar@git://user@host/foo/bar.git#v1.2.3',
266+
'expectedResult' => ['@foo/bar', 'git://user@host/foo/bar.git#v1.2.3'],
267+
],
268+
'simple package, file reference' => [
269+
'versionString' => 'foo-bar@file:vendor/foo/bar',
270+
'expectedResult' => ['foo-bar', 'file:vendor/foo/bar'],
271+
],
272+
'namespaced package, file reference' => [
273+
'versionString' => '@foo/bar@file:vendor/foo/bar',
274+
'expectedResult' => ['@foo/bar', 'file:vendor/foo/bar'],
275+
],
276+
];
234277
}
235278

279+
236280
/**
237281
* Single-value keys should not be split at spaces if they are surrounded with quotes
238282
* @throws ParserException

0 commit comments

Comments
 (0)