From 6780413ddf539ae41f8af7af14bc9ac0002071fa Mon Sep 17 00:00:00 2001 From: evanweible-wf Date: Wed, 12 Aug 2015 12:49:27 -0500 Subject: [PATCH] CLI improvements & cleanup. --- bin/dart_dev.dart | 2 +- lib/io.dart | 4 ---- lib/process.dart | 3 --- lib/src/dart_dev_cli.dart | 20 ++++++++++++++++---- lib/src/{io.dart => reporter.dart} | 12 +----------- lib/src/tasks/analyze/api.dart | 2 +- lib/src/tasks/analyze/cli.dart | 2 +- lib/src/tasks/examples/api.dart | 18 ++++++++++++++++-- lib/src/tasks/examples/cli.dart | 5 ++++- lib/src/tasks/format/api.dart | 2 +- lib/src/tasks/format/cli.dart | 13 ++++++++++++- lib/src/tasks/init/api.dart | 2 ++ lib/src/tasks/test/api.dart | 2 +- lib/src/tasks/test/cli.dart | 5 ++++- lib/src/util.dart | 28 ++++++++++++++++++++++++++++ lib/util.dart | 9 +++++++++ tool/dev.dart | 4 ++-- 17 files changed, 99 insertions(+), 34 deletions(-) delete mode 100644 lib/io.dart delete mode 100644 lib/process.dart rename lib/src/{io.dart => reporter.dart} (85%) create mode 100644 lib/src/util.dart create mode 100644 lib/util.dart diff --git a/bin/dart_dev.dart b/bin/dart_dev.dart index 7901f680..8e10cc41 100644 --- a/bin/dart_dev.dart +++ b/bin/dart_dev.dart @@ -3,7 +3,7 @@ library dart_dev.bin.dart_dev; import 'dart:io'; import 'package:dart_dev/dart_dev.dart' show dev; -import 'package:dart_dev/process.dart' show TaskProcess; +import 'package:dart_dev/util.dart' show TaskProcess; main(List args) async { File devFile = new File('./tool/dev.dart'); diff --git a/lib/io.dart b/lib/io.dart deleted file mode 100644 index 1b50bf4a..00000000 --- a/lib/io.dart +++ /dev/null @@ -1,4 +0,0 @@ -library dart_dev.io; - -export 'package:dart_dev/src/io.dart' - show parseArgsFromCommand, parseExecutableFromCommand, Reporter, reporter; diff --git a/lib/process.dart b/lib/process.dart deleted file mode 100644 index ff5ae83a..00000000 --- a/lib/process.dart +++ /dev/null @@ -1,3 +0,0 @@ -library dart_dev.process; - -export 'package:dart_dev/src/task_process.dart' show TaskProcess; diff --git a/lib/src/dart_dev_cli.dart b/lib/src/dart_dev_cli.dart index 22175f0c..9f73c1c4 100644 --- a/lib/src/dart_dev_cli.dart +++ b/lib/src/dart_dev_cli.dart @@ -5,9 +5,12 @@ import 'dart:io'; import 'package:args/args.dart'; -import 'package:dart_dev/io.dart' - show parseArgsFromCommand, parseExecutableFromCommand, reporter; -import 'package:dart_dev/process.dart'; +import 'package:dart_dev/util.dart' + show + TaskProcess, + parseArgsFromCommand, + parseExecutableFromCommand, + reporter; import 'package:dart_dev/src/tasks/cli.dart'; import 'package:dart_dev/src/tasks/config.dart'; @@ -75,7 +78,16 @@ Future _run(List args) async { _parser.addCommand(command, cli.argParser); }); - ArgResults env = _parser.parse(args); + ArgResults env; + try { + env = _parser.parse(args); + } on FormatException catch (e) { + reporter.error('${e.message}\n', shout: true); + reporter.log(_generateUsage(), shout: true); + exitCode = 1; + return; + } + String task; if (env.command != null) { task = env.command.name; diff --git a/lib/src/io.dart b/lib/src/reporter.dart similarity index 85% rename from lib/src/io.dart rename to lib/src/reporter.dart index c393a813..9fca2159 100644 --- a/lib/src/io.dart +++ b/lib/src/reporter.dart @@ -1,4 +1,4 @@ -library dart_dev.src.io; +library dart_dev.src.reporter; import 'dart:async'; import 'dart:io'; @@ -12,16 +12,6 @@ final AnsiPen _green = new AnsiPen()..green(); final AnsiPen _red = new AnsiPen()..red(); final AnsiPen _yellow = new AnsiPen()..yellow(); -String parseExecutableFromCommand(String command) { - return command.split(' ').first; -} - -List parseArgsFromCommand(String command) { - var parts = command.split(' '); - if (parts.length <= 1) return []; - return parts.getRange(1, parts.length).toList(); -} - class Reporter { bool color = true; bool quiet = false; diff --git a/lib/src/tasks/analyze/api.dart b/lib/src/tasks/analyze/api.dart index 5d712d4c..11f7ba3e 100644 --- a/lib/src/tasks/analyze/api.dart +++ b/lib/src/tasks/analyze/api.dart @@ -3,7 +3,7 @@ library dart_dev.src.tasks.analyze.api; import 'dart:async'; import 'dart:io'; -import 'package:dart_dev/process.dart'; +import 'package:dart_dev/util.dart' show TaskProcess; import 'package:dart_dev/src/tasks/analyze/config.dart'; import 'package:dart_dev/src/tasks/task.dart'; diff --git a/lib/src/tasks/analyze/cli.dart b/lib/src/tasks/analyze/cli.dart index 48afebae..d535d1a7 100644 --- a/lib/src/tasks/analyze/cli.dart +++ b/lib/src/tasks/analyze/cli.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'package:args/args.dart'; -import 'package:dart_dev/io.dart' show reporter; +import 'package:dart_dev/util.dart' show reporter; import 'package:dart_dev/src/tasks/analyze/api.dart'; import 'package:dart_dev/src/tasks/analyze/config.dart'; diff --git a/lib/src/tasks/examples/api.dart b/lib/src/tasks/examples/api.dart index 40531581..e2d4269d 100644 --- a/lib/src/tasks/examples/api.dart +++ b/lib/src/tasks/examples/api.dart @@ -1,14 +1,23 @@ library dart_dev.src.tasks.examples.api; import 'dart:async'; +import 'dart:io'; -import 'package:dart_dev/process.dart'; +import 'package:dart_dev/util.dart' show TaskProcess; import 'package:dart_dev/src/tasks/examples/config.dart'; import 'package:dart_dev/src/tasks/task.dart'; +bool hasExamples() { + Directory exampleDir = new Directory('example'); + return exampleDir.existsSync(); +} + ExamplesTask serveExamples( {String hostname: defaultHostname, int port: defaultPort}) { + if (!hasExamples()) throw new Exception( + 'This project does not have any examples.'); + var dartiumExecutable = 'dartium'; var dartiumArgs = ['http://$hostname:$port']; @@ -50,7 +59,12 @@ class ExamplesTask extends Task { StreamController _pubServeOutput = new StreamController(); ExamplesTask(String this.dartiumCommand, String this.pubServeCommand, - Future this.done); + Future this.done) { + done.then((_) { + _dartiumOutput.close(); + _pubServeOutput.close(); + }); + } Stream get dartiumOutput => _dartiumOutput.stream; Stream get pubServeOutput => _pubServeOutput.stream; diff --git a/lib/src/tasks/examples/cli.dart b/lib/src/tasks/examples/cli.dart index 2909b491..c21b7916 100644 --- a/lib/src/tasks/examples/cli.dart +++ b/lib/src/tasks/examples/cli.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'package:args/args.dart'; -import 'package:dart_dev/io.dart' show reporter; +import 'package:dart_dev/util.dart' show reporter; import 'package:dart_dev/src/tasks/examples/api.dart'; import 'package:dart_dev/src/tasks/examples/config.dart'; @@ -29,6 +29,9 @@ class ExamplesCli extends TaskCli { port = int.parse(port); } + if (!hasExamples()) return new CliResult.fail( + 'This project does not have any examples.'); + ExamplesTask task = serveExamples(hostname: hostname, port: port); reporter.logGroup(task.pubServeCommand, outputStream: task.pubServeOutput); await task.done; diff --git a/lib/src/tasks/format/api.dart b/lib/src/tasks/format/api.dart index 1ace7c44..9dd635ba 100644 --- a/lib/src/tasks/format/api.dart +++ b/lib/src/tasks/format/api.dart @@ -2,7 +2,7 @@ library dart_dev.src.tasks.format.api; import 'dart:async'; -import 'package:dart_dev/process.dart'; +import 'package:dart_dev/util.dart' show TaskProcess; import 'package:dart_dev/src/tasks/format/config.dart'; import 'package:dart_dev/src/tasks/task.dart'; diff --git a/lib/src/tasks/format/cli.dart b/lib/src/tasks/format/cli.dart index d78aba1a..beb1c123 100644 --- a/lib/src/tasks/format/cli.dart +++ b/lib/src/tasks/format/cli.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'package:args/args.dart'; -import 'package:dart_dev/io.dart' show reporter; +import 'package:dart_dev/util.dart' show hasImmediateDependency, reporter; import 'package:dart_dev/src/tasks/format/api.dart'; import 'package:dart_dev/src/tasks/format/config.dart'; @@ -22,6 +22,17 @@ class FormatCli extends TaskCli { final String command = 'format'; Future run(ArgResults parsedArgs) async { + try { + if (!hasImmediateDependency('dart_style')) return new CliResult.fail( + 'Package "dart_style" must be an immediate dependency in order to run its executables.'); + } catch (e) { + // It's possible that this check may throw if the pubspec.yaml + // could not be found or if the yaml could not be parsed. + // We silence this error and let the task continue in case it + // was a false negative. If it was accurate, then the task will + // fail anyway and the error will be available in the output. + } + bool check = TaskCli.valueOf('check', parsedArgs, config.format.check); List directories = config.format.directories; diff --git a/lib/src/tasks/init/api.dart b/lib/src/tasks/init/api.dart index 3caf74bf..2a5e74d5 100644 --- a/lib/src/tasks/init/api.dart +++ b/lib/src/tasks/init/api.dart @@ -10,6 +10,8 @@ const String _initialConfig = '''library tool.dev; import 'package:dart_dev/dart_dev.dart' show dev, config; main(List args) async { + // https://github.com/Workiva/dart_dev + // Perform task configuration here as necessary. // Available task configurations: diff --git a/lib/src/tasks/test/api.dart b/lib/src/tasks/test/api.dart index 39275e46..1e6ae54c 100644 --- a/lib/src/tasks/test/api.dart +++ b/lib/src/tasks/test/api.dart @@ -2,7 +2,7 @@ library dart_dev.src.tasks.test.api; import 'dart:async'; -import 'package:dart_dev/process.dart'; +import 'package:dart_dev/util.dart' show TaskProcess; import 'package:dart_dev/src/tasks/task.dart'; diff --git a/lib/src/tasks/test/cli.dart b/lib/src/tasks/test/cli.dart index 0d6210d2..c1468291 100644 --- a/lib/src/tasks/test/cli.dart +++ b/lib/src/tasks/test/cli.dart @@ -4,7 +4,7 @@ import 'dart:async'; import 'package:args/args.dart'; -import 'package:dart_dev/io.dart'; +import 'package:dart_dev/util.dart' show hasImmediateDependency, reporter; import 'package:dart_dev/src/tasks/cli.dart'; import 'package:dart_dev/src/tasks/config.dart'; @@ -27,6 +27,9 @@ class TestCli extends TaskCli { final String command = 'test'; Future run(ArgResults parsedArgs) async { + if (!hasImmediateDependency('test')) return new CliResult.fail( + 'Package "test" must be an immediate dependency in order to run its executables.'); + bool unit = parsedArgs['unit']; bool integration = parsedArgs['integration']; List platforms = diff --git a/lib/src/util.dart b/lib/src/util.dart new file mode 100644 index 00000000..5012fa47 --- /dev/null +++ b/lib/src/util.dart @@ -0,0 +1,28 @@ +library dart_dev.src.util; + +import 'dart:io'; + +import 'package:yaml/yaml.dart'; + +bool hasImmediateDependency(String packageName) { + File pubspec = new File('pubspec.yaml'); + Map pubspecYaml = loadYaml(pubspec.readAsStringSync()); + List deps = []; + if (pubspecYaml.containsKey('dependencies')) { + deps.addAll((pubspecYaml['dependencies'] as Map).keys); + } + if (pubspecYaml.containsKey('dev_dependencies')) { + deps.addAll((pubspecYaml['dev_dependencies'] as Map).keys); + } + return deps.contains(packageName); +} + +String parseExecutableFromCommand(String command) { + return command.split(' ').first; +} + +List parseArgsFromCommand(String command) { + var parts = command.split(' '); + if (parts.length <= 1) return []; + return parts.getRange(1, parts.length).toList(); +} diff --git a/lib/util.dart b/lib/util.dart new file mode 100644 index 00000000..ec970609 --- /dev/null +++ b/lib/util.dart @@ -0,0 +1,9 @@ +library dart_dev.util; + +export 'package:dart_dev/src/reporter.dart' show Reporter, reporter; +export 'package:dart_dev/src/task_process.dart' show TaskProcess; +export 'package:dart_dev/src/util.dart' + show + hasImmediateDependency, + parseArgsFromCommand, + parseExecutableFromCommand; diff --git a/tool/dev.dart b/tool/dev.dart index c86e1695..a62951ee 100644 --- a/tool/dev.dart +++ b/tool/dev.dart @@ -3,8 +3,8 @@ library dart_dev.dev; import 'package:dart_dev/dart_dev.dart'; main(args) async { - config.analyze.entryPoints = ['lib/', 'test/', 'tool/']; - config.format.directories = ['lib/', 'test/', 'tool/']; + config.analyze.entryPoints = ['bin/', 'lib/', 'tool/']; + config.format.directories = ['bin/', 'lib/', 'tool/']; await dev(args); }