Updated project structure to get credit for having an example Also moved the non-public libraries into a src directory to hide them, and updated some documentation in the example.
diff --git a/CHANGELOG.md b/CHANGELOG.md index f6775b2..aafbdf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -1,5 +1,11 @@ # Change Log for `process_runner` +## 2.0.1 + +* Modified the package structure to get credit for having an example +* Moved sub-libraries into lib/src directory to hide them from dartdoc. +* Updated example documentation. + ## 2.0.0 * Breaking change to modify the stderr, stdout, and output members of
diff --git a/analysis_options.yaml b/analysis_options.yaml index 10d58ab..0c9a12a 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml
@@ -11,6 +11,10 @@ # See the configuration guide for more # https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# Too many false positives: pedantic enforces "omit_local_variable_types", and +# we don't. +# include: package:pedantic/analysis_options.yaml + analyzer: strong-mode: implicit-casts: false @@ -29,12 +33,6 @@ # Stream and not importing dart:async # Please see https://github.com/flutter/flutter/pull/24528 for details. sdk_version_async_exported_from_core: ignore - exclude: - - "bin/cache/**" - # the following two are relative to the stocks example and the flutter package respectively - # see https://github.com/dart-lang/sdk/issues/28463 - - "lib/i18n/messages_*.dart" - - "lib/src/http/**" enable-experiment: - non-nullable @@ -104,7 +102,7 @@ - flutter_style_todos - hash_and_equals - implementation_imports - # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 + - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 - iterable_contains_unrelated_type # - join_return_with_assignment # not yet tested - library_names @@ -120,7 +118,7 @@ - non_constant_identifier_names # - null_closures # not yet tested # - omit_local_variable_types # opposite of always_specify_types - # - one_member_abstracts # too many false positives + - one_member_abstracts # too many false positives # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 - overridden_fields - package_api_docs @@ -177,13 +175,13 @@ - throw_in_finally # - type_annotate_public_apis # subset of always_specify_types - type_init_formals - # - unawaited_futures # too many false positives + - unawaited_futures # - unnecessary_await_in_return # not yet tested - unnecessary_brace_in_string_interps - unnecessary_const # - unnecessary_final # conflicts with prefer_final_locals - unnecessary_getters_setters - # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 + - unnecessary_lambdas - unnecessary_new - unnecessary_null_aware_assignments - unnecessary_null_in_if_null_operators @@ -199,7 +197,7 @@ # - use_key_in_widget_constructors # not yet tested - use_rethrow_when_possible # - use_setters_to_change_properties # not yet tested - # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 - # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review + - use_string_buffers + - use_to_and_as_if_applicable - valid_regexps - void_checks
diff --git a/example/bin/main.dart b/example/main.dart similarity index 65% rename from example/bin/main.dart rename to example/main.dart index 45100d8..0172923 100644 --- a/example/bin/main.dart +++ b/example/main.dart
@@ -2,6 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// This example shows how to send a bunch of jobs to ProcessPool for processing. +// +// This example program is actually pretty useful even if you don't use +// process_runner for your Dart project. It can speed up processing of a bunch +// of single-threaded CPU-intensive commands by a multple of the number of +// processor cores you have (modulo being disk/network bound, of course). + import 'dart:io'; import 'package:args/args.dart'; @@ -74,55 +81,72 @@ parser.addFlag('help', help: 'Print help.'); parser.addFlag('report', help: 'Print progress on the jobs while running.', defaultsTo: false); parser.addOption('workers', + abbr: 'w', help: 'Specify the number of workers jobs to run simultanously. Defaults ' 'to the number of processors on the machine.'); parser.addOption('workingDirectory', - help: 'Specify the working directory to run on', defaultsTo: '.'); + abbr: 'd', help: 'Specify the working directory to run on', defaultsTo: '.'); parser.addMultiOption('cmd', + abbr: 'c', help: 'Specify a command to add to the commands to be run. Entire ' 'command must be quoted by the shell. Commands specified with this ' 'option run before those specified with --cmdFile'); - parser.addOption('cmdFile', + parser.addOption('file', + abbr: 'f', help: 'Specify the name of a file to read commands from, one per line, as ' 'they would appear on the command line, with spaces escaped or ' - 'quoted. Specify "-" to read from stdin.'); - final ArgResults flags = parser.parse(args); + 'quoted. Specify "-" to read from stdin.', + defaultsTo: '-'); + final ArgResults options = parser.parse(args); - if (flags['help'] as bool) { + if (options['help'] as bool) { print('main.dart [flags]'); print(parser.usage); exit(0); } + // Collect the commands to be run from the command file. + final String commandFile = options['file'] as String; List<String> fileCommands = <String>[]; - if (flags['cmdFile'] != null) { - if (flags['cmdFile'] == '-') { + if (commandFile != null) { + // Read from stdin if the --file option is set to '-'. + if (commandFile == '-') { String line = stdin.readLineSync(); while (line != null) { fileCommands.add(line); line = stdin.readLineSync(); } } else { - final File cmdFile = File(flags['cmdFile'] as String); + // Read the commands from a file. + final File cmdFile = File(commandFile); if (!cmdFile.existsSync()) { - print('Command file "$cmdFile" doesn\'t exist.'); + print('Command file "$commandFile" doesn\'t exist.'); exit(1); } fileCommands = cmdFile.readAsLinesSync(); } } + + // Collect all the commands, both from the input file, and from the command + // line. The command line commands come first (although they could all be + // executed simultaneously, depending on the number of workers, and number of + // commands). final List<String> commands = <String>[ - ...flags['cmd'] as List<String>, + ...options['cmd'] as List<String>, ...fileCommands, ]; + + // Split each command entry into a list of strings, taking into account some + // simple quoting and escaping. final List<List<String>> splitCommands = commands.map<List<String>>(splitIntoArgs).toList(); - int numWorkers = int.parse((flags['workers'] as String) ?? '-1'); - numWorkers = numWorkers == -1 ? null : numWorkers; + // If the numWorkers is set to null, then the ProcessPool will automatically + // select the number of processes based on how many CPU cores the machine has. + final int numWorkers = int.tryParse(options['workers'] as String ?? ''); - final bool printReport = (flags['report'] as bool) ?? false; + final bool printReport = (options['report'] as bool) ?? false; - final Directory workingDirectory = Directory((flags['workingDirectory'] as String) ?? '.'); + final Directory workingDirectory = Directory((options['workingDirectory'] as String) ?? '.'); final ProcessPool pool = ProcessPool( numWorkers: numWorkers,
diff --git a/lib/process_runner.dart b/lib/process_runner.dart index 862e36a..309e76d 100644 --- a/lib/process_runner.dart +++ b/lib/process_runner.dart
@@ -4,5 +4,5 @@ library process_runner; -export 'process_pool.dart'; -export 'process_runner_impl.dart'; +export 'src/process_pool.dart'; +export 'src/process_runner.dart';
diff --git a/lib/process_pool.dart b/lib/src/process_pool.dart similarity index 96% rename from lib/process_pool.dart rename to lib/src/process_pool.dart index 846abc1..7d96c89 100644 --- a/lib/process_pool.dart +++ b/lib/src/process_pool.dart
@@ -10,6 +10,10 @@ import 'process_runner.dart'; +/// A class that represents a job to be done by a [ProcessPool]. +/// +/// Create a list of these to pass to [ProcessPool.startWorkers] or +/// [ProcessPool.runToCompletion]. class WorkerJob { WorkerJob( this.command, { @@ -196,7 +200,7 @@ /// To listen to jobs as they are completed, use [startWorkers] instead. Future<List<WorkerJob>> runToCompletion(List<WorkerJob> jobs) async { final List<WorkerJob> results = <WorkerJob>[]; - await startWorkers(jobs).forEach((WorkerJob job) => results.add(job)); + await startWorkers(jobs).forEach(results.add); return results; }
diff --git a/lib/process_runner_impl.dart b/lib/src/process_runner.dart similarity index 100% rename from lib/process_runner_impl.dart rename to lib/src/process_runner.dart
diff --git a/test/src/process_runner_test.dart b/test/src/process_runner_test.dart index 835724e..b507da4 100644 --- a/test/src/process_runner_test.dart +++ b/test/src/process_runner_test.dart
@@ -52,7 +52,7 @@ ], }; fakeProcessManager.fakeResults = calls; - expectLater(() => processRunner.runProcess(calls.keys.first), throwsException); + await expectLater(() => processRunner.runProcess(calls.keys.first), throwsException); }); }); }