Skip to content

Commit

Permalink
merge to master
Browse files Browse the repository at this point in the history
  • Loading branch information
devoncarew committed Apr 10, 2015
2 parents ee1dd15 + 2d3cdea commit 27fb09e
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 139 deletions.
3 changes: 3 additions & 0 deletions changelog.md
Expand Up @@ -8,6 +8,9 @@
variables. They're injected into the zone running the current task.
- `copyFile` and `copyDirectory` and deprecated in favor of a new `copy` method
- `deleteEntity` is deprecated in favor of a new `delete` method
- Renamed `runProcess`/`runProcessAsync`/`runDartScript` to `run`/`runAsync`/`Dart.run`.
Process result info (stdout, stderr, exitCode) is now exposed by these
methods and some others which call them.
- Added a wrapper class around `pub global activate` applications - `PubApplication`
- Grinder can now create a simple starter script for a project - run `pub run grinder:init`

Expand Down
205 changes: 67 additions & 138 deletions lib/grinder_tools.dart
Expand Up @@ -8,18 +8,21 @@
library grinder.tools;

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;

import 'package:cli_util/cli_util.dart' as cli_util;
import 'package:which/which.dart';

import 'grinder.dart';
import 'src/run.dart' as run_lib;
import 'src/run_utils.dart';
import 'src/utils.dart';
import 'src/_mserve.dart';
import 'src/_wip.dart';

export 'src/run.dart';

final Directory BIN_DIR = new Directory('bin');
final Directory BUILD_DIR = new Directory('build');
final Directory LIB_DIR = new Directory('lib');
Expand All @@ -43,9 +46,10 @@ Directory getSdkDir([List<String> cliArgs]) => cli_util.getSdkDir(cliArgs);

File get dartVM => joinFile(sdkDir, ['bin', _sdkBin('dart')]);

