Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Unified Diff: lib/src/package.dart

Issue 1862833002: Resolve symlinks when publishing from Git repos. (Closed) Base URL: git@github.com:dart-lang/pub.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/package.dart
diff --git a/lib/src/package.dart b/lib/src/package.dart
index 2ba4c3eef34f54ba132a656ea5570b9c1b9a77d3..e82f4da0306ea43aed9150cf63e1a16bad65f5c5 100644
--- a/lib/src/package.dart
+++ b/lib/src/package.dart
@@ -252,9 +252,14 @@ class Package {
files = files.map((file) {
if (Platform.operatingSystem != 'windows') return "$dir/$file";
return "$dir\\${file.replaceAll("/", "\\")}";
- }).where((file) {
- // Filter out broken symlinks, since git doesn't do so automatically.
- return fileExists(file);
+ }).expand((file) {
+ if (fileExists(file)) return [file];
+ if (!dirExists(file)) return [];
+
+ // `git ls-files` only returns files, except in the case of a symlink to
+ // a directory. So if we're here, [file] refers to a valid symlink to a
+ // directory.
+ return recursive ? _listSymlinkedDir(file) : [file];
});
} else {
files = listDir(beneath, recursive: recursive, includeDirs: false,
@@ -279,6 +284,38 @@ class Package {
}).toList();
}
+ /// List all files recursively beneath [link], which should be a symlink to a
+ /// directory.
+ ///
+ /// This is used by [list] when listing a Git repository, since `git ls-files`
+ /// can't natively follow symlinks.
+ Iterable<String> _listSymlinkedDir(String link) {
+ assert(linkExists(link));
+ assert(dirExists(link));
+ assert(p.isWithin(dir, link));
+
+ var target = new Directory(link).resolveSymbolicLinksSync();
+
+ List<String> targetFiles;
+ if (p.isWithin(dir, target)) {
+ // If the link points within this repo, use git to list the target
+ // location so we respect .gitignore.
+ targetFiles = listFiles(
+ beneath: p.relative(target, from: dir),
+ recursive: true,
+ useGitIgnore: true);
+ } else {
+ // If the link points outside this repo, just use the default listing
+ // logic.
+ targetFiles = listDir(target, recursive: true, includeDirs: false,
+ whitelist: _WHITELISTED_FILES);
+ }
+
+ // Re-write the paths so they're underneath the symlink.
+ return targetFiles.map((targetFile) =>
+ p.join(link, p.relative(targetFile, from: target)));
+ }
+
/// Returns a debug string for the package.
String toString() => '$name $version ($dir)';
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698