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

Unified Diff: sdk/lib/_internal/pub_generated/lib/src/global_packages.dart

Issue 566093003: Create binstubs for executables when activating a package. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revise! Created 6 years, 3 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
Index: sdk/lib/_internal/pub_generated/lib/src/global_packages.dart
diff --git a/sdk/lib/_internal/pub_generated/lib/src/global_packages.dart b/sdk/lib/_internal/pub_generated/lib/src/global_packages.dart
index 85a1983f66e66f026736507a0325d3125e37b403..7035105649086102fafdaebc48d3a51b6b6737f7 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/global_packages.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/global_packages.dart
@@ -11,18 +11,22 @@ import 'lock_file.dart';
import 'log.dart' as log;
import 'package.dart';
import 'pubspec.dart';
-import 'system_cache.dart';
+import 'sdk.dart' as sdk;
import 'solver/version_solver.dart';
import 'source/cached.dart';
import 'source/git.dart';
import 'source/path.dart';
+import 'system_cache.dart';
import 'utils.dart';
import 'version.dart';
+final _binStubPackagePattern = new RegExp(r"Package: ([a-zA-Z0-9_-]+)");
class GlobalPackages {
final SystemCache cache;
String get _directory => p.join(cache.rootDir, "global_packages");
+ String get _binStubDir => p.join(cache.rootDir, "bin");
GlobalPackages(this.cache);
- Future activateGit(String repo) {
+ Future activateGit(String repo, List<String> executables,
+ {bool overwriteBinStubs}) {
final completer0 = new Completer();
scheduleMicrotask(() {
try {
@@ -34,7 +38,11 @@ class GlobalPackages {
_installInCache(
new PackageDep(name, "git", VersionConstraint.any, repo)).then((x1) {
try {
- x1;
+ var package = x1;
+ _updateBinStubs(
+ package,
+ executables,
+ overwriteBinStubs: overwriteBinStubs);
completer0.complete(null);
} catch (e1) {
completer0.completeError(e1);
@@ -54,11 +62,35 @@ class GlobalPackages {
});
return completer0.future;
}
- Future activateHosted(String name, VersionConstraint constraint) {
- _describeActive(name);
- return _installInCache(new PackageDep(name, "hosted", constraint, name));
+ Future activateHosted(String name, VersionConstraint constraint,
+ List<String> executables, {bool overwriteBinStubs}) {
+ final completer0 = new Completer();
+ scheduleMicrotask(() {
+ try {
+ _describeActive(name);
+ _installInCache(
+ new PackageDep(name, "hosted", constraint, name)).then((x0) {
+ try {
+ var package = x0;
+ _updateBinStubs(
+ package,
+ executables,
+ overwriteBinStubs: overwriteBinStubs);
+ completer0.complete(null);
+ } catch (e0) {
+ completer0.completeError(e0);
+ }
+ }, onError: (e1) {
+ completer0.completeError(e1);
+ });
+ } catch (e2) {
+ completer0.completeError(e2);
+ }
+ });
+ return completer0.future;
}
- Future activatePath(String path) {
+ Future activatePath(String path, List<String> executables,
+ {bool overwriteBinStubs}) {
final completer0 = new Completer();
scheduleMicrotask(() {
try {
@@ -77,6 +109,10 @@ class GlobalPackages {
_writeLockFile(name, new LockFile([id]));
var binDir = p.join(_directory, name, 'bin');
join0() {
+ _updateBinStubs(
+ entrypoint.root,
+ executables,
+ overwriteBinStubs: overwriteBinStubs);
completer0.complete(null);
}
if (dirExists(binDir)) {
@@ -97,7 +133,7 @@ class GlobalPackages {
});
return completer0.future;
}
- Future _installInCache(PackageDep dep) {
+ Future<Package> _installInCache(PackageDep dep) {
final completer0 = new Completer();
scheduleMicrotask(() {
try {
@@ -128,7 +164,7 @@ class GlobalPackages {
try {
x3;
_writeLockFile(dep.name, lockFile);
- completer0.complete(null);
+ completer0.complete(graph.packages[dep.name]);
} catch (e3) {
completer0.completeError(e3);
}
@@ -255,14 +291,13 @@ class GlobalPackages {
return null;
}
}
- bool deactivate(String name, {bool logDeactivate: false}) {
+ bool deactivate(String name) {
var dir = p.join(_directory, name);
if (!dirExists(dir)) return false;
- if (logDeactivate) {
- var lockFile = new LockFile.load(_getLockFilePath(name), cache.sources);
- var id = lockFile.packages[name];
- log.message('Deactivated package ${_formatPackage(id)}.');
- }
+ _deleteBinStubs(name);
+ var lockFile = new LockFile.load(_getLockFilePath(name), cache.sources);
+ var id = lockFile.packages[name];
+ log.message('Deactivated package ${_formatPackage(id)}.');
deleteEntry(dir);
return true;
}
@@ -357,4 +392,132 @@ class GlobalPackages {
return '${log.bold(id.name)} ${id.version}';
}
}
+ void _updateBinStubs(Package package, List<String> executables,
+ {bool overwriteBinStubs}) {
+ _deleteBinStubs(package.name);
+ if ((executables != null && executables.isEmpty) ||
+ package.pubspec.executables.isEmpty) {
+ return;
+ }
+ ensureDir(_binStubDir);
+ var installed = [];
+ var collided = {};
+ var allExecutables = ordered(package.pubspec.executables.keys);
+ for (var executable in allExecutables) {
+ if (executables != null && !executables.contains(executable)) continue;
+ var script = package.pubspec.executables[executable];
+ var previousPackage =
+ _createBinStub(package, executable, script, overwrite: overwriteBinStubs);
+ if (previousPackage != null) {
+ collided[executable] = previousPackage;
+ if (!overwriteBinStubs) continue;
+ }
+ installed.add(executable);
+ }
+ if (installed.isNotEmpty) {
+ var names = namedSequence("executable", installed.map(log.bold));
+ log.message("Installed $names.");
+ }
+ if (collided.isNotEmpty) {
+ for (var command in ordered(collided.keys)) {
+ if (overwriteBinStubs) {
+ log.warning(
+ "Replaced ${log.bold(command)} previously installed from "
+ "${log.bold(collided[command])}.");
+ } else {
+ log.warning(
+ "Executable ${log.bold(command)} was already installed "
+ "from ${log.bold(collided[command])}.");
+ }
+ }
+ if (!overwriteBinStubs) {
+ log.warning(
+ "Deactivate the other package(s) or activate "
+ "${log.bold(package.name)} using --overwrite-executables.");
+ }
+ }
+ if (executables != null) {
+ var unknown = ordered(
+ executables.where((exe) => !package.pubspec.executables.keys.contains(exe)));
+ if (unknown.isNotEmpty) {
+ dataError("Unknown ${namedSequence('executable', unknown)}.");
+ }
+ }
+ var binFiles = package.listFiles(
+ beneath: "bin",
+ recursive: false).map((path) => p.relative(path, from: package.dir)).toList();
+ for (var executable in installed) {
+ var script = package.pubspec.executables[executable];
+ var scriptPath = p.join("bin", "$script.dart");
+ if (!binFiles.contains(scriptPath)) {
+ log.warning(
+ 'Warning: Executable "$executable" runs "$scriptPath", '
+ 'which was not found in ${log.bold(package.name)}.');
+ }
+ }
+ }
+ String _createBinStub(Package package, String executable, String script,
+ {bool overwrite}) {
+ var binStubPath = p.join(_binStubDir, executable);
+ var previousPackage;
+ if (fileExists(binStubPath)) {
+ var contents = readTextFile(binStubPath);
+ var match = _binStubPackagePattern.firstMatch(contents);
+ if (match != null) {
+ previousPackage = match[1];
+ if (!overwrite) return previousPackage;
+ } else {
+ log.fine("Could not parse binstub $binStubPath:\n$contents");
+ }
+ }
+ if (Platform.operatingSystem == "windows") {
+ var batch = """
+@echo off
+rem This file was created by pub v${sdk.version}.
+rem Package: ${package.name}
+rem Version: ${package.version}
+rem Executable: ${executable}
+rem Script: ${script}
+pub global run ${package.name}:$script "%*"
+""";
+ writeTextFile(binStubPath, batch);
+ } else {
+ var bash = """
+# This file was created by pub v${sdk.version}.
+# Package: ${package.name}
+# Version: ${package.version}
+# Executable: ${executable}
+# Script: ${script}
+pub global run ${package.name}:$script "\$@"
+""";
+ writeTextFile(binStubPath, bash);
+ var result = Process.runSync('chmod', ['+x', binStubPath]);
+ if (result.exitCode != 0) {
+ try {
+ deleteEntry(binStubPath);
+ } on IOException catch (err) {
+ log.fine("Could not delete binstub:\n$err");
+ }
+ fail(
+ 'Could not make "$binStubPath" executable (exit code '
+ '${result.exitCode}):\n${result.stderr}');
+ }
+ }
+ return previousPackage;
+ }
+ void _deleteBinStubs(String package) {
+ if (!dirExists(_binStubDir)) return;
+ for (var file in listDir(_binStubDir, includeDirs: false)) {
+ var contents = readTextFile(file);
+ var match = _binStubPackagePattern.firstMatch(contents);
+ if (match == null) {
+ log.fine("Could not parse binstub $file:\n$contents");
+ continue;
+ }
+ if (match[1] == package) {
+ log.fine("Deleting old binstub $file");
+ deleteEntry(file);
+ }
+ }
+ }
}

Powered by Google App Engine
This is Rietveld 408576698