Skip to content

Attempt pub get/upgrade before running build or serve #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions webdev/bin/webdev.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import 'dart:async';

import 'package:webdev/webdev.dart';
import 'package:build_runner/src/logging/std_io_logging.dart';
import 'package:logging/logging.dart';

Future main(List<String> args) async {
// TODO(nshahan) See if build_runner wants to expose their listener.
// Using log listener from build_runner to match output format.
final logListener = Logger.root.onRecord.listen(stdIOLogListener);
await webdevCommandRunner().run(args);
await logListener?.cancel();
}
7 changes: 2 additions & 5 deletions webdev/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,15 @@ environment:
sdk: ">=2.0.0-dev.3.0 <2.0.0"

dependencies:
angular: ^5.0.0-alpha+3
angular: ^5.0.0-alpha+4
browser: ^0.10.0

dev_dependencies:
webdev:
path: ../
##############################################################################
# Temporary until build_runner exposes a function to generate it's script.
build_runner:
git:
url: https://github.com/dart-lang/build.git
path: build_runner
build_runner: ^0.7.7
##############################################################################

dependency_overrides:
Expand Down
6 changes: 1 addition & 5 deletions webdev/lib/src/command/build_command.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:isolate';

import 'build_runner_command_base.dart';

Expand All @@ -15,9 +14,6 @@ class BuildCommand extends BuildRunnerCommandBase {
Future run() async {
final arguments = ['build'];
arguments.addAll(argResults.arguments);
var exitPort = new ReceivePort();
await Isolate.spawnUri(await buildRunnerScript, arguments, null,
onExit: exitPort.sendPort, automaticPackageResolution: true);
await exitPort.first;
await runBuildRunner(arguments);
}
}
96 changes: 88 additions & 8 deletions webdev/lib/src/command/build_runner_command_base.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import 'dart:async';
import 'dart:io';
import 'dart:isolate';

import 'package:args/command_runner.dart';
import 'package:build_runner/src/logging/logging.dart';
import 'package:logging/logging.dart';

var _logger = new Logger('webdev');

/// Extend to get a command with the arguments common to all build_runner
/// commands.
Expand All @@ -19,13 +24,88 @@ abstract class BuildRunnerCommandBase extends Command {
help: 'Enables verbose logging.');
}

Future<Uri> get buildRunnerScript async {
// TODO(nshahan) build_runner will expose this as a function call that will
// be imported to avoid running a binary in a transitive dependency with
// pub run.
final executable = 'pub';
final arguments = ['run', 'build_runner', 'generate-build-script'];
final results = await Process.run(executable, arguments);
return new Uri.file(results.stdout.toString().trim());
/// Runs `pub run build_runner` with [arguments] as an isolate.
///
/// Attempts to run `pub get` and `pub upgrade` if needed and will retry
/// running build_runner after.
Future runBuildRunner(List<String> arguments) async {
final result = await _runBuildRunnerGenerate();

if (result.exitCode != 0) {
print(result.exitCode);
_logger.severe('Unable to run `pub get` and `pub run build_runner`.'
'\nPlease fix the dependencies and retry.'
'\n\n${result.stderr}');
return;
}

var exitPort = new ReceivePort();
var errorPort = new ReceivePort();
var messagePort = new ReceivePort();
var errorListener = errorPort.listen((e) {
stderr.writeAll(e as List, '\n');
if (exitCode == 0) exitCode = 1;
});
await Isolate.spawnUri(_scriptPath(result), arguments, messagePort.sendPort,
onExit: exitPort.sendPort,
onError: errorPort.sendPort,
automaticPackageResolution: true);
try {
exitCode = await messagePort.first as int;
} on StateError catch (_) {
if (exitCode == 0) exitCode = 1;
}
await exitPort.first;
await errorListener.cancel();
}

/// Generates a build script and returns it's location.
///
/// Will attempt to get dependencies if needed.
Future<ProcessResult> _runBuildRunnerGenerate() async {
var result = await logTimedAsync(
_logger, 'Generating build script', _runGenerateBuildScript);

if (result.exitCode != 0) {
_logger.warning('Generating build script failed.');
result = await logTimedAsync(_logger, 'Getting dependencies', _runPubGet);

if (result.exitCode != 0) {
_logger.warning('Getting dependencies failed.');
result = await logTimedAsync(
_logger, 'Upgrading dependencies', _runPubUpgrade);

if (result.exitCode != 0) {
_logger.severe('Upgrading dependencies failed');
return result;
}
}

// Try running build_runner again.
result = await logTimedAsync(
_logger, 'Generating build script', _runGenerateBuildScript);
}

return result;
}

/// Parses the generated script path from the the results of running
/// `build_runner generate-build-script`.`
Uri _scriptPath(ProcessResult result) =>
new Uri.file(result.stdout.toString().trim());

/// Runs `build_runner generate-build-script` as a Process.
Future<ProcessResult> _runGenerateBuildScript() =>
// TODO(nshahan) build_runner will expose this as a function call that
// will be imported to avoid running a binary in a transitive dependency
// with pub run.
Process.run('pub', ['run', 'build_runner', 'generate-build-script']);

/// Runs `pub get` as a Process.
Future<ProcessResult> _runPubGet() =>
Process.run('pub', ['get', '--no-precompile']);

/// Runs `pub upgrade` as a Process.
Future<ProcessResult> _runPubUpgrade() =>
Process.run('pub', ['upgrade', '--no-precompile']);
}
6 changes: 1 addition & 5 deletions webdev/lib/src/command/serve_command.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:isolate';

import 'build_runner_command_base.dart';

Expand All @@ -24,9 +23,6 @@ class ServeCommand extends BuildRunnerCommandBase {
Future run() async {
final arguments = ['serve'];
arguments.addAll(argResults.arguments);
var exitPort = new ReceivePort();
await Isolate.spawnUri(await buildRunnerScript, arguments, null,
onExit: exitPort.sendPort, automaticPackageResolution: true);
await exitPort.first;
await runBuildRunner(arguments);
}
}
7 changes: 2 additions & 5 deletions webdev/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ environment:

dependencies:
args: ^1.2.0
build_runner:
git:
url: https://github.com/dart-lang/build.git
path: build_runner
build_web_compilers: ^0.1.1
build_runner: ^0.7.7
build_web_compilers: ^0.2.0

dev_dependencies:
test: "^0.12.0"