/// Run a dart [script] using [runProcess].
/// Run a dart [script] using [run_lib.run].
///
/// Returns the stdout.
@Deprecated('Use `Dart.run` instead.')
String runDartScript(String script,
{List<String> arguments : const [], bool quiet: false, String packageRoot,
String workingDirectory, int vmNewGenHeapMB, int vmOldGenHeapMB}) {
Expand All @@ -66,92 +70,10 @@ String runDartScript(String script,
args.add(script);
args.addAll(arguments);

return runProcess(_sdkBin('dart'), arguments: args, quiet: quiet,
return run_lib.run(_sdkBin('dart'), arguments: args, quiet: quiet,
workingDirectory: workingDirectory);
}

/// Synchronously run an [executable].
///
/// If [quiet] is false, [log]s the stdout. The stderr is always logged.
///
/// Returns the stdout.
///
/// All other optional parameters are forwarded to [Process.runSync].
String runProcess(String executable,
{List<String> arguments : const [],
bool quiet: false,
String workingDirectory,
Map<String, String> environment}) {
log("${executable} ${arguments.join(' ')}");

ProcessResult result = Process.runSync(
executable, arguments, workingDirectory: workingDirectory,
environment: environment);

if (!quiet) {
if (result.stdout != null && result.stdout.isNotEmpty) {
log(result.stdout.trim());
}
}

if (result.stderr != null && result.stderr.isNotEmpty) {
log(result.stderr);
}

if (result.exitCode != 0) {
throw new ProcessException._(executable, result.exitCode, result.stdout,
result.stderr);
}

return result.stdout;
}

/// Asynchronously run an [executable].
///
/// If [quiet] is false, [log]s the stdout as line breaks are encountered.
/// The stderr is always logged.
///
/// Returns a future for the stdout.
///
/// All other optional parameters are forwarded to [Process.start].
Future<String> runProcessAsync(String executable,
{List<String> arguments : const [],
bool quiet: false,
String workingDirectory}) {

if (!quiet) log("$executable ${arguments.join(' ')}");

List<int> stdout = [], stderr = [];

return Process.start(executable, arguments, workingDirectory: workingDirectory)
.then((Process process) {

// Handle stdout.
var broadcastStdout = process.stdout.asBroadcastStream();
var stdoutLines = _toLineStream(broadcastStdout);
broadcastStdout.listen((List<int> data) => stdout.addAll(data));
if (!quiet) {
stdoutLines.listen(_logStdout);
}

// Handle stderr.
var broadcastStderr = process.stderr.asBroadcastStream();
var stderrLines = _toLineStream(broadcastStderr);
broadcastStderr.listen((List<int> data) => stderr.addAll(data));
stderrLines.listen(_logStderr);

return process.exitCode.then((int code) {
var stdoutString = SYSTEM_ENCODING.decode(stdout);

if (code != 0) {
throw new ProcessException._(executable, code, stdoutString, SYSTEM_ENCODING.decode(stderr));
}

return stdoutString;
});
});
}

/// A default implementation of an `init` task. This task verifies that the
/// grind script is executed from the project root.
@Deprecated('the functionality of this method has been rolled into grinder startup')
Expand Down Expand Up @@ -191,7 +113,7 @@ class Pub {
FileSet publock = new FileSet.fromFile(new File('pubspec.lock'));

if (force || !publock.upToDate(pubspec)) {
return runProcessAsync(_sdkBin('pub'), arguments: ['get'],
return run_lib.runAsync(_sdkBin('pub'), arguments: ['get'],
workingDirectory: workingDirectory).then((_) => null);
}

Expand All @@ -209,7 +131,7 @@ class Pub {
* Run `pub upgrade` on the current project.
*/
static Future upgradeAsync({String workingDirectory}) {
return runProcessAsync(_sdkBin('pub'), arguments: ['upgrade'],
return run_lib.runAsync(_sdkBin('pub'), arguments: ['upgrade'],
workingDirectory: workingDirectory).then((_) => null);
}

Expand All @@ -228,7 +150,7 @@ class Pub {
if (outputDirectory != null) args.add('--output=${outputDirectory}');
if (directories != null && directories.isNotEmpty) args.addAll(directories);

runProcess(_sdkBin('pub'), arguments: args,
run_lib.run(_sdkBin('pub'), arguments: args,
workingDirectory: workingDirectory);
}

Expand All @@ -247,7 +169,7 @@ class Pub {
if (outputDirectory != null) args.add('--output=${outputDirectory}');
if (directories != null && directories.isNotEmpty) args.addAll(directories);

return runProcessAsync(_sdkBin('pub'), arguments: args,
return run_lib.runAsync(_sdkBin('pub'), arguments: args,
workingDirectory: workingDirectory).then((_) => null);
}

Expand All @@ -259,7 +181,7 @@ class Pub {
var scriptArg = script == null ? package : '$package:$script';
List args = ['run', scriptArg];
if (arguments != null) args.addAll(arguments);
return runProcess(_sdkBin('pub'), arguments: args,
return run_lib.run(_sdkBin('pub'), arguments: args,
workingDirectory: workingDirectory);
}

Expand All @@ -269,7 +191,7 @@ class Pub {
static PubGlobal get global => _global;

static String _run(String command, {bool quiet: false, String workingDirectory}) {
return runProcess(_sdkBin('pub'), quiet: quiet, arguments: [command],
return run_lib.run(_sdkBin('pub'), quiet: quiet, arguments: [command],
workingDirectory: workingDirectory);
}
}
Expand All @@ -283,7 +205,7 @@ class PubGlobal {
/// Install a new Dart application.
void activate(String packageName, {bool force: false}) {
if (force || !isActivated(packageName)) {
runProcess(_sdkBin('pub'), arguments: ['global', 'activate', packageName]);
run_lib.run(_sdkBin('pub'), arguments: ['global', 'activate', packageName]);
_activatedPackages.add(packageName);
}
}
Expand All @@ -294,7 +216,7 @@ class PubGlobal {
var scriptArg = script == null ? package : '$package:$script';
List args = ['global', 'run', scriptArg];
if (arguments != null) args.addAll(arguments);
return runProcess(_sdkBin('pub'), arguments: args,
return run_lib.run(_sdkBin('pub'), arguments: args,
workingDirectory: workingDirectory);
}

Expand All @@ -305,7 +227,7 @@ class PubGlobal {
//discoveryapis_generator 0.6.1
//...

var stdout = runProcess(_sdkBin('pub'), arguments: ['global', 'list'], quiet: true);
var stdout = run_lib.run(_sdkBin('pub'), arguments: ['global', 'list'], quiet: true);

var lines = stdout.trim().split('\n');
return lines.map((line) {
Expand Down Expand Up @@ -402,6 +324,46 @@ class _PubLocalApp extends PubApp {
}
}

/// Utility tasks for invoking dart.
class Dart {

/// Run a dart [script] using [run_lib.run].
///
/// Returns the stdout.
static String run(String script,
{List<String> arguments : const [], bool quiet: false,
String packageRoot, String workingDirectory, int vmNewGenHeapMB,
int vmOldGenHeapMB}) {
List<String> args = [];

if (packageRoot != null) {
args.add('--package-root=${packageRoot}');
}

if (vmNewGenHeapMB != null) {
args.add('--new_gen_heap_size=${vmNewGenHeapMB}');
}

if (vmOldGenHeapMB != null) {
args.add('--old_gen_heap_size=${vmOldGenHeapMB}');
}

args.add(script);
args.addAll(arguments);

return run_lib.run(_sdkBin('dart'), arguments: args, quiet: quiet,
workingDirectory: workingDirectory);
}

static String version({bool quiet: false}) {
run_lib.run(_sdkBin('dart'), arguments: ['--version'],
quiet: quiet);
// The stdout does not have a stable documented format, so use the provided
// metadata instead.
return Platform.version.substring(0, Platform.version.indexOf(' '));
}
}

/**
* Utility tasks for invoking dart2js.
*/
Expand All @@ -422,7 +384,7 @@ class Dart2js {
args.add('-o${outFile.path}');
args.add(sourceFile.path);

runProcess(_sdkBin('dart2js'), arguments: args);
run_lib.run(_sdkBin('dart2js'), arguments: args);
}

/**
Expand All @@ -441,15 +403,15 @@ class Dart2js {
args.add('-o${outFile.path}');
args.add(sourceFile.path);

return runProcessAsync(_sdkBin('dart2js'), arguments: args)
return run_lib.runAsync(_sdkBin('dart2js'), arguments: args)
.then((_) => null);
}

static String version({bool quiet: false}) =>
AppVersion.parse(_run('--version', quiet: quiet)).version;

static String _run(String command, {bool quiet: false}) =>
runProcess(_sdkBin('dart2js'), quiet: quiet, arguments: [command]);
run_lib.run(_sdkBin('dart2js'), quiet: quiet, arguments: [command]);
}

/**
Expand All @@ -471,10 +433,10 @@ class Analyzer {
if (fatalWarnings) args.add('--fatal-warnings');
args.addAll(files.map((f) => f is File ? f.path : f));

runProcess(_sdkBin('dartanalyzer'), arguments: args);
run_lib.run(_sdkBin('dartanalyzer'), arguments: args);
}

static String version({bool quiet: false}) => AppVersion.parse(runProcess(
static String version({bool quiet: false}) => AppVersion.parse(run_lib.run(
_sdkBin('dartanalyzer'), quiet: quiet, arguments: ['--version'])).version;
}

Expand All @@ -489,7 +451,7 @@ class Tests {
static void runCliTests({String directory: 'test', String testFile: 'all.dart'}) {
String file = '${directory}/${testFile}';
log('running tests: ${file}...');
runDartScript(file);
Dart.run(file);
}

/**
Expand Down Expand Up @@ -658,7 +620,7 @@ class Chrome {

// TODO: This process often won't terminate, so that's a problem.
log("starting chrome...");
runProcess(browserPath, arguments: args, environment: envVars);
run_lib.run(browserPath, arguments: args, environment: envVars);
}

Future<BrowserInstance> launchUrl(String url,
Expand All @@ -677,12 +639,12 @@ class Chrome {
return Process.start(browserPath, _args, environment: envVars)
.then((Process process) {
// Handle stdout.
var stdoutLines = _toLineStream(process.stdout);
stdoutLines.listen(_logStdout);
var stdoutLines = toLineStream(process.stdout);
stdoutLines.listen(logStdout);

// Handle stderr.
var stderrLines = _toLineStream(process.stderr);
stderrLines.listen(_logStderr);
var stderrLines = toLineStream(process.stderr);
stderrLines.listen(logStderr);

return new BrowserInstance(this, process);
});
Expand Down Expand Up @@ -849,36 +811,3 @@ class AppVersion {

String toString() => '$name $version';
}

/// An exception from a process which exited with a non-zero exit code.
class ProcessException {
final String executable;
final int exitCode;
final String stdout;
final String stderr;

ProcessException._(this.executable, this.exitCode, this.stdout, this.stderr);

String toString() => """
$executable failed with:
exit code: $exitCode
stdout:
$stdout
stderr:
$stderr""";
}

Stream<String> _toLineStream(Stream<List<int>> s) =>
s.transform(UTF8.decoder).transform(const LineSplitter());

_logStdout(String line) {
log(line);
}

_logStderr(String line) {
log('stderr: $line');
}

0 comments on commit 27fb09e

Please sign in to comment.