Use uris for paths in git source descriptions (#3063)
diff --git a/lib/src/source/git.dart b/lib/src/source/git.dart
index 0e9728d..5f1def9 100644
--- a/lib/src/source/git.dart
+++ b/lib/src/source/git.dart
@@ -142,6 +142,8 @@
return {'relative': relative, 'url': url};
}
+ /// Returns [path] normalized.
+ ///
/// Throws a [FormatException] if [path] isn't a relative url or null.
String _validatedPath(dynamic path) {
path ??= '.';
@@ -161,7 +163,7 @@
"The 'path' field of the description must not reach outside the "
'repository.');
}
- return p.normalize(parsed.toString());
+ return p.url.normalize(parsed.toString());
}
/// If [description] has a resolved ref, print it out in short-form.
@@ -352,7 +354,7 @@
return Package.load(
id.name,
- p.join(revisionCachePath, id.description['path']),
+ p.join(revisionCachePath, p.fromUri(id.description['path'])),
systemCache.sources);
});
}
diff --git a/test/get/git/path_test.dart b/test/get/git/path_test.dart
index 4831bd2..8bbd9e7 100644
--- a/test/get/git/path_test.dart
+++ b/test/get/git/path_test.dart
@@ -6,6 +6,8 @@
import 'package:path/path.dart' as p;
import 'package:pub/src/io.dart';
+import 'package:pub/src/lock_file.dart';
+import 'package:pub/src/source_registry.dart';
import 'package:test/test.dart';
import '../../descriptor.dart' as d;
@@ -47,14 +49,14 @@
var repo = d.git('foo.git', [
d.dir('sub', [
- d.dir('dir', [d.libPubspec('sub', '1.0.0'), d.libDir('sub', '1.0.0')])
+ d.dir('dir%', [d.libPubspec('sub', '1.0.0'), d.libDir('sub', '1.0.0')])
])
]);
await repo.create();
await d.appDir({
'sub': {
- 'git': {'url': '../foo.git', 'path': 'sub/dir'}
+ 'git': {'url': '../foo.git', 'path': 'sub/dir%25'}
}
}).create();
@@ -65,15 +67,65 @@
d.dir('cache', [d.gitPackageRepoCacheDir('foo')]),
d.hashDir('foo', [
d.dir('sub', [
- d.dir('dir', [d.libDir('sub', '1.0.0')])
+ d.dir('dir%', [d.libDir('sub', '1.0.0')])
])
])
])
]).validate();
await d.appPackagesFile({
- 'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir')
+ 'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25')
}).validate();
+
+ final lockFile = LockFile.load(
+ p.join(d.sandbox, appPath, 'pubspec.lock'), SourceRegistry());
+
+ expect(lockFile.packages['sub'].description['path'], 'sub/dir%25',
+ reason: 'use uris to specify the path relative to the repo');
+ });
+
+ test('depends on a package in a deep subdirectory, non-relative uri',
+ () async {
+ ensureGit();
+
+ var repo = d.git('foo.git', [
+ d.dir('sub', [
+ d.dir('dir%', [d.libPubspec('sub', '1.0.0'), d.libDir('sub', '1.0.0')])
+ ])
+ ]);
+ await repo.create();
+
+ await d.appDir({
+ 'sub': {
+ 'git': {
+ 'url': p.toUri(p.join(d.sandbox, 'foo.git')).toString(),
+ 'path': 'sub/dir%25'
+ }
+ }
+ }).create();
+
+ await pubGet();
+
+ await d.dir(cachePath, [
+ d.dir('git', [
+ d.dir('cache', [d.gitPackageRepoCacheDir('foo')]),
+ d.hashDir('foo', [
+ d.dir('sub', [
+ d.dir('dir%', [d.libDir('sub', '1.0.0')])
+ ])
+ ])
+ ])
+ ]).validate();
+
+ await d.appPackagesFile({
+ 'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25')
+ }).validate();
+
+ final lockFile = LockFile.load(
+ p.join(d.sandbox, appPath, 'pubspec.lock'), SourceRegistry());
+
+ expect(lockFile.packages['sub'].description['path'], 'sub/dir%25',
+ reason: 'use uris to specify the path relative to the repo');
});
test('depends on multiple packages in subdirectories', () async {