From bfdf0272c40a405d008d3dde3f12050e6a97a956 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 5 Nov 2021 13:02:20 +0100 Subject: [PATCH 001/150] exp: non io --- .gitignore | 1 - dart_test.yaml | 4 + lib/src/lines_utils.dart | 2 +- lib/src/mixin/shell_common.dart | 7 + lib/src/platform/platform.dart | 1 + lib/src/platform/platform_io.dart | 8 + lib/src/platform/platform_stub.dart | 17 ++ lib/src/shell.dart | 4 +- lib/src/shell_common.dart | 111 ++++++++ lib/src/shell_context_common.dart | 19 ++ lib/src/shell_context_io.dart | 22 ++ lib/src/shell_environment.dart | 317 +--------------------- lib/src/shell_environment_common.dart | 362 ++++++++++++++++++++++++++ lib/src/shell_utils.dart | 20 +- lib/src/shell_utils_common.dart | 27 ++ test/shell_common_api_test.dart | 21 ++ test/src_dartbin_cmd_test.dart | 4 + test/src_shell_test.dart | 3 + test/src_shell_utils_test.dart | 3 + test/src_user_config_test.dart | 3 + 20 files changed, 627 insertions(+), 329 deletions(-) create mode 100644 dart_test.yaml create mode 100644 lib/src/mixin/shell_common.dart create mode 100644 lib/src/platform/platform.dart create mode 100644 lib/src/platform/platform_io.dart create mode 100644 lib/src/platform/platform_stub.dart create mode 100644 lib/src/shell_common.dart create mode 100644 lib/src/shell_context_common.dart create mode 100644 lib/src/shell_context_io.dart create mode 100644 lib/src/shell_environment_common.dart create mode 100644 lib/src/shell_utils_common.dart create mode 100644 test/shell_common_api_test.dart diff --git a/.gitignore b/.gitignore index 73b24ef..b42e507 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ .buildlog .pub/ build/ -packages .packages .dart/ diff --git a/dart_test.yaml b/dart_test.yaml new file mode 100644 index 0000000..b3e203d --- /dev/null +++ b/dart_test.yaml @@ -0,0 +1,4 @@ +platforms: + - vm + - node +concurrency: 1 \ No newline at end of file diff --git a/lib/src/lines_utils.dart b/lib/src/lines_utils.dart index fbe7a23..66059c7 100644 --- a/lib/src/lines_utils.dart +++ b/lib/src/lines_utils.dart @@ -2,7 +2,7 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; -import 'package:process_run/src/shell.dart'; +import 'package:process_run/src/shell_common.dart'; import 'package:process_run/src/shell_utils.dart'; import 'common/import.dart'; diff --git a/lib/src/mixin/shell_common.dart b/lib/src/mixin/shell_common.dart new file mode 100644 index 0000000..7689ec8 --- /dev/null +++ b/lib/src/mixin/shell_common.dart @@ -0,0 +1,7 @@ +export 'package:process_run/src/shell_common.dart' show Shell; +export 'package:process_run/src/shell_environment_common.dart' + show + ShellEnvironmentPaths, + ShellEnvironment, + ShellEnvironmentVars, + ShellEnvironmentAliases; diff --git a/lib/src/platform/platform.dart b/lib/src/platform/platform.dart new file mode 100644 index 0000000..e67cc23 --- /dev/null +++ b/lib/src/platform/platform.dart @@ -0,0 +1 @@ +export 'platform_stub.dart' if (dart.library.io) 'platform_io.dart'; diff --git a/lib/src/platform/platform_io.dart b/lib/src/platform/platform_io.dart new file mode 100644 index 0000000..9e5d458 --- /dev/null +++ b/lib/src/platform/platform_io.dart @@ -0,0 +1,8 @@ +import 'dart:io'; + +import 'package:process_run/src/shell_context_common.dart'; +import 'package:process_run/src/shell_context_io.dart'; + +bool get platformIoIsWindows => Platform.isWindows; + +ShellContext shellContext = ShellContextIo(); diff --git a/lib/src/platform/platform_stub.dart b/lib/src/platform/platform_stub.dart new file mode 100644 index 0000000..1b5b1ad --- /dev/null +++ b/lib/src/platform/platform_stub.dart @@ -0,0 +1,17 @@ +import 'package:process_run/src/shell_context_common.dart'; + +/// Only true for IO windows +bool get platformIoIsWindows => false; + +ShellContext? _shellContext; + +/// Must be set before use +ShellContext get shellContext { + if (_shellContext == null) { + throw StateError('shellContext must be set before use'); + } + return _shellContext!; +} + +/// Set shell context before use +set shellContext(ShellContext shellContext) => _shellContext = shellContext; diff --git a/lib/src/shell.dart b/lib/src/shell.dart index d4725b9..9be0aa8 100644 --- a/lib/src/shell.dart +++ b/lib/src/shell.dart @@ -6,12 +6,14 @@ import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/process_run.dart'; +import 'package:process_run/src/shell_common.dart' show shellDebug; import 'package:process_run/src/shell_utils.dart'; import 'package:synchronized/synchronized.dart'; import 'common/import.dart'; -var shellDebug = false; // devWarning(true); // false +export 'shell_common.dart' show shellDebug; + /// /// Run one or multiple plain text command(s). /// diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart new file mode 100644 index 0000000..f83b9cf --- /dev/null +++ b/lib/src/shell_common.dart @@ -0,0 +1,111 @@ +import 'dart:async'; +import 'dart:convert'; + +var shellDebug = false; // devWarning(true); // false + +class ProcessResult {} + +class Process {} + +class ProcessSignal { + const ProcessSignal(); + static const sigterm = ProcessSignal(); +} + +/// Multiplatform Shell utility to run a script with multiple commands. +/// +/// Extra path/env can be loaded using ~/.config/tekartik/process_run/env.yaml +/// +/// ``` +/// path: ~/bin +/// ``` +/// +/// or +/// +/// ``` +/// path: +/// - ~/bin +/// - ~/Android/Sdk/tools/bin +/// env: +/// ANDROID_TOP: ~/Android +/// FIREBASE_TOP: ~/.firebase +/// ``` +/// +/// A list of ProcessResult is returned +/// +abstract class Shell { + /// Create a new shell + Shell clone( + {bool? throwOnError, + String? workingDirectory, + // Don't change environment + @Deprecated('Don\'t change map') + Map? environment, + @Deprecated('Don\'t change includeParentEnvironment') + // Don't change includeParentEnvironment + bool? includeParentEnvironment, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, + bool? commentVerbose}); + + /// Create new shell at the given path + Shell cd(String path); + + /// Get the shell path, using workingDirectory or current directory if null. + String get path; + + /// Create a new shell at the given path, allowing popd on it + Shell pushd(String path); + + /// Pop the current directory to get the previous shell + /// throw State error if nothing in the stack + Shell popd(); + + /// Kills the current running process. + /// + /// Returns `true` if the signal is successfully delivered to the process. + /// Otherwise the signal could not be sent, usually meaning, + /// that the process is already dead. + bool kill([ProcessSignal signal = ProcessSignal.sigterm]); + + /// + /// Run one or multiple plain text command(s). + /// + /// Commands can be splitted by line. + /// + /// Commands can be on multiple line if ending with ' ^' or ' \'. (note that \ + /// must be escaped too so you might have to enter \\). + /// + /// Returns a list of executed command line results. + /// + /// [onProcess] is called for each started process. + /// + Future> run(String script, + {void Function(Process process)? onProcess}); + + /// Run a single [executable] with [arguments], resolving the [executable] if needed. + /// + /// Returns a process result (or throw if specified in the shell). + /// + /// [onProcess] is called for each started process. + Future runExecutableArguments( + String executable, List arguments, + {void Function(Process process)? onProcess}); +} + +/// Exception thrown in exitCode != 0 and throwOnError is true +class ShellException implements Exception { + final ProcessResult? result; + final String message; + + ShellException(this.message, this.result); + + @override + String toString() => 'ShellException($message)'; +} diff --git a/lib/src/shell_context_common.dart b/lib/src/shell_context_common.dart new file mode 100644 index 0000000..6fb0874 --- /dev/null +++ b/lib/src/shell_context_common.dart @@ -0,0 +1,19 @@ +import 'dart:convert'; + +import 'package:path/path.dart' as p; +import 'package:process_run/shell.dart'; + +/// abstract shell context +abstract class ShellContext { + /// Shell environment + ShellEnvironment get shellEnvironment; + + /// Which command. + Future which(String command); + + /// Path context. + p.Context get path; + + /// Default shell encoding (systemEncoding on iOS) + Encoding get encoding; +} diff --git a/lib/src/shell_context_io.dart b/lib/src/shell_context_io.dart new file mode 100644 index 0000000..013d4ea --- /dev/null +++ b/lib/src/shell_context_io.dart @@ -0,0 +1,22 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:path/path.dart' as p; +import 'package:process_run/shell.dart' as ds; +import 'package:process_run/src/shell_context_common.dart'; +import 'package:process_run/src/shell_environment.dart'; + +class ShellContextIo implements ShellContext { + @override + ShellEnvironment get shellEnvironment => + asShellEnvironment(ds.shellEnvironment); + + @override + p.Context get path => p.context; + + @override + Future which(String command) => ds.which(command); + + @override + Encoding get encoding => systemEncoding; +} diff --git a/lib/src/shell_environment.dart b/lib/src/shell_environment.dart index 5fe4451..3e22e40 100644 --- a/lib/src/shell_environment.dart +++ b/lib/src/shell_environment.dart @@ -1,206 +1,10 @@ -import 'dart:collection'; - -import 'package:collection/collection.dart'; -import 'package:process_run/shell.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/shell_utils.dart'; -/// Shell environment ordered paths helper. Changes the PATH variable -class ShellEnvironmentPaths with ListMixin { - final ShellEnvironment _environment; - - ShellEnvironmentPaths._(this._environment); - - List get _paths { - var pathVar = _environment[envPathKey]; - // Handle empty to black - if (pathVar?.isNotEmpty ?? false) { - return pathVar!.split(envPathSeparator); - } else { - return []; - } - } - - set _paths(List paths) { - if (paths.isEmpty) { - _environment.remove(envPathKey); - } else { - // remove duplicates - paths = LinkedHashSet.from(paths).toList(); - _environment[envPathKey] = paths.join(envPathSeparator); - } - } - - /// Prepend a path (i.e. higher in the hierarchy to handle a [which] resolution. - void prepend(String path) => insert(0, path); - - @override - int get length => _paths.length; - - @override - String operator [](int index) { - return _paths[index]; - } - - @override - void operator []=(int index, String? value) { - _paths = _paths..[index] = value!; - } - - @override - void add(String element) { - // Needed for nnbd - _paths = [..._paths, element]; - } - - @override - set length(int newLength) { - _paths = _paths..length = newLength; - } - - @override - void insert(int index, String element) { - _paths = _paths..insert(index, element); - } - - /// Merge an environment. - /// - /// the other object, paths are prepended. - void merge(ShellEnvironmentPaths paths) { - insertAll(0, paths); - } - - @override - int get hashCode => const ListEquality().hash(this); - - @override - bool operator ==(Object other) { - if (other is ShellEnvironmentPaths) { - return const ListEquality().equals(this, other); - } - return false; - } - - @override - String toString() => 'Path($length)'; - - /// Overriden to handle concurrent modification and avoid duplicates. - @override - void addAll(Iterable paths) { - _paths = _paths..addAll(paths); - } - - /// Overriden to handle concurrent modification and avoid duplicates. - @override - void insertAll(int index, Iterable paths) { - _paths = _paths..insertAll(index, paths); - } -} - -/// Shell environment aliases for executable -class ShellEnvironmentAliases with MapMixin { - final Map _map; - - ShellEnvironmentAliases._([Map? map]) - : _map = map ?? {}; - - /// the other object takes precedence, vars are added - void merge(ShellEnvironmentAliases other) { - addAll(other); - } - - @override - String? operator [](Object? key) => _map[key as String]; - - @override - void operator []=(String key, String value) => _map[key] = value; - - @override - void clear() => _map.clear(); - - @override - Iterable get keys => _map.keys; - - @override - String? remove(Object? key) => _map.remove(key); - - // Key hash is sufficient here - @override - int get hashCode => const ListEquality().hash(keys.toList()); - - @override - bool operator ==(Object other) { - if (other is ShellEnvironmentVars) { - return const MapEquality().equals(this, other); - } - return false; - } - - @override - String toString() => 'Aliases($length)'; -} - -/// Shell environment variables helper. Does not affect the PATH variable -class ShellEnvironmentVars with MapMixin { - final ShellEnvironment _environment; +import 'shell_environment_common.dart' as common; - ShellEnvironmentVars._(this._environment); - - /// Currently only the PATH key is ignored. - bool _ignoreKey(key) => key == envPathKey; - - @override - String? operator [](Object? key) { - if (_ignoreKey(key)) { - return null; - } - return _environment[key as String]; - } - - @override - void operator []=(String key, String value) { - if (!_ignoreKey(key)) { - _environment[key] = value; - } - } - - @override - void clear() { - removeWhere((key, value) => !_ignoreKey(key)); - } - - @override - Iterable get keys => - _environment.keys.where((key) => !_ignoreKey(key)); - - @override - String? remove(Object? key) { - if (!_ignoreKey(key)) { - return _environment.remove(key); - } - return null; - } - - /// the other object takes precedence, vars are added - void merge(ShellEnvironmentVars other) { - addAll(other); - } - - // Key hash is sufficient here - @override - int get hashCode => const ListEquality().hash(keys.toList()); - - @override - bool operator ==(Object other) { - if (other is ShellEnvironmentVars) { - return const MapEquality().equals(this, other); - } - return false; - } - - @override - String toString() => 'Vars($length)'; -} +export 'shell_environment_common.dart' + show ShellEnvironmentAliases, ShellEnvironmentPaths, ShellEnvironmentVars; /// Use current if already and environment object. ShellEnvironment asShellEnvironment(Map? environment) => @@ -209,29 +13,7 @@ ShellEnvironment asShellEnvironment(Map? environment) => : ShellEnvironment(environment: environment); /// Shell modifiable helpers. should not be modified after being set. -class ShellEnvironment with MapMixin { - /// The resulting _env - final _env = {}; - - /// The vars but the PATH variable - ShellEnvironmentVars? _vars; - - /// The vars but the PATH variable - ShellEnvironmentVars get vars => _vars ??= ShellEnvironmentVars._(this); - - /// The PATH variable as a convenient list. - ShellEnvironmentPaths? _paths; - - /// The PATH variable as a convenient list. - ShellEnvironmentPaths get paths => _paths ??= ShellEnvironmentPaths._(this); - - /// The aliases. - ShellEnvironmentAliases? _aliases; - - /// The aliases as convenient map. - ShellEnvironmentAliases get aliases => - _aliases ??= ShellEnvironmentAliases._(); - +class ShellEnvironment extends common.ShellEnvironmentBase { /// Create a new shell environment from the current shellEnvironment. /// /// Defaults create a full parent environment. @@ -239,16 +21,8 @@ class ShellEnvironment with MapMixin { /// It is recommended that you apply the environment to a shell. But it can /// also be set globally (be aware of the potential effect on other part of /// your application) to [shellEnvironment] - ShellEnvironment({Map? environment}) { - environment ??= shellEnvironment; - - // Copy vars/path - _env.addAll(environment); - // Copy alias - if (environment is ShellEnvironment) { - aliases.addAll(environment.aliases); - } - } + ShellEnvironment({Map? environment}) + : super.fromEnvironment(environment: environment); /// From a run start content, includeParentEnvironment should later be set /// to false @@ -265,64 +39,17 @@ class ShellEnvironment with MapMixin { return newEnvironment; } - @override - String? operator [](Object? key) => _env[key as String]; - - @override - void operator []=(String key, String value) => _env[key] = value; - - @override - void clear() { - _env.clear(); - } - - @override - Iterable get keys => _env.keys; - - @override - String? remove(Object? key) { - return _env.remove(key); - } - /// Create an empty shell environment. /// /// Mainly used for testing as it is not easy to which environment variable /// are required. - ShellEnvironment.empty(); + ShellEnvironment.empty() : super.empty(); /// From json. /// /// Mainly used for testing as it is not easy to which environment variable /// are required. - ShellEnvironment.fromJson(Map? map) { - try { - if (map != null) { - var rawVars = map['vars']; - if (rawVars is Map) { - vars.addAll(rawVars.cast()); - } - var rawPaths = map['paths']; - if (rawPaths is Iterable) { - paths.addAll(rawPaths.cast()); - } - var rawAliases = map['aliases']; - if (rawAliases is Map) { - aliases.addAll(rawAliases.cast()); - } - } - } catch (_) { - // Silent crash - } - } - - /// Merge an environment. - /// - /// the other object takes precedence, vars are added and paths prepended - void merge(ShellEnvironment other) { - vars.merge(other.vars); - paths.merge(other.paths); - aliases.merge(other.aliases); - } + ShellEnvironment.fromJson(Map? map) : super.fromJson(map); /// Find a [command] path location in the environment String? whichSync(String command) { @@ -336,32 +63,4 @@ class ShellEnvironment with MapMixin { Future which(String command) async { return whichSync(command); } - - /// `paths` and `vars` key - Map toJson() { - return {'paths': paths, 'vars': vars, 'aliases': aliases}; - } - - @override - int get hashCode => const ListEquality().hash(paths); - - @override - bool operator ==(Object other) { - if (other is ShellEnvironment) { - if (other.vars != vars) { - return false; - } - if (other.paths != paths) { - return false; - } - if (other.aliases != aliases) { - return false; - } - return true; - } - return false; - } - - @override - String toString() => 'ShellEnvironment($paths, $vars, $aliases)'; } diff --git a/lib/src/shell_environment_common.dart b/lib/src/shell_environment_common.dart new file mode 100644 index 0000000..68ccdc7 --- /dev/null +++ b/lib/src/shell_environment_common.dart @@ -0,0 +1,362 @@ +import 'dart:collection'; + +import 'package:collection/collection.dart'; +import 'package:process_run/src/platform/platform.dart'; +import 'package:process_run/src/shell_utils_common.dart'; +//import 'package:process_run/shell.dart'; +//import 'package:process_run/src/common/import.dart'; +//import 'package:process_run/src/shell_utils.dart'; + +/// Shell environment ordered paths helper. Changes the PATH variable +class ShellEnvironmentPaths with ListMixin { + final ShellEnvironment _environment; + + ShellEnvironmentPaths._(this._environment); + + List get _paths { + var pathVar = _environment[envPathKey]; + // Handle empty to black + if (pathVar?.isNotEmpty ?? false) { + return pathVar!.split(envPathSeparator); + } else { + return []; + } + } + + set _paths(List paths) { + if (paths.isEmpty) { + _environment.remove(envPathKey); + } else { + // remove duplicates + paths = LinkedHashSet.from(paths).toList(); + _environment[envPathKey] = paths.join(envPathSeparator); + } + } + + /// Prepend a path (i.e. higher in the hierarchy to handle a [which] resolution. + void prepend(String path) => insert(0, path); + + @override + int get length => _paths.length; + + @override + String operator [](int index) { + return _paths[index]; + } + + @override + void operator []=(int index, String? value) { + _paths = _paths..[index] = value!; + } + + @override + void add(String element) { + // Needed for nnbd + _paths = [..._paths, element]; + } + + @override + set length(int newLength) { + _paths = _paths..length = newLength; + } + + @override + void insert(int index, String element) { + _paths = _paths..insert(index, element); + } + + /// Merge an environment. + /// + /// the other object, paths are prepended. + void merge(ShellEnvironmentPaths paths) { + insertAll(0, paths); + } + + @override + int get hashCode => const ListEquality().hash(this); + + @override + bool operator ==(Object other) { + if (other is ShellEnvironmentPaths) { + return const ListEquality().equals(this, other); + } + return false; + } + + @override + String toString() => 'Path($length)'; + + /// Overriden to handle concurrent modification and avoid duplicates. + @override + void addAll(Iterable paths) { + _paths = _paths..addAll(paths); + } + + /// Overriden to handle concurrent modification and avoid duplicates. + @override + void insertAll(int index, Iterable paths) { + _paths = _paths..insertAll(index, paths); + } +} + +/// Shell environment aliases for executable +class ShellEnvironmentAliases with MapMixin { + final Map _map; + + ShellEnvironmentAliases._([Map? map]) + : _map = map ?? {}; + + /// the other object takes precedence, vars are added + void merge(ShellEnvironmentAliases other) { + addAll(other); + } + + @override + String? operator [](Object? key) => _map[key as String]; + + @override + void operator []=(String key, String value) => _map[key] = value; + + @override + void clear() => _map.clear(); + + @override + Iterable get keys => _map.keys; + + @override + String? remove(Object? key) => _map.remove(key); + + // Key hash is sufficient here + @override + int get hashCode => const ListEquality().hash(keys.toList()); + + @override + bool operator ==(Object other) { + if (other is ShellEnvironmentVars) { + return const MapEquality().equals(this, other); + } + return false; + } + + @override + String toString() => 'Aliases($length)'; +} + +/// Shell environment variables helper. Does not affect the PATH variable +class ShellEnvironmentVars with MapMixin { + final ShellEnvironment _environment; + + ShellEnvironmentVars._(this._environment); + + /// Currently only the PATH key is ignored. + bool _ignoreKey(key) => key == envPathKey; + + @override + String? operator [](Object? key) { + if (_ignoreKey(key)) { + return null; + } + return _environment[key as String]; + } + + @override + void operator []=(String key, String value) { + if (!_ignoreKey(key)) { + _environment[key] = value; + } + } + + @override + void clear() { + removeWhere((key, value) => !_ignoreKey(key)); + } + + @override + Iterable get keys => + _environment.keys.where((key) => !_ignoreKey(key)); + + @override + String? remove(Object? key) { + if (!_ignoreKey(key)) { + return _environment.remove(key); + } + return null; + } + + /// the other object takes precedence, vars are added + void merge(ShellEnvironmentVars other) { + addAll(other); + } + + // Key hash is sufficient here + @override + int get hashCode => const ListEquality().hash(keys.toList()); + + @override + bool operator ==(Object other) { + if (other is ShellEnvironmentVars) { + return const MapEquality().equals(this, other); + } + return false; + } + + @override + String toString() => 'Vars($length)'; +} + +/// Shell modifiable helpers. should not be modified after being set. +abstract class ShellEnvironmentBase + with MapMixin + implements ShellEnvironment { + /// The resulting _env + final _env = {}; + + /// The vars but the PATH variable + ShellEnvironmentVars? _vars; + + /// The vars but the PATH variable + @override + ShellEnvironmentVars get vars => _vars ??= ShellEnvironmentVars._(this); + + /// The PATH variable as a convenient list. + ShellEnvironmentPaths? _paths; + + /// The PATH variable as a convenient list. + @override + ShellEnvironmentPaths get paths => _paths ??= ShellEnvironmentPaths._(this); + + /// The aliases. + ShellEnvironmentAliases? _aliases; + + /// The aliases as convenient map. + @override + ShellEnvironmentAliases get aliases => + _aliases ??= ShellEnvironmentAliases._(); + + /// Create an empty shell environment. + /// + /// Mainly used for testing as it is not easy to which environment variable + /// are required. + ShellEnvironmentBase.empty(); + + /// Create a new shell environment from the current shellEnvironment. + /// + /// Defaults create a full parent environment. + /// + /// It is recommended that you apply the environment to a shell. But it can + /// also be set globally (be aware of the potential effect on other part of + /// your application) to [shellEnvironment] + ShellEnvironmentBase.fromEnvironment({Map? environment}) { + environment ??= shellContext.shellEnvironment; + + // Copy vars/path + _env.addAll(environment); + // Copy alias + if (environment is ShellEnvironment) { + aliases.addAll(environment.aliases); + } + } + + /// From json. + /// + /// Mainly used for testing as it is not easy to which environment variable + /// are required. + ShellEnvironmentBase.fromJson(Map? map) { + try { + if (map != null) { + var rawVars = map['vars']; + if (rawVars is Map) { + vars.addAll(rawVars.cast()); + } + var rawPaths = map['paths']; + if (rawPaths is Iterable) { + paths.addAll(rawPaths.cast()); + } + var rawAliases = map['aliases']; + if (rawAliases is Map) { + aliases.addAll(rawAliases.cast()); + } + } + } catch (_) { + // Silent crash + } + } + + @override + String? operator [](Object? key) => _env[key as String]; + + @override + void operator []=(String key, String value) => _env[key] = value; + + @override + void clear() { + _env.clear(); + } + + @override + Iterable get keys => _env.keys; + + @override + String? remove(Object? key) { + return _env.remove(key); + } + + /// Merge an environment. + /// + /// the other object takes precedence, vars are added and paths prepended + @override + void merge(ShellEnvironment other) { + vars.merge(other.vars); + paths.merge(other.paths); + aliases.merge(other.aliases); + } + + /// `paths` and `vars` key + @override + Map toJson() { + return {'paths': paths, 'vars': vars, 'aliases': aliases}; + } + + @override + int get hashCode => const ListEquality().hash(paths); + + @override + bool operator ==(Object other) { + if (other is ShellEnvironment) { + if (other.vars != vars) { + return false; + } + if (other.paths != paths) { + return false; + } + if (other.aliases != aliases) { + return false; + } + return true; + } + return false; + } + + @override + String toString() => 'ShellEnvironment($paths, $vars, $aliases)'; +} + +/// Shell modifiable helpers. should not be modified after being set. +abstract class ShellEnvironment with MapMixin { + /// The vars but the PATH variable + ShellEnvironmentVars get vars; + + /// The PATH variable as a convenient list. + ShellEnvironmentPaths get paths; + + /// The aliases as convenient map. + ShellEnvironmentAliases get aliases; + + /// Merge an environment. + /// + /// the other object takes precedence, vars are added and paths prepended + void merge(ShellEnvironment other); + + /// `paths` and `vars` key + Map toJson(); +} diff --git a/lib/src/shell_utils.dart b/lib/src/shell_utils.dart index aad43c1..ad1e92a 100644 --- a/lib/src/shell_utils.dart +++ b/lib/src/shell_utils.dart @@ -10,6 +10,9 @@ import 'package:process_run/src/user_config.dart'; import 'bin/shell/import.dart'; import 'env_utils.dart'; +import 'shell_utils_common.dart'; + +export 'shell_utils_common.dart'; /// True if the line is a comment. /// @@ -174,18 +177,11 @@ Map environmentFilterOutVmOptions( return environment ?? platformEnvironment; } -const windowsDefaultPathExt = ['.exe', '.bat', '.cmd', '.com']; List? _windowsPathExts; /// Default extension for PATHEXT on Windows List get windowsPathExts => _windowsPathExts ??= environmentGetWindowsPathExt(platformEnvironment) ?? windowsDefaultPathExt; -const String windowsEnvPathSeparator = ';'; -const String posixEnvPathSeparator = ':'; -const envPathKey = 'PATH'; - -String get envPathSeparator => - Platform.isWindows ? windowsEnvPathSeparator : posixEnvPathSeparator; List? environmentGetWindowsPathExt( Map platformEnvironment) => @@ -268,16 +264,6 @@ List getEnvironmentPaths([Map? environment]) { List _getEnvironmentPaths(Map environment) => environment[envPathKey]?.split(envPathSeparator) ?? []; -/// Write a string line to the ouput -void streamSinkWriteln(StreamSink> sink, String message, - {Encoding encoding = systemEncoding}) => - streamSinkWrite(sink, '$message\n', encoding: encoding); - -/// Write a string to a to sink -void streamSinkWrite(StreamSink> sink, String message, - {Encoding encoding = systemEncoding}) => - sink.add(encoding.encode(message)); - /// IOSink extension extension IOSinkExt on IOSink { /// Catch exception diff --git a/lib/src/shell_utils_common.dart b/lib/src/shell_utils_common.dart new file mode 100644 index 0000000..86e45b1 --- /dev/null +++ b/lib/src/shell_utils_common.dart @@ -0,0 +1,27 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:process_run/src/platform/platform.dart'; + +const windowsDefaultPathExt = ['.exe', '.bat', '.cmd', '.com']; + +const String windowsEnvPathSeparator = ';'; +const String posixEnvPathSeparator = ':'; +const envPathKey = 'PATH'; + +String get envPathSeparator => + platformIoIsWindows ? windowsEnvPathSeparator : posixEnvPathSeparator; + +/// Write a string line to the ouput +void streamSinkWriteln(StreamSink> sink, String message, + {Encoding? encoding}) { + encoding ??= shellContext.encoding; + streamSinkWrite(sink, '$message\n', encoding: encoding); +} + +/// Write a string to a to sink +void streamSinkWrite(StreamSink> sink, String message, + {Encoding? encoding}) { + encoding ??= shellContext.encoding; + sink.add(encoding.encode(message)); +} diff --git a/test/shell_common_api_test.dart b/test/shell_common_api_test.dart new file mode 100644 index 0000000..15bc3ab --- /dev/null +++ b/test/shell_common_api_test.dart @@ -0,0 +1,21 @@ +library process_run.test.shell_common_api_test; + +import 'package:process_run/src/mixin/shell_common.dart'; +import 'package:test/test.dart'; + +void main() { + group('shell_api_test', () { + test('public', () { + // ignore: unnecessary_statements + ShellEnvironment; + // ignore: unnecessary_statements + ShellEnvironmentPaths; + // ignore: unnecessary_statements + ShellEnvironmentVars; + // ignore: unnecessary_statements + ShellEnvironmentAliases; + // ignore: unnecessary_statements + Shell; + }); + }); +} diff --git a/test/src_dartbin_cmd_test.dart b/test/src_dartbin_cmd_test.dart index 441e5b2..c5d2bf1 100644 --- a/test/src_dartbin_cmd_test.dart +++ b/test/src_dartbin_cmd_test.dart @@ -1,3 +1,7 @@ +// TODO non vm +//@TestOn('vm') +library process_run.test.src_dart_bin_cmd_test; + import 'package:process_run/dartbin.dart'; import 'package:process_run/src/dartbin_cmd.dart' show parsePlatformVersion, parsePlatformChannel; diff --git a/test/src_shell_test.dart b/test/src_shell_test.dart index 9ba4741..bbd000b 100644 --- a/test/src_shell_test.dart +++ b/test/src_shell_test.dart @@ -1,3 +1,6 @@ +@TestOn('vm') +library process_run.test.src_shell_test; + import 'package:test/test.dart'; @Deprecated('Dev only, when uncommeing the line debug = devTrue') diff --git a/test/src_shell_utils_test.dart b/test/src_shell_utils_test.dart index e8338d7..3263b8d 100644 --- a/test/src_shell_utils_test.dart +++ b/test/src_shell_utils_test.dart @@ -1,3 +1,6 @@ +@TestOn('vm') +library process_run.test.src_shell_utils_test; + import 'dart:convert'; import 'package:process_run/shell.dart'; diff --git a/test/src_user_config_test.dart b/test/src_user_config_test.dart index 28dae98..8b0b132 100644 --- a/test/src_user_config_test.dart +++ b/test/src_user_config_test.dart @@ -1,3 +1,6 @@ +@TestOn('vm') +library process_run.test.src_user_config_test; + import 'dart:io'; import 'package:path/path.dart'; From 18c30c08ee599d716e09a5b02fc5b22891533123 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 9 Nov 2021 15:22:30 +0100 Subject: [PATCH 002/150] doc: add shell sudo doc --- doc/shell.md | 42 +++++++++++++++++++++++++++++++++++++++ example/sudo_example.dart | 23 +++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 example/sudo_example.dart diff --git a/doc/shell.md b/doc/shell.md index 72b3560..7972d92 100644 --- a/doc/shell.md +++ b/doc/shell.md @@ -88,4 +88,46 @@ try { } on ShellException catch (_) { // We might get a shell exception } +``` +### Running sudo (Linux) + +You can run your dart program using sudo to run all you child scripts as a super user. + +Running a shell script with sudo from inside a dart script ran in non super user mode +is a little bit trickier as it requires user interaction. One solution (tried on Ubuntu) is to use +`sudo --stdin` to specify reading the password from the stdin. + +You can then run script using the following: + +```dart +await shell.run('sudo --stdin lsof -i:22'); +``` + +A shared stdin object could be used to redirect dart program input to shell objects. + +Here is a more complex example: +```dart +import 'package:process_run/shell.dart'; + +/// Only works on linux, list the process listening on port 22 +void main(List arguments) async { + /// We have use a shared stdin if we want to reuse it. + var stdin = sharedStdIn; + + /// Use sudo --stdin to read the password from stdin + /// Use an alias for simplicity (only need to refer to sudo instead of sudo --stdin + var env = ShellEnvironment()..aliases['sudo'] = 'sudo --stdin'; + var shell = Shell( + stdin: sharedStdIn, + // lsof return exitCode 1 if not found + environment: env, + throwOnError: false); + + await shell.run('sudo lsof -i:22'); + // second time should not ask for password + await shell.run('sudo lsof -i:80'); + + /// Stop shared stdin + await stdin.terminate(); +} ``` \ No newline at end of file diff --git a/example/sudo_example.dart b/example/sudo_example.dart new file mode 100644 index 0000000..813219d --- /dev/null +++ b/example/sudo_example.dart @@ -0,0 +1,23 @@ +import 'package:process_run/shell.dart'; + +/// Only works on linux, list the process listening on port 22 +void main(List arguments) async { + /// We have use a shared stdin if we want to reuse it. + var stdin = sharedStdIn; + + /// Use sudo --stdin to read the password from stdin + /// Use an alias for simplicity (only need to refer to sudo instead of sudo --stdin + var env = ShellEnvironment()..aliases['sudo'] = 'sudo --stdin'; + var shell = Shell( + stdin: sharedStdIn, + // lsof return exitCode 1 if not found + environment: env, + throwOnError: false); + + await shell.run('sudo lsof -i:22'); + // second time should not ask for password + await shell.run('sudo lsof -i:80'); + + /// Stop shared stdin + await stdin.terminate(); +} From 9bf2935bbf4bed3786777c3bc3fba2557b27f583 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 9 Nov 2021 18:19:29 +0100 Subject: [PATCH 003/150] exp: non io --- example/shell/shell_common.dart | 8 ++ lib/src/shell.dart | 13 ++- lib/src/shell_common.dart | 167 ++++++++++++++++++++++++------ lib/src/shell_common_io.dart | 84 +++++++++++++++ lib/src/shell_context_common.dart | 11 +- lib/src/shell_context_io.dart | 26 ++++- 6 files changed, 267 insertions(+), 42 deletions(-) create mode 100644 example/shell/shell_common.dart create mode 100644 lib/src/shell_common_io.dart diff --git a/example/shell/shell_common.dart b/example/shell/shell_common.dart new file mode 100644 index 0000000..81eda9d --- /dev/null +++ b/example/shell/shell_common.dart @@ -0,0 +1,8 @@ +import 'package:process_run/src/shell_common.dart'; + +Future main() async { + var shell = Shell(); + var result = await shell.run('echo Hello'); + print(result); + print(await which('ls')); +} diff --git a/lib/src/shell.dart b/lib/src/shell.dart index 9be0aa8..9e5af83 100644 --- a/lib/src/shell.dart +++ b/lib/src/shell.dart @@ -6,11 +6,13 @@ import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/process_run.dart'; -import 'package:process_run/src/shell_common.dart' show shellDebug; +import 'package:process_run/src/shell_common.dart' + show ShellOptions, shellDebug; import 'package:process_run/src/shell_utils.dart'; import 'package:synchronized/synchronized.dart'; import 'common/import.dart'; +import 'shell_common.dart' as common; export 'shell_common.dart' show shellDebug; @@ -90,7 +92,7 @@ Future> run( /// /// A list of ProcessResult is returned /// -class Shell { +class Shell implements common.ShellCommon { final bool _throwOnError; final String? _workingDirectory; ShellEnvironment? _environment; @@ -151,7 +153,8 @@ class Shell { // Default to true bool? commandVerbose, // Default to false - bool? commentVerbose}) + bool? commentVerbose, + ShellOptions? options}) : _throwOnError = throwOnError, _workingDirectory = workingDirectory, _runInShell = runInShell, @@ -209,6 +212,7 @@ class Shell { _workingDirectory ?? Directory.current.path; /// Create new shell at the given path + @override Shell cd(String path) { if (isRelative(path)) { path = join(_workingDirectoryPath, path); @@ -221,13 +225,16 @@ class Shell { } /// Get the shell path, using workingDirectory or current directory if null. + @override String get path => _workingDirectoryPath; /// Create a new shell at the given path, allowing popd on it + @override Shell pushd(String path) => cd(path).._parentShell = this; /// Pop the current directory to get the previous shell /// throw State error if nothing in the stack + @override Shell popd() { if (_parentShell == null) { throw StateError('no previous shell'); diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index f83b9cf..42be30b 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -1,9 +1,38 @@ import 'dart:async'; import 'dart:convert'; +import 'package:process_run/src/platform/platform.dart'; + +import 'shell_environment_common.dart'; + var shellDebug = false; // devWarning(true); // false -class ProcessResult {} +/// The result of running a non-interactive +/// process started with [Process.run] or [Process.runSync]. +class ProcessResult { + /// Exit code for the process. + /// + /// See [Process.exitCode] for more information in the exit code + /// value. + final int exitCode; + + /// Standard output from the process. The value used for the + /// `stdoutEncoding` argument to `Process.run` determines the type. If + /// `null` was used, this value is of type `List` otherwise it is + /// of type `String`. + final Object? stdout; + + /// Standard error from the process. The value used for the + /// `stderrEncoding` argument to `Process.run` determines the type. If + /// `null` was used, this value is of type `List` + /// otherwise it is of type `String`. + final Object? stderr; + + /// Process id of the process. + final int pid; + + ProcessResult(this.pid, this.exitCode, this.stdout, this.stderr); +} class Process {} @@ -33,39 +62,9 @@ class ProcessSignal { /// /// A list of ProcessResult is returned /// -abstract class Shell { - /// Create a new shell - Shell clone( - {bool? throwOnError, - String? workingDirectory, - // Don't change environment - @Deprecated('Don\'t change map') - Map? environment, - @Deprecated('Don\'t change includeParentEnvironment') - // Don't change includeParentEnvironment - bool? includeParentEnvironment, - bool? runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose, - bool? commentVerbose}); - - /// Create new shell at the given path - Shell cd(String path); - - /// Get the shell path, using workingDirectory or current directory if null. - String get path; - - /// Create a new shell at the given path, allowing popd on it - Shell pushd(String path); - - /// Pop the current directory to get the previous shell - /// throw State error if nothing in the stack - Shell popd(); +abstract class Shell extends ShellCommon { + factory Shell({ShellOptions? options, ShellEnvironment? environment}) => + shellContext.newShell(options: options); /// Kills the current running process. /// @@ -99,6 +98,21 @@ abstract class Shell { {void Function(Process process)? onProcess}); } +abstract class ShellCommon { + /// Create new shell at the given path + ShellCommon cd(String path); + + /// Get the shell path, using workingDirectory or current directory if null. + String get path; + + /// Create a new shell at the given path, allowing popd on it + ShellCommon pushd(String path); + + /// Pop the current directory to get the previous shell + /// throw State error if nothing in the stack + ShellCommon popd(); +} + /// Exception thrown in exitCode != 0 and throwOnError is true class ShellException implements Exception { final ProcessResult? result; @@ -109,3 +123,88 @@ class ShellException implements Exception { @override String toString() => 'ShellException($message)'; } + +class ShellOptions { + final bool _throwOnError; + final String? _workingDirectory; + + final bool? _runInShell; + final Encoding? _stdoutEncoding; + final Encoding? _stderrEncoding; + final Stream>? _stdin; + final StreamSink>? _stdout; + final StreamSink>? _stderr; + final bool _verbose; + final bool _commandVerbose; + final bool _commentVerbose; + + /// [throwOnError] means that if an exit code is not 0, it will throw an error + /// + /// Unless specified [runInShell] will be false. However on windows, it will + /// default to true for non .exe files + /// + /// if [verbose] is not false or [commentVerbose] is true, it will display the + /// comments as well + const ShellOptions( + {bool throwOnError = true, + String? workingDirectory, + Map? environment, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool verbose = true, + // Default to true + bool? commandVerbose, + // Default to false + bool? commentVerbose}) + : _throwOnError = throwOnError, + _workingDirectory = workingDirectory, + _runInShell = runInShell, + _stdoutEncoding = stdoutEncoding, + _stderrEncoding = stderrEncoding, + _stdin = stdin, + _stdout = stdout, + _stderr = stderr, + _verbose = verbose, + _commandVerbose = commandVerbose ?? verbose, + _commentVerbose = commentVerbose ?? false; + + /// Create a new shell + ShellOptions clone( + {bool? throwOnError, + String? workingDirectory, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, + bool? commentVerbose}) { + return ShellOptions( + verbose: verbose ?? _verbose, + runInShell: runInShell ?? _runInShell, + commandVerbose: commandVerbose ?? _commandVerbose, + commentVerbose: commentVerbose ?? _commentVerbose, + stderr: stderr ?? _stderr, + stderrEncoding: stderrEncoding ?? _stderrEncoding, + stdin: stdin ?? _stdin, + stdout: stdout ?? _stdout, + stdoutEncoding: stdoutEncoding ?? _stdoutEncoding, + throwOnError: throwOnError ?? _throwOnError, + workingDirectory: workingDirectory ?? _workingDirectory); + } +} + +/// Which common implementation +Future which(String command, + {ShellEnvironment? environment, + bool includeParentEnvironment = true}) async { + return shellContext.which(command, + environment: environment, + includeParentEnvironment: includeParentEnvironment); +} diff --git a/lib/src/shell_common_io.dart b/lib/src/shell_common_io.dart new file mode 100644 index 0000000..f4dfe2a --- /dev/null +++ b/lib/src/shell_common_io.dart @@ -0,0 +1,84 @@ +import 'dart:async'; +import 'dart:io' as io; + +import 'package:process_run/shell.dart' as io; +import 'package:process_run/src/mixin/shell_common.dart'; +import 'package:process_run/src/shell_context_io.dart'; + +import 'shell_common.dart'; + +class ProcessResultIo implements ProcessResult { + final io.ProcessResult impl; + + ProcessResultIo(this.impl); + + @override + int get exitCode => impl.exitCode; + + @override + int get pid => impl.pid; + + @override + Object? get stderr => impl.stderr; + + @override + Object? get stdout => impl.stdout; + + @override + String toString() => 'exitCode $exitCode, pid $pid'; +} + +class ShellIo implements Shell { + final ShellContextIo shellContextIo; + late final ShellEnvironment environment; + late final ShellOptions? options; + late final io.Shell ioShell; + + ShellIo( + {required this.shellContextIo, + this.options, + bool includeParentEnvironment = true, + ShellEnvironment? environment}) { + this.environment = environment ?? shellContextIo.shellEnvironment; + ioShell = io.Shell( + options: options, + environment: this.environment, + includeParentEnvironment: includeParentEnvironment); + } + + @override + ShellCommon cd(String path) => ioShell.cd(path); + + @override + bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { + var ioProcessSignal = io.ProcessSignal.sigterm; + return ioShell.kill(ioProcessSignal); + } + + @override + String get path => ioShell.path; + + @override + ShellCommon popd() => ioShell.popd(); + + @override + ShellCommon pushd(String path) => ioShell.pushd(path); + + @override + Future> run(String script, + {void Function(Process process)? onProcess}) async { + var ioResult = await ioShell.run(script, + onProcess: onProcess == null ? null : (io.Process process) {}); + return ioResult + .map((ioProcessResult) => ProcessResultIo(ioProcessResult)) + .toList(); + } + + @override + Future runExecutableArguments( + String executable, List arguments, + {void Function(Process process)? onProcess}) async { + return ProcessResultIo( + await ioShell.runExecutableArguments(executable, arguments)); + } +} diff --git a/lib/src/shell_context_common.dart b/lib/src/shell_context_common.dart index 6fb0874..f982a9c 100644 --- a/lib/src/shell_context_common.dart +++ b/lib/src/shell_context_common.dart @@ -1,7 +1,8 @@ import 'dart:convert'; import 'package:path/path.dart' as p; -import 'package:process_run/shell.dart'; +import 'package:process_run/src/shell_common.dart'; +import 'package:process_run/src/shell_environment_common.dart'; /// abstract shell context abstract class ShellContext { @@ -9,11 +10,17 @@ abstract class ShellContext { ShellEnvironment get shellEnvironment; /// Which command. - Future which(String command); + Future which(String command, + {ShellEnvironment? environment, bool includeParentEnvironment = true}); /// Path context. p.Context get path; /// Default shell encoding (systemEncoding on iOS) Encoding get encoding; + + Shell newShell( + {ShellOptions? options, + ShellEnvironment? environment, + bool includeParentEnvironment = true}); } diff --git a/lib/src/shell_context_io.dart b/lib/src/shell_context_io.dart index 013d4ea..45a7627 100644 --- a/lib/src/shell_context_io.dart +++ b/lib/src/shell_context_io.dart @@ -3,20 +3,40 @@ import 'dart:io'; import 'package:path/path.dart' as p; import 'package:process_run/shell.dart' as ds; +import 'package:process_run/src/shell_common.dart'; +import 'package:process_run/src/shell_common_io.dart'; import 'package:process_run/src/shell_context_common.dart'; -import 'package:process_run/src/shell_environment.dart'; +import 'package:process_run/src/shell_environment.dart' as io; +import 'package:process_run/src/shell_environment_common.dart'; class ShellContextIo implements ShellContext { @override ShellEnvironment get shellEnvironment => - asShellEnvironment(ds.shellEnvironment); + io.ShellEnvironment(environment: ds.shellEnvironment); @override p.Context get path => p.context; @override - Future which(String command) => ds.which(command); + Future which(String command, + {ShellEnvironment? environment, + bool includeParentEnvironment = true}) => + ds.which(command, + environment: environment, + includeParentEnvironment: includeParentEnvironment); @override Encoding get encoding => systemEncoding; + + @override + ShellIo newShell( + {ShellOptions? options, + ShellEnvironment? environment, + bool includeParentEnvironment = true}) { + return ShellIo( + shellContextIo: this, + options: options, + environment: environment, + includeParentEnvironment: includeParentEnvironment); + } } From 1328d92bd9cb7f15818e0b135903ca63d8519f9c Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 10 Nov 2021 10:06:55 +0100 Subject: [PATCH 004/150] doc: sudo example --- doc/shell.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/doc/shell.md b/doc/shell.md index 7972d92..f818368 100644 --- a/doc/shell.md +++ b/doc/shell.md @@ -130,4 +130,34 @@ void main(List arguments) async { /// Stop shared stdin await stdin.terminate(); } +``` + +If you have the password in a variable and not access to stdin (for example in some flutter scenario), you +can do something like: + +```dart +import 'dart:io'; + +import 'package:http/http.dart'; +import 'package:process_run/shell.dart'; +import 'package:tekartik_common_utils/common_utils_import.dart'; + +void main(List arguments) async { + // Assuming you have the password in `pwd` variable + + // Use sudo --stdin to read the password from stdin + // Use an alias for simplicity (only need to refer to sudo instead of sudo --stdin + var env = ShellEnvironment()..aliases['sudo'] = 'sudo --stdin'; + + // Create a fake stdin stream from the password variable + var stdin = + ByteStream.fromBytes(systemEncoding.encode(pwd)).asBroadcastStream(); + + // Execute! + var shell = Shell(stdin: stdin, environment: env); + + // Should not ask for password + await shell.run('sudo lsof -i:22'); + await shell.run('sudo lsof -i:80'); +} ``` \ No newline at end of file From 88124366738483a5ce7a72833f22e2d3a8b88c51 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 15 Nov 2021 08:40:40 +0100 Subject: [PATCH 005/150] fix: ci --- .github/workflows/run_ci.yml | 5 +++-- doc/process_run_development.md | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index 69d436d..694387a 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -1,6 +1,7 @@ name: Run CI on: push: + workflow_dispatch: schedule: - cron: '0 0 * * 0' # every sunday at midnight @@ -17,9 +18,9 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] dart: [stable, beta, dev] steps: - - uses: cedx/setup-dart@v2 + - uses: dart-lang/setup-dart@v1 with: - release-channel: ${{ matrix.dart }} + sdk: ${{ matrix.dart }} - uses: actions/checkout@v2 - run: dart --version - run: dart pub get diff --git a/doc/process_run_development.md b/doc/process_run_development.md index 57b0581..2f19785 100644 --- a/doc/process_run_development.md +++ b/doc/process_run_development.md @@ -30,7 +30,7 @@ pub run build_runner test -- -p chrome -p firefox -p vm ``` dependency_overrides: process_run: - git: git://github.com/tekartik/process_run.dart + git: https://github.com/tekartik/process_run.dart ``` ### Publishing From ea6acd55f6aeb4e3334d5743560e5cecbee3cb8b Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 27 Nov 2021 16:12:46 +0100 Subject: [PATCH 006/150] feat! wip io abstraction --- lib/process_run.dart | 55 +------ lib/src/api/shell_common.dart | 24 ++++ lib/src/common/import.dart | 4 +- lib/src/common/import_common.dart | 3 + lib/src/lines_utils.dart | 143 +----------------- lib/src/lines_utils_common.dart | 144 +++++++++++++++++++ lib/src/platform/platform_io.dart | 1 + lib/src/process_result_common_extension.dart | 51 +++++++ lib/src/process_run.dart | 1 - lib/src/shell.dart | 7 +- lib/src/shell_common.dart | 68 +++++++-- lib/src/shell_common_io.dart | 85 ++++++----- lib/src/shell_context_common.dart | 6 +- lib/src/shell_context_io.dart | 14 +- lib/src/shell_environment_common.dart | 14 ++ lib/src/shell_utils.dart | 19 +-- lib/src/shell_utils_common.dart | 59 ++++++++ 17 files changed, 438 insertions(+), 260 deletions(-) create mode 100644 lib/src/api/shell_common.dart create mode 100644 lib/src/common/import_common.dart create mode 100644 lib/src/lines_utils_common.dart create mode 100644 lib/src/process_result_common_extension.dart diff --git a/lib/process_run.dart b/lib/process_run.dart index b792a87..2d84ae6 100644 --- a/lib/process_run.dart +++ b/lib/process_run.dart @@ -5,66 +5,17 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:process_run/src/characters.dart'; import 'package:process_run/src/process_run.dart'; import 'src/common/import.dart'; +export 'package:process_run/src/shell_utils_common.dart' + show argumentsToString, argumentToString; + export 'src/dev_process_run.dart'; export 'src/process_run.dart' show runExecutableArguments, executableArgumentsToString; -/// Helper to run a process and connect the input/output for verbosity -/// - -/// Helper to run a process and connect the input/output for verbosity -/// - -/// Use to safely enclose an argument if needed -/// -/// argument must not be null -String argumentToString(String argument) { - var hasWhitespace = false; - var singleQuoteCount = 0; - var doubleQuoteCount = 0; - if (argument.isEmpty) { - return '""'; - } - for (final rune in argument.runes) { - if ((!hasWhitespace) && (isWhitespace(rune))) { - hasWhitespace = true; - } else if (rune == 0x0027) { - // ' - singleQuoteCount++; - } else if (rune == 0x0022) { - // " - doubleQuoteCount++; - } - } - if (singleQuoteCount > 0) { - if (doubleQuoteCount > 0) { - // simply escape all double quotes - argument = '"${argument.replaceAll('"', '\\"')}"'; - } else { - argument = '"$argument"'; - } - } else if (doubleQuoteCount > 0) { - argument = "'$argument'"; - } else if (hasWhitespace) { - argument = '"$argument"'; - } - return argument; -} - -/// Convert multiple arguments to string than can be used in a terminal -String argumentsToString(List arguments) { - final argumentStrings = []; - for (final argument in arguments) { - argumentStrings.add(argumentToString(argument)); - } - return argumentStrings.join(' '); -} - /// Use runExecutableArguments instead /// /// if [commmandVerbose] or [verbose] is true, display the command. diff --git a/lib/src/api/shell_common.dart b/lib/src/api/shell_common.dart new file mode 100644 index 0000000..ce3dd6a --- /dev/null +++ b/lib/src/api/shell_common.dart @@ -0,0 +1,24 @@ +export 'package:process_run/src/lines_utils_common.dart' + show ShellLinesController, shellStreamLines; +export 'package:process_run/src/process_result_common_extension.dart' + show + ProcessRunProcessResultsExt, + ProcessRunProcessResultExt, + ProcessRunProcessExt; +export 'package:process_run/src/shell_common.dart' + show + Process, + ProcessResult, + ProcessSignal, + ShellOptions, + Shell, + ShellException; +export 'package:process_run/src/shell_environment_common.dart' + show + shellEnvironment, + ShellEnvironment, + ShellEnvironmentAliases, + ShellEnvironmentVars, + ShellEnvironmentPaths; +export 'package:process_run/src/shell_utils_common.dart' + show shellArgument, shellArguments; diff --git a/lib/src/common/import.dart b/lib/src/common/import.dart index 0f60c25..c27dbf8 100644 --- a/lib/src/common/import.dart +++ b/lib/src/common/import.dart @@ -1,4 +1,2 @@ -export 'dart:async'; - export 'dartbin.dart'; -export 'dev_utils.dart'; +export 'import_common.dart'; diff --git a/lib/src/common/import_common.dart b/lib/src/common/import_common.dart new file mode 100644 index 0000000..7306f72 --- /dev/null +++ b/lib/src/common/import_common.dart @@ -0,0 +1,3 @@ +export 'dart:async'; + +export 'dev_utils.dart'; diff --git a/lib/src/lines_utils.dart b/lib/src/lines_utils.dart index 66059c7..a5037dd 100644 --- a/lib/src/lines_utils.dart +++ b/lib/src/lines_utils.dart @@ -1,142 +1 @@ -import 'dart:convert'; -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:process_run/src/shell_common.dart'; -import 'package:process_run/src/shell_utils.dart'; - -import 'common/import.dart'; - -/// Basic shell lines controller. -/// -/// Usage: -/// ```dart -/// var controller = ShellLinesController(); -/// var shell = Shell(stdout: controller.sink, verbose: false); -/// controller.stream.listen((event) { -/// // Handle output -/// -/// // ... -/// -/// // If needed kill the shell -/// shell.kill(); -/// }); -/// try { -/// await shell.run('dart echo.dart some_text'); -/// } on ShellException catch (_) { -/// // We might get a shell exception -/// } -/// ``` -class ShellLinesController { - final Encoding encoding; - late StreamController> _controller; - - ShellLinesController({this.encoding = systemEncoding}) { - _controller = StreamController>(); - } - - /// Write a string with the specified encoding. - void write(String message) => - streamSinkWrite(sink, message, encoding: encoding); - - /// The sink for the Shell stderr/stdout - StreamSink> get sink => _controller.sink; - - /// The stream to listen to - Stream get stream => - shellStreamLines(_controller.stream, encoding: encoding); - - /// Dispose the controller. - void close() { - _controller.close(); - } - - void writeln(String message) { - write('$message\n'); - } -} - -/// Basic line streaming. Assuming system encoding -Stream shellStreamLines(Stream> stream, - {Encoding encoding = systemEncoding}) { - StreamSubscription? subscription; - List? currentLine; - const endOfLine = 10; - const lineFeed = 13; - late StreamController ctlr; - - // devPrint('listen (paused: $paused)'); - void addCurrentLine() { - if (subscription?.isPaused ?? false) { - // Do nothing, current line is discarded - } else { - if (currentLine?.isNotEmpty ?? false) { - try { - ctlr.add(encoding.decode(currentLine!)); - } catch (_) { -// Ignore nad encoded line - print('ignoring: $currentLine'); - } - } - } - currentLine = null; - } - - ctlr = StreamController(onPause: () { - if (shellDebug) { - print('onPause (paused: ${subscription?.isPaused})'); - } - // Last one - addCurrentLine(); - subscription?.pause(); - }, onResume: () { - // devPrint('onResume (paused: $paused)'); - if (subscription?.isPaused ?? false) { - subscription?.resume(); - } - }, onListen: () { - void addToCurrentLine(List data) { - if (currentLine == null) { - currentLine = data; - } else { - var newCurrentLine = Uint8List(currentLine!.length + data.length); - newCurrentLine.setAll(0, currentLine!); - newCurrentLine.setAll(currentLine!.length, data); - currentLine = newCurrentLine; - } - } - - subscription = stream.listen((data) { - // var _w; - // print('read $data'); - var paused = subscription?.isPaused ?? false; - // devPrint('read $data (paused: $paused)'); - if (paused) { - return; - } - // look for \n (10) - var start = 0; - for (var i = 0; i < data.length; i++) { - var byte = data[i]; - if (byte == endOfLine || byte == lineFeed) { - addToCurrentLine(data.sublist(start, i)); - addCurrentLine(); -// Skip it - start = i + 1; - } - } - // Store last current line - if (data.length > start) { - addToCurrentLine(data.sublist(start, data.length)); - } - }, onDone: () { - // Last one - addCurrentLine(); - ctlr.close(); - }); - }, onCancel: () { - subscription?.cancel(); - }); - - return ctlr.stream; -} +export 'lines_utils_common.dart'; diff --git a/lib/src/lines_utils_common.dart b/lib/src/lines_utils_common.dart new file mode 100644 index 0000000..6d53396 --- /dev/null +++ b/lib/src/lines_utils_common.dart @@ -0,0 +1,144 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:process_run/src/platform/platform.dart'; +import 'package:process_run/src/shell_common.dart'; +import 'package:process_run/src/shell_utils_common.dart'; + +import 'common/import.dart'; + +/// Basic shell lines controller. +/// +/// Usage: +/// ```dart +/// var controller = ShellLinesController(); +/// var shell = Shell(stdout: controller.sink, verbose: false); +/// controller.stream.listen((event) { +/// // Handle output +/// +/// // ... +/// +/// // If needed kill the shell +/// shell.kill(); +/// }); +/// try { +/// await shell.run('dart echo.dart some_text'); +/// } on ShellException catch (_) { +/// // We might get a shell exception +/// } +/// ``` +class ShellLinesController { + late final Encoding encoding; + late StreamController> _controller; + + ShellLinesController({Encoding? encoding}) { + this.encoding = encoding ?? shellContext.encoding; + _controller = StreamController>(); + } + + /// Write a string with the specified encoding. + void write(String message) => + streamSinkWrite(sink, message, encoding: encoding); + + /// The sink for the Shell stderr/stdout + StreamSink> get sink => _controller.sink; + + /// The stream to listen to + Stream get stream => + shellStreamLines(_controller.stream, encoding: encoding); + + /// Dispose the controller. + void close() { + _controller.close(); + } + + void writeln(String message) { + write('$message\n'); + } +} + +/// Basic line streaming. Assuming system encoding +Stream shellStreamLines(Stream> stream, + {Encoding? encoding}) { + encoding ??= shellContext.encoding; + StreamSubscription? subscription; + List? currentLine; + const endOfLine = 10; + const lineFeed = 13; + late StreamController ctlr; + + // devPrint('listen (paused: $paused)'); + void addCurrentLine() { + if (subscription?.isPaused ?? false) { + // Do nothing, current line is discarded + } else { + if (currentLine?.isNotEmpty ?? false) { + try { + ctlr.add(encoding!.decode(currentLine!)); + } catch (_) { +// Ignore nad encoded line + print('ignoring: $currentLine'); + } + } + } + currentLine = null; + } + + ctlr = StreamController(onPause: () { + if (shellDebug) { + print('onPause (paused: ${subscription?.isPaused})'); + } + // Last one + addCurrentLine(); + subscription?.pause(); + }, onResume: () { + // devPrint('onResume (paused: $paused)'); + if (subscription?.isPaused ?? false) { + subscription?.resume(); + } + }, onListen: () { + void addToCurrentLine(List data) { + if (currentLine == null) { + currentLine = data; + } else { + var newCurrentLine = Uint8List(currentLine!.length + data.length); + newCurrentLine.setAll(0, currentLine!); + newCurrentLine.setAll(currentLine!.length, data); + currentLine = newCurrentLine; + } + } + + subscription = stream.listen((data) { + // var _w; + // print('read $data'); + var paused = subscription?.isPaused ?? false; + // devPrint('read $data (paused: $paused)'); + if (paused) { + return; + } + // look for \n (10) + var start = 0; + for (var i = 0; i < data.length; i++) { + var byte = data[i]; + if (byte == endOfLine || byte == lineFeed) { + addToCurrentLine(data.sublist(start, i)); + addCurrentLine(); +// Skip it + start = i + 1; + } + } + // Store last current line + if (data.length > start) { + addToCurrentLine(data.sublist(start, data.length)); + } + }, onDone: () { + // Last one + addCurrentLine(); + ctlr.close(); + }); + }, onCancel: () { + subscription?.cancel(); + }); + + return ctlr.stream; +} diff --git a/lib/src/platform/platform_io.dart b/lib/src/platform/platform_io.dart index 9e5d458..a5730f2 100644 --- a/lib/src/platform/platform_io.dart +++ b/lib/src/platform/platform_io.dart @@ -5,4 +5,5 @@ import 'package:process_run/src/shell_context_io.dart'; bool get platformIoIsWindows => Platform.isWindows; +/// Global shell context ShellContext shellContext = ShellContextIo(); diff --git a/lib/src/process_result_common_extension.dart b/lib/src/process_result_common_extension.dart new file mode 100644 index 0000000..24d854f --- /dev/null +++ b/lib/src/process_result_common_extension.dart @@ -0,0 +1,51 @@ +import 'dart:convert'; + +import 'package:process_run/src/shell_common.dart'; + +import 'lines_utils.dart'; + +/// run response helper. +extension ProcessRunProcessResultsExt on List { + Iterable _outLinesToLines(Iterable> out) => + out.expand((lines) => lines); + + /// Join the out lines for a quick string access. + String get outText => outLines.join('\n'); + + /// Join the out lines for a quick string access. + String get errText => errLines.join('\n'); + + /// Out line lists + Iterable get outLines => + _outLinesToLines(map((result) => result.outLines)); + + /// Line lists + Iterable get errLines => + _outLinesToLines(map((result) => result.errLines)); +} + +/// run response helper. +extension ProcessRunProcessResultExt on ProcessResult { + Iterable _outStringToLines(String out) => LineSplitter.split(out); + + /// Join the out lines for a quick string access. + String get outText => outLines.join('\n'); + + /// Join the out lines for a quick string access. + String get errText => errLines.join('\n'); + + /// Out line lists + Iterable get outLines => _outStringToLines(stdout.toString()); + + /// Line lists + Iterable get errLines => _outStringToLines(stderr.toString()); +} + +/// Process helper. +extension ProcessRunProcessExt on Process { + /// Out lines stream + Stream get outLines => shellStreamLines(stdout); + + /// Err lines stream + Stream get errLines => shellStreamLines(stderr); +} diff --git a/lib/src/process_run.dart b/lib/src/process_run.dart index 73fdfc3..58e0602 100644 --- a/lib/src/process_run.dart +++ b/lib/src/process_run.dart @@ -3,7 +3,6 @@ import 'dart:io' as io; import 'dart:io'; import 'package:path/path.dart'; -import 'package:process_run/process_run.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/shell.dart'; import 'package:process_run/src/shell_utils.dart' as utils; diff --git a/lib/src/shell.dart b/lib/src/shell.dart index 9e5af83..4fb9546 100644 --- a/lib/src/shell.dart +++ b/lib/src/shell.dart @@ -12,7 +12,6 @@ import 'package:process_run/src/shell_utils.dart'; import 'package:synchronized/synchronized.dart'; import 'common/import.dart'; -import 'shell_common.dart' as common; export 'shell_common.dart' show shellDebug; @@ -92,7 +91,7 @@ Future> run( /// /// A list of ProcessResult is returned /// -class Shell implements common.ShellCommon { +class Shell { final bool _throwOnError; final String? _workingDirectory; ShellEnvironment? _environment; @@ -212,7 +211,6 @@ class Shell implements common.ShellCommon { _workingDirectory ?? Directory.current.path; /// Create new shell at the given path - @override Shell cd(String path) { if (isRelative(path)) { path = join(_workingDirectoryPath, path); @@ -225,16 +223,13 @@ class Shell implements common.ShellCommon { } /// Get the shell path, using workingDirectory or current directory if null. - @override String get path => _workingDirectoryPath; /// Create a new shell at the given path, allowing popd on it - @override Shell pushd(String path) => cd(path).._parentShell = this; /// Pop the current directory to get the previous shell /// throw State error if nothing in the stack - @override Shell popd() { if (_parentShell == null) { throw StateError('no previous shell'); diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index 42be30b..cc9988c 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -34,7 +34,41 @@ class ProcessResult { ProcessResult(this.pid, this.exitCode, this.stdout, this.stderr); } -class Process {} +abstract class Process { + /// A `Future` which completes with the exit code of the process + /// when the process completes. + /// + /// The handling of exit codes is platform specific. + /// + /// On Linux and OS X a normal exit code will be a positive value in + /// the range `[0..255]`. If the process was terminated due to a signal + /// the exit code will be a negative value in the range `[-255..-1]`, + /// where the absolute value of the exit code is the signal + /// number. For example, if a process crashes due to a segmentation + /// violation the exit code will be -11, as the signal SIGSEGV has the + /// number 11. + /// + /// On Windows a process can report any 32-bit value as an exit + /// code. When returning the exit code this exit code is turned into + /// a signed value. Some special values are used to report + /// termination due to some system event. E.g. if a process crashes + /// due to an access violation the 32-bit exit code is `0xc0000005`, + /// which will be returned as the negative number `-1073741819`. To + /// get the original 32-bit value use `(0x100000000 + exitCode) & + /// 0xffffffff`. + /// + /// There is no guarantee that [stdout] and [stderr] have finished reporting + /// the buffered output of the process when the returned future completes. + /// To be sure that all output is captured, + /// wait for the done event on the streams. + Future get exitCode; + + /// The standard output stream of the process as a `Stream`. + Stream> get stdout; + + /// The standard error stream of the process as a `Stream`. + Stream> get stderr; +} class ProcessSignal { const ProcessSignal(); @@ -62,9 +96,27 @@ class ProcessSignal { /// /// A list of ProcessResult is returned /// -abstract class Shell extends ShellCommon { - factory Shell({ShellOptions? options, ShellEnvironment? environment}) => - shellContext.newShell(options: options); +abstract class Shell { + factory Shell( + {ShellOptions? options, + Map? environment, + + /// Compat, prefer options + bool? verbose, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + StreamSink>? stdout, + StreamSink>? stderr, + bool? runInShell}) => + shellContext.newShell( + options: options?.clone( + verbose: verbose, + stderrEncoding: stderrEncoding, + stdoutEncoding: stdoutEncoding, + runInShell: runInShell, + stdout: stdout, + stderr: stderr), + environment: environment); /// Kills the current running process. /// @@ -96,21 +148,19 @@ abstract class Shell extends ShellCommon { Future runExecutableArguments( String executable, List arguments, {void Function(Process process)? onProcess}); -} -abstract class ShellCommon { /// Create new shell at the given path - ShellCommon cd(String path); + Shell cd(String path); /// Get the shell path, using workingDirectory or current directory if null. String get path; /// Create a new shell at the given path, allowing popd on it - ShellCommon pushd(String path); + Shell pushd(String path); /// Pop the current directory to get the previous shell /// throw State error if nothing in the stack - ShellCommon popd(); + Shell popd(); } /// Exception thrown in exitCode != 0 and throwOnError is true diff --git a/lib/src/shell_common_io.dart b/lib/src/shell_common_io.dart index f4dfe2a..2630ae3 100644 --- a/lib/src/shell_common_io.dart +++ b/lib/src/shell_common_io.dart @@ -2,8 +2,6 @@ import 'dart:async'; import 'dart:io' as io; import 'package:process_run/shell.dart' as io; -import 'package:process_run/src/mixin/shell_common.dart'; -import 'package:process_run/src/shell_context_io.dart'; import 'shell_common.dart'; @@ -28,57 +26,76 @@ class ProcessResultIo implements ProcessResult { String toString() => 'exitCode $exitCode, pid $pid'; } -class ShellIo implements Shell { - final ShellContextIo shellContextIo; - late final ShellEnvironment environment; - late final ShellOptions? options; - late final io.Shell ioShell; - - ShellIo( - {required this.shellContextIo, - this.options, - bool includeParentEnvironment = true, - ShellEnvironment? environment}) { - this.environment = environment ?? shellContextIo.shellEnvironment; - ioShell = io.Shell( - options: options, - environment: this.environment, - includeParentEnvironment: includeParentEnvironment); +Future _wrapIoException(Future Function() action) async { + try { + return await action(); + } on io.ShellException catch (e) { + throw ShellExceptionIo(e); } +} + +class ShellIo implements Shell { + late final io.Shell impl; + + ShellIo({ + required this.impl, + }); + + Shell _wrapIoShell(io.Shell ioShell) => ShellIo(impl: ioShell); @override - ShellCommon cd(String path) => ioShell.cd(path); + Shell cd(String path) => _wrapIoShell(impl.cd(path)); @override bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { var ioProcessSignal = io.ProcessSignal.sigterm; - return ioShell.kill(ioProcessSignal); + return impl.kill(ioProcessSignal); } @override - String get path => ioShell.path; + String get path => impl.path; @override - ShellCommon popd() => ioShell.popd(); + Shell popd() => _wrapIoShell(impl.popd()); @override - ShellCommon pushd(String path) => ioShell.pushd(path); + Shell pushd(String path) => _wrapIoShell(impl.pushd(path)); @override Future> run(String script, - {void Function(Process process)? onProcess}) async { - var ioResult = await ioShell.run(script, - onProcess: onProcess == null ? null : (io.Process process) {}); - return ioResult - .map((ioProcessResult) => ProcessResultIo(ioProcessResult)) - .toList(); - } + {void Function(Process process)? onProcess}) => + _wrapIoException(() async { + var ioResult = await impl.run(script, + onProcess: onProcess == null ? null : (io.Process process) {}); + return ioResult + .map((ioProcessResult) => ProcessResultIo(ioProcessResult)) + .toList(); + }); @override Future runExecutableArguments( - String executable, List arguments, - {void Function(Process process)? onProcess}) async { - return ProcessResultIo( - await ioShell.runExecutableArguments(executable, arguments)); + String executable, List arguments, + {void Function(Process process)? onProcess}) => + _wrapIoException(() async { + return ProcessResultIo( + await impl.runExecutableArguments(executable, arguments)); + }); +} + +class ShellExceptionIo implements ShellException { + final io.ShellException impl; + + ShellExceptionIo(this.impl); + + @override + String get message => impl.message; + + @override + ProcessResult? get result { + var implResult = impl.result; + if (implResult != null) { + return ProcessResultIo(implResult); + } + return null; } } diff --git a/lib/src/shell_context_common.dart b/lib/src/shell_context_common.dart index f982a9c..2100b04 100644 --- a/lib/src/shell_context_common.dart +++ b/lib/src/shell_context_common.dart @@ -21,6 +21,10 @@ abstract class ShellContext { Shell newShell( {ShellOptions? options, - ShellEnvironment? environment, + Map? environment, bool includeParentEnvironment = true}); + + ShellEnvironment newShellEnvironment({ + Map? environment, + }); } diff --git a/lib/src/shell_context_io.dart b/lib/src/shell_context_io.dart index 45a7627..63a0e80 100644 --- a/lib/src/shell_context_io.dart +++ b/lib/src/shell_context_io.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:path/path.dart' as p; import 'package:process_run/shell.dart' as ds; +import 'package:process_run/src/shell.dart' as io; import 'package:process_run/src/shell_common.dart'; import 'package:process_run/src/shell_common_io.dart'; import 'package:process_run/src/shell_context_common.dart'; @@ -29,14 +30,19 @@ class ShellContextIo implements ShellContext { Encoding get encoding => systemEncoding; @override - ShellIo newShell( + ShellEnvironment newShellEnvironment({Map? environment}) { + return io.ShellEnvironment(environment: environment); + } + + @override + Shell newShell( {ShellOptions? options, - ShellEnvironment? environment, + Map? environment, bool includeParentEnvironment = true}) { - return ShellIo( - shellContextIo: this, + var ioShell = io.Shell( options: options, environment: environment, includeParentEnvironment: includeParentEnvironment); + return ShellIo(impl: ioShell); } } diff --git a/lib/src/shell_environment_common.dart b/lib/src/shell_environment_common.dart index 68ccdc7..742d7a4 100644 --- a/lib/src/shell_environment_common.dart +++ b/lib/src/shell_environment_common.dart @@ -341,6 +341,9 @@ abstract class ShellEnvironmentBase String toString() => 'ShellEnvironment($paths, $vars, $aliases)'; } +/// The global environment +ShellEnvironment get shellEnvironment => shellContext.shellEnvironment; + /// Shell modifiable helpers. should not be modified after being set. abstract class ShellEnvironment with MapMixin { /// The vars but the PATH variable @@ -359,4 +362,15 @@ abstract class ShellEnvironment with MapMixin { /// `paths` and `vars` key Map toJson(); + + /// Create a new shell environment from the current shellEnvironment. + /// + /// Defaults create a full parent environment. + /// + /// It is recommended that you apply the environment to a shell. But it can + /// also be set globally (be aware of the potential effect on other part of + /// your application) to [shellEnvironment] + factory ShellEnvironment({Map? environment}) { + return shellContext.newShellEnvironment(environment: environment); + } } diff --git a/lib/src/shell_utils.dart b/lib/src/shell_utils.dart index ad1e92a..e362c67 100644 --- a/lib/src/shell_utils.dart +++ b/lib/src/shell_utils.dart @@ -6,13 +6,22 @@ import 'package:process_run/shell.dart'; import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/io/shell_words.dart' as io show shellSplit; import 'package:process_run/src/shell_environment.dart'; -import 'package:process_run/src/user_config.dart'; import 'bin/shell/import.dart'; import 'env_utils.dart'; import 'shell_utils_common.dart'; -export 'shell_utils_common.dart'; +// Compat +export 'shell_utils_common.dart' + show + argumentToString, + argumentsToString, + shellArguments, + shellArgument, + streamSinkWrite, + streamSinkWriteln, + envPathKey, + envPathSeparator; /// True if the line is a comment. /// @@ -114,12 +123,6 @@ String expandPath(String path) { return path; } -/// Use to safely enclose an argument if needed -String shellArgument(String argument) => argumentToString(argument); - -/// Convert multiple arguments to string than can be used in a terminal -String shellArguments(List argument) => argumentsToString(argument); - /// Convert executable + arguments to a single script line String shellExecutableArguments(String executable, List arguments) => executableArgumentsToString(executable, arguments); diff --git a/lib/src/shell_utils_common.dart b/lib/src/shell_utils_common.dart index 86e45b1..824fe61 100644 --- a/lib/src/shell_utils_common.dart +++ b/lib/src/shell_utils_common.dart @@ -3,6 +3,8 @@ import 'dart:convert'; import 'package:process_run/src/platform/platform.dart'; +import 'characters.dart'; + const windowsDefaultPathExt = ['.exe', '.bat', '.cmd', '.com']; const String windowsEnvPathSeparator = ';'; @@ -25,3 +27,60 @@ void streamSinkWrite(StreamSink> sink, String message, encoding ??= shellContext.encoding; sink.add(encoding.encode(message)); } + +/// Helper to run a process and connect the input/output for verbosity +/// + +/// Helper to run a process and connect the input/output for verbosity +/// + +/// Use to safely enclose an argument if needed +/// +/// argument must not be null +String argumentToString(String argument) { + var hasWhitespace = false; + var singleQuoteCount = 0; + var doubleQuoteCount = 0; + if (argument.isEmpty) { + return '""'; + } + for (final rune in argument.runes) { + if ((!hasWhitespace) && (isWhitespace(rune))) { + hasWhitespace = true; + } else if (rune == 0x0027) { + // ' + singleQuoteCount++; + } else if (rune == 0x0022) { + // " + doubleQuoteCount++; + } + } + if (singleQuoteCount > 0) { + if (doubleQuoteCount > 0) { + // simply escape all double quotes + argument = '"${argument.replaceAll('"', '\\"')}"'; + } else { + argument = '"$argument"'; + } + } else if (doubleQuoteCount > 0) { + argument = "'$argument'"; + } else if (hasWhitespace) { + argument = '"$argument"'; + } + return argument; +} + +/// Convert multiple arguments to string than can be used in a terminal +String argumentsToString(List arguments) { + final argumentStrings = []; + for (final argument in arguments) { + argumentStrings.add(argumentToString(argument)); + } + return argumentStrings.join(' '); +} + +/// Use to safely enclose an argument if needed +String shellArgument(String argument) => argumentToString(argument); + +/// Convert multiple arguments to string than can be used in a terminal +String shellArguments(List argument) => argumentsToString(argument); From ff71065e31b730e0ce3a8bf3fc4d612bc5968896 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 28 Nov 2021 21:03:22 +0100 Subject: [PATCH 007/150] doc: throwOnError --- .github/workflows/run_ci.yml | 2 +- doc/shell.md | 21 ++++++++++++++++++++- test/shell_run_test.dart | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index 694387a..b19b637 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -18,7 +18,7 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] dart: [stable, beta, dev] steps: - - uses: dart-lang/setup-dart@v1 + - uses: dart-lang/setup-dart@v1.3 with: sdk: ${{ matrix.dart }} - uses: actions/checkout@v2 diff --git a/doc/shell.md b/doc/shell.md index f818368..5c0690d 100644 --- a/doc/shell.md +++ b/doc/shell.md @@ -57,6 +57,25 @@ dir shell = shell.popd(); ``` + +### Handling errors + +By default, `run` will throw an error if the `exitCode` is not 0. You can prevent that +with the option `throwOnError` which is true by default: + +```dart +void main(List arguments) async { + // Prevent error to be thrown if exitCode is not 0 + var shell = Shell(throwOnError: false); + // This won't throw + await shell.run('dir dummy_folder'); + + shell = Shell(); + // This throws an error! + await shell.run('dir dummy_folder'); +} +``` + ### Adding system path If somehow you cannot modify the system path, it will look for any path (last) defined in @@ -160,4 +179,4 @@ void main(List arguments) async { await shell.run('sudo lsof -i:22'); await shell.run('sudo lsof -i:80'); } -``` \ No newline at end of file +``` diff --git a/test/shell_run_test.dart b/test/shell_run_test.dart index a4d10df..7bc294f 100644 --- a/test/shell_run_test.dart +++ b/test/shell_run_test.dart @@ -7,6 +7,8 @@ import 'package:path/path.dart'; import 'package:process_run/shell_run.dart'; import 'package:test/test.dart'; +import 'process_run_test_common.dart'; + /// Truncate at max element. String stringTruncate(String text, int len) { if (text.length <= len) { @@ -69,5 +71,37 @@ void main() { $bin '''); }); + test('throwOnError', () async { + var verbose = false; // devWarning(true); + var env = ShellEnvironment() + ..aliases['echo'] = 'dart run ${shellArgument(echoScriptPath)}'; + + // Prevent error to be thrown if exitCode is not 0 + var shell = + Shell(throwOnError: false, verbose: verbose, environment: env); + // This won't throw + var exitCode = (await shell.run('echo --exit-code 1')).first.exitCode; + expect(exitCode, 1); + + try { + await shell.run('dummy_command_BfwXVcrONHT3QIiMzNoS'); + fail('should fail'); + } on ShellException catch (e) { + // ShellException(dummy_command_BfwXVcrONHT3QIiMzNoS, error: ProcessException: No such file or directory) + if (verbose) { + print(e); + } + } + try { + shell = Shell(environment: env, verbose: verbose); + await shell.run('echo --exit-code 1'); + fail('should fail'); + } on ShellException catch (e) { + // ShellException(dart run ./example/echo.dart --exit-code 1, exitCode 1) + if (verbose) { + print(e); + } + } + }); }); } From 4c14791c85ed4386e45c4b9c9d4cc19238b0b1e0 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 29 Nov 2021 00:58:07 +0100 Subject: [PATCH 008/150] test: comment windows failing test (until tested on windows) --- test/shell_run_test.dart | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/test/shell_run_test.dart b/test/shell_run_test.dart index 7bc294f..a7696e3 100644 --- a/test/shell_run_test.dart +++ b/test/shell_run_test.dart @@ -83,14 +83,18 @@ void main() { var exitCode = (await shell.run('echo --exit-code 1')).first.exitCode; expect(exitCode, 1); - try { - await shell.run('dummy_command_BfwXVcrONHT3QIiMzNoS'); - fail('should fail'); - } on ShellException catch (e) { - // ShellException(dummy_command_BfwXVcrONHT3QIiMzNoS, error: ProcessException: No such file or directory) - if (verbose) { - print(e); + if (!Platform.isWindows) { + try { + await shell.run('dummy_command_BfwXVcrONHT3QIiMzNoS'); + fail('should fail'); + } on ShellException catch (e) { + // ShellException(dummy_command_BfwXVcrONHT3QIiMzNoS, error: ProcessException: No such file or directory) + if (verbose) { + print(e); + } } + } else { + //TODO test on Windows } try { shell = Shell(environment: env, verbose: verbose); From 43b39c1ae0dcb2eb754dc580859905209ac8de98 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 17 Dec 2021 09:51:13 +0100 Subject: [PATCH 009/150] compat: make PubCmd use dart but now --- lib/src/dartbin_cmd.dart | 3 +-- test/pub_test.dart | 15 ++------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/lib/src/dartbin_cmd.dart b/lib/src/dartbin_cmd.dart index 613b3a1..d4846cf 100644 --- a/lib/src/dartbin_cmd.dart +++ b/lib/src/dartbin_cmd.dart @@ -73,8 +73,7 @@ class DartDevcCmd extends _DartBinCmd { /// pub class PubCmd extends _DartBinCmd { - PubCmd(List arguments) - : super(getShellCmdBinFileName('pub'), arguments); + PubCmd(List arguments) : super('dart', ['pub', ...arguments]); } @Deprecated('Not supported anymore') diff --git a/test/pub_test.dart b/test/pub_test.dart index 48de447..39035d0 100644 --- a/test/pub_test.dart +++ b/test/pub_test.dart @@ -5,8 +5,6 @@ import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/src/script_filename.dart'; import 'package:process_run/which.dart'; -// ignore: import_of_legacy_library_into_null_safe -import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; void main() => defineTests(); @@ -17,19 +15,10 @@ void defineTests() { var result = await runCmd(PubCmd(['--help'])); expect(result.exitCode, 0); // Every other commands write to stdout but dartanalyzer - expect(result.stdout, contains('Usage: pub')); - - // pub version - result = await runCmd(PubCmd(['--version'])); - - var version = - Version.parse((result.stdout as String).trim().split(' ').last); - // 2.0.0+ now! - expect(version, greaterThan(Version(1, 24, 3))); - expect(result.exitCode, 0); + expect(result.stdout, contains('Usage: dart pub')); }); - test('which', () { + // To remove once put is removed var whichPub = whichSync('pub'); // might not be in path during the test if (whichPub != null) { From c82b6c62fec9f74c5e94cc6b53b929b241074c6c Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 17 Dec 2021 09:58:24 +0100 Subject: [PATCH 010/150] compat: make PubCmd use dart but now --- lib/src/dartbin_cmd.dart | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/src/dartbin_cmd.dart b/lib/src/dartbin_cmd.dart index d4846cf..edcfc45 100644 --- a/lib/src/dartbin_cmd.dart +++ b/lib/src/dartbin_cmd.dart @@ -42,9 +42,8 @@ class DartCmd extends _DartBinCmd { /// dartfmt command @Deprecated('dartfmt is deprecated itself') -class DartFmtCmd extends _DartBinCmd { - DartFmtCmd(List arguments) - : super(getShellCmdBinFileName('dart'), ['format', ...arguments]); +class DartFmtCmd extends DartCmd { + DartFmtCmd(List arguments) : super(['format', ...arguments]); } /// dartanalyzer @@ -72,8 +71,8 @@ class DartDevcCmd extends _DartBinCmd { } /// pub -class PubCmd extends _DartBinCmd { - PubCmd(List arguments) : super('dart', ['pub', ...arguments]); +class PubCmd extends DartCmd { + PubCmd(List arguments) : super(['pub', ...arguments]); } @Deprecated('Not supported anymore') From f45823a6f862762df73b88e5c43dcabd13729cf4 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 17 Dec 2021 09:59:39 +0100 Subject: [PATCH 011/150] 0.12.3 --- CHANGELOG.md | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a57938..94f93c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.2+2 +## 0.12.3 * Cache shellEnvironment when set * dart 2.14 lints diff --git a/pubspec.yaml b/pubspec.yaml index 445dcc3..ad50251 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.12.2+2 +version: 0.12.3 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart From 3e11365450f2d34fbf98f0a97568dce931da3035 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 17 Dec 2021 10:17:58 +0100 Subject: [PATCH 012/150] 0.12.3+1 --- CHANGELOG.md | 2 +- pubspec.yaml | 2 +- test/dartbin_cmd_test.dart | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94f93c9..b9a5839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.3 +## 0.12.3+1 * Cache shellEnvironment when set * dart 2.14 lints diff --git a/pubspec.yaml b/pubspec.yaml index ad50251..b395d38 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.12.3 +version: 0.12.3+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart diff --git a/test/dartbin_cmd_test.dart b/test/dartbin_cmd_test.dart index 3e8c026..816249b 100644 --- a/test/dartbin_cmd_test.dart +++ b/test/dartbin_cmd_test.dart @@ -43,7 +43,7 @@ void main() { }); test('toString', () { - expect(PubCmd(['--help']).toString(), 'pub --help'); + expect(PubCmd(['--help']).toString(), 'dart pub --help'); expect(DartDocCmd(['--help']).toString(), 'dartdoc --help'); expect(Dart2JsCmd(['--help']).toString(), 'dart2js --help'); // expect(DartDevcCmd(['--help']).toString(), 'dartdevc --help'); From 33a04150605753ad12e0f71acc44dd542110e406 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 19 Jan 2022 11:21:20 +0100 Subject: [PATCH 013/150] feat: test finding executable on windows --- lib/src/process_run.dart | 6 ++++++ test/windows_test.dart | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 test/windows_test.dart diff --git a/lib/src/process_run.dart b/lib/src/process_run.dart index 58e0602..699232c 100644 --- a/lib/src/process_run.dart +++ b/lib/src/process_run.dart @@ -56,6 +56,12 @@ Future runExecutableArguments( // Try to find it in path or use it as is executable = utils.findExecutableSync(executable, shellEnvironment.paths) ?? executable; + } else { + // resolve locally + executable = utils.findExecutableSync(basename(executable), [ + join(workingDirectory ?? Directory.current.path, dirname(executable)) + ]) ?? + executable; } // Fix runInShell on windows (force run in shell for non-.exe) diff --git a/test/windows_test.dart b/test/windows_test.dart new file mode 100644 index 0000000..c1a59ac --- /dev/null +++ b/test/windows_test.dart @@ -0,0 +1,38 @@ +@TestOn('vm') +library process_run_test_windows_test; + +import 'dart:io'; + +import 'package:path/path.dart'; +import 'package:process_run/shell_run.dart'; +import 'package:test/test.dart'; + +void main() { + test('compile and run exe', () async { + var echoExePath = join('build', 'windows', 'echo.exe'); + var echoExeDir = dirname(echoExePath); + var echoExeName = basename(echoExePath); + var shell = Shell(verbose: false); + if (!File(echoExePath).existsSync()) { + Directory(echoExeDir).createSync(recursive: true); + await shell.run( + 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o ${shellArgument(echoExePath)}'); + } + // Try relative access + var exePathShell = Shell(workingDirectory: echoExeDir, verbose: false); + var lines = (await exePathShell + .run('${shellArgument(join('.', echoExeName))} --stdout test')) + .outLines; + expect(lines, ['test']); + + // Without using a relative path, this should fail + try { + await exePathShell.run('${shellArgument(echoExeName)} --stdout test'); + fail('should fail'); + } on ShellException catch (e) { + // print(e); + } + + expect(lines, ['test']); + }, skip: !Platform.isWindows, timeout: const Timeout(Duration(minutes: 10))); +} From 39de2a5c617fcb7d67f6c66eb0b2e5f188b2dcff Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 19 Jan 2022 11:50:06 +0100 Subject: [PATCH 014/150] test: use a more specific application name for echo --- test/windows_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/windows_test.dart b/test/windows_test.dart index c1a59ac..ac6d360 100644 --- a/test/windows_test.dart +++ b/test/windows_test.dart @@ -9,7 +9,7 @@ import 'package:test/test.dart'; void main() { test('compile and run exe', () async { - var echoExePath = join('build', 'windows', 'echo.exe'); + var echoExePath = join('build', 'windows', 'process_run_echo.exe'); var echoExeDir = dirname(echoExePath); var echoExeName = basename(echoExePath); var shell = Shell(verbose: false); From 9fe1bfa960fe322af009a4a3d0766b0e91d3861c Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 19 Jan 2022 12:21:24 +0100 Subject: [PATCH 015/150] test: linux compile --- test/{windows_test.dart => compile_test.dart} | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) rename test/{windows_test.dart => compile_test.dart} (78%) diff --git a/test/windows_test.dart b/test/compile_test.dart similarity index 78% rename from test/windows_test.dart rename to test/compile_test.dart index ac6d360..c4cdc5b 100644 --- a/test/windows_test.dart +++ b/test/compile_test.dart @@ -9,7 +9,9 @@ import 'package:test/test.dart'; void main() { test('compile and run exe', () async { - var echoExePath = join('build', 'windows', 'process_run_echo.exe'); + var folder = Platform.isWindows ? 'windows' : 'linux'; + var exeExtension = Platform.isWindows ? '.exe' : ''; + var echoExePath = join('build', folder, 'process_run_echo$exeExtension'); var echoExeDir = dirname(echoExePath); var echoExeName = basename(echoExePath); var shell = Shell(verbose: false); @@ -34,5 +36,7 @@ void main() { } expect(lines, ['test']); - }, skip: !Platform.isWindows, timeout: const Timeout(Duration(minutes: 10))); + }, + skip: !(Platform.isWindows || Platform.isLinux), + timeout: const Timeout(Duration(minutes: 10))); } From 07233cd038eae8c17cde4aae4098b1f2a2d0cf58 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 19 Jan 2022 12:23:14 +0100 Subject: [PATCH 016/150] 0.12.3+2 --- CHANGELOG.md | 3 ++- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9a5839..6fc1d11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ -## 0.12.3+1 +## 0.12.3+2 * Cache shellEnvironment when set * dart 2.14 lints +* Resolve relative executable according to working directory ## 0.12.1+1 diff --git a/pubspec.yaml b/pubspec.yaml index b395d38..4c367c3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.12.3+1 +version: 0.12.3+2 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart From 8fe43c88458b695ff7443ea21c9a6285d98d1fe9 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 20 Jan 2022 09:32:11 +0100 Subject: [PATCH 017/150] ci: test compile on MacOS --- test/compile_test.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/compile_test.dart b/test/compile_test.dart index c4cdc5b..50dea73 100644 --- a/test/compile_test.dart +++ b/test/compile_test.dart @@ -9,7 +9,8 @@ import 'package:test/test.dart'; void main() { test('compile and run exe', () async { - var folder = Platform.isWindows ? 'windows' : 'linux'; + var folder = + Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); var exeExtension = Platform.isWindows ? '.exe' : ''; var echoExePath = join('build', folder, 'process_run_echo$exeExtension'); var echoExeDir = dirname(echoExePath); @@ -31,12 +32,12 @@ void main() { try { await exePathShell.run('${shellArgument(echoExeName)} --stdout test'); fail('should fail'); - } on ShellException catch (e) { + } on ShellException catch (_) { // print(e); } expect(lines, ['test']); }, - skip: !(Platform.isWindows || Platform.isLinux), + skip: !(Platform.isWindows || Platform.isLinux || Platform.isMacOS), timeout: const Timeout(Duration(minutes: 10))); } From 74b456c453fe97ca15ed1138ec15f0d5c78367b8 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 23 Jan 2022 11:16:46 +0100 Subject: [PATCH 018/150] fix: lint --- test/compile_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compile_test.dart b/test/compile_test.dart index c4cdc5b..cb951a6 100644 --- a/test/compile_test.dart +++ b/test/compile_test.dart @@ -31,7 +31,7 @@ void main() { try { await exePathShell.run('${shellArgument(echoExeName)} --stdout test'); fail('should fail'); - } on ShellException catch (e) { + } on ShellException catch (_) { // print(e); } From 834c328a2aee7f5bcfe16b15250e3b1216adfdce Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 30 Jan 2022 10:16:31 +0100 Subject: [PATCH 019/150] feat: dart2js now deprecated --- lib/cmd_run.dart | 1 + lib/src/dartbin_cmd.dart | 1 + test/cmd_run_api_test.dart | 1 + test/dart2js_test.dart | 8 ++++- test/dart_compile_js_test.dart | 48 +++++++++++++++++++++++++++++ test/dartbin_cmd_test.dart | 2 ++ test/dartbin_cmd_verbose_test_.dart | 10 +++++- 7 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 test/dart_compile_js_test.dart diff --git a/lib/cmd_run.dart b/lib/cmd_run.dart index e0e91cd..1eeb82f 100644 --- a/lib/cmd_run.dart +++ b/lib/cmd_run.dart @@ -43,6 +43,7 @@ export 'process_run.dart' export 'src/build_runner.dart' show PbrCmd; export 'src/dartbin_cmd.dart' show + // ignore: deprecated_member_use_from_same_package Dart2JsCmd, DartCmd, DartDocCmd, diff --git a/lib/src/dartbin_cmd.dart b/lib/src/dartbin_cmd.dart index edcfc45..20b51da 100644 --- a/lib/src/dartbin_cmd.dart +++ b/lib/src/dartbin_cmd.dart @@ -53,6 +53,7 @@ class DartAnalyzerCmd extends _DartBinCmd { } /// dart2js +@Deprecated('Use dart compile js') class Dart2JsCmd extends _DartBinCmd { Dart2JsCmd(List arguments) : super(getShellCmdBinFileName('dart2js'), arguments); diff --git a/test/cmd_run_api_test.dart b/test/cmd_run_api_test.dart index 771c065..3b00527 100644 --- a/test/cmd_run_api_test.dart +++ b/test/cmd_run_api_test.dart @@ -34,6 +34,7 @@ void main() { argumentsToString; argumentToString; PbrCmd; + // ignore: deprecated_member_use_from_same_package Dart2JsCmd; DartCmd; DartDocCmd; diff --git a/test/dart2js_test.dart b/test/dart2js_test.dart index 66fd343..d4d88da 100644 --- a/test/dart2js_test.dart +++ b/test/dart2js_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: deprecated_member_use_from_same_package + @TestOn('vm') library process_run.dart2js_test; @@ -6,6 +8,7 @@ import 'dart:mirrors'; import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; String getScriptPath(Type type) => @@ -51,5 +54,8 @@ void defineTests() { expect(result.exitCode, 0); //}, skip: 'failed on SDK 1.19.0'); - fixed in 1.19.1 }); - }); + }, + skip: dartVersion >= Version(2, 17, 0, pre: '0') + ? 'Remove this test once dart stable hits 2.17' + : null); // Starts failing with dart 2.17, dart2js is deprecated } diff --git a/test/dart_compile_js_test.dart b/test/dart_compile_js_test.dart new file mode 100644 index 0000000..a60453d --- /dev/null +++ b/test/dart_compile_js_test.dart @@ -0,0 +1,48 @@ +@TestOn('vm') +library process_run.dart2js_test; + +import 'dart:io'; +import 'dart:mirrors'; + +import 'package:path/path.dart'; +import 'package:process_run/shell.dart'; +import 'package:test/test.dart'; + +String getScriptPath(Type type) => + (reflectClass(type).owner as LibraryMirror).uri.toFilePath(); + +class Script { + static String get path => getScriptPath(Script); +} + +String projectTop = dirname(dirname(Script.path)); +String testOut = join(projectTop, '.dart_tool', 'process_run_test'); + +void main() => defineTests(); + +void defineTests() { + group('dart compile js', () { + test('build', () async { + // from dart2js: exec '$DART' --packages='$BIN_DIR/snapshots/resources/dart2js/.packages' '$SNAPSHOT' '$@' + + var source = join(projectTop, 'test', 'data', 'main.dart'); + var destination = join(testOut, 'dart_compile_js', 'main.js'); + + // delete dir if any + try { + await Directory(dirname(destination)).delete(recursive: true); + } catch (_) {} + try { + // await Directory(dirname(destination)).create(recursive: true); + } catch (_) {} + + expect(File(destination).existsSync(), isFalse); + var shell = Shell(verbose: false); + final result = (await shell.run( + 'dart compile js -o ${shellArgument(destination)} ${shellArgument(source)}')) + .first; + expect(result.exitCode, 0); + expect(File(destination).existsSync(), isTrue); + }); + }); +} diff --git a/test/dartbin_cmd_test.dart b/test/dartbin_cmd_test.dart index 816249b..6820eda 100644 --- a/test/dartbin_cmd_test.dart +++ b/test/dartbin_cmd_test.dart @@ -35,6 +35,7 @@ void main() { expect(exitCode, 0); } expect((await runCmd(DartAnalyzerCmd(['--help']))).exitCode, 0); + // ignore: deprecated_member_use_from_same_package expect((await runCmd(Dart2JsCmd(['--help']))).exitCode, 0); expect((await runCmd(DartDocCmd(['--help']))).exitCode, 0); // expect((await runCmd(DartDevcCmd(['--help']))).exitCode, 0); @@ -45,6 +46,7 @@ void main() { test('toString', () { expect(PubCmd(['--help']).toString(), 'dart pub --help'); expect(DartDocCmd(['--help']).toString(), 'dartdoc --help'); + // ignore: deprecated_member_use_from_same_package expect(Dart2JsCmd(['--help']).toString(), 'dart2js --help'); // expect(DartDevcCmd(['--help']).toString(), 'dartdevc --help'); expect(DartAnalyzerCmd(['--help']).toString(), 'dartanalyzer --help'); diff --git a/test/dartbin_cmd_verbose_test_.dart b/test/dartbin_cmd_verbose_test_.dart index fd12a97..260c6fe 100644 --- a/test/dartbin_cmd_verbose_test_.dart +++ b/test/dartbin_cmd_verbose_test_.dart @@ -2,7 +2,9 @@ library process_run.dartbin_cmd_verbose_test; import 'package:process_run/cmd_run.dart' show runCmd; +import 'package:process_run/shell.dart'; import 'package:process_run/src/dartbin_cmd.dart'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; void main() { @@ -18,7 +20,13 @@ void main() { expect( (await runCmd(DartAnalyzerCmd(['--help']), verbose: true)).exitCode, 0); - expect((await runCmd(Dart2JsCmd(['--help']), verbose: true)).exitCode, 0); + // To remove once dart stable hits 2.17.0 + if (dartVersion < Version(2, 17, 0, pre: '0')) { + expect( + // ignore: deprecated_member_use_from_same_package + (await runCmd(Dart2JsCmd(['--help']), verbose: true)).exitCode, + 0); + } expect((await runCmd(DartDocCmd(['--help']), verbose: true)).exitCode, 0); expect((await runCmd(PubCmd(['--help']), verbose: true)).exitCode, 0); }); From d4f0d0bb3d9c40c109e67d3d7b346e14e86d0f81 Mon Sep 17 00:00:00 2001 From: alex Date: Sun, 6 Feb 2022 16:29:03 +0100 Subject: [PATCH 020/150] feat: deprecate dartdoc --- lib/cmd_run.dart | 2 +- lib/src/dartbin_cmd.dart | 3 ++- test/cmd_run_api_test.dart | 2 +- test/dart_doc_test.dart | 25 +++++++++++++++++++++++++ test/dartbin_cmd_test.dart | 4 ++-- test/dartbin_cmd_verbose_test_.dart | 6 +++++- test/dartdoc_test.dart | 5 ++++- test/shell_run_test.dart | 2 +- 8 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 test/dart_doc_test.dart diff --git a/lib/cmd_run.dart b/lib/cmd_run.dart index 1eeb82f..f48a2aa 100644 --- a/lib/cmd_run.dart +++ b/lib/cmd_run.dart @@ -46,7 +46,7 @@ export 'src/dartbin_cmd.dart' // ignore: deprecated_member_use_from_same_package Dart2JsCmd, DartCmd, - DartDocCmd, + DartDocCmd, // ignore: deprecated_member_use_from_same_package DartFmtCmd, // ignore: deprecated_member_use_from_same_package DartDevcCmd, DartAnalyzerCmd, diff --git a/lib/src/dartbin_cmd.dart b/lib/src/dartbin_cmd.dart index 20b51da..1b8511f 100644 --- a/lib/src/dartbin_cmd.dart +++ b/lib/src/dartbin_cmd.dart @@ -41,7 +41,7 @@ class DartCmd extends _DartBinCmd { } /// dartfmt command -@Deprecated('dartfmt is deprecated itself') +@Deprecated('dartfmt is deprecated itself, use dart format') class DartFmtCmd extends DartCmd { DartFmtCmd(List arguments) : super(['format', ...arguments]); } @@ -60,6 +60,7 @@ class Dart2JsCmd extends _DartBinCmd { } /// dartdoc +@Deprecated('dartfmt is deprecated itself, user dart doc') class DartDocCmd extends _DartBinCmd { DartDocCmd(List arguments) : super(getShellCmdBinFileName('dartdoc'), arguments); diff --git a/test/cmd_run_api_test.dart b/test/cmd_run_api_test.dart index 3b00527..a01ee37 100644 --- a/test/cmd_run_api_test.dart +++ b/test/cmd_run_api_test.dart @@ -37,7 +37,7 @@ void main() { // ignore: deprecated_member_use_from_same_package Dart2JsCmd; DartCmd; - DartDocCmd; + DartDocCmd; // ignore: deprecated_member_use_from_same_package DartFmtCmd; // ignore: deprecated_member_use_from_same_package DartDevcCmd; DartAnalyzerCmd; diff --git a/test/dart_doc_test.dart b/test/dart_doc_test.dart new file mode 100644 index 0000000..0b428ce --- /dev/null +++ b/test/dart_doc_test.dart @@ -0,0 +1,25 @@ +@TestOn('vm') +library process_run.dartdoc_test; + +import 'package:path/path.dart'; +import 'package:process_run/cmd_run.dart'; +import 'package:test/test.dart'; + +String testOut = join('.dart_tool', 'process_run', 'test'); + +void main() => defineTests(); + +void defineTests() { + group('dartdoc', () { + test('build', () async { + // from dartdoc: exec '$DART' --packages='$BIN_DIR/snapshots/resources/dartdoc/.packages' '$SNAPSHOT' '$@' + + final result = await runExecutableArguments( + 'dart', ['doc', '--output', join(testOut, 'dartdoc_build'), '.'], + verbose: true); + //expect(result.stdout, contains('dartdoc')); + expect(result.exitCode, 0); + //}, skip: 'failed on SDK 1.19.0'); - fixed in 1.19.1 + }, timeout: const Timeout(Duration(minutes: 2))); + }); +} diff --git a/test/dartbin_cmd_test.dart b/test/dartbin_cmd_test.dart index 6820eda..b6db503 100644 --- a/test/dartbin_cmd_test.dart +++ b/test/dartbin_cmd_test.dart @@ -37,7 +37,7 @@ void main() { expect((await runCmd(DartAnalyzerCmd(['--help']))).exitCode, 0); // ignore: deprecated_member_use_from_same_package expect((await runCmd(Dart2JsCmd(['--help']))).exitCode, 0); - expect((await runCmd(DartDocCmd(['--help']))).exitCode, 0); + //expect((await runCmd(DartDocCmd(['--help']))).exitCode, 0); // expect((await runCmd(DartDevcCmd(['--help']))).exitCode, 0); expect((await runCmd(PubCmd(['--help']))).exitCode, 0); //expect((await runCmd(DartDevkCmd(['--help']))).exitCode, 0); @@ -45,7 +45,7 @@ void main() { test('toString', () { expect(PubCmd(['--help']).toString(), 'dart pub --help'); - expect(DartDocCmd(['--help']).toString(), 'dartdoc --help'); + // expect(DartDocCmd(['--help']).toString(), 'dartdoc --help'); // ignore: deprecated_member_use_from_same_package expect(Dart2JsCmd(['--help']).toString(), 'dart2js --help'); // expect(DartDevcCmd(['--help']).toString(), 'dartdevc --help'); diff --git a/test/dartbin_cmd_verbose_test_.dart b/test/dartbin_cmd_verbose_test_.dart index 260c6fe..2ffa114 100644 --- a/test/dartbin_cmd_verbose_test_.dart +++ b/test/dartbin_cmd_verbose_test_.dart @@ -26,8 +26,12 @@ void main() { // ignore: deprecated_member_use_from_same_package (await runCmd(Dart2JsCmd(['--help']), verbose: true)).exitCode, 0); + expect( + // ignore: deprecated_member_use_from_same_package + (await runCmd(DartDocCmd(['--help']), verbose: true)).exitCode, + 0); } - expect((await runCmd(DartDocCmd(['--help']), verbose: true)).exitCode, 0); + expect((await runCmd(PubCmd(['--help']), verbose: true)).exitCode, 0); }); }); diff --git a/test/dartdoc_test.dart b/test/dartdoc_test.dart index 59b57b4..025d43d 100644 --- a/test/dartdoc_test.dart +++ b/test/dartdoc_test.dart @@ -22,11 +22,13 @@ void main() => defineTests(); void defineTests() { group('dartdoc', () { test('help', () async { + // ignore: deprecated_member_use_from_same_package final result = await runCmd(DartDocCmd(['--help'])); expect(result.stdout, contains('--version')); expect(result.exitCode, 0); }); test('version', () async { + // ignore: deprecated_member_use_from_same_package final result = await runCmd(DartDocCmd(['--version'])); expect(result.stdout, contains('dartdoc')); expect(result.exitCode, 0); @@ -35,10 +37,11 @@ void defineTests() { // from dartdoc: exec '$DART' --packages='$BIN_DIR/snapshots/resources/dartdoc/.packages' '$SNAPSHOT' '$@' final result = await runCmd( + // ignore: deprecated_member_use_from_same_package DartDocCmd(['--output', join(testOut, 'dartdoc_build')])); //expect(result.stdout, contains('dartdoc')); expect(result.exitCode, 0); //}, skip: 'failed on SDK 1.19.0'); - fixed in 1.19.1 }, timeout: const Timeout(Duration(minutes: 2))); - }); + }, skip: 'Deprecated'); } diff --git a/test/shell_run_test.dart b/test/shell_run_test.dart index a7696e3..2faec8a 100644 --- a/test/shell_run_test.dart +++ b/test/shell_run_test.dart @@ -47,7 +47,7 @@ void main() { test('--version', () async { for (var bin in [ - 'dartdoc', + // 'dartdoc', deprecated 'dart', 'pub', // 'dartfmt', deprecated From e9da293f3156c5b4a1888f1106f64484dde07fb7 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 11 Feb 2022 00:43:03 +0100 Subject: [PATCH 021/150] fix: handle --output and --output-dir for dart doc test --- test/dart_doc_test.dart | 24 ++++++++++++++++++------ test/shell_run_test.dart | 6 +++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/test/dart_doc_test.dart b/test/dart_doc_test.dart index 0b428ce..2196c81 100644 --- a/test/dart_doc_test.dart +++ b/test/dart_doc_test.dart @@ -10,15 +10,27 @@ String testOut = join('.dart_tool', 'process_run', 'test'); void main() => defineTests(); void defineTests() { - group('dartdoc', () { + group('dart_doc', () { test('build', () async { // from dartdoc: exec '$DART' --packages='$BIN_DIR/snapshots/resources/dartdoc/.packages' '$SNAPSHOT' '$@' - final result = await runExecutableArguments( - 'dart', ['doc', '--output', join(testOut, 'dartdoc_build'), '.'], - verbose: true); - //expect(result.stdout, contains('dartdoc')); - expect(result.exitCode, 0); + try { + // Try output-dir first + final result = await runExecutableArguments('dart', + ['doc', '--output-dir', join(testOut, 'dartdoc_build'), '.'], + verbose: true); + //expect(result.stdout, contains('dartdoc')); + expect(result.exitCode, 0); + } catch (e) { + // New for dev? + print('failed with --output-dir: $e'); + // Try output-dir first + final result = await runExecutableArguments( + 'dart', ['doc', '--output', join(testOut, 'dartdoc_build'), '.'], + verbose: true); + //expect(result.stdout, contains('dartdoc')); + expect(result.exitCode, 0); + } //}, skip: 'failed on SDK 1.19.0'); - fixed in 1.19.1 }, timeout: const Timeout(Duration(minutes: 2))); }); diff --git a/test/shell_run_test.dart b/test/shell_run_test.dart index 2faec8a..d318aca 100644 --- a/test/shell_run_test.dart +++ b/test/shell_run_test.dart @@ -49,10 +49,10 @@ void main() { for (var bin in [ // 'dartdoc', deprecated 'dart', - 'pub', + // 'pub', deprecated // 'dartfmt', deprecated - 'dart2js', - 'dartanalyzer', + // 'dart2js', deprecated + // 'dartanalyzer', deprecated ]) { stdout.writeln(''); var result = (await run('$bin --version', From 710ed0b0e92326be5025c0b3a7d2b583a32e089c Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sun, 13 Feb 2022 09:45:18 +0100 Subject: [PATCH 022/150] fix: pub no longer exists --- doc/shell.md | 2 +- example/info.dart | 1 - test/shell_test.dart | 22 ++++++++++++++-------- test/src_shell_utils_test.dart | 6 +++++- test/which_test.dart | 5 ++++- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/doc/shell.md b/doc/shell.md index 5c0690d..a8cf9a8 100644 --- a/doc/shell.md +++ b/doc/shell.md @@ -86,7 +86,7 @@ If somehow you cannot modify the system path, it will look for any path (last) d ### Command line $ pub global active process_run -$ alias ds='pub global run process_run:shell' +$ alias ds='dart pub global run process_run:shell' ### Helper diff --git a/example/info.dart b/example/info.dart index 4ccba59..d577f4f 100644 --- a/example/info.dart +++ b/example/info.dart @@ -8,6 +8,5 @@ Future main() async { print('flutterExecutablePath: $flutterExecutablePath'); print('which(\'dart\'): ${await which('dart')}'); print('which(\'flutter\'): ${await which('flutter')}'); - print('which(\'pub\'): ${await which('pub')}'); await run('dart --version'); } diff --git a/test/shell_test.dart b/test/shell_test.dart index 4cccbe5..17012f8 100644 --- a/test/shell_test.dart +++ b/test/shell_test.dart @@ -10,6 +10,7 @@ import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/dartbin_cmd.dart' show parseDartBinVersionOutput; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import 'hex_utils.dart'; @@ -382,13 +383,16 @@ dart current_dir.dart }); test('pub_no_path', () async { - print(userPaths); - var environment = Map.from(shellEnvironment) - ..remove('PATH'); - var shell = Shell(environment: environment, verbose: false); - var results = await shell.run('''pub --version'''); - expect(results.length, 1); - expect(results.first.exitCode, 0); + // No longer supported + if (dartVersion < Version(2, 17, 0, pre: '0')) { + print(userPaths); + var environment = Map.from(shellEnvironment) + ..remove('PATH'); + var shell = Shell(environment: environment, verbose: false); + var results = await shell.run('''pub --version'''); + expect(results.length, 1); + expect(results.first.exitCode, 0); + } }); test('escape backslash', () async { @@ -428,7 +432,9 @@ _tekartik_dummy_app_that_does_not_exits await _testCommand('dart --version'); // dart.exe on windows await _testCommand( '${shellArgument(dartExecutable!)} --version'); // dart.exe on windows - await _testCommand('pub --version'); // dart.exe on windows + if (dartVersion < Version(2, 17, 0, pre: '0')) { + await _testCommand('pub --version'); // dart.exe on windows + } // on windows, system command or alias in PowerShell await _testCommand('echo Hello world'); }); diff --git a/test/src_shell_utils_test.dart b/test/src_shell_utils_test.dart index 3263b8d..40801ec 100644 --- a/test/src_shell_utils_test.dart +++ b/test/src_shell_utils_test.dart @@ -6,6 +6,7 @@ import 'dart:convert'; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/shell_utils.dart'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; void main() { @@ -99,7 +100,10 @@ void main() { expect(findExecutableSync('pub', []), isNull); expect(findExecutableSync('dart', [dartSdkBinDirPath]), dartExecutable); - expect(findExecutableSync('pub', [dartSdkBinDirPath]), isNotNull); + if (dartVersion < Version(2, 17, 0, pre: '0')) { + // no longer supported + expect(findExecutableSync('pub', [dartSdkBinDirPath]), isNotNull); + } }); test('folder not executable', () { expect(findExecutableSync('test', ['.']), isNull); diff --git a/test/which_test.dart b/test/which_test.dart index 07018f7..2ceb913 100644 --- a/test/which_test.dart +++ b/test/which_test.dart @@ -6,6 +6,7 @@ import 'dart:io'; import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import 'dartbin_test.dart'; @@ -39,7 +40,9 @@ void main() { join(dirname(whichSync('flutter')), getBashOrBatExecutableFilename('dart')));*/ } - expect(whichSync('pub', environment: empty), isNotNull); + if (dartVersion < Version(2, 17, 0, pre: '0')) { + expect(whichSync('pub', environment: empty), isNotNull); + } expect(whichSync('current_dir', environment: empty), isNull); expect( From 5e017039bb6ac59ea0488547c7b5a5b22b27872a Mon Sep 17 00:00:00 2001 From: jgtoriginal Date: Wed, 15 Jun 2022 17:29:11 +0100 Subject: [PATCH 023/150] ruinning sudo on mac --- doc/shell.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/doc/shell.md b/doc/shell.md index a8cf9a8..25e695f 100644 --- a/doc/shell.md +++ b/doc/shell.md @@ -180,3 +180,19 @@ void main(List arguments) async { await shell.run('sudo lsof -i:80'); } ``` + +### Running sudo (MacOS) + +Turn off Sandboxing by removing it from the Signing & Capabilities tab: + + + +Then run your commands via `osascript` like so: + +``` + await shell.run(''' + osascript -e 'do shell script "[YOUR_SHELL_COMMAND_GOES_HERE]" with administrator privileges' + ''') +``` + +That will prompt for the user to type his password and then will run the script. From 83fa30c60717ab6e963f3b3f7155cd1735500f61 Mon Sep 17 00:00:00 2001 From: jgtoriginal Date: Wed, 15 Jun 2022 17:31:56 +0100 Subject: [PATCH 024/150] adding image guide --- doc/shell.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/shell.md b/doc/shell.md index 25e695f..22d9e6a 100644 --- a/doc/shell.md +++ b/doc/shell.md @@ -185,7 +185,7 @@ void main(List arguments) async { Turn off Sandboxing by removing it from the Signing & Capabilities tab: - +![alt text](https://i.stack.imgur.com/iTRFC.png) Then run your commands via `osascript` like so: From 591087316a2bd717531ee9494d3f338836331c28 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 29 Jun 2022 13:30:10 +0200 Subject: [PATCH 025/150] wip --- example/shell/shell_common.dart | 2 +- lib/src/io/io_import.dart | 1 + lib/src/platform/platform_io.dart | 4 + lib/src/platform/platform_stub.dart | 7 + lib/src/shell.dart | 154 +++++++++-------- lib/src/shell_common.dart | 115 +++++-------- lib/src/shell_common_io.dart | 51 +----- lib/src/shell_context_common.dart | 5 +- lib/src/shell_context_io.dart | 9 +- lib/src/shell_environment_common.dart | 12 +- lib/src/shell_io.dart | 1 + test/dart2js_test.dart | 61 ------- test/dartbin_cmd_test.dart | 3 - test/shell_common_test.dart | 228 ++++++++++++++++++++++++++ test/src/shell_impl_test.dart | 2 +- 15 files changed, 374 insertions(+), 281 deletions(-) create mode 100644 lib/src/io/io_import.dart create mode 100644 lib/src/shell_io.dart delete mode 100644 test/dart2js_test.dart create mode 100644 test/shell_common_test.dart diff --git a/example/shell/shell_common.dart b/example/shell/shell_common.dart index 81eda9d..344b854 100644 --- a/example/shell/shell_common.dart +++ b/example/shell/shell_common.dart @@ -1,4 +1,4 @@ -import 'package:process_run/src/shell_common.dart'; +import 'package:process_run/shell.dart'; Future main() async { var shell = Shell(); diff --git a/lib/src/io/io_import.dart b/lib/src/io/io_import.dart new file mode 100644 index 0000000..be872dc --- /dev/null +++ b/lib/src/io/io_import.dart @@ -0,0 +1 @@ +export 'dart:io' show ProcessResult, Process, ProcessSignal; diff --git a/lib/src/platform/platform_io.dart b/lib/src/platform/platform_io.dart index a5730f2..f91ce93 100644 --- a/lib/src/platform/platform_io.dart +++ b/lib/src/platform/platform_io.dart @@ -7,3 +7,7 @@ bool get platformIoIsWindows => Platform.isWindows; /// Global shell context ShellContext shellContext = ShellContextIo(); + +void clearShellContext() { + throw StateError('clearShellContext Not supported'); +} diff --git a/lib/src/platform/platform_stub.dart b/lib/src/platform/platform_stub.dart index 1b5b1ad..c85a683 100644 --- a/lib/src/platform/platform_stub.dart +++ b/lib/src/platform/platform_stub.dart @@ -1,3 +1,4 @@ +import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/shell_context_common.dart'; /// Only true for IO windows @@ -15,3 +16,9 @@ ShellContext get shellContext { /// Set shell context before use set shellContext(ShellContext shellContext) => _shellContext = shellContext; + +/// Internal use only. +@visibleForTesting +void clearShellContext() { + _shellContext = null; +} diff --git a/lib/src/shell.dart b/lib/src/shell.dart index 4fb9546..4df834b 100644 --- a/lib/src/shell.dart +++ b/lib/src/shell.dart @@ -1,18 +1,17 @@ import 'dart:convert'; -import 'dart:io'; import 'dart:io' as io; import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; +import 'package:process_run/src/bin/shell/import.dart'; +import 'package:process_run/src/platform/platform.dart'; import 'package:process_run/src/process_run.dart'; import 'package:process_run/src/shell_common.dart' show ShellOptions, shellDebug; import 'package:process_run/src/shell_utils.dart'; import 'package:synchronized/synchronized.dart'; -import 'common/import.dart'; - export 'shell_common.dart' show shellDebug; /// @@ -92,18 +91,7 @@ Future> run( /// A list of ProcessResult is returned /// class Shell { - final bool _throwOnError; - final String? _workingDirectory; - ShellEnvironment? _environment; - final bool? _runInShell; - final Encoding _stdoutEncoding; - final Encoding _stderrEncoding; - final Stream>? _stdin; - final StreamSink>? _stdout; - final StreamSink>? _stderr; - final bool _verbose; - final bool _commandVerbose; - final bool _commentVerbose; + final ShellOptions _options; /// Incremental internal runId var _runId = 0; @@ -128,7 +116,7 @@ class Shell { /// Resolve environment List get _userPaths => - _userPathsCache ??= List.from(_environment!.paths); + _userPathsCache ??= List.from(_options.environment.paths); /// [throwOnError] means that if an exit code is not 0, it will throw an error /// @@ -137,39 +125,42 @@ class Shell { /// /// if [verbose] is not false or [commentVerbose] is true, it will display the /// comments as well - Shell( - {bool throwOnError = true, - String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool? runInShell, - Encoding stdoutEncoding = systemEncoding, - Encoding stderrEncoding = systemEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool verbose = true, - // Default to true - bool? commandVerbose, - // Default to false - bool? commentVerbose, - ShellOptions? options}) - : _throwOnError = throwOnError, - _workingDirectory = workingDirectory, - _runInShell = runInShell, - _stdoutEncoding = stdoutEncoding, - _stderrEncoding = stderrEncoding, - _stdin = stdin, - _stdout = stdout, - _stderr = stderr, - _verbose = verbose, - _commandVerbose = commandVerbose ?? verbose, - _commentVerbose = commentVerbose ?? false { - // Fix environment right away - _environment = ShellEnvironment.full( - environment: environment, - includeParentEnvironment: includeParentEnvironment); - } + factory Shell( + {bool throwOnError = true, + String? workingDirectory, + Map? environment, + bool includeParentEnvironment = true, + bool? runInShell, + Encoding stdoutEncoding = systemEncoding, + Encoding stderrEncoding = systemEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool verbose = true, + // Default to true + bool? commandVerbose, + // Default to false + bool? commentVerbose, + ShellOptions? options}) => + shellContext.newShell( + options: options ?? + ShellOptions( + verbose: verbose, + stdin: stdin, + stdout: stdout, + stderr: stderr, + throwOnError: throwOnError, + workingDirectory: workingDirectory, + runInShell: runInShell, + commandVerbose: commandVerbose ?? verbose, + environment: environment, + commentVerbose: commentVerbose ?? false, + stderrEncoding: stderrEncoding, + stdoutEncoding: stdoutEncoding)); + + /// Internal use only. + @protected + Shell.implWithOptions(ShellOptions options) : _options = options; /// Create a new shell Shell clone( @@ -191,33 +182,34 @@ class Shell { bool? commandVerbose, bool? commentVerbose}) { return Shell( - verbose: verbose ?? _verbose, - environment: _environment, - runInShell: runInShell ?? _runInShell, - commandVerbose: commandVerbose ?? _commandVerbose, - commentVerbose: commentVerbose ?? _commentVerbose, - includeParentEnvironment: false, - stderr: stderr ?? _stderr, - stderrEncoding: stderrEncoding ?? _stderrEncoding, - stdin: stdin ?? _stdin, - stdout: stdout ?? _stdout, - stdoutEncoding: stdoutEncoding ?? _stdoutEncoding, - throwOnError: throwOnError ?? _throwOnError, - workingDirectory: workingDirectory ?? _workingDirectory); + options: _options.clone( + throwOnError: throwOnError, + workingDirectory: workingDirectory, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdin: stdin, + stderr: stderr, + stdout: stdout, + commentVerbose: commentVerbose, + commandVerbose: commandVerbose, + verbose: verbose, + shellEnvironment: + environment is ShellEnvironment ? environment : null)); } /// non null String get _workingDirectoryPath => - _workingDirectory ?? Directory.current.path; + _options.workingDirectory ?? Directory.current.path; /// Create new shell at the given path Shell cd(String path) { if (isRelative(path)) { path = join(_workingDirectoryPath, path); } - if (_commandVerbose) { - streamSinkWriteln(_stdout ?? stdout, '\$ cd $path', - encoding: _stdoutEncoding); + if (_options.commandVerbose) { + streamSinkWriteln(_options.stdout ?? stdout, '\$ cd $path', + encoding: _options.stdoutEncoding); } return clone(workingDirectory: path); } @@ -234,7 +226,7 @@ class Shell { if (_parentShell == null) { throw StateError('no previous shell'); } - if (_commandVerbose) { + if (_options.commandVerbose) { stdout.writeln('\$ cd ${_parentShell!._workingDirectoryPath}'); } return _parentShell!; @@ -292,7 +284,7 @@ class Shell { } // Display the comments if (isLineComment(command!)) { - if (_commentVerbose) { + if (_options.commentVerbose) { stdout.writeln(command); } continue; @@ -302,7 +294,7 @@ class Shell { var arguments = parts.sublist(1); // Find alias - var alias = _environment!.aliases[executable]; + var alias = _options.environment.aliases[executable]; if (alias != null) { // The alias itself should be split parts = shellSplit(alias); @@ -383,23 +375,23 @@ class Shell { var processCmd = _ProcessCmd(executableFullPath, arguments, executableShortName: executable) - ..runInShell = _runInShell - ..environment = _environment + ..runInShell = _options.runInShell + ..environment = _options.environment ..includeParentEnvironment = false - ..stderrEncoding = _stderrEncoding - ..stdoutEncoding = _stdoutEncoding - ..workingDirectory = _workingDirectory; + ..stderrEncoding = _options.stderrEncoding! + ..stdoutEncoding = _options.stdoutEncoding! + ..workingDirectory = _options.workingDirectory; try { if (shellDebug) { print('$_runId: Before $processCmd'); } try { processResult = await processCmdRun(processCmd, - verbose: _verbose, - commandVerbose: _commandVerbose, - stderr: _stderr, - stdin: _stdin, - stdout: _stdout, onProcess: (process) { + verbose: _options.verbose, + commandVerbose: _options.commandVerbose, + stderr: _options.stderr, + stdin: _options.stdin, + stdout: _options.stdout, onProcess: (process) { _currentProcess = process; _currentProcessCmd = processCmd; _currentProcessRunId = runId; @@ -424,13 +416,13 @@ class Shell { } } // devPrint('After $processCmd'); - if (_throwOnError && processResult.exitCode != 0) { + if (_options.throwOnError && processResult.exitCode != 0) { throw ShellException( '$processCmd, exitCode ${processResult.exitCode}, workingDirectory: $_workingDirectoryPath', processResult); } } on ProcessException catch (e) { - var stderr = _stderr ?? io.stderr; + var stderr = _options.stderr ?? io.stderr; void _writeln([String? msg]) { stderr.add(utf8.encode(msg ?? '')); stderr.add(utf8.encode('\n')); diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index cc9988c..1641823 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -1,79 +1,17 @@ import 'dart:async'; import 'dart:convert'; +import 'package:process_run/shell.dart'; import 'package:process_run/src/platform/platform.dart'; -import 'shell_environment_common.dart'; +import 'io/io_import.dart' show ProcessResult, Process, ProcessSignal; -var shellDebug = false; // devWarning(true); // false - -/// The result of running a non-interactive -/// process started with [Process.run] or [Process.runSync]. -class ProcessResult { - /// Exit code for the process. - /// - /// See [Process.exitCode] for more information in the exit code - /// value. - final int exitCode; - - /// Standard output from the process. The value used for the - /// `stdoutEncoding` argument to `Process.run` determines the type. If - /// `null` was used, this value is of type `List` otherwise it is - /// of type `String`. - final Object? stdout; - - /// Standard error from the process. The value used for the - /// `stderrEncoding` argument to `Process.run` determines the type. If - /// `null` was used, this value is of type `List` - /// otherwise it is of type `String`. - final Object? stderr; - - /// Process id of the process. - final int pid; - - ProcessResult(this.pid, this.exitCode, this.stdout, this.stderr); -} - -abstract class Process { - /// A `Future` which completes with the exit code of the process - /// when the process completes. - /// - /// The handling of exit codes is platform specific. - /// - /// On Linux and OS X a normal exit code will be a positive value in - /// the range `[0..255]`. If the process was terminated due to a signal - /// the exit code will be a negative value in the range `[-255..-1]`, - /// where the absolute value of the exit code is the signal - /// number. For example, if a process crashes due to a segmentation - /// violation the exit code will be -11, as the signal SIGSEGV has the - /// number 11. - /// - /// On Windows a process can report any 32-bit value as an exit - /// code. When returning the exit code this exit code is turned into - /// a signed value. Some special values are used to report - /// termination due to some system event. E.g. if a process crashes - /// due to an access violation the 32-bit exit code is `0xc0000005`, - /// which will be returned as the negative number `-1073741819`. To - /// get the original 32-bit value use `(0x100000000 + exitCode) & - /// 0xffffffff`. - /// - /// There is no guarantee that [stdout] and [stderr] have finished reporting - /// the buffered output of the process when the returned future completes. - /// To be sure that all output is captured, - /// wait for the done event on the streams. - Future get exitCode; +export 'package:process_run/shell.dart' + show Shell, ShellException, ShellEnvironment; - /// The standard output stream of the process as a `Stream`. - Stream> get stdout; +export 'io/io_import.dart' show ProcessResult, Process, ProcessSignal; - /// The standard error stream of the process as a `Stream`. - Stream> get stderr; -} - -class ProcessSignal { - const ProcessSignal(); - static const sigterm = ProcessSignal(); -} +var shellDebug = false; // devWarning(true); // false /// Multiplatform Shell utility to run a script with multiple commands. /// @@ -96,8 +34,9 @@ class ProcessSignal { /// /// A list of ProcessResult is returned /// -abstract class Shell { - factory Shell( +abstract class ShellCore { + /* + ShellCore( {ShellOptions? options, Map? environment, @@ -116,7 +55,7 @@ abstract class Shell { runInShell: runInShell, stdout: stdout, stderr: stderr), - environment: environment); + environment: environment);*/ /// Kills the current running process. /// @@ -163,6 +102,7 @@ abstract class Shell { Shell popd(); } +/* /// Exception thrown in exitCode != 0 and throwOnError is true class ShellException implements Exception { final ProcessResult? result; @@ -173,6 +113,7 @@ class ShellException implements Exception { @override String toString() => 'ShellException($message)'; } +*/ class ShellOptions { final bool _throwOnError; @@ -188,6 +129,16 @@ class ShellOptions { final bool _commandVerbose; final bool _commentVerbose; + late final ShellEnvironment? _environment; + + String? get workingDirectory => _workingDirectory; + ShellEnvironment get environment => _environment!; + StreamSink>? get stdout => _stdout; + StreamSink>? get stderr => _stderr; + Stream>? get stdin => _stdin; + Encoding? get stdoutEncoding => _stdoutEncoding; + Encoding? get stderrEncoding => _stderrEncoding; + /// [throwOnError] means that if an exit code is not 0, it will throw an error /// /// Unless specified [runInShell] will be false. However on windows, it will @@ -195,10 +146,11 @@ class ShellOptions { /// /// if [verbose] is not false or [commentVerbose] is true, it will display the /// comments as well - const ShellOptions( + ShellOptions( {bool throwOnError = true, String? workingDirectory, Map? environment, + bool includeParentEnvironment = true, bool? runInShell, Encoding? stdoutEncoding, Encoding? stderrEncoding, @@ -220,7 +172,21 @@ class ShellOptions { _stderr = stderr, _verbose = verbose, _commandVerbose = commandVerbose ?? verbose, - _commentVerbose = commentVerbose ?? false; + _commentVerbose = commentVerbose ?? false { + _environment = ShellEnvironment.full( + environment: environment, + includeParentEnvironment: includeParentEnvironment); + } + + bool get commandVerbose => _commandVerbose; + + bool get commentVerbose => _commentVerbose; + + bool? get runInShell => _runInShell; + + bool? get verbose => _verbose; + + bool get throwOnError => _throwOnError; /// Create a new shell ShellOptions clone( @@ -234,7 +200,8 @@ class ShellOptions { StreamSink>? stderr, bool? verbose, bool? commandVerbose, - bool? commentVerbose}) { + bool? commentVerbose, + ShellEnvironment? shellEnvironment}) { return ShellOptions( verbose: verbose ?? _verbose, runInShell: runInShell ?? _runInShell, diff --git a/lib/src/shell_common_io.dart b/lib/src/shell_common_io.dart index 2630ae3..3e985f1 100644 --- a/lib/src/shell_common_io.dart +++ b/lib/src/shell_common_io.dart @@ -1,4 +1,3 @@ -import 'dart:async'; import 'dart:io' as io; import 'package:process_run/shell.dart' as io; @@ -26,6 +25,7 @@ class ProcessResultIo implements ProcessResult { String toString() => 'exitCode $exitCode, pid $pid'; } +/* Future _wrapIoException(Future Function() action) async { try { return await action(); @@ -33,53 +33,12 @@ Future _wrapIoException(Future Function() action) async { throw ShellExceptionIo(e); } } + */ -class ShellIo implements Shell { - late final io.Shell impl; - +class ShellIo extends Shell { ShellIo({ - required this.impl, - }); - - Shell _wrapIoShell(io.Shell ioShell) => ShellIo(impl: ioShell); - - @override - Shell cd(String path) => _wrapIoShell(impl.cd(path)); - - @override - bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { - var ioProcessSignal = io.ProcessSignal.sigterm; - return impl.kill(ioProcessSignal); - } - - @override - String get path => impl.path; - - @override - Shell popd() => _wrapIoShell(impl.popd()); - - @override - Shell pushd(String path) => _wrapIoShell(impl.pushd(path)); - - @override - Future> run(String script, - {void Function(Process process)? onProcess}) => - _wrapIoException(() async { - var ioResult = await impl.run(script, - onProcess: onProcess == null ? null : (io.Process process) {}); - return ioResult - .map((ioProcessResult) => ProcessResultIo(ioProcessResult)) - .toList(); - }); - - @override - Future runExecutableArguments( - String executable, List arguments, - {void Function(Process process)? onProcess}) => - _wrapIoException(() async { - return ProcessResultIo( - await impl.runExecutableArguments(executable, arguments)); - }); + required ShellOptions options, + }) : super.implWithOptions(options); } class ShellExceptionIo implements ShellException { diff --git a/lib/src/shell_context_common.dart b/lib/src/shell_context_common.dart index 2100b04..42369a3 100644 --- a/lib/src/shell_context_common.dart +++ b/lib/src/shell_context_common.dart @@ -2,7 +2,6 @@ import 'dart:convert'; import 'package:path/path.dart' as p; import 'package:process_run/src/shell_common.dart'; -import 'package:process_run/src/shell_environment_common.dart'; /// abstract shell context abstract class ShellContext { @@ -21,8 +20,8 @@ abstract class ShellContext { Shell newShell( {ShellOptions? options, - Map? environment, - bool includeParentEnvironment = true}); + @Deprecated('Use options') Map? environment, + @Deprecated('Use options') bool includeParentEnvironment = true}); ShellEnvironment newShellEnvironment({ Map? environment, diff --git a/lib/src/shell_context_io.dart b/lib/src/shell_context_io.dart index 63a0e80..7e4c347 100644 --- a/lib/src/shell_context_io.dart +++ b/lib/src/shell_context_io.dart @@ -3,12 +3,10 @@ import 'dart:io'; import 'package:path/path.dart' as p; import 'package:process_run/shell.dart' as ds; -import 'package:process_run/src/shell.dart' as io; import 'package:process_run/src/shell_common.dart'; import 'package:process_run/src/shell_common_io.dart'; import 'package:process_run/src/shell_context_common.dart'; import 'package:process_run/src/shell_environment.dart' as io; -import 'package:process_run/src/shell_environment_common.dart'; class ShellContextIo implements ShellContext { @override @@ -39,10 +37,7 @@ class ShellContextIo implements ShellContext { {ShellOptions? options, Map? environment, bool includeParentEnvironment = true}) { - var ioShell = io.Shell( - options: options, - environment: environment, - includeParentEnvironment: includeParentEnvironment); - return ShellIo(impl: ioShell); + var ioShell = ShellIo(options: options ?? ShellOptions()); + return ioShell; } } diff --git a/lib/src/shell_environment_common.dart b/lib/src/shell_environment_common.dart index 742d7a4..855de45 100644 --- a/lib/src/shell_environment_common.dart +++ b/lib/src/shell_environment_common.dart @@ -1,15 +1,17 @@ import 'dart:collection'; import 'package:collection/collection.dart'; +import 'package:process_run/shell.dart'; import 'package:process_run/src/platform/platform.dart'; import 'package:process_run/src/shell_utils_common.dart'; //import 'package:process_run/shell.dart'; //import 'package:process_run/src/common/import.dart'; //import 'package:process_run/src/shell_utils.dart'; +export 'package:process_run/shell.dart' show ShellEnvironment; /// Shell environment ordered paths helper. Changes the PATH variable class ShellEnvironmentPaths with ListMixin { - final ShellEnvironment _environment; + final ShellEnvironmentCore _environment; ShellEnvironmentPaths._(this._environment); @@ -144,7 +146,7 @@ class ShellEnvironmentAliases with MapMixin { /// Shell environment variables helper. Does not affect the PATH variable class ShellEnvironmentVars with MapMixin { - final ShellEnvironment _environment; + final ShellEnvironmentCore _environment; ShellEnvironmentVars._(this._environment); @@ -207,7 +209,7 @@ class ShellEnvironmentVars with MapMixin { /// Shell modifiable helpers. should not be modified after being set. abstract class ShellEnvironmentBase with MapMixin - implements ShellEnvironment { + implements ShellEnvironmentCore { /// The resulting _env final _env = {}; @@ -345,7 +347,7 @@ abstract class ShellEnvironmentBase ShellEnvironment get shellEnvironment => shellContext.shellEnvironment; /// Shell modifiable helpers. should not be modified after being set. -abstract class ShellEnvironment with MapMixin { +abstract class ShellEnvironmentCore with MapMixin { /// The vars but the PATH variable ShellEnvironmentVars get vars; @@ -363,6 +365,7 @@ abstract class ShellEnvironment with MapMixin { /// `paths` and `vars` key Map toJson(); + /* /// Create a new shell environment from the current shellEnvironment. /// /// Defaults create a full parent environment. @@ -373,4 +376,5 @@ abstract class ShellEnvironment with MapMixin { factory ShellEnvironment({Map? environment}) { return shellContext.newShellEnvironment(environment: environment); } + */ } diff --git a/lib/src/shell_io.dart b/lib/src/shell_io.dart new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/src/shell_io.dart @@ -0,0 +1 @@ + diff --git a/test/dart2js_test.dart b/test/dart2js_test.dart deleted file mode 100644 index d4d88da..0000000 --- a/test/dart2js_test.dart +++ /dev/null @@ -1,61 +0,0 @@ -// ignore_for_file: deprecated_member_use_from_same_package - -@TestOn('vm') -library process_run.dart2js_test; - -import 'dart:io'; -import 'dart:mirrors'; - -import 'package:path/path.dart'; -import 'package:process_run/cmd_run.dart'; -import 'package:pub_semver/pub_semver.dart'; -import 'package:test/test.dart'; - -String getScriptPath(Type type) => - (reflectClass(type).owner as LibraryMirror).uri.toFilePath(); - -class Script { - static String get path => getScriptPath(Script); -} - -String projectTop = dirname(dirname(Script.path)); -String testOut = join(projectTop, 'test_out'); - -void main() => defineTests(); - -void defineTests() { - group('dart2js', () { - test('help', () async { - final result = await runCmd(Dart2JsCmd(['--help'])); - expect(result.stdout, contains('Usage: dart2js')); - expect(result.exitCode, 0); - }); - test('version', () async { - final result = await runCmd(Dart2JsCmd(['--version'])); - expect(result.stdout, contains('dart2js')); - expect(result.exitCode, 0); - }); - test('build', () async { - // from dart2js: exec '$DART' --packages='$BIN_DIR/snapshots/resources/dart2js/.packages' '$SNAPSHOT' '$@' - - var destination = join(testOut, 'dart2js_build', 'main.js'); - - // delete dir if any - try { - await Directory(dirname(destination)).create(recursive: true); - } catch (_) {} - - final result = await runCmd( - Dart2JsCmd( - ['-o', destination, join(projectTop, 'test', 'data', 'main.dart')]), - //verbose: true - ); - //expect(result.stdout, contains('dart2js')); - expect(result.exitCode, 0); - //}, skip: 'failed on SDK 1.19.0'); - fixed in 1.19.1 - }); - }, - skip: dartVersion >= Version(2, 17, 0, pre: '0') - ? 'Remove this test once dart stable hits 2.17' - : null); // Starts failing with dart 2.17, dart2js is deprecated -} diff --git a/test/dartbin_cmd_test.dart b/test/dartbin_cmd_test.dart index b6db503..f373f9e 100644 --- a/test/dartbin_cmd_test.dart +++ b/test/dartbin_cmd_test.dart @@ -35,9 +35,6 @@ void main() { expect(exitCode, 0); } expect((await runCmd(DartAnalyzerCmd(['--help']))).exitCode, 0); - // ignore: deprecated_member_use_from_same_package - expect((await runCmd(Dart2JsCmd(['--help']))).exitCode, 0); - //expect((await runCmd(DartDocCmd(['--help']))).exitCode, 0); // expect((await runCmd(DartDevcCmd(['--help']))).exitCode, 0); expect((await runCmd(PubCmd(['--help']))).exitCode, 0); //expect((await runCmd(DartDevkCmd(['--help']))).exitCode, 0); diff --git a/test/shell_common_test.dart b/test/shell_common_test.dart new file mode 100644 index 0000000..bdb8b87 --- /dev/null +++ b/test/shell_common_test.dart @@ -0,0 +1,228 @@ +library process_run.test.shell_common_api_test; + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:path/src/context.dart'; +import 'package:process_run/shell.dart'; +import 'package:process_run/src/env_utils.dart'; +import 'package:process_run/src/platform/platform.dart'; +import 'package:process_run/src/shell_common.dart'; +import 'package:process_run/src/shell_context_common.dart'; +import 'package:process_run/src/shell_environment_common.dart'; +import 'package:test/test.dart'; + +class ShellContextMock implements ShellContext { + @override + // TODO: implement encoding + Encoding get encoding => throw UnimplementedError(); + + @override + Shell newShell( + {ShellOptions? options, + Map? environment, + bool includeParentEnvironment = true}) { + // TODO: implement newShell + return ShellMock(); + } + + @override + ShellEnvironment newShellEnvironment({Map? environment}) { + // TODO: implement newShellEnvironment + throw UnimplementedError(); + } + + @override + // TODO: implement path + Context get path => throw UnimplementedError(); + + @override + final ShellEnvironment shellEnvironment = ShellEnvironmentMock(); + + @override + Future which(String command, + {ShellEnvironment? environment, bool includeParentEnvironment = true}) { + // TODO: implement which + throw UnimplementedError(); + } +} + +class ShellEnvironmentMock extends ShellEnvironmentBase + implements ShellEnvironment { + ShellEnvironmentMock() : super.empty(); + + @override + Future which(String command) async { + // TODO: implement which + throw UnimplementedError(); + } + + @override + String? whichSync(String command) { + throw UnimplementedError(); + } +} + +class ProcessMock implements Process { + final ProcessResult result; + final List outLines; + + ProcessMock(this.result, this.outLines); + + @override + // TODO: implement exitCode + Future get exitCode => throw UnimplementedError(); + + @override + bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { + // TODO: implement kill + // throw UnimplementedError(); + return true; + } + + @override + // TODO: implement pid + int get pid => throw UnimplementedError(); + + @override + // TODO: implement stderr + Stream> get stderr => throw UnimplementedError(); + + @override + // TODO: implement stdin + IOSink get stdin => throw UnimplementedError(); + + @override + // TODO: implement stdout + Stream> get stdout => throw UnimplementedError(); +} + +class ShellMock implements Shell { + var scripts = []; + + @override + Shell cd(String path) { + // TODO: implement cd + throw UnimplementedError(); + } + + @override + bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { + // TODO: implement kill + throw UnimplementedError(); + } + + @override + // TODO: implement path + String get path => throw UnimplementedError(); + + @override + Shell popd() { + // TODO: implement popd + throw UnimplementedError(); + } + + @override + Shell pushd(String path) { + // TODO: implement pushd + throw UnimplementedError(); + } + + @override + Future> run(String script, + {void Function(Process process)? onProcess}) async { + scripts.add(script); + // Take "hola" from "echo hola" + var outLines = [script.split(' ').last]; + var result = ProcessResult(1, 0, outLines.join('\n'), ''); + if (onProcess != null) { + onProcess(ProcessMock(result, outLines)); + } + return [result]; + } + + @override + Future runExecutableArguments( + String executable, List arguments, + {void Function(Process process)? onProcess}) { + // TODO: implement runExecutableArguments + throw UnimplementedError(); + } + + @override + Shell clone( + {bool? throwOnError, + String? workingDirectory, + Map? environment, + bool? includeParentEnvironment, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, + bool? commentVerbose}) { + // TODO: implement clone + throw UnimplementedError(); + } +} + +void main() { + group('shell_common_test', () { + Future testLinuxEcho(Shell shell) async { + var results = await shell.run('echo hola', onProcess: (process) { + process.kill(); + }); + expect(results.first.exitCode, 0); + + var outLines = results.outLines; + expect(outLines, ['hola']); + } + + test('mock', () async { + var shell = ShellMock(); + await testLinuxEcho(shell); + expect(shell.scripts, ['echo hola']); + }); + test('context', () async { + if (!isRunningAsJavascript) { + if (!Platform.isLinux) { + // Only io linux test for now + // TODO test on windows and mac + return; + } + } + shellContext = ShellContextMock(); + var shell = Shell(); + await testLinuxEcho(shell); + + if (isRunningAsJavascript) { + clearShellContext(); + } + try { + shell = Shell(); + if (isRunningAsJavascript) { + fail('should fail'); + } + } on StateError catch (e) { + if (!isRunningAsJavascript) { + rethrow; + } + print(e); + } + //expect(shell.scripts, ['echo hola']); + }); + test('io', () async { + if (!isRunningAsJavascript) { + if (Platform.isLinux) { + var shell = Shell(); + await testLinuxEcho(shell); + } + } + //expect(shell.scripts, ['hola']); + }); + }); +} diff --git a/test/src/shell_impl_test.dart b/test/src/shell_impl_test.dart index de094f3..3ff4c76 100644 --- a/test/src/shell_impl_test.dart +++ b/test/src/shell_impl_test.dart @@ -241,7 +241,7 @@ void main() { expect(result, '1'); shell = Shell( - verbose: false, + verbose: devWarning(true), // false, environment: platformEnvironment, includeParentEnvironment: false); result = From 7fe41c8eeed1f9476e1d62f9c00bc002fa5fc094 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sun, 3 Jul 2022 11:03:01 +0200 Subject: [PATCH 026/150] fix: shell options --- example/echo.dart | 34 ++++++++++++++++---------------- lib/shell.dart | 2 +- lib/src/bin/shell/env.dart | 4 ++-- lib/src/bin/shell/env_edit.dart | 10 +++++----- lib/src/common/dev_utils.dart | 2 +- lib/src/shell.dart | 12 ++++++----- lib/src/shell_common.dart | 21 +++++++++++++++++++- lib/src/shell_environment.dart | 1 + lib/src/shell_utils.dart | 6 +++--- lib/src/user_config.dart | 12 +++++------ test/echo_test.dart | 27 +++++++++++++------------ test/process_run_test.dart | 28 +++++++++++++------------- test/shell_api_test.dart | 1 + test/shell_environment_test.dart | 18 ++++++++--------- test/shell_test.dart | 26 ++++++++++++------------ test/src/shell_impl_test.dart | 17 ++++++++-------- test/src_shell_utils_test.dart | 12 +++++------ 17 files changed, 128 insertions(+), 105 deletions(-) diff --git a/example/echo.dart b/example/echo.dart index 4accf56..3af96c6 100755 --- a/example/echo.dart +++ b/example/echo.dart @@ -64,22 +64,22 @@ Future main(List arguments) async { parser.addFlag('version', help: 'Print the command version', negatable: false); - final _argsResult = parser.parse(arguments); + final argsResult = parser.parse(arguments); int? parseInt(dynamic value) { return int.tryParse(value?.toString() ?? ''); } - final help = _argsResult['help'] as bool; - final verbose = _argsResult['verbose'] as bool?; - final wait = parseInt(_argsResult['wait']); - final writeLine = _argsResult['write-line'] as bool?; + final help = argsResult['help'] as bool; + final verbose = argsResult['verbose'] as bool?; + final wait = parseInt(argsResult['wait']); + final writeLine = argsResult['write-line'] as bool?; if (wait != null) { await Future.delayed(Duration(milliseconds: wait)); } - void _printUsage() { + void printUsage() { stdout.writeln('Echo utility'); stdout.writeln(); stdout.writeln('Usage: $currentScriptName []'); @@ -92,11 +92,11 @@ Future main(List arguments) async { } if (help) { - _printUsage(); + printUsage(); return; } - final displayVersion = _argsResult['version'] as bool; + final displayVersion = argsResult['version'] as bool; if (displayVersion) { stdout.write('$currentScriptName version $version'); @@ -105,7 +105,7 @@ Future main(List arguments) async { } // handle stdin if asked for it - if (_argsResult['stdin'] as bool) { + if (argsResult['stdin'] as bool) { // devPrint('reading stdin $stdin'); if (verbose!) { //stderr.writeln('stdin $stdin'); @@ -120,14 +120,14 @@ Future main(List arguments) async { } } // handle stdout - final outputText = _argsResult['stdout'] as String?; + final outputText = argsResult['stdout'] as String?; if (outputText != null) { stdout.write(outputText); if (writeLine!) { stdout.writeln(); } } - final hexOutputText = _argsResult['stdout-hex'] as String?; + final hexOutputText = argsResult['stdout-hex'] as String?; if (hexOutputText != null) { stdout.add(hexToBytes(hexOutputText)); if (writeLine!) { @@ -135,14 +135,14 @@ Future main(List arguments) async { } } // handle stderr - final stderrText = _argsResult['stderr'] as String?; + final stderrText = argsResult['stderr'] as String?; if (stderrText != null) { stderr.write(stderrText); if (writeLine!) { stdout.writeln(); } } - final stderrHexTest = _argsResult['stderr-hex'] as String?; + final stderrHexTest = argsResult['stderr-hex'] as String?; if (stderrHexTest != null) { stderr.add(hexToBytes(stderrHexTest)); if (writeLine!) { @@ -150,7 +150,7 @@ Future main(List arguments) async { } } - final envVar = _argsResult['stdout-env'] as String?; + final envVar = argsResult['stdout-env'] as String?; if (envVar != null) { stdout.write(Platform.environment[envVar] ?? ''); if (writeLine!) { @@ -158,18 +158,18 @@ Future main(List arguments) async { } } - if (_argsResult['all-env'] as bool) { + if (argsResult['all-env'] as bool) { var env = ShellEnvironment(environment: Platform.environment); stdout.writeln(const JsonEncoder.withIndent(' ').convert(env.toJson())); } // handle the rest, default to output - for (final rest in _argsResult.rest) { + for (final rest in argsResult.rest) { stdout.writeln(rest); } // exit code! - final exitCodeText = _argsResult['exit-code'] as String?; + final exitCodeText = argsResult['exit-code'] as String?; if (exitCodeText != null) { exit(int.parse(exitCodeText)); } diff --git a/lib/shell.dart b/lib/shell.dart index 212af3f..7efa116 100644 --- a/lib/shell.dart +++ b/lib/shell.dart @@ -21,7 +21,7 @@ export 'package:process_run/dartbin.dart' dartChannelBeta, dartChannelDev, dartChannelMaster; - +export 'package:process_run/src/api/shell_common.dart' show ShellOptions; // We reuse io sharedStdIn definition. export 'package:process_run/src/io/shared_stdin.dart' show sharedStdIn; export 'package:process_run/src/shell_utils.dart' diff --git a/lib/src/bin/shell/env.dart b/lib/src/bin/shell/env.dart index ffc8a95..aefedcf 100644 --- a/lib/src/bin/shell/env.dart +++ b/lib/src/bin/shell/env.dart @@ -151,7 +151,7 @@ Future main(List arguments) async { Future shellEnv(ArgParser parser, ArgResults results) async { final help = results[flagHelp] as bool; - void _printUsage() { + void printUsage() { stdout.writeln('Manipulate local and global env vars'); stdout.writeln(); stdout.writeln('Usage: ds env var '); @@ -162,7 +162,7 @@ Future shellEnv(ArgParser parser, ArgResults results) async { } if (help) { - _printUsage(); + printUsage(); return; } diff --git a/lib/src/bin/shell/env_edit.dart b/lib/src/bin/shell/env_edit.dart index 7de2082..d5311df 100644 --- a/lib/src/bin/shell/env_edit.dart +++ b/lib/src/bin/shell/env_edit.dart @@ -16,28 +16,28 @@ class ShellEnvEditCommand extends ShellEnvCommandBase { } await envFileReadOrCreate(write: true); - Future _run(String command) async { + Future doRun(String command) async { await run(command, commandVerbose: verbose); } if (Platform.isLinux) { if (await which('gedit') != null) { - await _run('gedit ${shellArgument(envFilePath!)}'); + await doRun('gedit ${shellArgument(envFilePath!)}'); return true; } } else if (Platform.isWindows) { if (await which('notepad') != null) { - await _run('notepad ${shellArgument(envFilePath!)}'); + await doRun('notepad ${shellArgument(envFilePath!)}'); return true; } } else if (Platform.isMacOS) { if (await which('open') != null) { - await _run('open -a TextEdit ${shellArgument(envFilePath!)}'); + await doRun('open -a TextEdit ${shellArgument(envFilePath!)}'); return true; } } if (await which('vi') != null) { - await _run('vi ${shellArgument(envFilePath!)}'); + await doRun('vi ${shellArgument(envFilePath!)}'); return true; } print('no editor found'); diff --git a/lib/src/common/dev_utils.dart b/lib/src/common/dev_utils.dart index 70817f4..93a05e4 100644 --- a/lib/src/common/dev_utils.dart +++ b/lib/src/common/dev_utils.dart @@ -12,7 +12,7 @@ bool _devPrintEnabled = true; set devPrintEnabled(bool enabled) => _devPrintEnabled = enabled; @Deprecated('Dev only') -void devPrint(Object object) { +void devPrint(Object? object) { if (_devPrintEnabled) { print(object); } diff --git a/lib/src/shell.dart b/lib/src/shell.dart index 4df834b..20353e8 100644 --- a/lib/src/shell.dart +++ b/lib/src/shell.dart @@ -154,6 +154,7 @@ class Shell { runInShell: runInShell, commandVerbose: commandVerbose ?? verbose, environment: environment, + includeParentEnvironment: includeParentEnvironment, commentVerbose: commentVerbose ?? false, stderrEncoding: stderrEncoding, stdoutEncoding: stdoutEncoding)); @@ -382,6 +383,7 @@ class Shell { ..stdoutEncoding = _options.stdoutEncoding! ..workingDirectory = _options.workingDirectory; try { + // devPrint(_options.environment.keys.where((element) => element.contains('TEKARTIK'))); if (shellDebug) { print('$_runId: Before $processCmd'); } @@ -423,7 +425,7 @@ class Shell { } } on ProcessException catch (e) { var stderr = _options.stderr ?? io.stderr; - void _writeln([String? msg]) { + void writeln([String? msg]) { stderr.add(utf8.encode(msg ?? '')); stderr.add(utf8.encode('\n')); } @@ -431,15 +433,15 @@ class Shell { var workingDirectory = processCmd.workingDirectory ?? Directory.current.path; - _writeln(); + writeln(); if (!Directory(workingDirectory).existsSync()) { - _writeln('Missing working directory $workingDirectory'); + writeln('Missing working directory $workingDirectory'); } else { - _writeln(''' + writeln(''' Check that $executableFullPath exists command: $processCmd'''); } - _writeln(); + writeln(); throw ShellException( '$processCmd, error: $e, workingDirectory: $_workingDirectoryPath', diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index 1641823..fad71b3 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -115,6 +115,7 @@ class ShellException implements Exception { } */ +/// Shell options. class ShellOptions { final bool _throwOnError; final String? _workingDirectory; @@ -131,12 +132,25 @@ class ShellOptions { late final ShellEnvironment? _environment; + /// Specified working directory (null for not specified). String? get workingDirectory => _workingDirectory; + + /// Full environment used (including parent environment). ShellEnvironment get environment => _environment!; + + /// stdout. StreamSink>? get stdout => _stdout; + + /// stderr. StreamSink>? get stderr => _stderr; + + /// stdin. Stream>? get stdin => _stdin; + + /// stdout encoding. Encoding? get stdoutEncoding => _stdoutEncoding; + + /// stderr encoding. Encoding? get stderrEncoding => _stderrEncoding; /// [throwOnError] means that if an exit code is not 0, it will throw an error @@ -178,14 +192,19 @@ class ShellOptions { includeParentEnvironment: includeParentEnvironment); } + /// True if commands are displayed. bool get commandVerbose => _commandVerbose; + /// True if comments are displayed. bool get commentVerbose => _commentVerbose; + /// True if runInShell is specified. bool? get runInShell => _runInShell; - bool? get verbose => _verbose; + /// True if verbose is turned on. + bool get verbose => _verbose; + /// True if it should throw if an error occurred. bool get throwOnError => _throwOnError; /// Create a new shell diff --git a/lib/src/shell_environment.dart b/lib/src/shell_environment.dart index 3e22e40..f751de3 100644 --- a/lib/src/shell_environment.dart +++ b/lib/src/shell_environment.dart @@ -30,6 +30,7 @@ class ShellEnvironment extends common.ShellEnvironmentBase { {Map? environment, bool includeParentEnvironment = true}) { ShellEnvironment newEnvironment; + // devPrint(environment?.keys.where((element) => element.contains('TEKA'))); if (includeParentEnvironment) { newEnvironment = ShellEnvironment(); newEnvironment.merge(asShellEnvironment(environment)); diff --git a/lib/src/shell_utils.dart b/lib/src/shell_utils.dart index e362c67..7a12478 100644 --- a/lib/src/shell_utils.dart +++ b/lib/src/shell_utils.dart @@ -52,7 +52,7 @@ List scriptToCommands(String script) { for (var line in LineSplitter.split(script)) { line = line.trim(); - void _addAndClearCurrent(String? command) { + void addAndClearCurrent(String? command) { commands.add(command); currentCommand = null; } @@ -69,13 +69,13 @@ List scriptToCommands(String script) { // remove ending character currentCommand = line.substring(0, line.length - 1).trim(); } else { - _addAndClearCurrent(line); + addAndClearCurrent(line); } } } else { // terminate current if (currentCommand != null) { - _addAndClearCurrent(currentCommand); + addAndClearCurrent(currentCommand); } } } diff --git a/lib/src/user_config.dart b/lib/src/user_config.dart index dc45daf..8781751 100644 --- a/lib/src/user_config.dart +++ b/lib/src/user_config.dart @@ -163,7 +163,7 @@ EnvFileConfig loadFromMap(Map map) { // var: // ANDROID_TOP: /home/user/Android // FIREBASE_TOP: /home/user/.firebase - void _addVar(String key, String value) { + void addVar(String key, String value) { // devPrint('$key: $value'); fileVars[key] = value; } @@ -177,7 +177,7 @@ EnvFileConfig loadFromMap(Map map) { var entry = item.entries.first; var key = entry.key.toString(); var value = entry.value.toString(); - _addVar(key, value); + addVar(key, value); } } else { // devPrint(item.runtimeType); @@ -187,7 +187,7 @@ EnvFileConfig loadFromMap(Map map) { } if (vars is Map) { vars.forEach((key, value) { - _addVar(key.toString(), value.toString()); + addVar(key.toString(), value.toString()); }); } @@ -200,7 +200,7 @@ EnvFileConfig loadFromMap(Map map) { // // alias: // - ll: ls -l - void _addAlias(String key, String value) { + void addAlias(String key, String value) { // devPrint('$key: $value'); if (value.isNotEmpty) { fileAliases[key] = value; @@ -216,7 +216,7 @@ EnvFileConfig loadFromMap(Map map) { var entry = item.entries.first; var key = entry.key.toString(); var value = entry.value.toString(); - _addAlias(key, value); + addAlias(key, value); } } else { // devPrint(item.runtimeType); @@ -226,7 +226,7 @@ EnvFileConfig loadFromMap(Map map) { } if (alias is Map) { alias.forEach((key, value) { - _addAlias(key.toString(), value.toString()); + addAlias(key.toString(), value.toString()); }); } } catch (e) { diff --git a/test/echo_test.dart b/test/echo_test.dart index 93e344c..a242295 100644 --- a/test/echo_test.dart +++ b/test/echo_test.dart @@ -6,15 +6,16 @@ import 'dart:io'; import 'package:process_run/process_run.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/dartbin_impl.dart'; import 'package:test/test.dart'; import 'process_run_test_common.dart'; -var echo = 'dart run example/echo.dart'; +var echo = '$resolvedDartExecutable run example/echo.dart'; void main() { group('echo', () { - Future _runCheck( + Future runCheck( Function(ProcessResult result) check, String executable, List arguments, { @@ -63,9 +64,9 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( checkOut, dartExecutable!, [echoScriptPath, '--stdout', 'out']); - await _runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); + await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); }); test('stdout_bin', () async { @@ -83,10 +84,10 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( check123, dartExecutable!, [echoScriptPath, '--stdout-hex', '010203'], stdoutEncoding: null); - await _runCheck(checkEmpty, dartExecutable!, [echoScriptPath], + await runCheck(checkEmpty, dartExecutable!, [echoScriptPath], stdoutEncoding: null); }); @@ -127,10 +128,10 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( checkErr, dartExecutable!, [echoScriptPath, '--stderr', 'err'], stdout: stdout); - await _runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); + await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); }); test('stdin', () async { @@ -163,10 +164,10 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( check123, dartExecutable!, [echoScriptPath, '--stderr-hex', '010203'], stderrEncoding: null); - await _runCheck(checkEmpty, dartExecutable!, [echoScriptPath], + await runCheck(checkEmpty, dartExecutable!, [echoScriptPath], stderrEncoding: null); }); @@ -185,9 +186,9 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( check123, dartExecutable!, [echoScriptPath, '--exit-code', '123']); - await _runCheck(check0, dartExecutable!, [echoScriptPath]); + await runCheck(check0, dartExecutable!, [echoScriptPath]); }); test('crash', () async { @@ -198,7 +199,7 @@ void main() { expect(result.exitCode, 255); } - await _runCheck( + await runCheck( check, dartExecutable!, [echoScriptPath, '--exit-code', 'crash']); }); }); diff --git a/test/process_run_test.dart b/test/process_run_test.dart index 4d2d845..10f37eb 100644 --- a/test/process_run_test.dart +++ b/test/process_run_test.dart @@ -51,7 +51,7 @@ void main() { }); group('run', () { - Future _runCheck( + Future runCheck( Function(ProcessResult result) check, String executable, List arguments, { @@ -100,9 +100,9 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( checkOut, dartExecutable!, [echoScriptPath, '--stdout', 'out']); - await _runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); + await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); }); test('stdout_bin', () async { @@ -120,10 +120,10 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( check123, dartExecutable!, [echoScriptPath, '--stdout-hex', '010203'], stdoutEncoding: null); - await _runCheck(checkEmpty, dartExecutable!, [echoScriptPath], + await runCheck(checkEmpty, dartExecutable!, [echoScriptPath], stdoutEncoding: null); }); @@ -142,10 +142,10 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( checkErr, dartExecutable!, [echoScriptPath, '--stderr', 'err'], stdout: stdout); - await _runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); + await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); }); test('stdin', () async { @@ -178,10 +178,10 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( check123, dartExecutable!, [echoScriptPath, '--stderr-hex', '010203'], stderrEncoding: null); - await _runCheck(checkEmpty, dartExecutable!, [echoScriptPath], + await runCheck(checkEmpty, dartExecutable!, [echoScriptPath], stderrEncoding: null); }); @@ -200,9 +200,9 @@ void main() { expect(result.exitCode, 0); } - await _runCheck( + await runCheck( check123, dartExecutable!, [echoScriptPath, '--exit-code', '123']); - await _runCheck(check0, dartExecutable!, [echoScriptPath]); + await runCheck(check0, dartExecutable!, [echoScriptPath]); }); test('crash', () async { @@ -213,7 +213,7 @@ void main() { expect(result.exitCode, 255); } - await _runCheck( + await runCheck( check, dartExecutable!, [echoScriptPath, '--exit-code', 'crash']); }); @@ -287,10 +287,10 @@ void main() { // use 'type' on windows if (Platform.isWindows) { - await _runCheck(check, 'type', ['pubspec.yaml'], + await runCheck(check, 'type', ['pubspec.yaml'], workingDirectory: projectTop, runInShell: true); } else { - await _runCheck(check, 'cat', ['pubspec.yaml'], + await runCheck(check, 'cat', ['pubspec.yaml'], workingDirectory: projectTop); } }); diff --git a/test/shell_api_test.dart b/test/shell_api_test.dart index 250ab58..d203995 100644 --- a/test/shell_api_test.dart +++ b/test/shell_api_test.dart @@ -37,6 +37,7 @@ void main() { prompt; run; Shell; + ShellOptions; ShellException; ShellEnvironment; ShellEnvironmentPaths; diff --git a/test/shell_environment_test.dart b/test/shell_environment_test.dart index e512f84..547d0d5 100644 --- a/test/shell_environment_test.dart +++ b/test/shell_environment_test.dart @@ -19,16 +19,16 @@ void main() { group('ShellEnvironment', () { test('empty', () { - var _prev = shellEnvironment; + var prevEnv = shellEnvironment; expect(shellEnvironment, isNotEmpty); var env = ShellEnvironment.empty(); try { shellEnvironment = env; expect(shellEnvironment, isEmpty); shellEnvironment = null; - expect(shellEnvironment, _prev); + expect(shellEnvironment, prevEnv); } finally { - shellEnvironment = _prev; + shellEnvironment = prevEnv; expect(shellEnvironment, isNotEmpty); } }); @@ -93,7 +93,7 @@ void main() { }); test('global vars ', () async { - var _prev = shellEnvironment; + var prevEnv = shellEnvironment; expect(shellEnvironment, isNotEmpty); var shell = Shell(verbose: false); var env = ShellEnvironment() @@ -117,7 +117,7 @@ void main() { // expect(result, {}); expect(result.vars['TEST_PROCESS_RUN_VAR1'], 'test_process_run_value1'); } finally { - shellEnvironment = _prev; + shellEnvironment = prevEnv; } }); // not working @@ -186,7 +186,7 @@ void main() { if (whichSync(current_dir) != null) { stderr.writeln('Global current_dir found, skipping'); } - var _prev = shellEnvironment; + var prevEnv = shellEnvironment; expect(shellEnvironment, isNotEmpty); var shell = Shell(); @@ -206,7 +206,7 @@ void main() { var shell = Shell(); await shell.run(current_dir); } finally { - shellEnvironment = _prev; + shellEnvironment = prevEnv; } }); test('local empty include parent', () async { @@ -307,13 +307,13 @@ void main() { }); test('overriding', () async { - var _prev = shellEnvironment; + var prevEnv = shellEnvironment; try { var env = ShellEnvironment()..paths.prepend('T1'); shellEnvironment = env; expect(ShellEnvironment().paths.first, 'T1'); } finally { - shellEnvironment = _prev; + shellEnvironment = prevEnv; } }); } diff --git a/test/shell_test.dart b/test/shell_test.dart index 17012f8..24675eb 100644 --- a/test/shell_test.dart +++ b/test/shell_test.dart @@ -278,7 +278,7 @@ dart example/echo.dart -o ${shellArgument(weirdText)} late Shell shell; StreamSubscription? subscription; - void _init() { + void init() { lines.clear(); subscription?.cancel(); linesController = ShellLinesController(); @@ -291,16 +291,16 @@ dart example/echo.dart -o ${shellArgument(weirdText)} }); } - _init(); + init(); await shell.run('dart echo.dart some_text'); expect(lines, ['some_text']); - _init(); + init(); subscription?.pause(); await shell.run('dart echo.dart some_text'); expect(lines, []); - _init(); + init(); await shell.run('dart echo.dart some_text1'); expect(lines, ['some_text1']); @@ -416,7 +416,7 @@ _tekartik_dummy_app_that_does_not_exits }); // skip windows for now }); - Future _testCommand(String command) async { + Future testCommand(String command) async { var shell = Shell(verbose: debug); try { await shell.run(command); @@ -427,21 +427,21 @@ _tekartik_dummy_app_that_does_not_exits test('various command', () async { // that can be installed or not - await _testCommand('firebase --version'); // firebase.cmd on windows - await _testCommand('flutter --version'); // flutter.bat on windows - await _testCommand('dart --version'); // dart.exe on windows - await _testCommand( + await testCommand('firebase --version'); // firebase.cmd on windows + await testCommand('flutter --version'); // flutter.bat on windows + await testCommand('dart --version'); // dart.exe on windows + await testCommand( '${shellArgument(dartExecutable!)} --version'); // dart.exe on windows if (dartVersion < Version(2, 17, 0, pre: '0')) { - await _testCommand('pub --version'); // dart.exe on windows + await testCommand('pub --version'); // dart.exe on windows } // on windows, system command or alias in PowerShell - await _testCommand('echo Hello world'); + await testCommand('echo Hello world'); }); test('echo', () async { - await _testCommand('echo Hello world'); // alias to Write-Output - await _testCommand('echo Hello world'); // alias to Write-Output + await testCommand('echo Hello world'); // alias to Write-Output + await testCommand('echo Hello world'); // alias to Write-Output }); test('pipe', () async { diff --git a/test/src/shell_impl_test.dart b/test/src/shell_impl_test.dart index 3ff4c76..4f189d0 100644 --- a/test/src/shell_impl_test.dart +++ b/test/src/shell_impl_test.dart @@ -2,7 +2,6 @@ import 'dart:io'; import 'package:path/path.dart'; -import 'package:process_run/dartbin.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/shell_run.dart'; import 'package:process_run/src/common/constant.dart'; @@ -100,26 +99,26 @@ void main() { } }); - var _flutterExecutablePath = flutterExecutablePath; + var localFlutterExecutablePath = flutterExecutablePath; test('userEnvironment in flutter context', () async { try { - var flutterBinDirPath = dirname(_flutterExecutablePath!); + var flutterBinDirPath = dirname(localFlutterExecutablePath!); platformEnvironment = newEnvNoOverride() ..paths.prepend(flutterBinDirPath); // '/opt/app/flutter/dev/flutter/bin', // '/opt/app/flutter/dev/flutter/bin/cache/dart-sdk/bin' if (dartSdkBinDirPath.contains(flutterBinDirPath)) { - expect( - userPaths, [dirname(_flutterExecutablePath), dartSdkBinDirPath]); + expect(userPaths, + [dirname(localFlutterExecutablePath), dartSdkBinDirPath]); } else { - expect( - userPaths, [dartSdkBinDirPath, dirname(_flutterExecutablePath)]); + expect(userPaths, + [dartSdkBinDirPath, dirname(localFlutterExecutablePath)]); } } finally { platformEnvironment = null; } - }, skip: _flutterExecutablePath == null); + }, skip: localFlutterExecutablePath == null); test('userEnvironment', () async { try { @@ -241,7 +240,7 @@ void main() { expect(result, '1'); shell = Shell( - verbose: devWarning(true), // false, + verbose: false, environment: platformEnvironment, includeParentEnvironment: false); result = diff --git a/test/src_shell_utils_test.dart b/test/src_shell_utils_test.dart index 40801ec..2e8b4fe 100644 --- a/test/src_shell_utils_test.dart +++ b/test/src_shell_utils_test.dart @@ -82,17 +82,17 @@ void main() { }); test('shellJoin', () { - void _test(String command, {String? expected}) { + void testSplitJoin(String command, {String? expected}) { var parts = shellSplit(command); var joined = shellJoin(parts); expect(joined, expected ?? command, reason: parts.toString()); } - _test('foo'); - _test('foo bar'); - _test(r'\'); - _test('"foo bar"'); - _test("'foo bar'", expected: '"foo bar"'); + testSplitJoin('foo'); + testSplitJoin('foo bar'); + testSplitJoin(r'\'); + testSplitJoin('"foo bar"'); + testSplitJoin("'foo bar'", expected: '"foo bar"'); }); test('no_env', () { From 216b5be9d7cb226bc366a702956e3e6b5f13c4b4 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sun, 3 Jul 2022 11:26:11 +0200 Subject: [PATCH 027/150] fix: shell options --- lib/shell.dart | 3 ++- lib/src/process_run.dart | 26 ++++---------------------- lib/src/shell_io.dart | 1 - lib/src/shell_utils_common.dart | 2 ++ lib/src/shell_utils_io.dart | 27 +++++++++++++++++++++++++++ 5 files changed, 35 insertions(+), 24 deletions(-) delete mode 100644 lib/src/shell_io.dart create mode 100644 lib/src/shell_utils_io.dart diff --git a/lib/shell.dart b/lib/shell.dart index 7efa116..a848c20 100644 --- a/lib/shell.dart +++ b/lib/shell.dart @@ -1,7 +1,7 @@ /// {@canonicalFor prompt.prompt} /// {@canonicalFor prompt.promptConfirm} /// {@canonicalFor prompt.promptTerminate} -/// {@canonicalFor shell_utils.shellArgument} +/// {@canonicalFor process_run.src.shell_utils_common.shellArgument} /// {@canonicalFor user_config.userLoadEnv} /// {@canonicalFor user_config.userLoadEnvFile} /// {@canonicalFor shell_utils.platformEnvironment} @@ -10,6 +10,7 @@ /// {@canonicalFor user_config.userEnvironment} /// {@canonicalFor shell_utils.userHomePath} /// {@canonicalFor user_config.userPaths} +/// {@canonicalFor process_run.runExecutableArguments} library process_run.shell; export 'package:process_run/dartbin.dart' diff --git a/lib/src/process_run.dart b/lib/src/process_run.dart index 699232c..340f103 100644 --- a/lib/src/process_run.dart +++ b/lib/src/process_run.dart @@ -4,14 +4,17 @@ import 'dart:io'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; +import 'package:process_run/src/process_run.dart'; import 'package:process_run/src/shell.dart'; import 'package:process_run/src/shell_utils.dart' as utils; import 'package:process_run/src/shell_utils.dart'; import 'common/import.dart'; +export 'shell_utils_io.dart' show executableArgumentsToString; + /// -/// if [commmandVerbose] or [verbose] is true, display the command. +/// if [commandVerbose] or [verbose] is true, display the command. /// if [verbose] is true, stream stdout & stdin /// /// Optional [onProcess(process)] is called to allow killing the process. @@ -187,27 +190,6 @@ Future runExecutableArguments( return result; } -/// Convenient way to display a command -String executableArgumentsToString( - String? executable, List? arguments) { - final sb = StringBuffer(); - if (Platform.isWindows && (basename(executable!) == executable)) { - var ext = extension(executable); - switch (ext) { - case '.exe': - case '.bat': - case '.cmd': - case '.com': - executable = executable.substring(0, executable.length - 4); - } - } - sb.write(executable); - if (arguments is List && arguments!.isNotEmpty) { - sb.write(' ${argumentsToString(arguments)}'); - } - return sb.toString(); -} - /// Command runner. not exported /// Execute a predefined ProcessCmd command diff --git a/lib/src/shell_io.dart b/lib/src/shell_io.dart deleted file mode 100644 index 8b13789..0000000 --- a/lib/src/shell_io.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/src/shell_utils_common.dart b/lib/src/shell_utils_common.dart index 824fe61..da00ba5 100644 --- a/lib/src/shell_utils_common.dart +++ b/lib/src/shell_utils_common.dart @@ -1,3 +1,5 @@ +library process_run.src.shell_utils_common; + import 'dart:async'; import 'dart:convert'; diff --git a/lib/src/shell_utils_io.dart b/lib/src/shell_utils_io.dart new file mode 100644 index 0000000..438f97f --- /dev/null +++ b/lib/src/shell_utils_io.dart @@ -0,0 +1,27 @@ +library process_run.src.shell_utils_io; + +import 'dart:io'; + +import 'package:path/path.dart'; +import 'package:process_run/src/shell_utils.dart'; + +/// Convenient way to display a command +String executableArgumentsToString( + String? executable, List? arguments) { + final sb = StringBuffer(); + if (Platform.isWindows && (basename(executable!) == executable)) { + var ext = extension(executable); + switch (ext) { + case '.exe': + case '.bat': + case '.cmd': + case '.com': + executable = executable.substring(0, executable.length - 4); + } + } + sb.write(executable); + if (arguments is List && arguments!.isNotEmpty) { + sb.write(' ${argumentsToString(arguments)}'); + } + return sb.toString(); +} From c32617d4774bd03b2b063fae5efb246b4b50941c Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sun, 17 Jul 2022 11:06:29 +0200 Subject: [PATCH 028/150] deprecate DartAnalyzer command --- lib/cmd_run.dart | 1 + lib/src/dartbin_cmd.dart | 1 + test/cmd_run_api_test.dart | 1 + test/dartanalyzer_test.dart | 27 --------------------------- test/dartbin_cmd_test.dart | 4 ++-- test/dartbin_cmd_verbose_test_.dart | 4 +--- 6 files changed, 6 insertions(+), 32 deletions(-) delete mode 100644 test/dartanalyzer_test.dart diff --git a/lib/cmd_run.dart b/lib/cmd_run.dart index f48a2aa..abfde91 100644 --- a/lib/cmd_run.dart +++ b/lib/cmd_run.dart @@ -49,6 +49,7 @@ export 'src/dartbin_cmd.dart' DartDocCmd, // ignore: deprecated_member_use_from_same_package DartFmtCmd, // ignore: deprecated_member_use_from_same_package DartDevcCmd, + // ignore: deprecated_member_use_from_same_package DartAnalyzerCmd, PubCmd, PubGlobalRunCmd, diff --git a/lib/src/dartbin_cmd.dart b/lib/src/dartbin_cmd.dart index 1b8511f..5462cb6 100644 --- a/lib/src/dartbin_cmd.dart +++ b/lib/src/dartbin_cmd.dart @@ -47,6 +47,7 @@ class DartFmtCmd extends DartCmd { } /// dartanalyzer +@Deprecated('dartanalyzer is deprecated itself, use dart analyze') class DartAnalyzerCmd extends _DartBinCmd { DartAnalyzerCmd(List arguments) : super(getShellCmdBinFileName('dartanalyzer'), arguments); diff --git a/test/cmd_run_api_test.dart b/test/cmd_run_api_test.dart index a01ee37..224eab3 100644 --- a/test/cmd_run_api_test.dart +++ b/test/cmd_run_api_test.dart @@ -40,6 +40,7 @@ void main() { DartDocCmd; // ignore: deprecated_member_use_from_same_package DartFmtCmd; // ignore: deprecated_member_use_from_same_package DartDevcCmd; + // ignore: deprecated_member_use_from_same_package DartAnalyzerCmd; PubCmd; PubGlobalRunCmd; diff --git a/test/dartanalyzer_test.dart b/test/dartanalyzer_test.dart deleted file mode 100644 index 3272768..0000000 --- a/test/dartanalyzer_test.dart +++ /dev/null @@ -1,27 +0,0 @@ -@TestOn('vm') -library process_run.dartanalyzer_test; - -import 'package:process_run/cmd_run.dart'; -// ignore: import_of_legacy_library_into_null_safe -import 'package:pub_semver/pub_semver.dart'; -import 'package:test/test.dart'; - -void main() => defineTests(); - -void defineTests() { - group('dartanalyzer', () { - test('help', () async { - var result = await runCmd(DartAnalyzerCmd(['--help'])); - expect(result.exitCode, 0); - // Every other commands write to stdout but dartanalyzer - expect(result.stderr, contains('Usage: dartanalyzer')); - - // dartanalyzer version 2.0.0-dev.63.0 - result = await runCmd(DartAnalyzerCmd(['--version'])); - var version = - Version.parse((result.stdout as String).trim().split(' ').last); - expect(version, greaterThan(Version(1, 0, 0))); - expect(result.exitCode, 0); - }); - }); -} diff --git a/test/dartbin_cmd_test.dart b/test/dartbin_cmd_test.dart index f373f9e..ffc48b5 100644 --- a/test/dartbin_cmd_test.dart +++ b/test/dartbin_cmd_test.dart @@ -34,7 +34,7 @@ void main() { // Somehow the exit code is 1 on windows expect(exitCode, 0); } - expect((await runCmd(DartAnalyzerCmd(['--help']))).exitCode, 0); + // expect((await runCmd(DartAnalyzerCmd(['--help']))).exitCode, 0); // expect((await runCmd(DartDevcCmd(['--help']))).exitCode, 0); expect((await runCmd(PubCmd(['--help']))).exitCode, 0); //expect((await runCmd(DartDevkCmd(['--help']))).exitCode, 0); @@ -46,7 +46,7 @@ void main() { // ignore: deprecated_member_use_from_same_package expect(Dart2JsCmd(['--help']).toString(), 'dart2js --help'); // expect(DartDevcCmd(['--help']).toString(), 'dartdevc --help'); - expect(DartAnalyzerCmd(['--help']).toString(), 'dartanalyzer --help'); + //expect(DartAnalyzerCmd(['--help']).toString(), 'dartanalyzer --help'); expect(DartFmtCmd(// ignore: deprecated_member_use_from_same_package ['--help']).toString(), 'dart format --help'); expect(DartCmd(['--help']).toString(), 'dart --help'); diff --git a/test/dartbin_cmd_verbose_test_.dart b/test/dartbin_cmd_verbose_test_.dart index 2ffa114..a8f4814 100644 --- a/test/dartbin_cmd_verbose_test_.dart +++ b/test/dartbin_cmd_verbose_test_.dart @@ -17,9 +17,7 @@ void main() { verbose: true)) .exitCode, 0); - expect( - (await runCmd(DartAnalyzerCmd(['--help']), verbose: true)).exitCode, - 0); + // To remove once dart stable hits 2.17.0 if (dartVersion < Version(2, 17, 0, pre: '0')) { expect( From 6604bff3f4b3a110add398729645dfb13afd5d30 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 14 Nov 2022 00:57:38 +0100 Subject: [PATCH 029/150] feat: add Shell.shellVarOverride to allow settings through env variables --- lib/src/bin/shell/env_var_delete.dart | 29 ++---- lib/src/bin/shell/env_var_get.dart | 8 +- lib/src/bin/shell/env_var_set.dart | 28 ++---- lib/src/dartbin_cmd.dart | 5 +- lib/src/io/env_io.dart | 73 +++++++++++++++ lib/src/io/env_var_delete_io.dart | 31 +++++++ lib/src/io/env_var_get_io.dart | 17 ++++ lib/src/io/env_var_set_io.dart | 50 +++++++++++ lib/src/process_cmd.dart | 4 +- lib/src/process_run.dart | 2 +- lib/src/shell.dart | 122 +++++++++++++++----------- lib/src/shell_common.dart | 56 +++++++++--- lib/src/shell_common_io.dart | 12 ++- lib/src/shell_context_common.dart | 2 + lib/src/shell_context_io.dart | 1 + pubspec.yaml | 2 +- test/dartbin_test.dart | 14 +-- test/shell_common_test.dart | 21 +---- test/shell_run_test.dart | 2 + test/shell_test.dart | 21 ++++- 20 files changed, 356 insertions(+), 144 deletions(-) create mode 100644 lib/src/io/env_io.dart create mode 100644 lib/src/io/env_var_delete_io.dart create mode 100644 lib/src/io/env_var_get_io.dart create mode 100644 lib/src/io/env_var_set_io.dart diff --git a/lib/src/bin/shell/env_var_delete.dart b/lib/src/bin/shell/env_var_delete.dart index 67d9487..7ecb0c3 100644 --- a/lib/src/bin/shell/env_var_delete.dart +++ b/lib/src/bin/shell/env_var_delete.dart @@ -1,11 +1,13 @@ -import 'dart:convert'; import 'dart:io'; -import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/env_var_delete_io.dart'; class ShellEnvVarDeleteCommand extends ShellEnvCommandBase { + late final helper = + ShellEnvVarDeleteIoHelper(local: local, verbose: verbose ?? false); + ShellEnvVarDeleteCommand() : super( name: 'delete', @@ -26,28 +28,7 @@ class ShellEnvVarDeleteCommand extends ShellEnvCommandBase { stderr.writeln('At least 1 arguments expected'); exit(1); } else { - if (verbose!) { - stdout.writeln('file $label: $envFilePath'); - stdout.writeln('before: ${jsonEncode(ShellEnvironment().vars)}'); - } - - var fileContent = await envFileReadOrCreate(); - var modified = false; - for (var name in rest) { - modified = fileContent.deleteVar(name) || modified; - } - if (modified) { - if (verbose!) { - stdout.writeln('writing file'); - } - await fileContent.write(); - } - - // Force reload - shellEnvironment = null; - if (verbose!) { - stdout.writeln('After: ${jsonEncode(ShellEnvironment().vars)}'); - } + await helper.deleteMulti(rest); return true; } } diff --git a/lib/src/bin/shell/env_var_get.dart b/lib/src/bin/shell/env_var_get.dart index ddb497d..b5e6e85 100644 --- a/lib/src/bin/shell/env_var_get.dart +++ b/lib/src/bin/shell/env_var_get.dart @@ -1,12 +1,14 @@ import 'dart:io'; -import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/env_var_get_io.dart'; import 'dump.dart'; class ShellEnvVarGetCommand extends ShellEnvCommandBase { + late final helper = ShellEnvVarGetIoHelper(); + ShellEnvVarGetCommand() : super( name: 'get', @@ -29,9 +31,7 @@ class ShellEnvVarGetCommand extends ShellEnvCommandBase { stderr.writeln('At least 1 arguments expected'); exit(1); } else { - Map map = ShellEnvironment().vars; - map = Map.from(map) - ..removeWhere((key, value) => !rest.contains(key)); + var map = helper.getMulti(rest); if (map.isEmpty) { stdout.writeln('not found'); } else { diff --git a/lib/src/bin/shell/env_var_set.dart b/lib/src/bin/shell/env_var_set.dart index 3c6742c..9777e62 100644 --- a/lib/src/bin/shell/env_var_set.dart +++ b/lib/src/bin/shell/env_var_set.dart @@ -1,12 +1,13 @@ -import 'dart:convert'; import 'dart:io'; -import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; -import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/env_var_set_io.dart'; class ShellEnvVarSetCommand extends ShellEnvCommandBase { + late final helper = + ShellEnvVarSetIoHelper(local: local, verbose: verbose ?? false); + ShellEnvVarSetCommand() : super( name: 'set', @@ -26,27 +27,10 @@ class ShellEnvVarSetCommand extends ShellEnvCommandBase { stderr.writeln('At least 2 arguments expected'); exit(1); } else { - if (verbose!) { - stdout.writeln('file $label: $envFilePath'); - stdout.writeln('before: ${jsonEncode(ShellEnvironment().vars)}'); - } var name = rest[0]; var value = rest.sublist(1).join(' '); - var fileContent = await envFileReadOrCreate(); - if (fileContent.addVar(name, value)) { - if (verbose!) { - stdout.writeln('writing file'); - } - await fileContent.write(); - } - if (local && name == localEnvFilePathEnvKey) { - stderr.writeln('$name cannot be set in local file'); - } - // Force reload - shellEnvironment = null; - if (verbose!) { - stdout.writeln('After: ${jsonEncode(ShellEnvironment().vars)}'); - } + await helper.setValue(name, value); + return true; } } diff --git a/lib/src/dartbin_cmd.dart b/lib/src/dartbin_cmd.dart index 5462cb6..9d9c11a 100644 --- a/lib/src/dartbin_cmd.dart +++ b/lib/src/dartbin_cmd.dart @@ -139,8 +139,9 @@ String parsePlatformChannel(String text) { Future getDartBinVersion() async { // $ dart --version // Linux: Dart VM version: 2.7.0 (Unknown timestamp) on "linux_x64" - var cmd = DartCmd(['--version']); - var result = await runCmd(cmd); + + var result = + await runExecutableArguments('dart', ['--version'], verbose: false); // Take from stderr first var version = parseDartBinVersionOutput(result.stderr.toString().trim()); diff --git a/lib/src/io/env_io.dart b/lib/src/io/env_io.dart new file mode 100644 index 0000000..f628c64 --- /dev/null +++ b/lib/src/io/env_io.dart @@ -0,0 +1,73 @@ +import 'dart:convert'; + +import 'package:process_run/src/bin/shell/env_file_content.dart'; +import 'package:process_run/src/user_config.dart'; + +class ShellEnvIoHelper { + final bool local; + final bool verbose; + + ShellEnvIoHelper({required this.local, required this.verbose}); + + String get label => local ? 'local' : 'user'; + + Future envFileReadOrCreate({bool write = false}) async { + var fileContent = EnvFileContent(_envFilePath!); + if (!await fileContent.read()) { + fileContent.lines = sampleFileContent; + } + if (write) { + await fileContent.write(); + } + return fileContent; + } + + String? get envFilePath => _envFilePath; + + String? get _envFilePath => local + ? getLocalEnvFilePath(userEnvironment) + : getUserEnvFilePath(userEnvironment); + + List? _sampleFileContent; + + List get sampleFileContent => _sampleFileContent ??= () { + var content = local + ? ''' +# Local Environment path and variable for `Shell.run` calls. +# +# `path(s)` is a list of path, `var(s)` is a key/value map. +# +# Content example. See for more information +# +# path: +# - ./local +# - bin/ +# var: +# MY_PWD: my_password +# MY_USER: my user +# alias: +# qr: /path/to/my_qr_app + ''' + : ''' +# Environment path and variable for `Shell.run` calls. +# +# `path` is a list of path, `var` is a key/value map. +# +# Content example. See for more information +# +# path: +# - ~/Android/Sdk/tools/bin +# - ~/Android/Sdk/platform-tools +# - ~/.gem/bin/ +# - ~/.pub-cache/bin +# var: +# ANDROID_TOP: ~/.android +# FLUTTER_BIN: ~/.flutter/bin +# alias: +# qr: /path/to/my_qr_app + +'''; + + return LineSplitter.split(content).toList(); + }(); +} diff --git a/lib/src/io/env_var_delete_io.dart b/lib/src/io/env_var_delete_io.dart new file mode 100644 index 0000000..fd3eb75 --- /dev/null +++ b/lib/src/io/env_var_delete_io.dart @@ -0,0 +1,31 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:process_run/shell.dart'; +import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/env_io.dart'; + +class ShellEnvVarDeleteIoHelper extends ShellEnvIoHelper { + ShellEnvVarDeleteIoHelper({required super.local, required super.verbose}); + + Future deleteMulti(List keys) async { + var fileContent = await envFileReadOrCreate(); + var modified = false; + for (var name in keys) { + modified = fileContent.deleteVar(name) || modified; + } + if (modified) { + if (verbose) { + stdout.writeln('writing file'); + } + await fileContent.write(); + } + + // Force reload + shellEnvironment = null; + if (verbose) { + stdout.writeln('After: ${jsonEncode(ShellEnvironment().vars)}'); + } + return ShellEnvironment(); + } +} diff --git a/lib/src/io/env_var_get_io.dart b/lib/src/io/env_var_get_io.dart new file mode 100644 index 0000000..63ef105 --- /dev/null +++ b/lib/src/io/env_var_get_io.dart @@ -0,0 +1,17 @@ +import 'package:process_run/shell.dart'; + +class ShellEnvVarGetIoHelper { + ShellEnvVarGetIoHelper(); + + Map getMulti(List keys) { + Map map = ShellEnvironment().vars; + map = Map.from(map) + ..removeWhere((key, value) => !keys.contains(key)); + return map; + } + + String? get(String key) { + var value = ShellEnvironment().vars[key]; + return value; + } +} diff --git a/lib/src/io/env_var_set_io.dart b/lib/src/io/env_var_set_io.dart new file mode 100644 index 0000000..c73532a --- /dev/null +++ b/lib/src/io/env_var_set_io.dart @@ -0,0 +1,50 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:process_run/shell.dart'; +import 'package:process_run/src/common/constant.dart'; +import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/env_io.dart'; + +import '../platform/platform.dart'; + +class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { + /// Local should be true by default + ShellEnvVarSetIoHelper({required super.local, super.verbose = true}); + + Future setValue(String name, String? value) async { + if (verbose) { + stdout.writeln('file $label: $envFilePath'); + stdout.writeln('before: ${jsonEncode(ShellEnvironment().vars)}'); + } + + var fileContent = await envFileReadOrCreate(); + bool modified; + if (value != null) { + modified = fileContent.addVar(name, value); + } else { + modified = fileContent.deleteVar(name); + } + if (modified) { + if (verbose) { + stdout.writeln('writing file'); + } + await fileContent.write(); + } + if (local && name == localEnvFilePathEnvKey) { + stderr.writeln('$name cannot be set in local file'); + } + // Force reload + var newShellEnvironment = shellContext.newShellEnvironment( + environment: Map.from(shellEnvironment)); + if (value == null) { + newShellEnvironment.vars.remove(name); + } else { + newShellEnvironment.vars[name] = value; + } + if (verbose) { + stdout.writeln('After: ${jsonEncode(ShellEnvironment().vars)}'); + } + return newShellEnvironment; + } +} diff --git a/lib/src/process_cmd.dart b/lib/src/process_cmd.dart index 9938ecf..64edb2e 100644 --- a/lib/src/process_cmd.dart +++ b/lib/src/process_cmd.dart @@ -13,8 +13,8 @@ class ProcessCmd { Map? environment; bool includeParentEnvironment; bool? runInShell; - Encoding stdoutEncoding; - Encoding stderrEncoding; + Encoding? stdoutEncoding; + Encoding? stderrEncoding; ProcessCmd(this.executable, this.arguments, {this.workingDirectory, diff --git a/lib/src/process_run.dart b/lib/src/process_run.dart index 340f103..d9dd43b 100644 --- a/lib/src/process_run.dart +++ b/lib/src/process_run.dart @@ -43,7 +43,7 @@ Future runExecutableArguments( if (commandVerbose == true) { utils.streamSinkWriteln(stdout ?? io.stdout, '\$ ${executableArgumentsToString(executable, arguments)}', - encoding: stdoutEncoding!); + encoding: stdoutEncoding); } // Build our environment diff --git a/lib/src/shell.dart b/lib/src/shell.dart index 20353e8..2e85c59 100644 --- a/lib/src/shell.dart +++ b/lib/src/shell.dart @@ -8,7 +8,7 @@ import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/platform/platform.dart'; import 'package:process_run/src/process_run.dart'; import 'package:process_run/src/shell_common.dart' - show ShellOptions, shellDebug; + show ShellCore, ShellOptions, shellDebug; import 'package:process_run/src/shell_utils.dart'; import 'package:synchronized/synchronized.dart'; @@ -90,7 +90,7 @@ Future> run( /// /// A list of ProcessResult is returned /// -class Shell { +abstract class Shell implements ShellCore { final ShellOptions _options; /// Incremental internal runId @@ -126,50 +126,60 @@ class Shell { /// if [verbose] is not false or [commentVerbose] is true, it will display the /// comments as well factory Shell( - {bool throwOnError = true, - String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool? runInShell, - Encoding stdoutEncoding = systemEncoding, - Encoding stderrEncoding = systemEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool verbose = true, - // Default to true - bool? commandVerbose, - // Default to false - bool? commentVerbose, - ShellOptions? options}) => - shellContext.newShell( - options: options ?? - ShellOptions( - verbose: verbose, - stdin: stdin, - stdout: stdout, - stderr: stderr, - throwOnError: throwOnError, - workingDirectory: workingDirectory, - runInShell: runInShell, - commandVerbose: commandVerbose ?? verbose, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - commentVerbose: commentVerbose ?? false, - stderrEncoding: stderrEncoding, - stdoutEncoding: stdoutEncoding)); + {bool throwOnError = true, + String? workingDirectory, + Map? environment, + bool includeParentEnvironment = true, + bool? runInShell, + Encoding stdoutEncoding = systemEncoding, + Encoding stderrEncoding = systemEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool verbose = true, + // Default to true + bool? commandVerbose, + // Default to false + bool? commentVerbose, + ShellOptions? options}) { + var shell = shellContext.newShell( + options: options ?? + ShellOptions( + verbose: verbose, + stdin: stdin, + stdout: stdout, + stderr: stderr, + throwOnError: throwOnError, + workingDirectory: workingDirectory, + runInShell: runInShell, + commandVerbose: commandVerbose ?? verbose, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + commentVerbose: commentVerbose ?? false, + stderrEncoding: stderrEncoding, + stdoutEncoding: stdoutEncoding)); + return shell; + } /// Internal use only. @protected Shell.implWithOptions(ShellOptions options) : _options = options; + /// Shell options. + @override + ShellOptions get options => _options; + /// Create a new shell + @Deprecated('Use clone with options') Shell clone( {bool? throwOnError, String? workingDirectory, // Don't change environment @Deprecated('Don\'t change map') Map? environment, + + /// Explicetely set e new environment +// ShellEnvironment? shellEnvironment, @Deprecated('Don\'t change includeParentEnvironment') // Don't change includeParentEnvironment bool? includeParentEnvironment, @@ -182,21 +192,24 @@ class Shell { bool? verbose, bool? commandVerbose, bool? commentVerbose}) { + var localShellEnvironment = + // Compat + (environment is ShellEnvironment ? environment : null); return Shell( - options: _options.clone( - throwOnError: throwOnError, - workingDirectory: workingDirectory, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding, - stdin: stdin, - stderr: stderr, - stdout: stdout, - commentVerbose: commentVerbose, - commandVerbose: commandVerbose, - verbose: verbose, - shellEnvironment: - environment is ShellEnvironment ? environment : null)); + options: options.clone( + throwOnError: throwOnError, + workingDirectory: workingDirectory, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdin: stdin, + stderr: stderr, + stdout: stdout, + commentVerbose: commentVerbose, + commandVerbose: commandVerbose, + shellEnvironment: localShellEnvironment, + verbose: verbose, + )); } /// non null @@ -204,6 +217,7 @@ class Shell { _options.workingDirectory ?? Directory.current.path; /// Create new shell at the given path + @override Shell cd(String path) { if (isRelative(path)) { path = join(_workingDirectoryPath, path); @@ -212,17 +226,20 @@ class Shell { streamSinkWriteln(_options.stdout ?? stdout, '\$ cd $path', encoding: _options.stdoutEncoding); } - return clone(workingDirectory: path); + return cloneWithOptions(options.clone(workingDirectory: path)); } /// Get the shell path, using workingDirectory or current directory if null. + @override String get path => _workingDirectoryPath; /// Create a new shell at the given path, allowing popd on it + @override Shell pushd(String path) => cd(path).._parentShell = this; /// Pop the current directory to get the previous shell /// throw State error if nothing in the stack + @override Shell popd() { if (_parentShell == null) { throw StateError('no previous shell'); @@ -238,6 +255,7 @@ class Shell { /// Returns `true` if the signal is successfully delivered to the process. /// Otherwise the signal could not be sent, usually meaning, /// that the process is already dead. + @override bool kill([ProcessSignal signal = ProcessSignal.sigterm]) { // Picked the current 'timestamp' of the run killed _killedRunId = _runId; @@ -272,6 +290,7 @@ class Shell { /// /// [onProcess] is called for each started process. /// + @override Future> run(String script, {void Function(Process process)? onProcess}) { // devPrint('Running $script'); @@ -319,6 +338,7 @@ class Shell { /// Returns a process result (or throw if specified in the shell). /// /// [onProcess] is called for each started process. + @override Future runExecutableArguments( String executable, List arguments, {void Function(Process process)? onProcess}) async { @@ -379,8 +399,8 @@ class Shell { ..runInShell = _options.runInShell ..environment = _options.environment ..includeParentEnvironment = false - ..stderrEncoding = _options.stderrEncoding! - ..stdoutEncoding = _options.stdoutEncoding! + ..stderrEncoding = _options.stderrEncoding ?? io.systemEncoding + ..stdoutEncoding = _options.stdoutEncoding ?? io.systemEncoding ..workingDirectory = _options.workingDirectory; try { // devPrint(_options.environment.keys.where((element) => element.contains('TEKARTIK'))); diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index fad71b3..ff423f0 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:process_run/shell.dart'; import 'package:process_run/src/platform/platform.dart'; +import 'package:process_run/src/shell_context_common.dart'; import 'io/io_import.dart' show ProcessResult, Process, ProcessSignal; @@ -100,20 +101,17 @@ abstract class ShellCore { /// Pop the current directory to get the previous shell /// throw State error if nothing in the stack Shell popd(); -} -/* -/// Exception thrown in exitCode != 0 and throwOnError is true -class ShellException implements Exception { - final ProcessResult? result; - final String message; + /// override in local (default) or user settings, null means delete, + /// [local] defaults to true. + Future shellVarOverride(String name, String? value, {bool? local}); - ShellException(this.message, this.result); + /// Clone a new shell with the given options. + Shell cloneWithOptions(ShellOptions options); - @override - String toString() => 'ShellException($message)'; + /// Shell options. + ShellOptions get options; } -*/ /// Shell options. class ShellOptions { @@ -232,7 +230,8 @@ class ShellOptions { stdout: stdout ?? _stdout, stdoutEncoding: stdoutEncoding ?? _stdoutEncoding, throwOnError: throwOnError ?? _throwOnError, - workingDirectory: workingDirectory ?? _workingDirectory); + workingDirectory: workingDirectory ?? _workingDirectory, + environment: shellEnvironment); } } @@ -244,3 +243,38 @@ Future which(String command, environment: environment, includeParentEnvironment: includeParentEnvironment); } + +/// Default missing implementation. +mixin ShellMixin implements ShellCore { + // Set lazily after newShell; + late ShellContext shellContext; + + @override + Future shellVarOverride(String name, String? value, {bool? local}) { + throw UnimplementedError('shellVarOverride'); + } + + @override + Shell cloneWithOptions(ShellOptions options) { + var shell = shellContext.newShell(options: options); + return shell; + } + + Shell clone( + {bool? throwOnError, + String? workingDirectory, + Map? environment, + bool? includeParentEnvironment, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, + bool? commentVerbose}) { + // TODO: implement clone + throw UnimplementedError(); + } +} diff --git a/lib/src/shell_common_io.dart b/lib/src/shell_common_io.dart index 3e985f1..e716214 100644 --- a/lib/src/shell_common_io.dart +++ b/lib/src/shell_common_io.dart @@ -1,6 +1,7 @@ import 'dart:io' as io; import 'package:process_run/shell.dart' as io; +import 'package:process_run/src/io/env_var_set_io.dart'; import 'shell_common.dart'; @@ -35,10 +36,19 @@ Future _wrapIoException(Future Function() action) async { } */ -class ShellIo extends Shell { +class ShellIo extends Shell with ShellMixin { ShellIo({ required ShellOptions options, }) : super.implWithOptions(options); + + @override + Future shellVarOverride(String name, String? value, + {bool? local}) async { + var helper = + ShellEnvVarSetIoHelper(local: local ?? true, verbose: options.verbose); + var env = await helper.setValue(name, value); + return shellContext.newShell(options: options.clone(shellEnvironment: env)); + } } class ShellExceptionIo implements ShellException { diff --git a/lib/src/shell_context_common.dart b/lib/src/shell_context_common.dart index 42369a3..ca3e478 100644 --- a/lib/src/shell_context_common.dart +++ b/lib/src/shell_context_common.dart @@ -18,6 +18,8 @@ abstract class ShellContext { /// Default shell encoding (systemEncoding on iOS) Encoding get encoding; + /// New shell must set itself as a shell Context, shell environement is + /// no longer relevent. Shell newShell( {ShellOptions? options, @Deprecated('Use options') Map? environment, diff --git a/lib/src/shell_context_io.dart b/lib/src/shell_context_io.dart index 7e4c347..0ffebd5 100644 --- a/lib/src/shell_context_io.dart +++ b/lib/src/shell_context_io.dart @@ -38,6 +38,7 @@ class ShellContextIo implements ShellContext { Map? environment, bool includeParentEnvironment = true}) { var ioShell = ShellIo(options: options ?? ShellOptions()); + ioShell.shellContext = this; return ioShell; } } diff --git a/pubspec.yaml b/pubspec.yaml index 4c367c3..eef3b76 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ description: Process run helpers for Linux/Win/Mac and which like feature for fi homepage: https://github.com/tekartik/process_run.dart environment: - sdk: '>=2.14.0 <3.0.0' + sdk: '>=2.18.0 <3.0.0' dependencies: path: '>=1.8.0 <3.0.0' diff --git a/test/dartbin_test.dart b/test/dartbin_test.dart index 8adc4ae..93eeb21 100644 --- a/test/dartbin_test.dart +++ b/test/dartbin_test.dart @@ -20,16 +20,18 @@ import 'package:test/test.dart'; void main() => defineTests(); void testDartVersionOutput(ProcessResult result) { + var errText = result.errText; if (dartVersion >= Version(2, 15, 0, pre: '0')) { + var outText = result.outText; // New output is on stdout - expect(result.outText.toLowerCase(), contains('dart')); - expect(result.outText.toString().toLowerCase(), contains('version')); - expect(result.outText, contains(Platform.version)); + expect(outText.toLowerCase(), contains('dart')); + expect(outText.toString().toLowerCase(), contains('version')); + expect(outText, contains(Platform.version)); } else { // Before it was on stderr - expect(result.errText.toLowerCase(), contains('dart')); - expect(result.errText.toLowerCase(), contains('version')); - expect(result.errText, contains(Platform.version)); + expect(errText.toLowerCase(), contains('dart')); + expect(errText.toLowerCase(), contains('version')); + expect(errText, contains(Platform.version)); } } diff --git a/test/shell_common_test.dart b/test/shell_common_test.dart index bdb8b87..6c712aa 100644 --- a/test/shell_common_test.dart +++ b/test/shell_common_test.dart @@ -98,7 +98,7 @@ class ProcessMock implements Process { Stream> get stdout => throw UnimplementedError(); } -class ShellMock implements Shell { +class ShellMock with ShellMixin implements Shell { var scripts = []; @override @@ -151,23 +151,8 @@ class ShellMock implements Shell { } @override - Shell clone( - {bool? throwOnError, - String? workingDirectory, - Map? environment, - bool? includeParentEnvironment, - bool? runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose, - bool? commentVerbose}) { - // TODO: implement clone - throw UnimplementedError(); - } + // TODO: implement options + ShellOptions get options => throw UnimplementedError(); } void main() { diff --git a/test/shell_run_test.dart b/test/shell_run_test.dart index d318aca..cbb83a7 100644 --- a/test/shell_run_test.dart +++ b/test/shell_run_test.dart @@ -89,6 +89,7 @@ void main() { fail('should fail'); } on ShellException catch (e) { // ShellException(dummy_command_BfwXVcrONHT3QIiMzNoS, error: ProcessException: No such file or directory) + // ignore: dead_code if (verbose) { print(e); } @@ -102,6 +103,7 @@ void main() { fail('should fail'); } on ShellException catch (e) { // ShellException(dart run ./example/echo.dart --exit-code 1, exitCode 1) + // ignore: dead_code if (verbose) { print(e); } diff --git a/test/shell_test.dart b/test/shell_test.dart index 24675eb..e69bcff 100644 --- a/test/shell_test.dart +++ b/test/shell_test.dart @@ -176,10 +176,11 @@ dart example/echo.dart -o ${shellArgument(weirdText)} try { await () async { var shell = Shell().cd('example'); + await shell.run('dart run echo.dart --version'); late Future future; try { future = shell.run('dart run echo.dart --wait 30000'); - await future.timeout(const Duration(milliseconds: 15000)); + await future.timeout(const Duration(milliseconds: 2500)); fail('should fail'); } on TimeoutException catch (_) { // 1: TimeoutException after 0:00:02.000000: Future not completed @@ -582,4 +583,22 @@ _tekartik_dummy_app_that_does_not_exits ['\$ dart example/echo.dart -o 你好é', '你好é']); } }); + + test('var set/get/delete', () async { + var keyName = 'TEST_VALUE_SHELL_VAR_OVERRIDE'; + var shell = Shell(); + shell = await shell.shellVarOverride(keyName, 'dummy1'); + expect(shell.options.environment.vars[keyName], 'dummy1'); + //await safeShell.run('ds env var set TEST_VALUE dummy1'); + var text = (await Shell().run('ds env var get $keyName')).outText; + expect(text, contains('dummy1')); + //await Shell().run('ds env var delete TEST_VALUE'); + shell = await shell.shellVarOverride(keyName, null); + expect(shell.options.environment.vars.containsKey(keyName), isFalse); + text = (await Shell().run('ds env var get $keyName')).outText; + expect(text, isNot(contains('dummy1'))); + }); + test('dump', () async { + await Shell().run('ds env var dump'); + }); } From e8d8af20c760df3ac6cb182cdedc94eac8220a74 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 14 Nov 2022 12:18:22 +0100 Subject: [PATCH 030/150] fix: Shell.shellVarOverride --- lib/src/bin/shell/env_var_delete.dart | 5 +++-- lib/src/bin/shell/env_var_set.dart | 5 +++-- lib/src/io/env_io.dart | 9 +++++--- lib/src/io/env_var_delete_io.dart | 12 ++++++++--- lib/src/io/env_var_set_io.dart | 12 +++++------ lib/src/shell_common.dart | 6 +++++- lib/src/shell_common_io.dart | 6 +++--- lib/src/shell_context_io.dart | 2 +- test/shell_test.dart | 31 +++++++++++++++++++++++---- 9 files changed, 63 insertions(+), 25 deletions(-) diff --git a/lib/src/bin/shell/env_var_delete.dart b/lib/src/bin/shell/env_var_delete.dart index 7ecb0c3..44e61b7 100644 --- a/lib/src/bin/shell/env_var_delete.dart +++ b/lib/src/bin/shell/env_var_delete.dart @@ -1,12 +1,13 @@ import 'dart:io'; +import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_var_delete_io.dart'; class ShellEnvVarDeleteCommand extends ShellEnvCommandBase { - late final helper = - ShellEnvVarDeleteIoHelper(local: local, verbose: verbose ?? false); + late final helper = ShellEnvVarDeleteIoHelper( + shell: Shell(), local: local, verbose: verbose ?? false); ShellEnvVarDeleteCommand() : super( diff --git a/lib/src/bin/shell/env_var_set.dart b/lib/src/bin/shell/env_var_set.dart index 9777e62..62acb06 100644 --- a/lib/src/bin/shell/env_var_set.dart +++ b/lib/src/bin/shell/env_var_set.dart @@ -1,12 +1,13 @@ import 'dart:io'; +import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_var_set_io.dart'; class ShellEnvVarSetCommand extends ShellEnvCommandBase { - late final helper = - ShellEnvVarSetIoHelper(local: local, verbose: verbose ?? false); + late final helper = ShellEnvVarSetIoHelper( + shell: Shell(), local: local, verbose: verbose ?? false); ShellEnvVarSetCommand() : super( diff --git a/lib/src/io/env_io.dart b/lib/src/io/env_io.dart index f628c64..db3ce27 100644 --- a/lib/src/io/env_io.dart +++ b/lib/src/io/env_io.dart @@ -1,13 +1,16 @@ import 'dart:convert'; +import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env_file_content.dart'; import 'package:process_run/src/user_config.dart'; class ShellEnvIoHelper { + final Shell shell; final bool local; final bool verbose; - ShellEnvIoHelper({required this.local, required this.verbose}); + ShellEnvIoHelper( + {required this.shell, required this.local, required this.verbose}); String get label => local ? 'local' : 'user'; @@ -25,8 +28,8 @@ class ShellEnvIoHelper { String? get envFilePath => _envFilePath; String? get _envFilePath => local - ? getLocalEnvFilePath(userEnvironment) - : getUserEnvFilePath(userEnvironment); + ? getLocalEnvFilePath(shell.options.environment) + : getUserEnvFilePath(shell.options.environment); List? _sampleFileContent; diff --git a/lib/src/io/env_var_delete_io.dart b/lib/src/io/env_var_delete_io.dart index fd3eb75..92c87b7 100644 --- a/lib/src/io/env_var_delete_io.dart +++ b/lib/src/io/env_var_delete_io.dart @@ -6,7 +6,8 @@ import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_io.dart'; class ShellEnvVarDeleteIoHelper extends ShellEnvIoHelper { - ShellEnvVarDeleteIoHelper({required super.local, required super.verbose}); + ShellEnvVarDeleteIoHelper( + {required super.shell, required super.local, required super.verbose}); Future deleteMulti(List keys) async { var fileContent = await envFileReadOrCreate(); @@ -21,11 +22,16 @@ class ShellEnvVarDeleteIoHelper extends ShellEnvIoHelper { await fileContent.write(); } - // Force reload - shellEnvironment = null; if (verbose) { stdout.writeln('After: ${jsonEncode(ShellEnvironment().vars)}'); } + + // Convenient fix, although it could be wrong... + var newShellEnvironment = shell.context.newShellEnvironment( + environment: Map.from(shell.options.environment)); + + newShellEnvironment.vars.removeWhere((name, _) => keys.contains(name)); + return ShellEnvironment(); } } diff --git a/lib/src/io/env_var_set_io.dart b/lib/src/io/env_var_set_io.dart index c73532a..9f0f4ed 100644 --- a/lib/src/io/env_var_set_io.dart +++ b/lib/src/io/env_var_set_io.dart @@ -5,12 +5,12 @@ import 'package:process_run/shell.dart'; import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_io.dart'; - -import '../platform/platform.dart'; +import 'package:process_run/src/shell_common.dart'; class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { /// Local should be true by default - ShellEnvVarSetIoHelper({required super.local, super.verbose = true}); + ShellEnvVarSetIoHelper( + {required super.shell, required super.local, super.verbose = true}); Future setValue(String name, String? value) async { if (verbose) { @@ -34,9 +34,9 @@ class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { if (local && name == localEnvFilePathEnvKey) { stderr.writeln('$name cannot be set in local file'); } - // Force reload - var newShellEnvironment = shellContext.newShellEnvironment( - environment: Map.from(shellEnvironment)); + // reload + var newShellEnvironment = shell.context.newShellEnvironment( + environment: Map.from(shell.options.environment)); if (value == null) { newShellEnvironment.vars.remove(name); } else { diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index ff423f0..15ab9ed 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -111,6 +111,9 @@ abstract class ShellCore { /// Shell options. ShellOptions get options; + + /// Shell context. + ShellContext get context; } /// Shell options. @@ -247,7 +250,8 @@ Future which(String command, /// Default missing implementation. mixin ShellMixin implements ShellCore { // Set lazily after newShell; - late ShellContext shellContext; + @override + late ShellContext context; @override Future shellVarOverride(String name, String? value, {bool? local}) { diff --git a/lib/src/shell_common_io.dart b/lib/src/shell_common_io.dart index e716214..a207bb3 100644 --- a/lib/src/shell_common_io.dart +++ b/lib/src/shell_common_io.dart @@ -44,10 +44,10 @@ class ShellIo extends Shell with ShellMixin { @override Future shellVarOverride(String name, String? value, {bool? local}) async { - var helper = - ShellEnvVarSetIoHelper(local: local ?? true, verbose: options.verbose); + var helper = ShellEnvVarSetIoHelper( + shell: this, local: local ?? true, verbose: options.verbose); var env = await helper.setValue(name, value); - return shellContext.newShell(options: options.clone(shellEnvironment: env)); + return context.newShell(options: options.clone(shellEnvironment: env)); } } diff --git a/lib/src/shell_context_io.dart b/lib/src/shell_context_io.dart index 0ffebd5..1727786 100644 --- a/lib/src/shell_context_io.dart +++ b/lib/src/shell_context_io.dart @@ -38,7 +38,7 @@ class ShellContextIo implements ShellContext { Map? environment, bool includeParentEnvironment = true}) { var ioShell = ShellIo(options: options ?? ShellOptions()); - ioShell.shellContext = this; + ioShell.context = this; return ioShell; } } diff --git a/test/shell_test.dart b/test/shell_test.dart index e69bcff..d98ae31 100644 --- a/test/shell_test.dart +++ b/test/shell_test.dart @@ -585,17 +585,40 @@ _tekartik_dummy_app_that_does_not_exits }); test('var set/get/delete', () async { - var keyName = 'TEST_VALUE_SHELL_VAR_OVERRIDE'; - var shell = Shell(); + var localFile = '.dart_tool/process_run/test/local1.yaml'; + var userFile = '.dart_tool/process_run/test/user1.yaml'; + var safeShellEnvironment = ShellEnvironment() + ..aliases['ds'] = 'dart run bin/shell.dart' + ..vars[userEnvFilePathEnvKey] = userFile + ..vars[localEnvFilePathEnvKey] = localFile; + + var shell = Shell(environment: safeShellEnvironment, verbose: false); + var keyName = 'TEST_VALUE'; + var userKeyName = 'USER_TEST_VALUE'; + + try { + await File(localFile).delete(); + } catch (_) {} + try { + await File(userFile).delete(); + } catch (_) {} + expect(File(localFile).existsSync(), isFalse); shell = await shell.shellVarOverride(keyName, 'dummy1'); expect(shell.options.environment.vars[keyName], 'dummy1'); + expect(File(localFile).existsSync(), isTrue); + expect(File(userFile).existsSync(), isFalse); + shell = await shell.shellVarOverride(userKeyName, 'dummy2', local: false); + expect(File(userFile).existsSync(), isTrue); + expect(shell.options.environment.vars[keyName], 'dummy1'); + expect(shell.options.environment.vars[userKeyName], 'dummy2'); + //await safeShell.run('ds env var set TEST_VALUE dummy1'); - var text = (await Shell().run('ds env var get $keyName')).outText; + var text = (await shell.run('ds env var get $keyName')).outText; expect(text, contains('dummy1')); //await Shell().run('ds env var delete TEST_VALUE'); shell = await shell.shellVarOverride(keyName, null); expect(shell.options.environment.vars.containsKey(keyName), isFalse); - text = (await Shell().run('ds env var get $keyName')).outText; + text = (await shell.run('ds env var get $keyName')).outText; expect(text, isNot(contains('dummy1'))); }); test('dump', () async { From 12963060bfb37607f177b604456b51f673260309 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 14 Nov 2022 12:34:34 +0100 Subject: [PATCH 031/150] fix: Shell.shellVarOverride environment --- lib/src/io/env_var_delete_io.dart | 2 +- lib/src/io/env_var_set_io.dart | 2 +- test/shell_test.dart | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/src/io/env_var_delete_io.dart b/lib/src/io/env_var_delete_io.dart index 92c87b7..a278251 100644 --- a/lib/src/io/env_var_delete_io.dart +++ b/lib/src/io/env_var_delete_io.dart @@ -28,7 +28,7 @@ class ShellEnvVarDeleteIoHelper extends ShellEnvIoHelper { // Convenient fix, although it could be wrong... var newShellEnvironment = shell.context.newShellEnvironment( - environment: Map.from(shell.options.environment)); + environment: ShellEnvironment(environment: shell.options.environment)); newShellEnvironment.vars.removeWhere((name, _) => keys.contains(name)); diff --git a/lib/src/io/env_var_set_io.dart b/lib/src/io/env_var_set_io.dart index 9f0f4ed..cd20ff7 100644 --- a/lib/src/io/env_var_set_io.dart +++ b/lib/src/io/env_var_set_io.dart @@ -36,7 +36,7 @@ class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { } // reload var newShellEnvironment = shell.context.newShellEnvironment( - environment: Map.from(shell.options.environment)); + environment: ShellEnvironment(environment: shell.options.environment)); if (value == null) { newShellEnvironment.vars.remove(name); } else { diff --git a/test/shell_test.dart b/test/shell_test.dart index d98ae31..7d92201 100644 --- a/test/shell_test.dart +++ b/test/shell_test.dart @@ -587,12 +587,14 @@ _tekartik_dummy_app_that_does_not_exits test('var set/get/delete', () async { var localFile = '.dart_tool/process_run/test/local1.yaml'; var userFile = '.dart_tool/process_run/test/user1.yaml'; + var dsCommand = 'dart run bin/shell.dart'; var safeShellEnvironment = ShellEnvironment() - ..aliases['ds'] = 'dart run bin/shell.dart' + ..aliases['ds'] = dsCommand ..vars[userEnvFilePathEnvKey] = userFile ..vars[localEnvFilePathEnvKey] = localFile; - var shell = Shell(environment: safeShellEnvironment, verbose: false); + var shell = Shell(environment: safeShellEnvironment, verbose: true); + expect(shell.options.environment.aliases['ds'], dsCommand); var keyName = 'TEST_VALUE'; var userKeyName = 'USER_TEST_VALUE'; @@ -604,6 +606,7 @@ _tekartik_dummy_app_that_does_not_exits } catch (_) {} expect(File(localFile).existsSync(), isFalse); shell = await shell.shellVarOverride(keyName, 'dummy1'); + expect(shell.options.environment.aliases['ds'], dsCommand); expect(shell.options.environment.vars[keyName], 'dummy1'); expect(File(localFile).existsSync(), isTrue); expect(File(userFile).existsSync(), isFalse); @@ -620,6 +623,7 @@ _tekartik_dummy_app_that_does_not_exits expect(shell.options.environment.vars.containsKey(keyName), isFalse); text = (await shell.run('ds env var get $keyName')).outText; expect(text, isNot(contains('dummy1'))); + expect(shell.options.environment.aliases['ds'], dsCommand); }); test('dump', () async { await Shell().run('ds env var dump'); From 06d2b3b4112e78744280aa856acd1f0e2685c0f1 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 14 Nov 2022 13:11:18 +0100 Subject: [PATCH 032/150] fix: test --- test/shell_test.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/shell_test.dart b/test/shell_test.dart index 7d92201..5c0f2b1 100644 --- a/test/shell_test.dart +++ b/test/shell_test.dart @@ -23,6 +23,7 @@ bool debug = false; // To set in both variable for a full empty environment var dummyEnvPath = join('test', 'data', 'test_env.yaml_dummy'); + ShellEnvironment newEnvNoOverride() => ShellEnvironment(environment: { userEnvFilePathEnvKey: dummyEnvPath, @@ -625,7 +626,4 @@ _tekartik_dummy_app_that_does_not_exits expect(text, isNot(contains('dummy1'))); expect(shell.options.environment.aliases['ds'], dsCommand); }); - test('dump', () async { - await Shell().run('ds env var dump'); - }); } From d6e24fb72ab2e87a1e2ae2ecc17ff712f5e5baeb Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 5 Dec 2022 12:08:09 +0100 Subject: [PATCH 033/150] feat: more test around ShellLinesController --- example/streamer.dart | 115 ++++++++++++++++++++++++++ test/process_run_test_common.dart | 1 + test/shell_lines_controller_test.dart | 49 +++++++++++ 3 files changed, 165 insertions(+) create mode 100755 example/streamer.dart create mode 100644 test/shell_lines_controller_test.dart diff --git a/example/streamer.dart b/example/streamer.dart new file mode 100755 index 0000000..d5f0f66 --- /dev/null +++ b/example/streamer.dart @@ -0,0 +1,115 @@ +#!/usr/bin/env dart + +import 'dart:async'; +import 'dart:io'; + +// ignore: import_of_legacy_library_into_null_safe +import 'package:args/args.dart'; +import 'package:path/path.dart'; +import 'package:process_run/shell.dart'; +import 'package:process_run/src/common/import.dart'; + +// ignore: import_of_legacy_library_into_null_safe +import 'package:pub_semver/pub_semver.dart'; + +import 'shell/common.dart'; + +var echoEnv = ShellEnvironment()..aliases.addAll(commonAliases); + +Version version = Version(0, 1, 0); + +String get currentScriptName => basenameWithoutExtension(Platform.script.path); + +/* +Global options: +-h, --help Usage help +-d, --udelay delay in microseconds +-c, --count count of print +-t, --timeout timeout in millis + --version Print the command version +*/ + +const udelayOption = 'udelay'; + +/// +/// write rest arguments as lines +/// +Future main(List arguments) async { + //setupQuickLogging(); + + final parser = ArgParser(allowTrailingOptions: false); + parser.addFlag('help', abbr: 'h', help: 'Usage help', negatable: false); + // parser.addFlag('verbose', abbr: 'v', help: 'Verbose', negatable: false); + parser.addOption(udelayOption, + abbr: 'd', help: 'delay in microseconds', defaultsTo: null); + parser.addOption('count', + abbr: 'c', help: 'count of print', defaultsTo: null); + parser.addOption('timeout', + abbr: 't', help: 'timeout in millis', defaultsTo: null); + parser.addFlag('version', + help: 'Print the command version', negatable: false); + + final argsResult = parser.parse(arguments); + + int? parseInt(dynamic value) { + return int.tryParse(value?.toString() ?? ''); + } + + final help = argsResult['help'] as bool; + final count = parseInt(argsResult['count']); + final delay = parseInt(argsResult[udelayOption]); + final timeout = parseInt(argsResult['timeout']); + + void printUsage() { + stdout.writeln('Streamer utility'); + stdout.writeln(); + stdout.writeln('Usage: $currentScriptName []'); + stdout.writeln(); + stdout.writeln('Example: $currentScriptName -c 100'); + stdout.writeln('will display 100 lines of logs [1], [2]...[100]'); + stdout.writeln(); + stdout.writeln('Global options:'); + stdout.writeln(parser.usage); + } + + if (help) { + printUsage(); + return; + } + + final displayVersion = argsResult['version'] as bool; + + if (displayVersion) { + stdout.write('$currentScriptName version $version'); + stdout.writeln('VM: ${Platform.resolvedExecutable} ${Platform.version}'); + return; + } + + var index = 0; + Future doPrint() async { + if (delay != null) { + await Future.delayed(Duration(microseconds: delay)); + } + index++; + print('[$index]'); + } + + Future doCount(int count) async { + var localCount = count; + while (localCount-- > 0) { + await doPrint(); + } + } + + if (count != null) { + await doCount(count); + } else if (timeout != null) { + var sw = Stopwatch()..start(); + + while (sw.elapsed < Duration(milliseconds: timeout)) { + await doPrint(); + } + } else { + await doCount(10); + } +} diff --git a/test/process_run_test_common.dart b/test/process_run_test_common.dart index 5aa954c..266e092 100644 --- a/test/process_run_test_common.dart +++ b/test/process_run_test_common.dart @@ -11,6 +11,7 @@ String get projectTop => '.'; String get testDir => join('.dart_tool', 'process_run', 'test'); String get echoScriptPath => join(projectTop, 'example', 'echo.dart'); +String get streamerScriptPath => join(projectTop, 'example', 'streamer.dart'); // does not exists String get dummyExecutable => join(dirname(testDir), 'example', 'dummy'); diff --git a/test/shell_lines_controller_test.dart b/test/shell_lines_controller_test.dart new file mode 100644 index 0000000..4531253 --- /dev/null +++ b/test/shell_lines_controller_test.dart @@ -0,0 +1,49 @@ +@TestOn('vm') +library process_run.test.shell_test; + +import 'package:process_run/shell.dart'; +import 'package:process_run/src/common/import.dart'; +import 'package:test/test.dart'; + +import 'process_run_test_common.dart'; + +void main() { + group('ShellLinesController', () { + late ShellEnvironment env; + setUpAll(() { + env = ShellEnvironment() + ..aliases['streamer'] = 'dart run ${shellArgument(streamerScriptPath)}'; + }); + test('stream all', () async { + var ctlr = ShellLinesController(); + var lines = []; + ctlr.stream.listen((event) { + lines.add(event); + }); + var shell = Shell(environment: env, stdout: ctlr.sink, verbose: false); + await shell.run('streamer --count 10000'); + expect(lines, hasLength(10000)); + ctlr.close(); + }); + test('stream some', () async { + var ctlr = ShellLinesController(); + var lines = []; + var shell = Shell(environment: env, stdout: ctlr.sink, verbose: false); + late StreamSubscription subscription; + subscription = ctlr.stream.listen((event) { + lines.add(event); + if (lines.length >= 10000) { + shell.kill(); + subscription.cancel(); + } + }); + + // Wait more than 30s + try { + await shell.run('streamer --timeout 60000'); + } catch (e) { + // Should fail + } + }, timeout: const Timeout(Duration(milliseconds: 30000))); + }); +} From 9b087513eddbc89d8a1b9663ee49cf43a6f89618 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 5 Dec 2022 12:15:49 +0100 Subject: [PATCH 034/150] fix: remove unused stream example code --- example/streamer.dart | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/example/streamer.dart b/example/streamer.dart index d5f0f66..6869c8c 100755 --- a/example/streamer.dart +++ b/example/streamer.dart @@ -6,16 +6,11 @@ import 'dart:io'; // ignore: import_of_legacy_library_into_null_safe import 'package:args/args.dart'; import 'package:path/path.dart'; -import 'package:process_run/shell.dart'; import 'package:process_run/src/common/import.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; -import 'shell/common.dart'; - -var echoEnv = ShellEnvironment()..aliases.addAll(commonAliases); - Version version = Version(0, 1, 0); String get currentScriptName => basenameWithoutExtension(Platform.script.path); @@ -32,7 +27,8 @@ Global options: const udelayOption = 'udelay'; /// -/// write rest arguments as lines +/// Stream lines to stdout, according to count (count of lines), delay (delay +/// between 2 lines) and/or timeout (stop after timeout) /// Future main(List arguments) async { //setupQuickLogging(); From 244e737cec7ffb2ebf9e00f1d4d9426c7debea75 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 11 Jan 2023 11:45:15 +0100 Subject: [PATCH 035/150] [process_run] v0.12.4 --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fc1d11..711d834 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.12.4 + +* requires dart sdk 2.18 + ## 0.12.3+2 * Cache shellEnvironment when set diff --git a/pubspec.yaml b/pubspec.yaml index eef3b76..1d521c0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.12.3+2 +version: 0.12.4 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart From 0ac71a097fcf7766a75ea5e63c83db3fb4aa9f58 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 11 Jan 2023 15:29:28 +0100 Subject: [PATCH 036/150] [process_run] strict-casts support --- analysis_options.yaml | 6 +++--- example/echo.dart | 2 +- example/streamer.dart | 2 +- lib/src/process_cmd.dart | 4 ++-- lib/src/shell.dart | 4 ++-- lib/src/shell_environment_common.dart | 16 ++++++++-------- lib/src/user_config.dart | 2 +- test/echo_test.dart | 6 +++--- test/process_run_test.dart | 6 +++--- test/process_run_test_common.dart | 4 ++-- test/shell_environment_test.dart | 7 +++++-- test/shell_test.dart | 10 +++++----- test/src_shell_utils_test.dart | 4 ++-- test/src_user_config_test.dart | 6 +++--- 14 files changed, 41 insertions(+), 38 deletions(-) diff --git a/analysis_options.yaml b/analysis_options.yaml index 8821318..279d957 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -10,9 +10,9 @@ include: package:lints/recommended.yaml # See the configuration guide for more # https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer analyzer: - # Strong mode is sometimes harder to keep - strong-mode: - implicit-casts: false + language: + strict-casts: true + strict-inference: true errors: # treat missing required parameters as a warning (not a hint) missing_required_param: warning diff --git a/example/echo.dart b/example/echo.dart index 3af96c6..3a54c44 100755 --- a/example/echo.dart +++ b/example/echo.dart @@ -76,7 +76,7 @@ Future main(List arguments) async { final writeLine = argsResult['write-line'] as bool?; if (wait != null) { - await Future.delayed(Duration(milliseconds: wait)); + await Future.delayed(Duration(milliseconds: wait)); } void printUsage() { diff --git a/example/streamer.dart b/example/streamer.dart index 6869c8c..07d7598 100755 --- a/example/streamer.dart +++ b/example/streamer.dart @@ -84,7 +84,7 @@ Future main(List arguments) async { var index = 0; Future doPrint() async { if (delay != null) { - await Future.delayed(Duration(microseconds: delay)); + await Future.delayed(Duration(microseconds: delay)); } index++; print('[$index]'); diff --git a/lib/src/process_cmd.dart b/lib/src/process_cmd.dart index 64edb2e..cdc1e99 100644 --- a/lib/src/process_cmd.dart +++ b/lib/src/process_cmd.dart @@ -39,7 +39,7 @@ class ProcessCmd { bool operator ==(Object other) { if (other is ProcessCmd) { return (other.executable == executable && - const ListEquality().equals(other.arguments, arguments)); + const ListEquality().equals(other.arguments, arguments)); } return false; } @@ -76,7 +76,7 @@ ProcessCmd processCmd(String executable, List arguments, stderrEncoding: stderrEncoding); } -bool _isNotEmpty(stdout) { +bool _isNotEmpty(Object? stdout) { if (stdout is List) { return stdout.isNotEmpty; } else if (stdout is String) { diff --git a/lib/src/shell.dart b/lib/src/shell.dart index 2e85c59..09bcfca 100644 --- a/lib/src/shell.dart +++ b/lib/src/shell.dart @@ -478,12 +478,12 @@ abstract class Shell implements ShellCore { if (!completer.isCompleted) { completer.complete(value); } - }).catchError((e) { + }).catchError((Object e) { if (shellDebug) { print('$runId: error $e'); } if (!completer.isCompleted) { - completer.completeError(e as Object); + completer.completeError(e); } }); return completer.future; diff --git a/lib/src/shell_environment_common.dart b/lib/src/shell_environment_common.dart index 855de45..2d9191f 100644 --- a/lib/src/shell_environment_common.dart +++ b/lib/src/shell_environment_common.dart @@ -75,12 +75,12 @@ class ShellEnvironmentPaths with ListMixin { } @override - int get hashCode => const ListEquality().hash(this); + int get hashCode => const ListEquality().hash(this); @override bool operator ==(Object other) { if (other is ShellEnvironmentPaths) { - return const ListEquality().equals(this, other); + return const ListEquality().equals(this, other); } return false; } @@ -130,12 +130,12 @@ class ShellEnvironmentAliases with MapMixin { // Key hash is sufficient here @override - int get hashCode => const ListEquality().hash(keys.toList()); + int get hashCode => const ListEquality().hash(keys.toList()); @override bool operator ==(Object other) { if (other is ShellEnvironmentVars) { - return const MapEquality().equals(this, other); + return const MapEquality().equals(this, other); } return false; } @@ -151,7 +151,7 @@ class ShellEnvironmentVars with MapMixin { ShellEnvironmentVars._(this._environment); /// Currently only the PATH key is ignored. - bool _ignoreKey(key) => key == envPathKey; + bool _ignoreKey(Object? key) => key == envPathKey; @override String? operator [](Object? key) { @@ -192,12 +192,12 @@ class ShellEnvironmentVars with MapMixin { // Key hash is sufficient here @override - int get hashCode => const ListEquality().hash(keys.toList()); + int get hashCode => const ListEquality().hash(keys.toList()); @override bool operator ==(Object other) { if (other is ShellEnvironmentVars) { - return const MapEquality().equals(this, other); + return const MapEquality().equals(this, other); } return false; } @@ -320,7 +320,7 @@ abstract class ShellEnvironmentBase } @override - int get hashCode => const ListEquality().hash(paths); + int get hashCode => const ListEquality().hash(paths); @override bool operator ==(Object other) { diff --git a/lib/src/user_config.dart b/lib/src/user_config.dart index 8781751..2ef1b59 100644 --- a/lib/src/user_config.dart +++ b/lib/src/user_config.dart @@ -291,7 +291,7 @@ void userLoadEnvFileConfig(EnvFileConfig envFileConfig) { var vars = Map.from(config.vars); var added = envFileConfig; // devPrint('adding config: $config'); - if (const ListEquality().equals( + if (const ListEquality().equals( paths.sublist(0, min(added.paths.length, paths.length)), added.paths)) { // don't add if already in same order at the beginning } else { diff --git a/test/echo_test.dart b/test/echo_test.dart index a242295..20325a2 100644 --- a/test/echo_test.dart +++ b/test/echo_test.dart @@ -16,7 +16,7 @@ var echo = '$resolvedDartExecutable run example/echo.dart'; void main() { group('echo', () { Future runCheck( - Function(ProcessResult result) check, + Object? Function(ProcessResult result) check, String executable, List arguments, { String? workingDirectory, @@ -79,7 +79,7 @@ void main() { void checkEmpty(ProcessResult result) { expect(result.stderr, ''); - expect(result.stdout, []); + expect(result.stdout, []); expect(result.pid, isNotNull); expect(result.exitCode, 0); } @@ -159,7 +159,7 @@ void main() { void checkEmpty(ProcessResult result) { expect(result.stdout, ''); - expect(result.stderr, []); + expect(result.stderr, []); expect(result.pid, isNotNull); expect(result.exitCode, 0); } diff --git a/test/process_run_test.dart b/test/process_run_test.dart index 10f37eb..c824a28 100644 --- a/test/process_run_test.dart +++ b/test/process_run_test.dart @@ -52,7 +52,7 @@ void main() { group('run', () { Future runCheck( - Function(ProcessResult result) check, + Object? Function(ProcessResult result) check, String executable, List arguments, { String? workingDirectory, @@ -115,7 +115,7 @@ void main() { void checkEmpty(ProcessResult result) { expect(result.stderr, ''); - expect(result.stdout, []); + expect(result.stdout, []); expect(result.pid, isNotNull); expect(result.exitCode, 0); } @@ -173,7 +173,7 @@ void main() { void checkEmpty(ProcessResult result) { expect(result.stdout, ''); - expect(result.stderr, []); + expect(result.stderr, []); expect(result.pid, isNotNull); expect(result.exitCode, 0); } diff --git a/test/process_run_test_common.dart b/test/process_run_test_common.dart index 266e092..cecac93 100644 --- a/test/process_run_test_common.dart +++ b/test/process_run_test_common.dart @@ -41,7 +41,7 @@ class TestSink implements StreamSink { /// /// If [onDone] is passed, it's called when the user calls [close]. Its result /// is piped to the [done] future. - TestSink({Function()? onDone}) : _onDone = onDone ?? (() {}); + TestSink({Object? Function()? onDone}) : _onDone = onDone ?? (() {}); @override void add(T event) { @@ -55,7 +55,7 @@ class TestSink implements StreamSink { @override Future addStream(Stream stream) { - var completer = Completer.sync(); + var completer = Completer.sync(); stream.listen(add, onError: addError, onDone: completer.complete); return completer.future; } diff --git a/test/shell_environment_test.dart b/test/shell_environment_test.dart index 547d0d5..74f0740 100644 --- a/test/shell_environment_test.dart +++ b/test/shell_environment_test.dart @@ -237,8 +237,11 @@ void main() { expect(ShellEnvironment.empty(), ShellEnvironment.empty()); }); test('toJson', () async { - expect(ShellEnvironment.empty().toJson(), - {'paths': [], 'vars': {}, 'aliases': {}}); + expect(ShellEnvironment.empty().toJson(), { + 'paths': [], + 'vars': {}, + 'aliases': {} + }); expect(basicEnv.toJson(), { 'paths': ['path1'], 'vars': {'VAR1': 'var1'}, diff --git a/test/shell_test.dart b/test/shell_test.dart index 5c0f2b1..2570743 100644 --- a/test/shell_test.dart +++ b/test/shell_test.dart @@ -121,10 +121,10 @@ dart example/echo.dart -o 你好 'dart example/echo.dart --stdout-hex ${bytesToHex(utf8.encode('Hello\nWorld'))}'); expect(results.outLines, ['Hello', 'World']); expect(results[0].outLines, ['Hello', 'World']); - expect(results.errLines, []); + expect(results.errLines, isEmpty); results = await shell.run('dart example/echo.dart -e Hello'); - expect(results.outLines, []); + expect(results.outLines, isEmpty); expect(results.errLines, ['Hello']); results = await shell.run(''' @@ -226,7 +226,7 @@ dart example/echo.dart -o ${shellArgument(weirdText)} try { var future = shell.run('dart echo.dart --wait 10000'); - await Future.delayed(const Duration(milliseconds: 3000)); + await Future.delayed(const Duration(milliseconds: 3000)); shell.kill(); await future.timeout(const Duration(milliseconds: 8000)); fail('should fail'); @@ -300,7 +300,7 @@ dart example/echo.dart -o ${shellArgument(weirdText)} init(); subscription?.pause(); await shell.run('dart echo.dart some_text'); - expect(lines, []); + expect(lines, isEmpty); init(); @@ -321,7 +321,7 @@ dart example/echo.dart -o ${shellArgument(weirdText)} }); }); expect(count, 2); - expect(lines, []); + expect(lines, isEmpty); lines.clear(); subscription!.resume(); await shell.run(''' diff --git a/test/src_shell_utils_test.dart b/test/src_shell_utils_test.dart index 2e8b4fe..c291dc0 100644 --- a/test/src_shell_utils_test.dart +++ b/test/src_shell_utils_test.dart @@ -12,7 +12,7 @@ import 'package:test/test.dart'; void main() { group('shell_utils', () { test('scriptToCommands', () { - expect(scriptToCommands(''), []); + expect(scriptToCommands(''), isEmpty); // expect(scriptToCommands('\\'), ['\\']); expect(scriptToCommands(' e\n#\n # comment\nf \n '), ['e', '#', '# comment', 'f']); @@ -49,7 +49,7 @@ void main() { 'DART_VM_OPTIONS': '--pause-isolates-on-start --enable-vm-service:51156' }; env = environmentFilterOutVmOptions(env); - expect(env, {}); + expect(env, isEmpty); env = { 'DART_VM_OPTIONS': '--enable-vm-service:51156', 'TEKARTIK_DART_VM_OPTIONS': '--profile' diff --git a/test/src_user_config_test.dart b/test/src_user_config_test.dart index 8b0b132..acd7cca 100644 --- a/test/src_user_config_test.dart +++ b/test/src_user_config_test.dart @@ -139,7 +139,7 @@ void main() { 'vars': {'test': '1'} }); expect(userConfig.vars, {'test': '1', 'PATH': ''}); - expect(userConfig.paths, []); + expect(userConfig.paths, isEmpty); userLoadConfigMap({ 'path': ['my_path'] }); @@ -174,7 +174,7 @@ void main() { 'PATH': ['other_path', 'my_path'].join(envPathSeparator) }); expect(userConfig.paths, ['other_path', 'my_path']); - userLoadConfigMap({'path': []}); + userLoadConfigMap({'path': []}); expect(userConfig.vars, { 'PATH': ['other_path', 'my_path'].join(envPathSeparator) }); @@ -189,7 +189,7 @@ void main() { var config = loadFromMap({ 'var': {'test': 1} }); - expect(config.paths, []); + expect(config.paths, []); expect(config.vars, {'test': '1'}); }); From 49c73afb2fd655349b62fcc230e83563bff7f3d9 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 11 Jan 2023 15:31:37 +0100 Subject: [PATCH 037/150] [process_run] v0.12.5 --- CHANGELOG.md | 3 ++- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 711d834..09aaec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ -## 0.12.4 +## 0.12.5 * requires dart sdk 2.18 +* strict-casts support ## 0.12.3+2 diff --git a/pubspec.yaml b/pubspec.yaml index 1d521c0..3672613 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.12.4 +version: 0.12.5 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart From 42089042a27eb3df6aae176c30f8bab0ef54b6a9 Mon Sep 17 00:00:00 2001 From: Alex Li Date: Mon, 16 Jan 2023 20:18:40 +0800 Subject: [PATCH 038/150] =?UTF-8?q?=F0=9F=90=9B=20Fix=20`clone`=20in=20`Sh?= =?UTF-8?q?ellMixin`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/src/shell_common.dart | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index 15ab9ed..f628d76 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -264,6 +264,7 @@ mixin ShellMixin implements ShellCore { return shell; } + @Deprecated('Use clone with options') Shell clone( {bool? throwOnError, String? workingDirectory, @@ -278,7 +279,22 @@ mixin ShellMixin implements ShellCore { bool? verbose, bool? commandVerbose, bool? commentVerbose}) { - // TODO: implement clone - throw UnimplementedError(); + return cloneWithOptions( + ShellOptions( + throwOnError: throwOnError ?? options.throwOnError, + workingDirectory: workingDirectory ?? options.workingDirectory, + environment: environment ?? options.environment, + includeParentEnvironment: includeParentEnvironment ?? true, + runInShell: runInShell ?? options.runInShell, + stdoutEncoding: stdoutEncoding ?? options.stdoutEncoding, + stderrEncoding: stderrEncoding ?? options.stderrEncoding, + stdin: stdin ?? options.stdin, + stdout: stdout ?? options.stdout, + stderr: stderr ?? options.stderr, + verbose: verbose ?? options.verbose, + commandVerbose: commandVerbose ?? options.commandVerbose, + commentVerbose: commentVerbose ?? options.commentVerbose, + ), + ); } } From 4b9cffdd7a3da2f872e6ee30438ccf0e639a3f48 Mon Sep 17 00:00:00 2001 From: Alex Li Date: Mon, 16 Jan 2023 20:25:14 +0800 Subject: [PATCH 039/150] =?UTF-8?q?=F0=9F=94=96=200.12.5+1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09aaec2..b39bb6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.12.5+1 + +* Fix `clone` in `ShellMixin`. + ## 0.12.5 * requires dart sdk 2.18 diff --git a/pubspec.yaml b/pubspec.yaml index 3672613..71ace56 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.12.5 +version: 0.12.5+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart From c9064068e7053be6e2416669d374c5c47f421c89 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 16 Jan 2023 16:59:34 +0100 Subject: [PATCH 040/150] [process_run] v0.15.2+1 add unit test for clone/cloneWithOptions --- lib/src/shell_common.dart | 3 +++ test/shell_common_test.dart | 27 ++++++++++++++++++--------- test/shell_test.dart | 12 ++++++++++++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index f628d76..6d9635b 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -253,6 +253,9 @@ mixin ShellMixin implements ShellCore { @override late ShellContext context; + @override + String get path => options.workingDirectory ?? '.'; + @override Future shellVarOverride(String name, String? value, {bool? local}) { throw UnimplementedError('shellVarOverride'); diff --git a/test/shell_common_test.dart b/test/shell_common_test.dart index 6c712aa..4f07a6b 100644 --- a/test/shell_common_test.dart +++ b/test/shell_common_test.dart @@ -23,8 +23,7 @@ class ShellContextMock implements ShellContext { {ShellOptions? options, Map? environment, bool includeParentEnvironment = true}) { - // TODO: implement newShell - return ShellMock(); + return ShellMock(options: options); } @override @@ -34,7 +33,6 @@ class ShellContextMock implements ShellContext { } @override - // TODO: implement path Context get path => throw UnimplementedError(); @override @@ -101,6 +99,10 @@ class ProcessMock implements Process { class ShellMock with ShellMixin implements Shell { var scripts = []; + ShellMock({ShellOptions? options}) { + this.options = options ?? ShellOptions(); + } + @override Shell cd(String path) { // TODO: implement cd @@ -113,10 +115,6 @@ class ShellMock with ShellMixin implements Shell { throw UnimplementedError(); } - @override - // TODO: implement path - String get path => throw UnimplementedError(); - @override Shell popd() { // TODO: implement popd @@ -151,8 +149,7 @@ class ShellMock with ShellMixin implements Shell { } @override - // TODO: implement options - ShellOptions get options => throw UnimplementedError(); + late final ShellOptions options; } void main() { @@ -209,5 +206,17 @@ void main() { } //expect(shell.scripts, ['hola']); }); + test('cloneWithOptions', () async { + var shell = + ShellMock().cloneWithOptions(ShellOptions(workingDirectory: 'a/b')); + expect(shell.path, 'a/b'); + expect(shell.options.workingDirectory, 'a/b'); + }); + test('clone', () async { + // ignore: deprecated_member_use_from_same_package + var shell = ShellMock().clone(workingDirectory: 'a/b'); + expect(shell.path, 'a/b'); + expect(shell.options.workingDirectory, 'a/b'); + }); }); } diff --git a/test/shell_test.dart b/test/shell_test.dart index 2570743..7343c9f 100644 --- a/test/shell_test.dart +++ b/test/shell_test.dart @@ -626,4 +626,16 @@ _tekartik_dummy_app_that_does_not_exits expect(text, isNot(contains('dummy1'))); expect(shell.options.environment.aliases['ds'], dsCommand); }); + + test('cloneWithOptions', () async { + var shell = Shell().cloneWithOptions(ShellOptions(workingDirectory: 'a/b')); + expect(shell.path, 'a/b'); + expect(shell.options.workingDirectory, 'a/b'); + }); + test('clone', () async { + // ignore: deprecated_member_use_from_same_package + var shell = Shell().clone(workingDirectory: 'a/b'); + expect(shell.path, 'a/b'); + expect(shell.options.workingDirectory, 'a/b'); + }); } From cbc5a9f1eca12d768af9fc6ee0202966c04b83d4 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 16 Jan 2023 17:53:37 +0100 Subject: [PATCH 041/150] [process_run] fix: use the proper context. --- lib/src/shell_common.dart | 2 +- test/shell_common_test.dart | 21 +++++++++++++------ tool/run_test_node.dart | 10 +++++++++ tool/{quick_test.dart => run_test_quick.dart} | 6 +++--- 4 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 tool/run_test_node.dart rename tool/{quick_test.dart => run_test_quick.dart} (55%) diff --git a/lib/src/shell_common.dart b/lib/src/shell_common.dart index 6d9635b..540f7c1 100644 --- a/lib/src/shell_common.dart +++ b/lib/src/shell_common.dart @@ -263,7 +263,7 @@ mixin ShellMixin implements ShellCore { @override Shell cloneWithOptions(ShellOptions options) { - var shell = shellContext.newShell(options: options); + var shell = context.newShell(options: options); return shell; } diff --git a/test/shell_common_test.dart b/test/shell_common_test.dart index 4f07a6b..110dc5b 100644 --- a/test/shell_common_test.dart +++ b/test/shell_common_test.dart @@ -23,7 +23,7 @@ class ShellContextMock implements ShellContext { {ShellOptions? options, Map? environment, bool includeParentEnvironment = true}) { - return ShellMock(options: options); + return ShellMock(options: options, context: this); } @override @@ -96,11 +96,15 @@ class ProcessMock implements Process { Stream> get stdout => throw UnimplementedError(); } +var shellOptionsMock = + ShellOptions(environment: {}, includeParentEnvironment: false); + class ShellMock with ShellMixin implements Shell { var scripts = []; - ShellMock({ShellOptions? options}) { - this.options = options ?? ShellOptions(); + ShellMock({ShellContextMock? context, ShellOptions? options}) { + this.context = context ?? ShellContextMock(); + this.options = options ?? shellOptionsMock; } @override @@ -207,14 +211,19 @@ void main() { //expect(shell.scripts, ['hola']); }); test('cloneWithOptions', () async { - var shell = - ShellMock().cloneWithOptions(ShellOptions(workingDirectory: 'a/b')); + var shell = ShellMock().cloneWithOptions(ShellOptions( + workingDirectory: 'a/b', + environment: {}, + includeParentEnvironment: false)); expect(shell.path, 'a/b'); expect(shell.options.workingDirectory, 'a/b'); }); test('clone', () async { // ignore: deprecated_member_use_from_same_package - var shell = ShellMock().clone(workingDirectory: 'a/b'); + var shell = ShellMock().clone( + workingDirectory: 'a/b', + environment: {}, + includeParentEnvironment: false); expect(shell.path, 'a/b'); expect(shell.options.workingDirectory, 'a/b'); }); diff --git a/tool/run_test_node.dart b/tool/run_test_node.dart new file mode 100644 index 0000000..0f44d53 --- /dev/null +++ b/tool/run_test_node.dart @@ -0,0 +1,10 @@ +import 'package:process_run/shell.dart'; + +Future main() async { + var shell = Shell(); + + await shell.run(''' +# Run node tests +dart test -p node +'''); +} diff --git a/tool/quick_test.dart b/tool/run_test_quick.dart similarity index 55% rename from tool/quick_test.dart rename to tool/run_test_quick.dart index 4a190f4..77d1986 100644 --- a/tool/quick_test.dart +++ b/tool/run_test_quick.dart @@ -5,10 +5,10 @@ Future main() async { await shell.run(''' # Analyze code -dartanalyzer --fatal-warnings --fatal-infos example lib tool test -dartfmt -n --set-exit-if-changed . +dart analyze --fatal-warnings --fatal-infos example lib tool test +dart format --set-exit-if-changed . # Run tests -pub run test -p vm +dart test -p vm '''); } From 45911c8a5dab601cf79c111213c2e0b663ad95f7 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 16 Jan 2023 17:55:33 +0100 Subject: [PATCH 042/150] [process_run] v0.12.5+2 --- CHANGELOG.md | 2 +- pubspec.yaml | 2 +- tool/run_test_quick.dart | 6 +----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b39bb6f..42ce5d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.5+1 +## 0.12.5+2 * Fix `clone` in `ShellMixin`. diff --git a/pubspec.yaml b/pubspec.yaml index 71ace56..1314b20 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.12.5+1 +version: 0.12.5+2 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart diff --git a/tool/run_test_quick.dart b/tool/run_test_quick.dart index 77d1986..87abac2 100644 --- a/tool/run_test_quick.dart +++ b/tool/run_test_quick.dart @@ -4,11 +4,7 @@ Future main() async { var shell = Shell(); await shell.run(''' -# Analyze code -dart analyze --fatal-warnings --fatal-infos example lib tool test -dart format --set-exit-if-changed . - # Run tests -dart test -p vm +dart test -p vm test/shell_test.dart '''); } From abbb703a94c12542bee12995827246dec39e7928 Mon Sep 17 00:00:00 2001 From: dujianxin Date: Tue, 4 Apr 2023 14:04:00 +0800 Subject: [PATCH 043/150] optimize reading config file. if the config file (~/tekartik/process_run/env.yaml) does not exist, an exception (PathNotFoundException) is thrown and captured by Sentry, it is not necessary to record this exception most of the time. --- lib/src/user_config.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/user_config.dart b/lib/src/user_config.dart index 2ef1b59..5e6c293 100644 --- a/lib/src/user_config.dart +++ b/lib/src/user_config.dart @@ -246,7 +246,11 @@ EnvFileConfig _loadFromPath(String path) { try { // Look for any config file in ~/tekartik/process_run/env.yaml try { - fileContent = File(path).readAsStringSync(); + var configFile = File(path); + + if (configFile.existsSync()) { + fileContent = configFile.readAsStringSync(); + } } catch (e) { // stderr.writeln('error reading env file $path $e'); } From e9fb31b3cb89a2bcd60e5710e2f40f6399f1c8b1 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 5 Apr 2023 10:05:30 +0200 Subject: [PATCH 044/150] fix: typo --- lib/src/shell_utils_common.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/shell_utils_common.dart b/lib/src/shell_utils_common.dart index da00ba5..03db617 100644 --- a/lib/src/shell_utils_common.dart +++ b/lib/src/shell_utils_common.dart @@ -85,4 +85,4 @@ String argumentsToString(List arguments) { String shellArgument(String argument) => argumentToString(argument); /// Convert multiple arguments to string than can be used in a terminal -String shellArguments(List argument) => argumentsToString(argument); +String shellArguments(List arguments) => argumentsToString(arguments); From 6742e246f9d867b2cb76bb1d78bc7864c90c95cc Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 5 Apr 2023 10:10:29 +0200 Subject: [PATCH 045/150] test: loadFromPath with missing file --- test/src_user_config_test.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/src_user_config_test.dart b/test/src_user_config_test.dart index acd7cca..878b4f3 100644 --- a/test/src_user_config_test.dart +++ b/test/src_user_config_test.dart @@ -201,5 +201,10 @@ void main() { join('flutter', 'bin', 'cache', 'dart-sdk', 'bin')), join('flutter', 'bin')); }); + + test('loadFromMap missing file', () async { + var config = loadFromPath('dummy_file'); + expect(config.isEmpty, isTrue); + }); }); } From b73842c64f2a4967c7975bafc17ba47aab24a81a Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 6 Apr 2023 15:26:05 +0200 Subject: [PATCH 046/150] test: loadFromPath with missing file --- CHANGELOG.md | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42ce5d2..54ad6c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.5+2 +## 0.12.5+3 * Fix `clone` in `ShellMixin`. diff --git a/pubspec.yaml b/pubspec.yaml index 1314b20..6b3e01e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.12.5+2 +version: 0.12.5+3 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart From bf1d124544fa01ea90f32cd4aa565426e5496b5e Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 20 Apr 2023 16:17:27 +0200 Subject: [PATCH 047/150] feat: remove deprecated methods --- .github/dependabot.yml | 9 ++++++ lib/cmd/dartbin_cmd.dart | 5 --- lib/cmd/process_cmd.dart | 5 --- lib/process_run.dart | 43 +------------------------- lib/shell.dart | 5 +++ lib/src/dartbin_cmd.dart | 21 ------------- lib/src/dev_process_run.dart | 31 ------------------- lib/src/flutterbin_cmd.dart | 1 - lib/src/process_cmd.dart | 12 ------- lib/src/process_run.dart | 1 - lib/src/shell.dart | 1 - lib/src/shell_utils.dart | 1 - test/process_run_0_14_compat_test.dart | 8 +++++ test/process_run_in_test2_.dart | 1 - test/process_run_in_test_.dart | 1 - test/process_run_out_test_.dart | 1 - test/process_run_test.dart | 3 -- 17 files changed, 23 insertions(+), 126 deletions(-) create mode 100644 .github/dependabot.yml delete mode 100644 lib/cmd/dartbin_cmd.dart delete mode 100644 lib/cmd/process_cmd.dart delete mode 100644 lib/src/dev_process_run.dart create mode 100644 test/process_run_0_14_compat_test.dart diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1603cdd --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +# Dependabot configuration file. +# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates +version: 2 + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/lib/cmd/dartbin_cmd.dart b/lib/cmd/dartbin_cmd.dart deleted file mode 100644 index 7ed267f..0000000 --- a/lib/cmd/dartbin_cmd.dart +++ /dev/null @@ -1,5 +0,0 @@ -// 0.2.0 2015/12/9 -@Deprecated('Use shell instead') -library process_run.cmd.dartbin_cmd.deprecated; - -export 'package:process_run/src/dartbin_cmd.dart'; diff --git a/lib/cmd/process_cmd.dart b/lib/cmd/process_cmd.dart deleted file mode 100644 index b3a7eee..0000000 --- a/lib/cmd/process_cmd.dart +++ /dev/null @@ -1,5 +0,0 @@ -// 0.2.0 2015/12/9 -@Deprecated('Use shell instead') -library process_run.cmd.process_cmd.deprecated; - -export 'package:process_run/src/process_cmd.dart'; diff --git a/lib/process_run.dart b/lib/process_run.dart index 2d84ae6..231b132 100644 --- a/lib/process_run.dart +++ b/lib/process_run.dart @@ -1,50 +1,9 @@ /// /// Helper to run a process and connect the input/output for verbosity /// -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; - -import 'package:process_run/src/process_run.dart'; - -import 'src/common/import.dart'; - export 'package:process_run/src/shell_utils_common.dart' show argumentsToString, argumentToString; -export 'src/dev_process_run.dart'; +export 'shell.dart'; export 'src/process_run.dart' show runExecutableArguments, executableArgumentsToString; - -/// Use runExecutableArguments instead -/// -/// if [commmandVerbose] or [verbose] is true, display the command. -/// if [verbose] is true, stream stdout & stdin -@Deprecated('Use runExecutableArguments instead') -Future run(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool? runInShell, - Encoding? stdoutEncoding = systemEncoding, - Encoding? stderrEncoding = systemEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose}) => - runExecutableArguments( - executable, - arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stderrEncoding: stderrEncoding, - stdoutEncoding: stdoutEncoding, - stdin: stdin, - stdout: stdout, - stderr: stderr, - verbose: verbose, - commandVerbose: commandVerbose, - ); diff --git a/lib/shell.dart b/lib/shell.dart index a848c20..a800b98 100644 --- a/lib/shell.dart +++ b/lib/shell.dart @@ -23,6 +23,7 @@ export 'package:process_run/dartbin.dart' dartChannelDev, dartChannelMaster; export 'package:process_run/src/api/shell_common.dart' show ShellOptions; + // We reuse io sharedStdIn definition. export 'package:process_run/src/io/shared_stdin.dart' show sharedStdIn; export 'package:process_run/src/shell_utils.dart' @@ -34,6 +35,8 @@ export 'package:process_run/src/shell_utils.dart' platformEnvironment, shellArguments, shellExecutableArguments; +export 'package:process_run/src/shell_utils_common.dart' + show argumentsToString, argumentToString; export 'package:process_run/src/user_config.dart' show userPaths, userEnvironment, userLoadEnvFile, userLoadEnv; @@ -51,6 +54,8 @@ export 'src/process_cmd.dart' /// Deprecated ProcessCmd; +export 'src/process_run.dart' + show runExecutableArguments, executableArgumentsToString; export 'src/prompt.dart' show promptConfirm, promptTerminate, prompt; export 'src/shell.dart' show run, Shell, ShellException; export 'src/shell_environment.dart' diff --git a/lib/src/dartbin_cmd.dart b/lib/src/dartbin_cmd.dart index 9d9c11a..1bdc284 100644 --- a/lib/src/dartbin_cmd.dart +++ b/lib/src/dartbin_cmd.dart @@ -11,27 +11,6 @@ import 'common/import.dart'; String dartBinFileName = 'dart${Platform.isWindows ? '.exe' : ''}'; -@Deprecated('Use DartCmd instead') -ProcessCmd dartCmd(List arguments) => DartCmd(arguments); - -@Deprecated('Use DartFmtCmd instead') -ProcessCmd dartfmtCmd(List args) => DartFmtCmd(args); - -@Deprecated('Use DartAnalyzerCmd instead') -ProcessCmd dartanalyzerCmd(List args) => DartAnalyzerCmd(args); - -@Deprecated('Use Dart2JsCmd instead') -ProcessCmd dart2jsCmd(List args) => Dart2JsCmd(args); - -@Deprecated('Use DartDocCmd instead') -ProcessCmd dartdocCmd(List args) => DartDocCmd(args); - -@Deprecated('Use DartDevcCmd instead') -ProcessCmd dartdevcCmd(List args) => DartDevcCmd(args); - -@Deprecated('Use PubCmd instead') -ProcessCmd pubCmd(List args) => PubCmd(args); - /// Call dart executable /// /// To prevent 'Observatory server failed to start after 1 tries' when diff --git a/lib/src/dev_process_run.dart b/lib/src/dev_process_run.dart deleted file mode 100644 index c4e221a..0000000 --- a/lib/src/dev_process_run.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; - -import 'package:process_run/cmd_run.dart'; - -@Deprecated('Dev only, verbose') -Future devRun(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool runInShell = false, - Encoding stdoutEncoding = systemEncoding, - Encoding stderrEncoding = systemEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - @Deprecated('use stdout') bool connectStdout = false, - @Deprecated('use stderr') bool connectStderr = false, - @Deprecated('use stdin') bool connectStdin = false}) => - run(executable, arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stderrEncoding: stderrEncoding, - stdoutEncoding: stdoutEncoding, - stdin: stdin, - stderr: stderr, - stdout: stdout, - verbose: true); diff --git a/lib/src/flutterbin_cmd.dart b/lib/src/flutterbin_cmd.dart index f6d1f80..930c06a 100644 --- a/lib/src/flutterbin_cmd.dart +++ b/lib/src/flutterbin_cmd.dart @@ -1,6 +1,5 @@ import 'dart:convert'; -import 'package:process_run/process_run.dart' hide run; import 'package:process_run/shell_run.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; diff --git a/lib/src/process_cmd.dart b/lib/src/process_cmd.dart index cdc1e99..74b8f22 100644 --- a/lib/src/process_cmd.dart +++ b/lib/src/process_cmd.dart @@ -1,10 +1,8 @@ -import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:collection/collection.dart'; import 'package:process_run/process_run.dart'; -import 'package:process_run/process_run.dart' as process_run; class ProcessCmd { String? executable; @@ -46,16 +44,6 @@ class ProcessCmd { @override String toString() => executableArgumentsToString(executable, arguments); - - /// Execute - @Deprecated('Use runCmd instead') - Future run() => process_run.run(executable!, arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding); } // Use ProcessCmd instead diff --git a/lib/src/process_run.dart b/lib/src/process_run.dart index d9dd43b..9955640 100644 --- a/lib/src/process_run.dart +++ b/lib/src/process_run.dart @@ -4,7 +4,6 @@ import 'dart:io'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; -import 'package:process_run/src/process_run.dart'; import 'package:process_run/src/shell.dart'; import 'package:process_run/src/shell_utils.dart' as utils; import 'package:process_run/src/shell_utils.dart'; diff --git a/lib/src/shell.dart b/lib/src/shell.dart index 09bcfca..1d7e04d 100644 --- a/lib/src/shell.dart +++ b/lib/src/shell.dart @@ -2,7 +2,6 @@ import 'dart:convert'; import 'dart:io' as io; import 'package:path/path.dart'; -import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/platform/platform.dart'; diff --git a/lib/src/shell_utils.dart b/lib/src/shell_utils.dart index 7a12478..ae5d73a 100644 --- a/lib/src/shell_utils.dart +++ b/lib/src/shell_utils.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:path/path.dart'; -import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/io/shell_words.dart' as io show shellSplit; diff --git a/test/process_run_0_14_compat_test.dart b/test/process_run_0_14_compat_test.dart new file mode 100644 index 0000000..0110786 --- /dev/null +++ b/test/process_run_0_14_compat_test.dart @@ -0,0 +1,8 @@ +import 'package:process_run/process_run.dart'; +import 'package:test/test.dart'; + +void main() { + test('run', () async { + await run('echo test'); + }); +} diff --git a/test/process_run_in_test2_.dart b/test/process_run_in_test2_.dart index d75106b..71ae10e 100644 --- a/test/process_run_in_test2_.dart +++ b/test/process_run_in_test2_.dart @@ -3,7 +3,6 @@ library process_run.process_run_in_test2_; import 'dart:async'; -import 'package:process_run/dartbin.dart'; import 'package:process_run/process_run.dart'; import 'package:test/test.dart'; diff --git a/test/process_run_in_test_.dart b/test/process_run_in_test_.dart index 2a17ba3..2a09b6a 100644 --- a/test/process_run_in_test_.dart +++ b/test/process_run_in_test_.dart @@ -1,7 +1,6 @@ @TestOn('vm') library process_run.process_run_in_test; -import 'package:process_run/dartbin.dart'; import 'package:process_run/process_run.dart'; import 'package:test/test.dart'; diff --git a/test/process_run_out_test_.dart b/test/process_run_out_test_.dart index a751ea7..0502210 100644 --- a/test/process_run_out_test_.dart +++ b/test/process_run_out_test_.dart @@ -3,7 +3,6 @@ library process_run.process_run_out_test; import 'dart:io'; -import 'package:process_run/dartbin.dart'; import 'package:process_run/process_run.dart'; import 'package:test/test.dart'; diff --git a/test/process_run_test.dart b/test/process_run_test.dart index c824a28..84de687 100644 --- a/test/process_run_test.dart +++ b/test/process_run_test.dart @@ -6,10 +6,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:path/path.dart'; -import 'package:process_run/dartbin.dart'; import 'package:process_run/process_run.dart'; -import 'package:process_run/shell.dart' - show platformEnvironment, Shell, shellArgument; import 'package:process_run/src/shell_utils.dart' show envPathKey, envPathSeparator; import 'package:test/test.dart'; From 6bfcb64589188bf16e5d73dddde084c69c1acbcd Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 20 Apr 2023 16:28:19 +0200 Subject: [PATCH 048/150] feat: move package to sub folder --- .github/workflows/run_ci.yml | 2 +- .travis.yml | 12 --- README.md | 100 +----------------- .gitignore => packages/process_run/.gitignore | 0 .../process_run/CHANGELOG.md | 0 LICENSE => packages/process_run/LICENSE | 0 packages/process_run/README.md | 83 +++++++++++++++ .../process_run/analysis_options.yaml | 0 {bin => packages/process_run/bin}/shell.dart | 0 .../process_run/dart_test.yaml | 0 {doc => packages/process_run/doc}/more.md | 1 - .../doc}/process_run_development.md | 0 {doc => packages/process_run/doc}/shell.md | 2 +- .../process_run/doc}/shell_bin_info.md | 0 .../process_run/doc}/user_config.md | 0 .../process_run/example}/cmd_demo.dart | 0 .../example}/dart_bin_version.dart | 0 .../process_run/example}/demo.dart | 0 .../process_run/example}/echo.dart | 0 .../process_run/example}/example.dart | 0 .../example}/flutter_bin_version.dart | 0 .../process_run/example}/hex_utils.dart | 0 .../process_run/example}/info.dart | 0 .../process_run/example}/my_script.dart | 0 .../example}/no_env_user_paths.dart | 0 .../process_run/example}/prompt.dart | 0 .../process_run/example}/shell/common.dart | 0 .../example}/shell/env_file_location_new.dart | 0 .../example}/shell/env_file_location_old.dart | 0 .../example}/shell/get_var_now.dart | 0 .../example}/shell/prepend_path_dummy.dart | 0 .../example}/shell/set_alias_ll.dart | 0 .../example}/shell/set_var_now.dart | 0 .../example}/shell/shared_stdin.dart | 0 .../example}/shell/shared_stdin_not_used.dart | 0 .../example}/shell/shell_common.dart | 0 .../example}/shell/shell_info.dart | 0 .../example}/shell/shell_info_dump.dart | 0 .../process_run/example}/shell_bin.dart | 0 .../process_run/example}/streamer.dart | 0 .../process_run/example}/sudo_example.dart | 0 .../process_run/example}/user_paths.dart | 0 .../process_run/lib}/cmd_run.dart | 0 .../process_run/lib}/dartbin.dart | 0 .../process_run/lib}/package/package.dart | 0 .../process_run/lib}/process_cmd.dart | 0 .../process_run/lib}/process_run.dart | 1 + {lib => packages/process_run/lib}/shell.dart | 0 .../process_run/lib}/shell_run.dart | 0 .../lib}/src/api/shell_common.dart | 0 .../process_run/lib}/src/bin/shell/dump.dart | 0 .../process_run/lib}/src/bin/shell/env.dart | 4 +- .../lib}/src/bin/shell/env_alias.dart | 0 .../lib}/src/bin/shell/env_alias_delete.dart | 0 .../lib}/src/bin/shell/env_alias_dump.dart | 0 .../lib}/src/bin/shell/env_alias_get.dart | 0 .../lib}/src/bin/shell/env_alias_set.dart | 0 .../lib}/src/bin/shell/env_delete.dart | 0 .../lib}/src/bin/shell/env_edit.dart | 0 .../lib}/src/bin/shell/env_file_content.dart | 0 .../lib}/src/bin/shell/env_path.dart | 0 .../lib}/src/bin/shell/env_path_delete.dart | 0 .../lib}/src/bin/shell/env_path_dump.dart | 0 .../lib}/src/bin/shell/env_path_get.dart | 0 .../lib}/src/bin/shell/env_path_prepend.dart | 0 .../lib}/src/bin/shell/env_var.dart | 0 .../lib}/src/bin/shell/env_var_delete.dart | 0 .../lib}/src/bin/shell/env_var_dump.dart | 0 .../lib}/src/bin/shell/env_var_get.dart | 0 .../lib}/src/bin/shell/env_var_set.dart | 0 .../lib}/src/bin/shell/import.dart | 0 .../process_run/lib}/src/bin/shell/run.dart | 0 .../process_run/lib}/src/bin/shell/shell.dart | 0 .../lib}/src/bin/shell/shell_bin_command.dart | 0 .../process_run/lib}/src/build_runner.dart | 0 .../process_run/lib}/src/characters.dart | 0 .../process_run/lib}/src/command_line.dart | 0 .../process_run/lib}/src/common/constant.dart | 0 .../process_run/lib}/src/common/dartbin.dart | 0 .../lib}/src/common/dev_utils.dart | 0 .../process_run/lib}/src/common/import.dart | 0 .../lib}/src/common/import_common.dart | 0 .../process_run/lib}/src/dartbin_cmd.dart | 0 .../process_run/lib}/src/dartbin_impl.dart | 0 .../process_run/lib}/src/dev_cmd_run.dart | 0 .../process_run/lib}/src/env_utils.dart | 0 .../process_run/lib}/src/flutterbin_cmd.dart | 0 .../process_run/lib}/src/io/env_io.dart | 4 +- .../lib}/src/io/env_var_delete_io.dart | 0 .../lib}/src/io/env_var_get_io.dart | 0 .../lib}/src/io/env_var_set_io.dart | 0 .../process_run/lib}/src/io/io_import.dart | 0 .../process_run/lib}/src/io/shared_stdin.dart | 0 .../process_run/lib}/src/io/shell_words.dart | 0 .../process_run/lib}/src/lines_utils.dart | 0 .../lib}/src/lines_utils_common.dart | 0 .../lib}/src/mixin/file_content.dart | 0 .../process_run/lib}/src/mixin/shell_bin.dart | 0 .../lib}/src/mixin/shell_common.dart | 0 .../lib}/src/platform/platform.dart | 0 .../lib}/src/platform/platform_io.dart | 0 .../lib}/src/platform/platform_stub.dart | 0 .../process_run/lib}/src/process_cmd.dart | 0 .../src/process_result_common_extension.dart | 0 .../process_run/lib}/src/process_run.dart | 0 .../process_run/lib}/src/prompt.dart | 0 .../process_run/lib}/src/script_filename.dart | 0 .../process_run/lib}/src/shell.dart | 0 .../process_run/lib}/src/shell_common.dart | 0 .../process_run/lib}/src/shell_common_io.dart | 0 .../lib}/src/shell_context_common.dart | 0 .../lib}/src/shell_context_io.dart | 0 .../lib}/src/shell_environment.dart | 0 .../lib}/src/shell_environment_common.dart | 0 .../process_run/lib}/src/shell_utils.dart | 0 .../lib}/src/shell_utils_common.dart | 0 .../process_run/lib}/src/shell_utils_io.dart | 0 .../process_run/lib}/src/user_config.dart | 2 +- .../process_run/lib}/src/utils.dart | 0 .../process_run/lib}/src/webdev.dart | 0 .../process_run/lib}/src/which.dart | 0 .../lib}/utils/process_result_extension.dart | 0 {lib => packages/process_run/lib}/which.dart | 0 .../process_run/pubspec.yaml | 2 +- .../process_run/test}/bin/bin_shell_test.dart | 0 .../process_run/test}/build_runner_test.dart | 0 .../process_run/test}/cmd_run_api_test.dart | 0 .../test}/cmd_run_exception_test.dart | 0 .../process_run/test}/cmd_run_test.dart | 0 .../process_run/test}/compile_test.dart | 0 .../test}/dart_compile_js_test.dart | 0 .../process_run/test}/dart_doc_test.dart | 0 .../process_run/test}/dartbin_api_test.dart | 0 .../process_run/test}/dartbin_cmd_test.dart | 0 .../test}/dartbin_cmd_verbose_test_.dart | 0 .../process_run/test}/dartbin_test.dart | 0 .../process_run/test}/dartdevc_test.dart | 0 .../process_run/test}/dartdoc_test.dart | 0 .../process_run/test}/dartfmt_test.dart | 0 .../process_run/test}/data/main.dart | 0 .../process_run/test}/data/test_env1.yaml | 0 .../process_run/test}/data/test_env2.yaml | 0 .../test}/data/test_env3_empty.yaml | 0 ...est_user_env1_local_env_file_override.yaml | 0 .../test}/data/test_user_env2_empty.yaml | 0 .../test}/data/test_user_env3_safe.yaml | 0 .../process_run/test}/doc_test.dart | 0 .../process_run/test}/echo_test.dart | 0 .../test}/example_hex_utils_test_.dart | 0 .../test}/flutterbin_cmd_test.dart | 0 .../test}/flutterbin_impl_test.dart | 0 .../process_run/test}/hex_utils.dart | 0 .../process_run/test}/package_test.dart | 0 .../test}/process_cmd_api_test.dart | 0 .../process_run/test}/process_cmd_test.dart | 0 .../test}/process_run_0_14_compat_test.dart | 0 .../test}/process_run_in_test2_.dart | 0 .../test}/process_run_in_test_.dart | 0 .../test}/process_run_out_test_.dart | 0 .../process_run/test}/process_run_test.dart | 0 .../test}/process_run_test_common.dart | 0 .../process_run/test}/pub_test.dart | 0 .../process_run/test}/shell_api_test.dart | 0 .../test}/shell_common_api_test.dart | 0 .../process_run/test}/shell_common_test.dart | 0 .../test}/shell_environment_test.dart | 0 .../test}/shell_lines_controller_test.dart | 0 .../process_run/test}/shell_run_test.dart | 0 .../process_run/test}/shell_test.dart | 0 .../process_run/test}/src/current_dir | 0 .../process_run/test}/src/current_dir.bat | 0 .../process_run/test}/src/current_dir.dart | 0 .../test}/src/shell_impl_test.dart | 0 .../process_run/test}/src/success_test.dart | 0 .../test}/src_dartbin_cmd_test.dart | 0 .../process_run/test}/src_shell_test.dart | 0 .../test}/src_shell_utils_test.dart | 0 .../test}/src_user_config_test.dart | 0 .../process_run/test}/webdev_test.dart | 0 .../process_run/test}/which_test.dart | 0 .../process_run/tool}/manual_test_prompt.dart | 0 .../process_run/tool}/run_ci.dart | 5 +- .../process_run/tool}/run_test_node.dart | 0 .../process_run/tool}/run_test_quick.dart | 0 {tool => packages/process_run/tool}/tag.dart | 0 .../process_run/tool}/travis.dart | 0 186 files changed, 97 insertions(+), 121 deletions(-) delete mode 100644 .travis.yml rename .gitignore => packages/process_run/.gitignore (100%) rename CHANGELOG.md => packages/process_run/CHANGELOG.md (100%) rename LICENSE => packages/process_run/LICENSE (100%) create mode 100644 packages/process_run/README.md rename analysis_options.yaml => packages/process_run/analysis_options.yaml (100%) rename {bin => packages/process_run/bin}/shell.dart (100%) rename dart_test.yaml => packages/process_run/dart_test.yaml (100%) rename {doc => packages/process_run/doc}/more.md (99%) rename {doc => packages/process_run/doc}/process_run_development.md (100%) rename {doc => packages/process_run/doc}/shell.md (99%) rename {doc => packages/process_run/doc}/shell_bin_info.md (100%) rename {doc => packages/process_run/doc}/user_config.md (100%) rename {example => packages/process_run/example}/cmd_demo.dart (100%) rename {example => packages/process_run/example}/dart_bin_version.dart (100%) rename {example => packages/process_run/example}/demo.dart (100%) rename {example => packages/process_run/example}/echo.dart (100%) rename {example => packages/process_run/example}/example.dart (100%) rename {example => packages/process_run/example}/flutter_bin_version.dart (100%) rename {example => packages/process_run/example}/hex_utils.dart (100%) rename {example => packages/process_run/example}/info.dart (100%) rename {example => packages/process_run/example}/my_script.dart (100%) rename {example => packages/process_run/example}/no_env_user_paths.dart (100%) rename {example => packages/process_run/example}/prompt.dart (100%) rename {example => packages/process_run/example}/shell/common.dart (100%) rename {example => packages/process_run/example}/shell/env_file_location_new.dart (100%) rename {example => packages/process_run/example}/shell/env_file_location_old.dart (100%) rename {example => packages/process_run/example}/shell/get_var_now.dart (100%) rename {example => packages/process_run/example}/shell/prepend_path_dummy.dart (100%) rename {example => packages/process_run/example}/shell/set_alias_ll.dart (100%) rename {example => packages/process_run/example}/shell/set_var_now.dart (100%) rename {example => packages/process_run/example}/shell/shared_stdin.dart (100%) rename {example => packages/process_run/example}/shell/shared_stdin_not_used.dart (100%) rename {example => packages/process_run/example}/shell/shell_common.dart (100%) rename {example => packages/process_run/example}/shell/shell_info.dart (100%) rename {example => packages/process_run/example}/shell/shell_info_dump.dart (100%) rename {example => packages/process_run/example}/shell_bin.dart (100%) rename {example => packages/process_run/example}/streamer.dart (100%) rename {example => packages/process_run/example}/sudo_example.dart (100%) rename {example => packages/process_run/example}/user_paths.dart (100%) rename {lib => packages/process_run/lib}/cmd_run.dart (100%) rename {lib => packages/process_run/lib}/dartbin.dart (100%) rename {lib => packages/process_run/lib}/package/package.dart (100%) rename {lib => packages/process_run/lib}/process_cmd.dart (100%) rename {lib => packages/process_run/lib}/process_run.dart (87%) rename {lib => packages/process_run/lib}/shell.dart (100%) rename {lib => packages/process_run/lib}/shell_run.dart (100%) rename {lib => packages/process_run/lib}/src/api/shell_common.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/dump.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env.dart (97%) rename {lib => packages/process_run/lib}/src/bin/shell/env_alias.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_alias_delete.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_alias_dump.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_alias_get.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_alias_set.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_delete.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_edit.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_file_content.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_path.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_path_delete.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_path_dump.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_path_get.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_path_prepend.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_var.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_var_delete.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_var_dump.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_var_get.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/env_var_set.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/import.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/run.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/shell.dart (100%) rename {lib => packages/process_run/lib}/src/bin/shell/shell_bin_command.dart (100%) rename {lib => packages/process_run/lib}/src/build_runner.dart (100%) rename {lib => packages/process_run/lib}/src/characters.dart (100%) rename {lib => packages/process_run/lib}/src/command_line.dart (100%) rename {lib => packages/process_run/lib}/src/common/constant.dart (100%) rename {lib => packages/process_run/lib}/src/common/dartbin.dart (100%) rename {lib => packages/process_run/lib}/src/common/dev_utils.dart (100%) rename {lib => packages/process_run/lib}/src/common/import.dart (100%) rename {lib => packages/process_run/lib}/src/common/import_common.dart (100%) rename {lib => packages/process_run/lib}/src/dartbin_cmd.dart (100%) rename {lib => packages/process_run/lib}/src/dartbin_impl.dart (100%) rename {lib => packages/process_run/lib}/src/dev_cmd_run.dart (100%) rename {lib => packages/process_run/lib}/src/env_utils.dart (100%) rename {lib => packages/process_run/lib}/src/flutterbin_cmd.dart (100%) rename {lib => packages/process_run/lib}/src/io/env_io.dart (92%) rename {lib => packages/process_run/lib}/src/io/env_var_delete_io.dart (100%) rename {lib => packages/process_run/lib}/src/io/env_var_get_io.dart (100%) rename {lib => packages/process_run/lib}/src/io/env_var_set_io.dart (100%) rename {lib => packages/process_run/lib}/src/io/io_import.dart (100%) rename {lib => packages/process_run/lib}/src/io/shared_stdin.dart (100%) rename {lib => packages/process_run/lib}/src/io/shell_words.dart (100%) rename {lib => packages/process_run/lib}/src/lines_utils.dart (100%) rename {lib => packages/process_run/lib}/src/lines_utils_common.dart (100%) rename {lib => packages/process_run/lib}/src/mixin/file_content.dart (100%) rename {lib => packages/process_run/lib}/src/mixin/shell_bin.dart (100%) rename {lib => packages/process_run/lib}/src/mixin/shell_common.dart (100%) rename {lib => packages/process_run/lib}/src/platform/platform.dart (100%) rename {lib => packages/process_run/lib}/src/platform/platform_io.dart (100%) rename {lib => packages/process_run/lib}/src/platform/platform_stub.dart (100%) rename {lib => packages/process_run/lib}/src/process_cmd.dart (100%) rename {lib => packages/process_run/lib}/src/process_result_common_extension.dart (100%) rename {lib => packages/process_run/lib}/src/process_run.dart (100%) rename {lib => packages/process_run/lib}/src/prompt.dart (100%) rename {lib => packages/process_run/lib}/src/script_filename.dart (100%) rename {lib => packages/process_run/lib}/src/shell.dart (100%) rename {lib => packages/process_run/lib}/src/shell_common.dart (100%) rename {lib => packages/process_run/lib}/src/shell_common_io.dart (100%) rename {lib => packages/process_run/lib}/src/shell_context_common.dart (100%) rename {lib => packages/process_run/lib}/src/shell_context_io.dart (100%) rename {lib => packages/process_run/lib}/src/shell_environment.dart (100%) rename {lib => packages/process_run/lib}/src/shell_environment_common.dart (100%) rename {lib => packages/process_run/lib}/src/shell_utils.dart (100%) rename {lib => packages/process_run/lib}/src/shell_utils_common.dart (100%) rename {lib => packages/process_run/lib}/src/shell_utils_io.dart (100%) rename {lib => packages/process_run/lib}/src/user_config.dart (99%) rename {lib => packages/process_run/lib}/src/utils.dart (100%) rename {lib => packages/process_run/lib}/src/webdev.dart (100%) rename {lib => packages/process_run/lib}/src/which.dart (100%) rename {lib => packages/process_run/lib}/utils/process_result_extension.dart (100%) rename {lib => packages/process_run/lib}/which.dart (100%) rename pubspec.yaml => packages/process_run/pubspec.yaml (87%) rename {test => packages/process_run/test}/bin/bin_shell_test.dart (100%) rename {test => packages/process_run/test}/build_runner_test.dart (100%) rename {test => packages/process_run/test}/cmd_run_api_test.dart (100%) rename {test => packages/process_run/test}/cmd_run_exception_test.dart (100%) rename {test => packages/process_run/test}/cmd_run_test.dart (100%) rename {test => packages/process_run/test}/compile_test.dart (100%) rename {test => packages/process_run/test}/dart_compile_js_test.dart (100%) rename {test => packages/process_run/test}/dart_doc_test.dart (100%) rename {test => packages/process_run/test}/dartbin_api_test.dart (100%) rename {test => packages/process_run/test}/dartbin_cmd_test.dart (100%) rename {test => packages/process_run/test}/dartbin_cmd_verbose_test_.dart (100%) rename {test => packages/process_run/test}/dartbin_test.dart (100%) rename {test => packages/process_run/test}/dartdevc_test.dart (100%) rename {test => packages/process_run/test}/dartdoc_test.dart (100%) rename {test => packages/process_run/test}/dartfmt_test.dart (100%) rename {test => packages/process_run/test}/data/main.dart (100%) rename {test => packages/process_run/test}/data/test_env1.yaml (100%) rename {test => packages/process_run/test}/data/test_env2.yaml (100%) rename {test => packages/process_run/test}/data/test_env3_empty.yaml (100%) rename {test => packages/process_run/test}/data/test_user_env1_local_env_file_override.yaml (100%) rename {test => packages/process_run/test}/data/test_user_env2_empty.yaml (100%) rename {test => packages/process_run/test}/data/test_user_env3_safe.yaml (100%) rename {test => packages/process_run/test}/doc_test.dart (100%) rename {test => packages/process_run/test}/echo_test.dart (100%) rename {test => packages/process_run/test}/example_hex_utils_test_.dart (100%) rename {test => packages/process_run/test}/flutterbin_cmd_test.dart (100%) rename {test => packages/process_run/test}/flutterbin_impl_test.dart (100%) rename {test => packages/process_run/test}/hex_utils.dart (100%) rename {test => packages/process_run/test}/package_test.dart (100%) rename {test => packages/process_run/test}/process_cmd_api_test.dart (100%) rename {test => packages/process_run/test}/process_cmd_test.dart (100%) rename {test => packages/process_run/test}/process_run_0_14_compat_test.dart (100%) rename {test => packages/process_run/test}/process_run_in_test2_.dart (100%) rename {test => packages/process_run/test}/process_run_in_test_.dart (100%) rename {test => packages/process_run/test}/process_run_out_test_.dart (100%) rename {test => packages/process_run/test}/process_run_test.dart (100%) rename {test => packages/process_run/test}/process_run_test_common.dart (100%) rename {test => packages/process_run/test}/pub_test.dart (100%) rename {test => packages/process_run/test}/shell_api_test.dart (100%) rename {test => packages/process_run/test}/shell_common_api_test.dart (100%) rename {test => packages/process_run/test}/shell_common_test.dart (100%) rename {test => packages/process_run/test}/shell_environment_test.dart (100%) rename {test => packages/process_run/test}/shell_lines_controller_test.dart (100%) rename {test => packages/process_run/test}/shell_run_test.dart (100%) rename {test => packages/process_run/test}/shell_test.dart (100%) rename {test => packages/process_run/test}/src/current_dir (100%) rename {test => packages/process_run/test}/src/current_dir.bat (100%) rename {test => packages/process_run/test}/src/current_dir.dart (100%) rename {test => packages/process_run/test}/src/shell_impl_test.dart (100%) rename {test => packages/process_run/test}/src/success_test.dart (100%) rename {test => packages/process_run/test}/src_dartbin_cmd_test.dart (100%) rename {test => packages/process_run/test}/src_shell_test.dart (100%) rename {test => packages/process_run/test}/src_shell_utils_test.dart (100%) rename {test => packages/process_run/test}/src_user_config_test.dart (100%) rename {test => packages/process_run/test}/webdev_test.dart (100%) rename {test => packages/process_run/test}/which_test.dart (100%) rename {tool => packages/process_run/tool}/manual_test_prompt.dart (100%) rename {tool => packages/process_run/tool}/run_ci.dart (66%) rename {tool => packages/process_run/tool}/run_test_node.dart (100%) rename {tool => packages/process_run/tool}/run_test_quick.dart (100%) rename {tool => packages/process_run/tool}/tag.dart (100%) rename {tool => packages/process_run/tool}/travis.dart (100%) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index b19b637..685ea6b 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} defaults: run: - working-directory: . + working-directory: packages/process_run strategy: fail-fast: false matrix: diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1ae13c3..0000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: dart -dart: - - stable - - beta - - dev -script: - - dart pub get - - dart run tool/travis.dart -matrix: - allow_failures: - # Temp for nnbd - - dart: dev \ No newline at end of file diff --git a/README.md b/README.md index 7ae531e..3570a62 100644 --- a/README.md +++ b/README.md @@ -1,99 +1,5 @@ -# process_run - Process run helpers for Linux/Win/Mac. -[![Build Status](https://travis-ci.org/tekartik/process_run.dart.svg?branch=master)](https://travis-ci.org/tekartik/process_run.dart) - -## Goals - -Currently using `Process.run` does not stream output which is not convenient for lengthy -operation. It requires using `Process.start` in a more complex way. - -`run` and `runCmd` add verbose helper for that. Also dart binaries (pub, dart2js...) and any -script can be called consistently on Mac/Windows/Linux - -`ProcessCmd` allow creating command object that can be run and modified. - -## Usage - -### which - -Like unix `which`, it searches for installed executables - -```dart -import 'package:process_run/which.dart'; -``` - -Find `flutter` and `firebase` executables: - -```dart -var flutterExectutable = whichSync('flutter'); -var firebaseExectutable = whichSync('firebase'); - -``` - -### shell - - -Allows to run script from Mac/Windows/Linux in a portable way. Empty lines are added for lisibility - -```dart -import 'package:process_run/shell.dart'; -``` - -Run a simple script: - -```dart -var shell = Shell(); - -await shell.run(''' - -# Display some text -echo Hello - -# Display dart version -dart --version - -# Display pub version -pub --version - -'''); -``` - -More information [on shell here](https://github.com/tekartik/process_run.dart/blob/master/doc/shell.md) - -### shell bin utility - -Binary utility that allow changing from the command line the environment (var, path, alias) used in Shell. - -More information [on shell bin here](https://github.com/tekartik/process_run.dart/blob/master/doc/shell_bin_info.md) - -### Flutter context - -#### MacOS - -If you want to run executable in a MacOS flutter context, you need to disable sandbox mode. See -[Removing sandboxing](https://stackoverflow.com/questions/7018354/remove-sandboxing) and -[ProcessException: Operation not permitted on macOS](https://github.com/tekartik/process_run.dart/issues/3) - -In `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`, change: - -``` - - com.apple.security.app-sandbox - - -``` - -to - -``` - - com.apple.security.app-sandbox - - -``` -### Additional features - -Addtional features and information are [available here](https://github.com/tekartik/process_run.dart/blob/master/doc/more.md) - +| package | descriptions | +|-------------------------------------|----------------------------------------| +| [process_run](packages/process_run) | Process run helpers for Linux/Win/Mac. | \ No newline at end of file diff --git a/.gitignore b/packages/process_run/.gitignore similarity index 100% rename from .gitignore rename to packages/process_run/.gitignore diff --git a/CHANGELOG.md b/packages/process_run/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to packages/process_run/CHANGELOG.md diff --git a/LICENSE b/packages/process_run/LICENSE similarity index 100% rename from LICENSE rename to packages/process_run/LICENSE diff --git a/packages/process_run/README.md b/packages/process_run/README.md new file mode 100644 index 0000000..3c56102 --- /dev/null +++ b/packages/process_run/README.md @@ -0,0 +1,83 @@ +# process_run + +Process run helpers for Linux/Win/Mac. + +### shell + +Allows to run script from Mac/Windows/Linux in a portable way. Empty lines are added for lisibility + +```dart +import 'package:process_run/shell.dart'; +``` + +Run a simple script: + +```dart +var shell = Shell(); + +await shell.run(''' + +# Display some text +echo Hello + +# Display dart version +dart --version + +# Display pub version +pub --version + +'''); +``` + +More information [on shell here](https://github.com/tekartik/process_run.dart/blob/master/packages/process_run/doc/shell.md) + +### which + +Like unix `which`, it searches for installed executables + +```dart +import 'package:process_run/which.dart'; +``` + +Find `flutter` and `firebase` executables: + +```dart +var flutterExectutable = whichSync('flutter'); +var firebaseExectutable = whichSync('firebase'); +``` + +### shell bin utility + +Binary utility that allow changing from the command line the environment (var, path, alias) used in Shell. + +More information [on shell bin here](https://github.com/tekartik/process_run.dart/blob/master/packages/process_run/doc/shell_bin_info.md) + +### Flutter context + +#### MacOS + +If you want to run executable in a MacOS flutter context, you need to disable sandbox mode. See +[Removing sandboxing](https://stackoverflow.com/questions/7018354/remove-sandboxing) and +[ProcessException: Operation not permitted on macOS](https://github.com/tekartik/process_run.dart/issues/3) + +In `macos/Runner/DebugProfile.entitlements` and `macos/Runner/Release.entitlements`, change: + +``` + + com.apple.security.app-sandbox + + +``` + +to + +``` + + com.apple.security.app-sandbox + + +``` +### Additional features + +Addtional features and information are [available here](https://github.com/tekartik/process_run.dart/blob/master/packages/process_run/doc/more.md) + diff --git a/analysis_options.yaml b/packages/process_run/analysis_options.yaml similarity index 100% rename from analysis_options.yaml rename to packages/process_run/analysis_options.yaml diff --git a/bin/shell.dart b/packages/process_run/bin/shell.dart similarity index 100% rename from bin/shell.dart rename to packages/process_run/bin/shell.dart diff --git a/dart_test.yaml b/packages/process_run/dart_test.yaml similarity index 100% rename from dart_test.yaml rename to packages/process_run/dart_test.yaml diff --git a/doc/more.md b/packages/process_run/doc/more.md similarity index 99% rename from doc/more.md rename to packages/process_run/doc/more.md index 360bf46..14df4f4 100644 --- a/doc/more.md +++ b/packages/process_run/doc/more.md @@ -13,7 +13,6 @@ Helper to format dart binaries argument that works cross-platforms Allow creating `ProcessCmd` object that can be run in different manner - ### Sample usage #### Using ProcessCmd diff --git a/doc/process_run_development.md b/packages/process_run/doc/process_run_development.md similarity index 100% rename from doc/process_run_development.md rename to packages/process_run/doc/process_run_development.md diff --git a/doc/shell.md b/packages/process_run/doc/shell.md similarity index 99% rename from doc/shell.md rename to packages/process_run/doc/shell.md index 22d9e6a..e7d45cb 100644 --- a/doc/shell.md +++ b/packages/process_run/doc/shell.md @@ -1,6 +1,6 @@ # Shell -Allows to run script from Mac/Windows/Linux in a portable way. Empty lines are added for lisibility +Allows to run script from Mac/Windows/Linux in a portable way. Empty lines are added for readibility ```dart var shell = Shell(); diff --git a/doc/shell_bin_info.md b/packages/process_run/doc/shell_bin_info.md similarity index 100% rename from doc/shell_bin_info.md rename to packages/process_run/doc/shell_bin_info.md diff --git a/doc/user_config.md b/packages/process_run/doc/user_config.md similarity index 100% rename from doc/user_config.md rename to packages/process_run/doc/user_config.md diff --git a/example/cmd_demo.dart b/packages/process_run/example/cmd_demo.dart similarity index 100% rename from example/cmd_demo.dart rename to packages/process_run/example/cmd_demo.dart diff --git a/example/dart_bin_version.dart b/packages/process_run/example/dart_bin_version.dart similarity index 100% rename from example/dart_bin_version.dart rename to packages/process_run/example/dart_bin_version.dart diff --git a/example/demo.dart b/packages/process_run/example/demo.dart similarity index 100% rename from example/demo.dart rename to packages/process_run/example/demo.dart diff --git a/example/echo.dart b/packages/process_run/example/echo.dart similarity index 100% rename from example/echo.dart rename to packages/process_run/example/echo.dart diff --git a/example/example.dart b/packages/process_run/example/example.dart similarity index 100% rename from example/example.dart rename to packages/process_run/example/example.dart diff --git a/example/flutter_bin_version.dart b/packages/process_run/example/flutter_bin_version.dart similarity index 100% rename from example/flutter_bin_version.dart rename to packages/process_run/example/flutter_bin_version.dart diff --git a/example/hex_utils.dart b/packages/process_run/example/hex_utils.dart similarity index 100% rename from example/hex_utils.dart rename to packages/process_run/example/hex_utils.dart diff --git a/example/info.dart b/packages/process_run/example/info.dart similarity index 100% rename from example/info.dart rename to packages/process_run/example/info.dart diff --git a/example/my_script.dart b/packages/process_run/example/my_script.dart similarity index 100% rename from example/my_script.dart rename to packages/process_run/example/my_script.dart diff --git a/example/no_env_user_paths.dart b/packages/process_run/example/no_env_user_paths.dart similarity index 100% rename from example/no_env_user_paths.dart rename to packages/process_run/example/no_env_user_paths.dart diff --git a/example/prompt.dart b/packages/process_run/example/prompt.dart similarity index 100% rename from example/prompt.dart rename to packages/process_run/example/prompt.dart diff --git a/example/shell/common.dart b/packages/process_run/example/shell/common.dart similarity index 100% rename from example/shell/common.dart rename to packages/process_run/example/shell/common.dart diff --git a/example/shell/env_file_location_new.dart b/packages/process_run/example/shell/env_file_location_new.dart similarity index 100% rename from example/shell/env_file_location_new.dart rename to packages/process_run/example/shell/env_file_location_new.dart diff --git a/example/shell/env_file_location_old.dart b/packages/process_run/example/shell/env_file_location_old.dart similarity index 100% rename from example/shell/env_file_location_old.dart rename to packages/process_run/example/shell/env_file_location_old.dart diff --git a/example/shell/get_var_now.dart b/packages/process_run/example/shell/get_var_now.dart similarity index 100% rename from example/shell/get_var_now.dart rename to packages/process_run/example/shell/get_var_now.dart diff --git a/example/shell/prepend_path_dummy.dart b/packages/process_run/example/shell/prepend_path_dummy.dart similarity index 100% rename from example/shell/prepend_path_dummy.dart rename to packages/process_run/example/shell/prepend_path_dummy.dart diff --git a/example/shell/set_alias_ll.dart b/packages/process_run/example/shell/set_alias_ll.dart similarity index 100% rename from example/shell/set_alias_ll.dart rename to packages/process_run/example/shell/set_alias_ll.dart diff --git a/example/shell/set_var_now.dart b/packages/process_run/example/shell/set_var_now.dart similarity index 100% rename from example/shell/set_var_now.dart rename to packages/process_run/example/shell/set_var_now.dart diff --git a/example/shell/shared_stdin.dart b/packages/process_run/example/shell/shared_stdin.dart similarity index 100% rename from example/shell/shared_stdin.dart rename to packages/process_run/example/shell/shared_stdin.dart diff --git a/example/shell/shared_stdin_not_used.dart b/packages/process_run/example/shell/shared_stdin_not_used.dart similarity index 100% rename from example/shell/shared_stdin_not_used.dart rename to packages/process_run/example/shell/shared_stdin_not_used.dart diff --git a/example/shell/shell_common.dart b/packages/process_run/example/shell/shell_common.dart similarity index 100% rename from example/shell/shell_common.dart rename to packages/process_run/example/shell/shell_common.dart diff --git a/example/shell/shell_info.dart b/packages/process_run/example/shell/shell_info.dart similarity index 100% rename from example/shell/shell_info.dart rename to packages/process_run/example/shell/shell_info.dart diff --git a/example/shell/shell_info_dump.dart b/packages/process_run/example/shell/shell_info_dump.dart similarity index 100% rename from example/shell/shell_info_dump.dart rename to packages/process_run/example/shell/shell_info_dump.dart diff --git a/example/shell_bin.dart b/packages/process_run/example/shell_bin.dart similarity index 100% rename from example/shell_bin.dart rename to packages/process_run/example/shell_bin.dart diff --git a/example/streamer.dart b/packages/process_run/example/streamer.dart similarity index 100% rename from example/streamer.dart rename to packages/process_run/example/streamer.dart diff --git a/example/sudo_example.dart b/packages/process_run/example/sudo_example.dart similarity index 100% rename from example/sudo_example.dart rename to packages/process_run/example/sudo_example.dart diff --git a/example/user_paths.dart b/packages/process_run/example/user_paths.dart similarity index 100% rename from example/user_paths.dart rename to packages/process_run/example/user_paths.dart diff --git a/lib/cmd_run.dart b/packages/process_run/lib/cmd_run.dart similarity index 100% rename from lib/cmd_run.dart rename to packages/process_run/lib/cmd_run.dart diff --git a/lib/dartbin.dart b/packages/process_run/lib/dartbin.dart similarity index 100% rename from lib/dartbin.dart rename to packages/process_run/lib/dartbin.dart diff --git a/lib/package/package.dart b/packages/process_run/lib/package/package.dart similarity index 100% rename from lib/package/package.dart rename to packages/process_run/lib/package/package.dart diff --git a/lib/process_cmd.dart b/packages/process_run/lib/process_cmd.dart similarity index 100% rename from lib/process_cmd.dart rename to packages/process_run/lib/process_cmd.dart diff --git a/lib/process_run.dart b/packages/process_run/lib/process_run.dart similarity index 87% rename from lib/process_run.dart rename to packages/process_run/lib/process_run.dart index 231b132..eb5fc48 100644 --- a/lib/process_run.dart +++ b/packages/process_run/lib/process_run.dart @@ -7,3 +7,4 @@ export 'package:process_run/src/shell_utils_common.dart' export 'shell.dart'; export 'src/process_run.dart' show runExecutableArguments, executableArgumentsToString; +export 'which.dart' show which, whichSync; diff --git a/lib/shell.dart b/packages/process_run/lib/shell.dart similarity index 100% rename from lib/shell.dart rename to packages/process_run/lib/shell.dart diff --git a/lib/shell_run.dart b/packages/process_run/lib/shell_run.dart similarity index 100% rename from lib/shell_run.dart rename to packages/process_run/lib/shell_run.dart diff --git a/lib/src/api/shell_common.dart b/packages/process_run/lib/src/api/shell_common.dart similarity index 100% rename from lib/src/api/shell_common.dart rename to packages/process_run/lib/src/api/shell_common.dart diff --git a/lib/src/bin/shell/dump.dart b/packages/process_run/lib/src/bin/shell/dump.dart similarity index 100% rename from lib/src/bin/shell/dump.dart rename to packages/process_run/lib/src/bin/shell/dump.dart diff --git a/lib/src/bin/shell/env.dart b/packages/process_run/lib/src/bin/shell/env.dart similarity index 97% rename from lib/src/bin/shell/env.dart rename to packages/process_run/lib/src/bin/shell/env.dart index aefedcf..1a8ea54 100644 --- a/lib/src/bin/shell/env.dart +++ b/packages/process_run/lib/src/bin/shell/env.dart @@ -58,7 +58,7 @@ class ShellEnvCommandBase extends ShellBinCommand { # # `path(s)` is a list of path, `var(s)` is a key/value map. # -# Content example. See for more information +# Content example. See for more information # # path: # - ./local @@ -74,7 +74,7 @@ class ShellEnvCommandBase extends ShellBinCommand { # # `path` is a list of path, `var` is a key/value map. # -# Content example. See for more information +# Content example. See for more information # # path: # - ~/Android/Sdk/tools/bin diff --git a/lib/src/bin/shell/env_alias.dart b/packages/process_run/lib/src/bin/shell/env_alias.dart similarity index 100% rename from lib/src/bin/shell/env_alias.dart rename to packages/process_run/lib/src/bin/shell/env_alias.dart diff --git a/lib/src/bin/shell/env_alias_delete.dart b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart similarity index 100% rename from lib/src/bin/shell/env_alias_delete.dart rename to packages/process_run/lib/src/bin/shell/env_alias_delete.dart diff --git a/lib/src/bin/shell/env_alias_dump.dart b/packages/process_run/lib/src/bin/shell/env_alias_dump.dart similarity index 100% rename from lib/src/bin/shell/env_alias_dump.dart rename to packages/process_run/lib/src/bin/shell/env_alias_dump.dart diff --git a/lib/src/bin/shell/env_alias_get.dart b/packages/process_run/lib/src/bin/shell/env_alias_get.dart similarity index 100% rename from lib/src/bin/shell/env_alias_get.dart rename to packages/process_run/lib/src/bin/shell/env_alias_get.dart diff --git a/lib/src/bin/shell/env_alias_set.dart b/packages/process_run/lib/src/bin/shell/env_alias_set.dart similarity index 100% rename from lib/src/bin/shell/env_alias_set.dart rename to packages/process_run/lib/src/bin/shell/env_alias_set.dart diff --git a/lib/src/bin/shell/env_delete.dart b/packages/process_run/lib/src/bin/shell/env_delete.dart similarity index 100% rename from lib/src/bin/shell/env_delete.dart rename to packages/process_run/lib/src/bin/shell/env_delete.dart diff --git a/lib/src/bin/shell/env_edit.dart b/packages/process_run/lib/src/bin/shell/env_edit.dart similarity index 100% rename from lib/src/bin/shell/env_edit.dart rename to packages/process_run/lib/src/bin/shell/env_edit.dart diff --git a/lib/src/bin/shell/env_file_content.dart b/packages/process_run/lib/src/bin/shell/env_file_content.dart similarity index 100% rename from lib/src/bin/shell/env_file_content.dart rename to packages/process_run/lib/src/bin/shell/env_file_content.dart diff --git a/lib/src/bin/shell/env_path.dart b/packages/process_run/lib/src/bin/shell/env_path.dart similarity index 100% rename from lib/src/bin/shell/env_path.dart rename to packages/process_run/lib/src/bin/shell/env_path.dart diff --git a/lib/src/bin/shell/env_path_delete.dart b/packages/process_run/lib/src/bin/shell/env_path_delete.dart similarity index 100% rename from lib/src/bin/shell/env_path_delete.dart rename to packages/process_run/lib/src/bin/shell/env_path_delete.dart diff --git a/lib/src/bin/shell/env_path_dump.dart b/packages/process_run/lib/src/bin/shell/env_path_dump.dart similarity index 100% rename from lib/src/bin/shell/env_path_dump.dart rename to packages/process_run/lib/src/bin/shell/env_path_dump.dart diff --git a/lib/src/bin/shell/env_path_get.dart b/packages/process_run/lib/src/bin/shell/env_path_get.dart similarity index 100% rename from lib/src/bin/shell/env_path_get.dart rename to packages/process_run/lib/src/bin/shell/env_path_get.dart diff --git a/lib/src/bin/shell/env_path_prepend.dart b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart similarity index 100% rename from lib/src/bin/shell/env_path_prepend.dart rename to packages/process_run/lib/src/bin/shell/env_path_prepend.dart diff --git a/lib/src/bin/shell/env_var.dart b/packages/process_run/lib/src/bin/shell/env_var.dart similarity index 100% rename from lib/src/bin/shell/env_var.dart rename to packages/process_run/lib/src/bin/shell/env_var.dart diff --git a/lib/src/bin/shell/env_var_delete.dart b/packages/process_run/lib/src/bin/shell/env_var_delete.dart similarity index 100% rename from lib/src/bin/shell/env_var_delete.dart rename to packages/process_run/lib/src/bin/shell/env_var_delete.dart diff --git a/lib/src/bin/shell/env_var_dump.dart b/packages/process_run/lib/src/bin/shell/env_var_dump.dart similarity index 100% rename from lib/src/bin/shell/env_var_dump.dart rename to packages/process_run/lib/src/bin/shell/env_var_dump.dart diff --git a/lib/src/bin/shell/env_var_get.dart b/packages/process_run/lib/src/bin/shell/env_var_get.dart similarity index 100% rename from lib/src/bin/shell/env_var_get.dart rename to packages/process_run/lib/src/bin/shell/env_var_get.dart diff --git a/lib/src/bin/shell/env_var_set.dart b/packages/process_run/lib/src/bin/shell/env_var_set.dart similarity index 100% rename from lib/src/bin/shell/env_var_set.dart rename to packages/process_run/lib/src/bin/shell/env_var_set.dart diff --git a/lib/src/bin/shell/import.dart b/packages/process_run/lib/src/bin/shell/import.dart similarity index 100% rename from lib/src/bin/shell/import.dart rename to packages/process_run/lib/src/bin/shell/import.dart diff --git a/lib/src/bin/shell/run.dart b/packages/process_run/lib/src/bin/shell/run.dart similarity index 100% rename from lib/src/bin/shell/run.dart rename to packages/process_run/lib/src/bin/shell/run.dart diff --git a/lib/src/bin/shell/shell.dart b/packages/process_run/lib/src/bin/shell/shell.dart similarity index 100% rename from lib/src/bin/shell/shell.dart rename to packages/process_run/lib/src/bin/shell/shell.dart diff --git a/lib/src/bin/shell/shell_bin_command.dart b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart similarity index 100% rename from lib/src/bin/shell/shell_bin_command.dart rename to packages/process_run/lib/src/bin/shell/shell_bin_command.dart diff --git a/lib/src/build_runner.dart b/packages/process_run/lib/src/build_runner.dart similarity index 100% rename from lib/src/build_runner.dart rename to packages/process_run/lib/src/build_runner.dart diff --git a/lib/src/characters.dart b/packages/process_run/lib/src/characters.dart similarity index 100% rename from lib/src/characters.dart rename to packages/process_run/lib/src/characters.dart diff --git a/lib/src/command_line.dart b/packages/process_run/lib/src/command_line.dart similarity index 100% rename from lib/src/command_line.dart rename to packages/process_run/lib/src/command_line.dart diff --git a/lib/src/common/constant.dart b/packages/process_run/lib/src/common/constant.dart similarity index 100% rename from lib/src/common/constant.dart rename to packages/process_run/lib/src/common/constant.dart diff --git a/lib/src/common/dartbin.dart b/packages/process_run/lib/src/common/dartbin.dart similarity index 100% rename from lib/src/common/dartbin.dart rename to packages/process_run/lib/src/common/dartbin.dart diff --git a/lib/src/common/dev_utils.dart b/packages/process_run/lib/src/common/dev_utils.dart similarity index 100% rename from lib/src/common/dev_utils.dart rename to packages/process_run/lib/src/common/dev_utils.dart diff --git a/lib/src/common/import.dart b/packages/process_run/lib/src/common/import.dart similarity index 100% rename from lib/src/common/import.dart rename to packages/process_run/lib/src/common/import.dart diff --git a/lib/src/common/import_common.dart b/packages/process_run/lib/src/common/import_common.dart similarity index 100% rename from lib/src/common/import_common.dart rename to packages/process_run/lib/src/common/import_common.dart diff --git a/lib/src/dartbin_cmd.dart b/packages/process_run/lib/src/dartbin_cmd.dart similarity index 100% rename from lib/src/dartbin_cmd.dart rename to packages/process_run/lib/src/dartbin_cmd.dart diff --git a/lib/src/dartbin_impl.dart b/packages/process_run/lib/src/dartbin_impl.dart similarity index 100% rename from lib/src/dartbin_impl.dart rename to packages/process_run/lib/src/dartbin_impl.dart diff --git a/lib/src/dev_cmd_run.dart b/packages/process_run/lib/src/dev_cmd_run.dart similarity index 100% rename from lib/src/dev_cmd_run.dart rename to packages/process_run/lib/src/dev_cmd_run.dart diff --git a/lib/src/env_utils.dart b/packages/process_run/lib/src/env_utils.dart similarity index 100% rename from lib/src/env_utils.dart rename to packages/process_run/lib/src/env_utils.dart diff --git a/lib/src/flutterbin_cmd.dart b/packages/process_run/lib/src/flutterbin_cmd.dart similarity index 100% rename from lib/src/flutterbin_cmd.dart rename to packages/process_run/lib/src/flutterbin_cmd.dart diff --git a/lib/src/io/env_io.dart b/packages/process_run/lib/src/io/env_io.dart similarity index 92% rename from lib/src/io/env_io.dart rename to packages/process_run/lib/src/io/env_io.dart index db3ce27..3e4b55c 100644 --- a/lib/src/io/env_io.dart +++ b/packages/process_run/lib/src/io/env_io.dart @@ -40,7 +40,7 @@ class ShellEnvIoHelper { # # `path(s)` is a list of path, `var(s)` is a key/value map. # -# Content example. See for more information +# Content example. See for more information # # path: # - ./local @@ -56,7 +56,7 @@ class ShellEnvIoHelper { # # `path` is a list of path, `var` is a key/value map. # -# Content example. See for more information +# Content example. See for more information # # path: # - ~/Android/Sdk/tools/bin diff --git a/lib/src/io/env_var_delete_io.dart b/packages/process_run/lib/src/io/env_var_delete_io.dart similarity index 100% rename from lib/src/io/env_var_delete_io.dart rename to packages/process_run/lib/src/io/env_var_delete_io.dart diff --git a/lib/src/io/env_var_get_io.dart b/packages/process_run/lib/src/io/env_var_get_io.dart similarity index 100% rename from lib/src/io/env_var_get_io.dart rename to packages/process_run/lib/src/io/env_var_get_io.dart diff --git a/lib/src/io/env_var_set_io.dart b/packages/process_run/lib/src/io/env_var_set_io.dart similarity index 100% rename from lib/src/io/env_var_set_io.dart rename to packages/process_run/lib/src/io/env_var_set_io.dart diff --git a/lib/src/io/io_import.dart b/packages/process_run/lib/src/io/io_import.dart similarity index 100% rename from lib/src/io/io_import.dart rename to packages/process_run/lib/src/io/io_import.dart diff --git a/lib/src/io/shared_stdin.dart b/packages/process_run/lib/src/io/shared_stdin.dart similarity index 100% rename from lib/src/io/shared_stdin.dart rename to packages/process_run/lib/src/io/shared_stdin.dart diff --git a/lib/src/io/shell_words.dart b/packages/process_run/lib/src/io/shell_words.dart similarity index 100% rename from lib/src/io/shell_words.dart rename to packages/process_run/lib/src/io/shell_words.dart diff --git a/lib/src/lines_utils.dart b/packages/process_run/lib/src/lines_utils.dart similarity index 100% rename from lib/src/lines_utils.dart rename to packages/process_run/lib/src/lines_utils.dart diff --git a/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart similarity index 100% rename from lib/src/lines_utils_common.dart rename to packages/process_run/lib/src/lines_utils_common.dart diff --git a/lib/src/mixin/file_content.dart b/packages/process_run/lib/src/mixin/file_content.dart similarity index 100% rename from lib/src/mixin/file_content.dart rename to packages/process_run/lib/src/mixin/file_content.dart diff --git a/lib/src/mixin/shell_bin.dart b/packages/process_run/lib/src/mixin/shell_bin.dart similarity index 100% rename from lib/src/mixin/shell_bin.dart rename to packages/process_run/lib/src/mixin/shell_bin.dart diff --git a/lib/src/mixin/shell_common.dart b/packages/process_run/lib/src/mixin/shell_common.dart similarity index 100% rename from lib/src/mixin/shell_common.dart rename to packages/process_run/lib/src/mixin/shell_common.dart diff --git a/lib/src/platform/platform.dart b/packages/process_run/lib/src/platform/platform.dart similarity index 100% rename from lib/src/platform/platform.dart rename to packages/process_run/lib/src/platform/platform.dart diff --git a/lib/src/platform/platform_io.dart b/packages/process_run/lib/src/platform/platform_io.dart similarity index 100% rename from lib/src/platform/platform_io.dart rename to packages/process_run/lib/src/platform/platform_io.dart diff --git a/lib/src/platform/platform_stub.dart b/packages/process_run/lib/src/platform/platform_stub.dart similarity index 100% rename from lib/src/platform/platform_stub.dart rename to packages/process_run/lib/src/platform/platform_stub.dart diff --git a/lib/src/process_cmd.dart b/packages/process_run/lib/src/process_cmd.dart similarity index 100% rename from lib/src/process_cmd.dart rename to packages/process_run/lib/src/process_cmd.dart diff --git a/lib/src/process_result_common_extension.dart b/packages/process_run/lib/src/process_result_common_extension.dart similarity index 100% rename from lib/src/process_result_common_extension.dart rename to packages/process_run/lib/src/process_result_common_extension.dart diff --git a/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart similarity index 100% rename from lib/src/process_run.dart rename to packages/process_run/lib/src/process_run.dart diff --git a/lib/src/prompt.dart b/packages/process_run/lib/src/prompt.dart similarity index 100% rename from lib/src/prompt.dart rename to packages/process_run/lib/src/prompt.dart diff --git a/lib/src/script_filename.dart b/packages/process_run/lib/src/script_filename.dart similarity index 100% rename from lib/src/script_filename.dart rename to packages/process_run/lib/src/script_filename.dart diff --git a/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart similarity index 100% rename from lib/src/shell.dart rename to packages/process_run/lib/src/shell.dart diff --git a/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart similarity index 100% rename from lib/src/shell_common.dart rename to packages/process_run/lib/src/shell_common.dart diff --git a/lib/src/shell_common_io.dart b/packages/process_run/lib/src/shell_common_io.dart similarity index 100% rename from lib/src/shell_common_io.dart rename to packages/process_run/lib/src/shell_common_io.dart diff --git a/lib/src/shell_context_common.dart b/packages/process_run/lib/src/shell_context_common.dart similarity index 100% rename from lib/src/shell_context_common.dart rename to packages/process_run/lib/src/shell_context_common.dart diff --git a/lib/src/shell_context_io.dart b/packages/process_run/lib/src/shell_context_io.dart similarity index 100% rename from lib/src/shell_context_io.dart rename to packages/process_run/lib/src/shell_context_io.dart diff --git a/lib/src/shell_environment.dart b/packages/process_run/lib/src/shell_environment.dart similarity index 100% rename from lib/src/shell_environment.dart rename to packages/process_run/lib/src/shell_environment.dart diff --git a/lib/src/shell_environment_common.dart b/packages/process_run/lib/src/shell_environment_common.dart similarity index 100% rename from lib/src/shell_environment_common.dart rename to packages/process_run/lib/src/shell_environment_common.dart diff --git a/lib/src/shell_utils.dart b/packages/process_run/lib/src/shell_utils.dart similarity index 100% rename from lib/src/shell_utils.dart rename to packages/process_run/lib/src/shell_utils.dart diff --git a/lib/src/shell_utils_common.dart b/packages/process_run/lib/src/shell_utils_common.dart similarity index 100% rename from lib/src/shell_utils_common.dart rename to packages/process_run/lib/src/shell_utils_common.dart diff --git a/lib/src/shell_utils_io.dart b/packages/process_run/lib/src/shell_utils_io.dart similarity index 100% rename from lib/src/shell_utils_io.dart rename to packages/process_run/lib/src/shell_utils_io.dart diff --git a/lib/src/user_config.dart b/packages/process_run/lib/src/user_config.dart similarity index 99% rename from lib/src/user_config.dart rename to packages/process_run/lib/src/user_config.dart index 5e6c293..c262191 100644 --- a/lib/src/user_config.dart +++ b/packages/process_run/lib/src/user_config.dart @@ -65,7 +65,7 @@ set userConfig(UserConfig userConfig) => _userConfig = userConfig; /// It can be overriden to include user defined paths loaded from /// ~/.config/tekartik/process_run/env.yam /// -/// See [https://github.com/tekartik/process_run.dart/blob/master/doc/user_config.md] +/// See [https://github.com/tekartik/process_run.dart/blob/master/packages/process_run/doc/user_config.md] /// in the documentation for more information. /// List get userPaths => userConfig.paths; diff --git a/lib/src/utils.dart b/packages/process_run/lib/src/utils.dart similarity index 100% rename from lib/src/utils.dart rename to packages/process_run/lib/src/utils.dart diff --git a/lib/src/webdev.dart b/packages/process_run/lib/src/webdev.dart similarity index 100% rename from lib/src/webdev.dart rename to packages/process_run/lib/src/webdev.dart diff --git a/lib/src/which.dart b/packages/process_run/lib/src/which.dart similarity index 100% rename from lib/src/which.dart rename to packages/process_run/lib/src/which.dart diff --git a/lib/utils/process_result_extension.dart b/packages/process_run/lib/utils/process_result_extension.dart similarity index 100% rename from lib/utils/process_result_extension.dart rename to packages/process_run/lib/utils/process_result_extension.dart diff --git a/lib/which.dart b/packages/process_run/lib/which.dart similarity index 100% rename from lib/which.dart rename to packages/process_run/lib/which.dart diff --git a/pubspec.yaml b/packages/process_run/pubspec.yaml similarity index 87% rename from pubspec.yaml rename to packages/process_run/pubspec.yaml index 6b3e01e..c5997f9 100644 --- a/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,7 +1,7 @@ name: process_run version: 0.12.5+3 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. -homepage: https://github.com/tekartik/process_run.dart +homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run environment: sdk: '>=2.18.0 <3.0.0' diff --git a/test/bin/bin_shell_test.dart b/packages/process_run/test/bin/bin_shell_test.dart similarity index 100% rename from test/bin/bin_shell_test.dart rename to packages/process_run/test/bin/bin_shell_test.dart diff --git a/test/build_runner_test.dart b/packages/process_run/test/build_runner_test.dart similarity index 100% rename from test/build_runner_test.dart rename to packages/process_run/test/build_runner_test.dart diff --git a/test/cmd_run_api_test.dart b/packages/process_run/test/cmd_run_api_test.dart similarity index 100% rename from test/cmd_run_api_test.dart rename to packages/process_run/test/cmd_run_api_test.dart diff --git a/test/cmd_run_exception_test.dart b/packages/process_run/test/cmd_run_exception_test.dart similarity index 100% rename from test/cmd_run_exception_test.dart rename to packages/process_run/test/cmd_run_exception_test.dart diff --git a/test/cmd_run_test.dart b/packages/process_run/test/cmd_run_test.dart similarity index 100% rename from test/cmd_run_test.dart rename to packages/process_run/test/cmd_run_test.dart diff --git a/test/compile_test.dart b/packages/process_run/test/compile_test.dart similarity index 100% rename from test/compile_test.dart rename to packages/process_run/test/compile_test.dart diff --git a/test/dart_compile_js_test.dart b/packages/process_run/test/dart_compile_js_test.dart similarity index 100% rename from test/dart_compile_js_test.dart rename to packages/process_run/test/dart_compile_js_test.dart diff --git a/test/dart_doc_test.dart b/packages/process_run/test/dart_doc_test.dart similarity index 100% rename from test/dart_doc_test.dart rename to packages/process_run/test/dart_doc_test.dart diff --git a/test/dartbin_api_test.dart b/packages/process_run/test/dartbin_api_test.dart similarity index 100% rename from test/dartbin_api_test.dart rename to packages/process_run/test/dartbin_api_test.dart diff --git a/test/dartbin_cmd_test.dart b/packages/process_run/test/dartbin_cmd_test.dart similarity index 100% rename from test/dartbin_cmd_test.dart rename to packages/process_run/test/dartbin_cmd_test.dart diff --git a/test/dartbin_cmd_verbose_test_.dart b/packages/process_run/test/dartbin_cmd_verbose_test_.dart similarity index 100% rename from test/dartbin_cmd_verbose_test_.dart rename to packages/process_run/test/dartbin_cmd_verbose_test_.dart diff --git a/test/dartbin_test.dart b/packages/process_run/test/dartbin_test.dart similarity index 100% rename from test/dartbin_test.dart rename to packages/process_run/test/dartbin_test.dart diff --git a/test/dartdevc_test.dart b/packages/process_run/test/dartdevc_test.dart similarity index 100% rename from test/dartdevc_test.dart rename to packages/process_run/test/dartdevc_test.dart diff --git a/test/dartdoc_test.dart b/packages/process_run/test/dartdoc_test.dart similarity index 100% rename from test/dartdoc_test.dart rename to packages/process_run/test/dartdoc_test.dart diff --git a/test/dartfmt_test.dart b/packages/process_run/test/dartfmt_test.dart similarity index 100% rename from test/dartfmt_test.dart rename to packages/process_run/test/dartfmt_test.dart diff --git a/test/data/main.dart b/packages/process_run/test/data/main.dart similarity index 100% rename from test/data/main.dart rename to packages/process_run/test/data/main.dart diff --git a/test/data/test_env1.yaml b/packages/process_run/test/data/test_env1.yaml similarity index 100% rename from test/data/test_env1.yaml rename to packages/process_run/test/data/test_env1.yaml diff --git a/test/data/test_env2.yaml b/packages/process_run/test/data/test_env2.yaml similarity index 100% rename from test/data/test_env2.yaml rename to packages/process_run/test/data/test_env2.yaml diff --git a/test/data/test_env3_empty.yaml b/packages/process_run/test/data/test_env3_empty.yaml similarity index 100% rename from test/data/test_env3_empty.yaml rename to packages/process_run/test/data/test_env3_empty.yaml diff --git a/test/data/test_user_env1_local_env_file_override.yaml b/packages/process_run/test/data/test_user_env1_local_env_file_override.yaml similarity index 100% rename from test/data/test_user_env1_local_env_file_override.yaml rename to packages/process_run/test/data/test_user_env1_local_env_file_override.yaml diff --git a/test/data/test_user_env2_empty.yaml b/packages/process_run/test/data/test_user_env2_empty.yaml similarity index 100% rename from test/data/test_user_env2_empty.yaml rename to packages/process_run/test/data/test_user_env2_empty.yaml diff --git a/test/data/test_user_env3_safe.yaml b/packages/process_run/test/data/test_user_env3_safe.yaml similarity index 100% rename from test/data/test_user_env3_safe.yaml rename to packages/process_run/test/data/test_user_env3_safe.yaml diff --git a/test/doc_test.dart b/packages/process_run/test/doc_test.dart similarity index 100% rename from test/doc_test.dart rename to packages/process_run/test/doc_test.dart diff --git a/test/echo_test.dart b/packages/process_run/test/echo_test.dart similarity index 100% rename from test/echo_test.dart rename to packages/process_run/test/echo_test.dart diff --git a/test/example_hex_utils_test_.dart b/packages/process_run/test/example_hex_utils_test_.dart similarity index 100% rename from test/example_hex_utils_test_.dart rename to packages/process_run/test/example_hex_utils_test_.dart diff --git a/test/flutterbin_cmd_test.dart b/packages/process_run/test/flutterbin_cmd_test.dart similarity index 100% rename from test/flutterbin_cmd_test.dart rename to packages/process_run/test/flutterbin_cmd_test.dart diff --git a/test/flutterbin_impl_test.dart b/packages/process_run/test/flutterbin_impl_test.dart similarity index 100% rename from test/flutterbin_impl_test.dart rename to packages/process_run/test/flutterbin_impl_test.dart diff --git a/test/hex_utils.dart b/packages/process_run/test/hex_utils.dart similarity index 100% rename from test/hex_utils.dart rename to packages/process_run/test/hex_utils.dart diff --git a/test/package_test.dart b/packages/process_run/test/package_test.dart similarity index 100% rename from test/package_test.dart rename to packages/process_run/test/package_test.dart diff --git a/test/process_cmd_api_test.dart b/packages/process_run/test/process_cmd_api_test.dart similarity index 100% rename from test/process_cmd_api_test.dart rename to packages/process_run/test/process_cmd_api_test.dart diff --git a/test/process_cmd_test.dart b/packages/process_run/test/process_cmd_test.dart similarity index 100% rename from test/process_cmd_test.dart rename to packages/process_run/test/process_cmd_test.dart diff --git a/test/process_run_0_14_compat_test.dart b/packages/process_run/test/process_run_0_14_compat_test.dart similarity index 100% rename from test/process_run_0_14_compat_test.dart rename to packages/process_run/test/process_run_0_14_compat_test.dart diff --git a/test/process_run_in_test2_.dart b/packages/process_run/test/process_run_in_test2_.dart similarity index 100% rename from test/process_run_in_test2_.dart rename to packages/process_run/test/process_run_in_test2_.dart diff --git a/test/process_run_in_test_.dart b/packages/process_run/test/process_run_in_test_.dart similarity index 100% rename from test/process_run_in_test_.dart rename to packages/process_run/test/process_run_in_test_.dart diff --git a/test/process_run_out_test_.dart b/packages/process_run/test/process_run_out_test_.dart similarity index 100% rename from test/process_run_out_test_.dart rename to packages/process_run/test/process_run_out_test_.dart diff --git a/test/process_run_test.dart b/packages/process_run/test/process_run_test.dart similarity index 100% rename from test/process_run_test.dart rename to packages/process_run/test/process_run_test.dart diff --git a/test/process_run_test_common.dart b/packages/process_run/test/process_run_test_common.dart similarity index 100% rename from test/process_run_test_common.dart rename to packages/process_run/test/process_run_test_common.dart diff --git a/test/pub_test.dart b/packages/process_run/test/pub_test.dart similarity index 100% rename from test/pub_test.dart rename to packages/process_run/test/pub_test.dart diff --git a/test/shell_api_test.dart b/packages/process_run/test/shell_api_test.dart similarity index 100% rename from test/shell_api_test.dart rename to packages/process_run/test/shell_api_test.dart diff --git a/test/shell_common_api_test.dart b/packages/process_run/test/shell_common_api_test.dart similarity index 100% rename from test/shell_common_api_test.dart rename to packages/process_run/test/shell_common_api_test.dart diff --git a/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart similarity index 100% rename from test/shell_common_test.dart rename to packages/process_run/test/shell_common_test.dart diff --git a/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart similarity index 100% rename from test/shell_environment_test.dart rename to packages/process_run/test/shell_environment_test.dart diff --git a/test/shell_lines_controller_test.dart b/packages/process_run/test/shell_lines_controller_test.dart similarity index 100% rename from test/shell_lines_controller_test.dart rename to packages/process_run/test/shell_lines_controller_test.dart diff --git a/test/shell_run_test.dart b/packages/process_run/test/shell_run_test.dart similarity index 100% rename from test/shell_run_test.dart rename to packages/process_run/test/shell_run_test.dart diff --git a/test/shell_test.dart b/packages/process_run/test/shell_test.dart similarity index 100% rename from test/shell_test.dart rename to packages/process_run/test/shell_test.dart diff --git a/test/src/current_dir b/packages/process_run/test/src/current_dir similarity index 100% rename from test/src/current_dir rename to packages/process_run/test/src/current_dir diff --git a/test/src/current_dir.bat b/packages/process_run/test/src/current_dir.bat similarity index 100% rename from test/src/current_dir.bat rename to packages/process_run/test/src/current_dir.bat diff --git a/test/src/current_dir.dart b/packages/process_run/test/src/current_dir.dart similarity index 100% rename from test/src/current_dir.dart rename to packages/process_run/test/src/current_dir.dart diff --git a/test/src/shell_impl_test.dart b/packages/process_run/test/src/shell_impl_test.dart similarity index 100% rename from test/src/shell_impl_test.dart rename to packages/process_run/test/src/shell_impl_test.dart diff --git a/test/src/success_test.dart b/packages/process_run/test/src/success_test.dart similarity index 100% rename from test/src/success_test.dart rename to packages/process_run/test/src/success_test.dart diff --git a/test/src_dartbin_cmd_test.dart b/packages/process_run/test/src_dartbin_cmd_test.dart similarity index 100% rename from test/src_dartbin_cmd_test.dart rename to packages/process_run/test/src_dartbin_cmd_test.dart diff --git a/test/src_shell_test.dart b/packages/process_run/test/src_shell_test.dart similarity index 100% rename from test/src_shell_test.dart rename to packages/process_run/test/src_shell_test.dart diff --git a/test/src_shell_utils_test.dart b/packages/process_run/test/src_shell_utils_test.dart similarity index 100% rename from test/src_shell_utils_test.dart rename to packages/process_run/test/src_shell_utils_test.dart diff --git a/test/src_user_config_test.dart b/packages/process_run/test/src_user_config_test.dart similarity index 100% rename from test/src_user_config_test.dart rename to packages/process_run/test/src_user_config_test.dart diff --git a/test/webdev_test.dart b/packages/process_run/test/webdev_test.dart similarity index 100% rename from test/webdev_test.dart rename to packages/process_run/test/webdev_test.dart diff --git a/test/which_test.dart b/packages/process_run/test/which_test.dart similarity index 100% rename from test/which_test.dart rename to packages/process_run/test/which_test.dart diff --git a/tool/manual_test_prompt.dart b/packages/process_run/tool/manual_test_prompt.dart similarity index 100% rename from tool/manual_test_prompt.dart rename to packages/process_run/tool/manual_test_prompt.dart diff --git a/tool/run_ci.dart b/packages/process_run/tool/run_ci.dart similarity index 66% rename from tool/run_ci.dart rename to packages/process_run/tool/run_ci.dart index baa7be7..0085485 100644 --- a/tool/run_ci.dart +++ b/packages/process_run/tool/run_ci.dart @@ -9,9 +9,8 @@ Future main() async { print(Platform.version); await shell.run(''' # Analyze code & format -dart pub global activate dart_style -dart pub global run dart_style:format -n --set-exit-if-changed bin example lib test tool - +dart format --set-exit-if-changed bin example lib test tool +dart analyze --fatal-infos --fatal-warnings . # Run tests dart test '''); diff --git a/tool/run_test_node.dart b/packages/process_run/tool/run_test_node.dart similarity index 100% rename from tool/run_test_node.dart rename to packages/process_run/tool/run_test_node.dart diff --git a/tool/run_test_quick.dart b/packages/process_run/tool/run_test_quick.dart similarity index 100% rename from tool/run_test_quick.dart rename to packages/process_run/tool/run_test_quick.dart diff --git a/tool/tag.dart b/packages/process_run/tool/tag.dart similarity index 100% rename from tool/tag.dart rename to packages/process_run/tool/tag.dart diff --git a/tool/travis.dart b/packages/process_run/tool/travis.dart similarity index 100% rename from tool/travis.dart rename to packages/process_run/tool/travis.dart From 44e7a7395970821a70172b696aea954b670b8aae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 14:28:53 +0000 Subject: [PATCH 049/150] build(deps): bump dart-lang/setup-dart from 1.3 to 1.4 Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/v1.3...v1.4) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/run_ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index 685ea6b..f498358 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -18,7 +18,7 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] dart: [stable, beta, dev] steps: - - uses: dart-lang/setup-dart@v1.3 + - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} - uses: actions/checkout@v2 From 215b21405add53ecb6ea5bc6c4cf30286fd389f4 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 20 Apr 2023 16:34:07 +0200 Subject: [PATCH 050/150] test: remove obsolete webdev test --- .gitignore | 7 ++++ .../process_run/test/build_runner_test.dart | 9 ----- packages/process_run/test/webdev_test.dart | 40 ------------------- 3 files changed, 7 insertions(+), 49 deletions(-) create mode 100644 .gitignore delete mode 100644 packages/process_run/test/webdev_test.dart diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..65808c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +# IDE +.vscode/ +.idea/ +*.iml + +# Local files +.local/ \ No newline at end of file diff --git a/packages/process_run/test/build_runner_test.dart b/packages/process_run/test/build_runner_test.dart index 2977f54..0c6bea5 100644 --- a/packages/process_run/test/build_runner_test.dart +++ b/packages/process_run/test/build_runner_test.dart @@ -12,15 +12,6 @@ void defineTests() { final result = await runCmd(PbrCmd(['--help'])); expect(result.exitCode, 0); expect(result.stdout, contains('Usage: build_runner')); - - /* - this does not work when ran from IDE - // The raw version is displayed - result = await runCmd(WebDevCmd(['--version'])..runInShell = true); - var version = Version.parse((result.stdout as String).trim()); - expect(version, greaterThan(Version(1, 0, 0))); - expect(result.exitCode, 0); - */ }); }); } diff --git a/packages/process_run/test/webdev_test.dart b/packages/process_run/test/webdev_test.dart deleted file mode 100644 index 3089a38..0000000 --- a/packages/process_run/test/webdev_test.dart +++ /dev/null @@ -1,40 +0,0 @@ -@TestOn('vm') -library process_run.dartfmt_test; - -import 'dart:convert'; - -import 'package:process_run/cmd_run.dart'; -import 'package:test/test.dart'; - -void main() => defineTests(); - -void defineTests() { - group('webdev', () { - setUp(() async { - var lines = LineSplitter.split( - (await runCmd(PubCmd(['global', 'list']))).stdout as String); - for (var line in lines) { - if (line.split(' ')[0] == 'webdev') { - return; - } - } - await runCmd(PubCmd(['global', 'activate', 'webdev'])); - }); - test('help', () async { - final result = await runCmd(WebDevCmd(['--help'])); - expect(result.exitCode, 0); - expect(result.stdout, contains('Usage: webdev')); - - /* - this does not work when ran from IDE - // The raw version is displayed - result = await runCmd(WebDevCmd(['--version'])..runInShell = true); - var version = Version.parse((result.stdout as String).trim()); - expect(version, greaterThan(Version(1, 0, 0))); - expect(result.exitCode, 0); - */ - }); - }, - // Setup (webdev) could be long - timeout: const Timeout(Duration(seconds: 300))); -} From 4a1b8840e5cfdd71d9ebb7942e4d52f6694e668a Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 20 Apr 2023 16:35:09 +0200 Subject: [PATCH 051/150] [process_run] v0.13.0 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 54ad6c2..6781646 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.13.0 + +* Dart 3 support + ## 0.12.5+3 * Fix `clone` in `ShellMixin`. diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index c5997f9..d5525c6 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,10 +1,10 @@ name: process_run -version: 0.12.5+3 +version: 0.13.0 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run environment: - sdk: '>=2.18.0 <3.0.0' + sdk: '>=2.18.0 <4.0.0' dependencies: path: '>=1.8.0 <3.0.0' From b93eff485fdb7047cb584716f0c68d9cc0352102 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 14:43:13 +0000 Subject: [PATCH 052/150] build(deps): bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/run_ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index f498358..098e76e 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -21,7 +21,7 @@ jobs: - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: dart --version - run: dart pub get - run: dart run tool/run_ci.dart \ No newline at end of file From 73da81475daa9353f8fd39871cc0366392311eb2 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 20 Apr 2023 16:45:45 +0200 Subject: [PATCH 053/150] test: remove compat test --- .../process_run/test/process_run_0_14_compat_test.dart | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 packages/process_run/test/process_run_0_14_compat_test.dart diff --git a/packages/process_run/test/process_run_0_14_compat_test.dart b/packages/process_run/test/process_run_0_14_compat_test.dart deleted file mode 100644 index 0110786..0000000 --- a/packages/process_run/test/process_run_0_14_compat_test.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:process_run/process_run.dart'; -import 'package:test/test.dart'; - -void main() { - test('run', () async { - await run('echo test'); - }); -} From b9fbf3cf83140f6761ed88615c93a380e5b9b0af Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 20 Apr 2023 17:28:59 +0200 Subject: [PATCH 054/150] add FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..c3c9be0 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: alextekartik From cb8829d0b88791f1cf42ade84d68f9ddb6054db8 Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 10 May 2023 23:10:01 +0200 Subject: [PATCH 055/150] test: run ci on 2.19.6 too --- .github/workflows/run_ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index 098e76e..a54e422 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -16,7 +16,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - dart: [stable, beta, dev] + dart: [2.19.6, stable, beta, dev] steps: - uses: dart-lang/setup-dart@v1.4 with: From 7849c6e4885c2400bb5779c6fc5d07aa90e4ecd0 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 12 Jun 2023 15:19:29 +0200 Subject: [PATCH 056/150] dart 3 format fix --- packages/process_run/lib/src/shell.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 1d7e04d..2b6ea08 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -174,14 +174,13 @@ abstract class Shell implements ShellCore { {bool? throwOnError, String? workingDirectory, // Don't change environment - @Deprecated('Don\'t change map') - Map? environment, + @Deprecated('Don\'t change map') Map? environment, /// Explicetely set e new environment // ShellEnvironment? shellEnvironment, @Deprecated('Don\'t change includeParentEnvironment') - // Don't change includeParentEnvironment - bool? includeParentEnvironment, + // Don't change includeParentEnvironment + bool? includeParentEnvironment, bool? runInShell, Encoding? stdoutEncoding, Encoding? stderrEncoding, From f2296378346453429ed0ebd61bf5ebb91b51cd72 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 10 Jul 2023 19:15:44 +0200 Subject: [PATCH 057/150] dart3a branch --- .github/dependabot.yml | 9 ---- .github/workflows/run_ci.yml | 2 +- .../process_run/lib/src/shell_common_io.dart | 41 +------------------ packages/process_run/pubspec.yaml | 2 +- 4 files changed, 3 insertions(+), 51 deletions(-) delete mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 1603cdd..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,9 +0,0 @@ -# Dependabot configuration file. -# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates -version: 2 - -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "monthly" diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index a54e422..1c83bfa 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -16,7 +16,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - dart: [2.19.6, stable, beta, dev] + dart: [3.0.5, stable, beta, dev] steps: - uses: dart-lang/setup-dart@v1.4 with: diff --git a/packages/process_run/lib/src/shell_common_io.dart b/packages/process_run/lib/src/shell_common_io.dart index a207bb3..45d364e 100644 --- a/packages/process_run/lib/src/shell_common_io.dart +++ b/packages/process_run/lib/src/shell_common_io.dart @@ -1,41 +1,8 @@ -import 'dart:io' as io; - import 'package:process_run/shell.dart' as io; import 'package:process_run/src/io/env_var_set_io.dart'; import 'shell_common.dart'; -class ProcessResultIo implements ProcessResult { - final io.ProcessResult impl; - - ProcessResultIo(this.impl); - - @override - int get exitCode => impl.exitCode; - - @override - int get pid => impl.pid; - - @override - Object? get stderr => impl.stderr; - - @override - Object? get stdout => impl.stdout; - - @override - String toString() => 'exitCode $exitCode, pid $pid'; -} - -/* -Future _wrapIoException(Future Function() action) async { - try { - return await action(); - } on io.ShellException catch (e) { - throw ShellExceptionIo(e); - } -} - */ - class ShellIo extends Shell with ShellMixin { ShellIo({ required ShellOptions options, @@ -60,11 +27,5 @@ class ShellExceptionIo implements ShellException { String get message => impl.message; @override - ProcessResult? get result { - var implResult = impl.result; - if (implResult != null) { - return ProcessResultIo(implResult); - } - return null; - } + ProcessResult? get result => impl.result; } diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index d5525c6..a641d36 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -4,7 +4,7 @@ description: Process run helpers for Linux/Win/Mac and which like feature for fi homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run environment: - sdk: '>=2.18.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: path: '>=1.8.0 <3.0.0' From d98f68506376a60da047c03cc6bbe876ffb8a9aa Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 22 Jul 2023 00:23:40 +0200 Subject: [PATCH 058/150] [process_run] v0.13.1 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 6781646..e0b0afb 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.13.1 + +* Dart 3 only + ## 0.13.0 * Dart 3 support diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index a641d36..a0cc971 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.13.0 +version: 0.13.1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 1f45eb89828d740efa2b9d9634a5e212dc38929e Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 14 Sep 2023 18:52:11 +0200 Subject: [PATCH 059/150] test: ci downgrade analysis --- .../workflows/run_ci_downgrade_analyze.yml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/run_ci_downgrade_analyze.yml diff --git a/.github/workflows/run_ci_downgrade_analyze.yml b/.github/workflows/run_ci_downgrade_analyze.yml new file mode 100644 index 0000000..ec9230d --- /dev/null +++ b/.github/workflows/run_ci_downgrade_analyze.yml @@ -0,0 +1,28 @@ +name: Run CI +on: + push: + pull_request: + workflow_dispatch: + schedule: + - cron: '0 0 * * 0' # every sunday at midnight + +jobs: + test: + name: Test on ${{ matrix.os }} / ${{ matrix.dart }} + runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: . + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + dart: [stable] + steps: + - uses: actions/checkout@v3 + - uses: dart-lang/setup-dart@v1.4 + with: + sdk: ${{ matrix.dart }} + - run: dart --version + - run: dart pub global activate dev_test + - run: dart pub global run dev_test:run_ci --pub-downgrade --analyze --no-override --recursive \ No newline at end of file From 2a5ede81df3ec082184bccfcf96a0c62f6585edd Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sun, 22 Oct 2023 17:22:29 +0200 Subject: [PATCH 060/150] [process_run] v0.13.2 export stringToArguments --- .github/workflows/run_ci_downgrade_analyze.yml | 4 ++-- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/lib/process_run.dart | 2 ++ packages/process_run/lib/shell.dart | 2 +- packages/process_run/lib/shell_run.dart | 2 ++ packages/process_run/lib/src/bin/shell/env.dart | 3 +-- packages/process_run/lib/src/bin/shell/env_file_content.dart | 2 +- packages/process_run/lib/src/common/dev_utils.dart | 1 + packages/process_run/lib/src/shell.dart | 5 ++--- packages/process_run/lib/src/shell_environment.dart | 5 ++--- packages/process_run/lib/src/shell_utils_common.dart | 5 +++++ packages/process_run/pubspec.yaml | 2 +- packages/process_run/test/shell_api_test.dart | 3 +++ 13 files changed, 27 insertions(+), 13 deletions(-) diff --git a/.github/workflows/run_ci_downgrade_analyze.yml b/.github/workflows/run_ci_downgrade_analyze.yml index ec9230d..6f19237 100644 --- a/.github/workflows/run_ci_downgrade_analyze.yml +++ b/.github/workflows/run_ci_downgrade_analyze.yml @@ -1,4 +1,4 @@ -name: Run CI +name: Run CI Downgrade analyze on: push: pull_request: @@ -25,4 +25,4 @@ jobs: sdk: ${{ matrix.dart }} - run: dart --version - run: dart pub global activate dev_test - - run: dart pub global run dev_test:run_ci --pub-downgrade --analyze --no-override --recursive \ No newline at end of file + - run: dart pub global run dev_test:run_ci --pub-downgrade --analyze --no-override --recursive diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index e0b0afb..3c7ef27 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.13.2 + +* Export `stringToArguments` in `shell.dart` + ## 0.13.1 * Dart 3 only diff --git a/packages/process_run/lib/process_run.dart b/packages/process_run/lib/process_run.dart index eb5fc48..7a2e416 100644 --- a/packages/process_run/lib/process_run.dart +++ b/packages/process_run/lib/process_run.dart @@ -1,6 +1,8 @@ /// /// Helper to run a process and connect the input/output for verbosity /// +library; + export 'package:process_run/src/shell_utils_common.dart' show argumentsToString, argumentToString; diff --git a/packages/process_run/lib/shell.dart b/packages/process_run/lib/shell.dart index a800b98..65ce319 100644 --- a/packages/process_run/lib/shell.dart +++ b/packages/process_run/lib/shell.dart @@ -36,7 +36,7 @@ export 'package:process_run/src/shell_utils.dart' shellArguments, shellExecutableArguments; export 'package:process_run/src/shell_utils_common.dart' - show argumentsToString, argumentToString; + show argumentsToString, argumentToString, stringToArguments; export 'package:process_run/src/user_config.dart' show userPaths, userEnvironment, userLoadEnvFile, userLoadEnv; diff --git a/packages/process_run/lib/shell_run.dart b/packages/process_run/lib/shell_run.dart index e9fd2b5..69104e1 100644 --- a/packages/process_run/lib/shell_run.dart +++ b/packages/process_run/lib/shell_run.dart @@ -1,2 +1,4 @@ /// Deprecated in 1.0.0. Prefer using shell in the future +library; + export 'shell.dart'; diff --git a/packages/process_run/lib/src/bin/shell/env.dart b/packages/process_run/lib/src/bin/shell/env.dart index 1a8ea54..ad5ab9c 100644 --- a/packages/process_run/lib/src/bin/shell/env.dart +++ b/packages/process_run/lib/src/bin/shell/env.dart @@ -16,8 +16,7 @@ import 'env_var.dart'; import 'import.dart'; class ShellEnvCommandBase extends ShellBinCommand { - ShellEnvCommandBase({required String name, String? description}) - : super(name: name, description: description) { + ShellEnvCommandBase({required super.name, super.description}) { parser.addFlag(flagLocal, abbr: 'l', help: 'Use local env', negatable: false, defaultsTo: true); parser.addFlag(flagUser, diff --git a/packages/process_run/lib/src/bin/shell/env_file_content.dart b/packages/process_run/lib/src/bin/shell/env_file_content.dart index 4b0cfaf..54fa815 100644 --- a/packages/process_run/lib/src/bin/shell/env_file_content.dart +++ b/packages/process_run/lib/src/bin/shell/env_file_content.dart @@ -96,7 +96,7 @@ class FileContent { } class EnvFileContent extends FileContent { - EnvFileContent(String path) : super(path); + EnvFileContent(super.path); bool addAlias(String alias, String command) => writeKeyValue(userConfigAliasKeys, alias, value: command); diff --git a/packages/process_run/lib/src/common/dev_utils.dart b/packages/process_run/lib/src/common/dev_utils.dart index 93a05e4..24e34da 100644 --- a/packages/process_run/lib/src/common/dev_utils.dart +++ b/packages/process_run/lib/src/common/dev_utils.dart @@ -1,4 +1,5 @@ /// Development helpers to generate warning in code +library; void _devPrint(Object object) { if (_devPrintEnabled) { diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 2b6ea08..65322af 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -495,9 +495,8 @@ abstract class Shell implements ShellCore { class _ProcessCmd extends ProcessCmd { final String executableShortName; - _ProcessCmd(String executable, List arguments, - {required this.executableShortName}) - : super(executable, arguments); + _ProcessCmd(String super.executable, super.arguments, + {required this.executableShortName}); @override String toString() => diff --git a/packages/process_run/lib/src/shell_environment.dart b/packages/process_run/lib/src/shell_environment.dart index f751de3..7813a39 100644 --- a/packages/process_run/lib/src/shell_environment.dart +++ b/packages/process_run/lib/src/shell_environment.dart @@ -21,8 +21,7 @@ class ShellEnvironment extends common.ShellEnvironmentBase { /// It is recommended that you apply the environment to a shell. But it can /// also be set globally (be aware of the potential effect on other part of /// your application) to [shellEnvironment] - ShellEnvironment({Map? environment}) - : super.fromEnvironment(environment: environment); + ShellEnvironment({super.environment}) : super.fromEnvironment(); /// From a run start content, includeParentEnvironment should later be set /// to false @@ -50,7 +49,7 @@ class ShellEnvironment extends common.ShellEnvironmentBase { /// /// Mainly used for testing as it is not easy to which environment variable /// are required. - ShellEnvironment.fromJson(Map? map) : super.fromJson(map); + ShellEnvironment.fromJson(super.map) : super.fromJson(); /// Find a [command] path location in the environment String? whichSync(String command) { diff --git a/packages/process_run/lib/src/shell_utils_common.dart b/packages/process_run/lib/src/shell_utils_common.dart index 03db617..979f269 100644 --- a/packages/process_run/lib/src/shell_utils_common.dart +++ b/packages/process_run/lib/src/shell_utils_common.dart @@ -6,6 +6,7 @@ import 'dart:convert'; import 'package:process_run/src/platform/platform.dart'; import 'characters.dart'; +import 'shell_utils.dart' as shell_utils; const windowsDefaultPathExt = ['.exe', '.bat', '.cmd', '.com']; @@ -86,3 +87,7 @@ String shellArgument(String argument) => argumentToString(argument); /// Convert multiple arguments to string than can be used in a terminal String shellArguments(List arguments) => argumentsToString(arguments); + +/// Convert a string command to arguments. +List stringToArguments(String command) => + shell_utils.shellSplit(command); diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index a0cc971..54abe17 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.13.1 +version: 0.13.2 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run diff --git a/packages/process_run/test/shell_api_test.dart b/packages/process_run/test/shell_api_test.dart index d203995..f6f58d7 100644 --- a/packages/process_run/test/shell_api_test.dart +++ b/packages/process_run/test/shell_api_test.dart @@ -53,6 +53,9 @@ void main() { ProcessCmd; processResultToDebugString; processCmdToDebugString; + + // shell_utils + stringToArguments; }); }); } From 63a9549276d8c97460b482ef8e34e5fcac351daf Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 17 Nov 2023 01:41:38 +0100 Subject: [PATCH 061/150] fix: Fix finding `flutter` on windows in unit tests --- packages/process_run/lib/src/shell_utils.dart | 99 ++++++++++++++----- 1 file changed, 76 insertions(+), 23 deletions(-) diff --git a/packages/process_run/lib/src/shell_utils.dart b/packages/process_run/lib/src/shell_utils.dart index ae5d73a..e1899cd 100644 --- a/packages/process_run/lib/src/shell_utils.dart +++ b/packages/process_run/lib/src/shell_utils.dart @@ -214,36 +214,89 @@ List shellSplit(String command) => String shellJoin(List parts) => parts.map((part) => shellArgument(part)).join(' '); -/// Find command in path -String? findExecutableSync(String command, List paths) { - for (var path in paths) { - var commandPath = absolute(normalize(join(path!, command))); +String? _findExecutableInPath(String command, String path) { + var commandPath = absolute(normalize(join(path, command))); - if (Platform.isWindows) { - for (var ext in windowsPathExts) { - var commandPathWithExt = '$commandPath$ext'; - if (File(commandPathWithExt).existsSync()) { - return normalize(commandPathWithExt); - } + if (Platform.isWindows) { + for (var ext in windowsPathExts) { + var commandPathWithExt = '$commandPath$ext'; + if (File(commandPathWithExt).existsSync()) { + return normalize(commandPathWithExt); } - // Try without extension - if (File(commandPath).existsSync()) { + } + // Try without extension + if (File(commandPath).existsSync()) { + return commandPath; + } + } else { + var stats = File(commandPath).statSync(); + if (stats.type == FileSystemEntityType.file || + stats.type == FileSystemEntityType.link) { + // Check executable permission + if (stats.mode & 0x49 != 0) { + // binary 001001001 + // executable return commandPath; } - } else { - var stats = File(commandPath).statSync(); - if (stats.type == FileSystemEntityType.file || - stats.type == FileSystemEntityType.link) { - // Check executable permission - if (stats.mode & 0x49 != 0) { - // binary 001001001 - // executable - return commandPath; - } - } } } + return null; +} +/// Find command in path +String? findExecutableSync(String command, List paths) { + for (var path in paths) { + var executable = _findExecutableInPath(command, path!); + if (executable != null) { + return executable; + } + } + + // Special case for flutter happen when running from test + // On windows the executable might be in flutter + // executable: C:\opt\app\flutter\stable\flutter\bin\cache\artifacts\engine\windows-x64\flutter_tester.exe + // Try without extension + if (command == 'flutter') { + // print('executable: ${Platform.executable}'); + return _findFlutterExecutableInParents(Platform.executable); + } + + return null; +} + +bool _isFlutterRoot(String path) { + try { + // "version" file contains: 3.13.0 + if (!File(join(path, 'version')).existsSync()) { + return false; + } + // bin/flutter(.exe) + if (_findExecutableInPath('flutter', join(path, 'bin')) == null) { + return false; + } + + return true; + } catch (_) {} + return false; +} + +/// +/// checking recursively the parent for any hg or git directory +/// +String? _findFlutterExecutableInParents(String path) { + path = normalize(absolute(path)); + String parent; + while (true) { + if (_isFlutterRoot(path)) { + return _findExecutableInPath('flutter', join(path, 'bin')); + } + + parent = dirname(path); + if (parent == path) { + break; + } + path = parent; + } return null; } From 1a0d32da1257be1f8750eadc08c79e2059fd9d69 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 17 Nov 2023 01:44:32 +0100 Subject: [PATCH 062/150] v0.13.3-1 --- packages/process_run/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 54abe17..1a8b3cb 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.13.2 +version: 0.13.3-1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 22ab19b454640bbd3d1b23ac4f9ebbe773783b12 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 17 Nov 2023 01:44:39 +0100 Subject: [PATCH 063/150] v0.13.3-1 --- packages/process_run/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 3c7ef27..2bcfcbe 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.13.3-1 + +* Fix finding `flutter` on windows in unit tests + ## 0.13.2 * Export `stringToArguments` in `shell.dart` From b9c607bb83f565adfe9f66f37d14fc6a7a32dc96 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 17 Nov 2023 10:51:08 +0100 Subject: [PATCH 064/150] [process_run] blindly fix pipe, windows no longer output \r\n in echo... --- packages/process_run/test/shell_test.dart | 24 ++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index 7343c9f..b002f1d 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -461,9 +461,27 @@ _tekartik_dummy_app_that_does_not_exits (await shell.run('echo Hello world')).first.stdout.toString(), mode: FileMode.append); - var separator = Platform.isWindows ? '\r\n' : '\n'; - expect(await file.readAsString(), - 'Hello world${separator}Hello world$separator'); + try { + // Update 2024-11-17 Windows used to have different separator. + var separator = '\n'; + expect(await file.readAsString(), + 'Hello world${separator}Hello world$separator'); + if (Platform.isWindows) { + stdout.writeln('report: echo output \\n'); + } + } catch (_) { + if (Platform.isWindows) { + // Old test + var separator = Platform.isWindows ? '\r\n' : '\n'; + expect(await file.readAsString(), + 'Hello world${separator}Hello world$separator'); + if (Platform.isWindows) { + stdout.writeln('report: echo output \\r\\n'); + } + } else { + rethrow; + } + } }); test('user', () { From 316cc7190f0cf85a743cbeab5c1aab54ef46e680 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 17 Nov 2023 10:53:03 +0100 Subject: [PATCH 065/150] dependabot --- .github/dependabot.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..44fa5c2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,16 @@ +# Dependabot configuration file. +# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates +version: 2 + +enable-beta-ecosystems: true +updates: + - package-ecosystem: "pub" + directory: "packages/process_run" + schedule: + interval: "monthly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + labels: + - autosubmit From 160a50db1d92420a61b7d9750e67706341859ead Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 25 Nov 2023 08:19:05 +0100 Subject: [PATCH 066/150] feat: remove charcode dependency --- .../lib/src/common/ascii_charcodes.dart | 28 +++++++++++++ .../process_run/lib/src/io/shell_words.dart | 41 ++++++++++--------- packages/process_run/pubspec.yaml | 1 - 3 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 packages/process_run/lib/src/common/ascii_charcodes.dart diff --git a/packages/process_run/lib/src/common/ascii_charcodes.dart b/packages/process_run/lib/src/common/ascii_charcodes.dart new file mode 100644 index 0000000..af389e8 --- /dev/null +++ b/packages/process_run/lib/src/common/ascii_charcodes.dart @@ -0,0 +1,28 @@ +/// "Horizontal Tab" control character, common name. +const int charcodeTab = 0x09; + +/// "Line feed" control character. +const int charcodeLf = 0x0A; + +// Visible characters. + +/// Space character. +const int charcodeSpace = 0x20; + +/// Character `"`. +const int charcodeDoubleQuote = 0x22; + +/// Character `#`. +const int charcodeHash = 0x23; + +/// Character `$`. +const int charcodeDollar = 0x24; + +/// Character `'`. +const int charcodeSingleQuote = 0x27; + +/// Character `\`. +const int charcodeBackslash = 0x5C; + +/// Character `` ` ``. +const int charcodeBackquote = 0x60; diff --git a/packages/process_run/lib/src/io/shell_words.dart b/packages/process_run/lib/src/io/shell_words.dart index 52f75b3..4a980d9 100644 --- a/packages/process_run/lib/src/io/shell_words.dart +++ b/packages/process_run/lib/src/io/shell_words.dart @@ -4,9 +4,10 @@ // ignore_for_file: comment_references -import 'package:charcode/charcode.dart'; import 'package:string_scanner/string_scanner.dart'; +import 'package:process_run/src/common/ascii_charcodes.dart'; + /// Splits [command] into tokens according to [the POSIX shell /// specification][spec]. /// @@ -34,7 +35,7 @@ List shellSplit(String command) { while (!scanner.isDone) { final next = scanner.readChar(); switch (next) { - case $backslash: + case charcodeBackslash: // Section 2.2.1: A that is not quoted shall preserve the // literal value of the following character, with the exception of a // . If a follows the , the shell shall @@ -42,25 +43,25 @@ List shellSplit(String command) { // shall be removed before splitting the input into tokens. Since the // escaped is removed entirely from the input and is not // replaced by any white space, it cannot serve as a token separator. - if (scanner.scanChar($lf)) break; + if (scanner.scanChar(charcodeLf)) break; hasToken = true; token.writeCharCode(scanner.readChar()); break; - case $single_quote: + case charcodeSingleQuote: hasToken = true; // Section 2.2.2: Enclosing characters in single-quotes ( '' ) shall // preserve the literal value of each character within the // single-quotes. A single-quote cannot occur within single-quotes. final firstQuote = scanner.position - 1; - while (!scanner.scanChar($single_quote)) { + while (!scanner.scanChar(charcodeSingleQuote)) { _checkUnmatchedQuote(scanner, firstQuote); token.writeCharCode(scanner.readChar()); } break; - case $double_quote: + case charcodeDoubleQuote: hasToken = true; // Section 2.2.3: Enclosing characters in double-quotes ( "" ) shall // preserve the literal value of all characters within the @@ -71,10 +72,10 @@ List shellSplit(String command) { // or dollar sign within double quotes, since those are dynamic // features.) final firstQuote = scanner.position - 1; - while (!scanner.scanChar($double_quote)) { + while (!scanner.scanChar(charcodeDoubleQuote)) { _checkUnmatchedQuote(scanner, firstQuote); - if (scanner.scanChar($backslash)) { + if (scanner.scanChar(charcodeBackslash)) { _checkUnmatchedQuote(scanner, firstQuote); // The shall retain its special meaning as an escape @@ -83,15 +84,15 @@ List shellSplit(String command) { // // $ ` " \ final next = scanner.readChar(); - if (next == $lf) continue; - if (next == $dollar || - next == $backquote || - next == $double_quote || - next == $backslash) { + if (next == charcodeLf) continue; + if (next == charcodeDollar || + next == charcodeBackquote || + next == charcodeDoubleQuote || + next == charcodeBackslash) { token.writeCharCode(next); } else { token - ..writeCharCode($backslash) + ..writeCharCode(charcodeBackslash) ..writeCharCode(next); } } else { @@ -100,25 +101,25 @@ List shellSplit(String command) { } break; - case $hash: + case charcodeHash: // Section 2.3: If the current character is a '#' [and the previous // characters was not part of a word], it and all subsequent characters // up to, but excluding, the next shall be discarded as a // comment. The that ends the line is not considered part of // the comment. if (hasToken) { - token.writeCharCode($hash); + token.writeCharCode(charcodeHash); break; } - while (!scanner.isDone && scanner.peekChar() != $lf) { + while (!scanner.isDone && scanner.peekChar() != charcodeLf) { scanner.readChar(); } break; - case $space: - case $tab: - case $lf: + case charcodeSpace: + case charcodeTab: + case charcodeLf: // ignore: invariant_booleans if (hasToken) results.add(token.toString()); hasToken = false; diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 1a8b3cb..c3248bf 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -9,7 +9,6 @@ environment: dependencies: path: '>=1.8.0 <3.0.0' collection: '>=1.15.0 <3.0.0' - charcode: '>=1.2.0 <3.0.0' string_scanner: '>=1.1.0 <3.0.0' yaml: '>=3.0.0 <5.0.0' meta: '>=1.3.0 <3.0.0' From 567647eab0d8b6c5e3ca98550584693cfeeb9cb2 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 25 Nov 2023 08:21:06 +0100 Subject: [PATCH 067/150] feat: remove charcode dependency --- packages/process_run/lib/src/io/shell_words.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/process_run/lib/src/io/shell_words.dart b/packages/process_run/lib/src/io/shell_words.dart index 4a980d9..bdc7cd0 100644 --- a/packages/process_run/lib/src/io/shell_words.dart +++ b/packages/process_run/lib/src/io/shell_words.dart @@ -4,9 +4,8 @@ // ignore_for_file: comment_references -import 'package:string_scanner/string_scanner.dart'; - import 'package:process_run/src/common/ascii_charcodes.dart'; +import 'package:string_scanner/string_scanner.dart'; /// Splits [command] into tokens according to [the POSIX shell /// specification][spec]. From 0afa4142f763b54fddf4ffeb0ea065cdd101dbc2 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 25 Nov 2023 08:21:15 +0100 Subject: [PATCH 068/150] [process_run] v0.13.3 --- packages/process_run/CHANGELOG.md | 3 ++- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 2bcfcbe..943ee62 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,6 +1,7 @@ -## 0.13.3-1 +## 0.13.3 * Fix finding `flutter` on windows in unit tests +* Remove `charcode` dependency. ## 0.13.2 diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index c3248bf..84c5873 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.13.3-1 +version: 0.13.3 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 250746f4c09325bdd89e60ff2f4fc9ce83a2b351 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 25 Nov 2023 07:22:22 +0000 Subject: [PATCH 069/150] build(deps): bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/run_ci.yml | 2 +- .github/workflows/run_ci_downgrade_analyze.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index 1c83bfa..f22ef90 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -21,7 +21,7 @@ jobs: - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: dart --version - run: dart pub get - run: dart run tool/run_ci.dart \ No newline at end of file diff --git a/.github/workflows/run_ci_downgrade_analyze.yml b/.github/workflows/run_ci_downgrade_analyze.yml index 6f19237..0b2957e 100644 --- a/.github/workflows/run_ci_downgrade_analyze.yml +++ b/.github/workflows/run_ci_downgrade_analyze.yml @@ -19,7 +19,7 @@ jobs: os: [ubuntu-latest] dart: [stable] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} From 3d7f26943bb1f46aca5bfb402f2f6f6b67536389 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 4 Dec 2023 01:00:41 +0100 Subject: [PATCH 070/150] ci --- .github/workflows/run_ci.yml | 23 ++++++++++++++----- .../workflows/run_ci_downgrade_analyze.yml | 11 +++++---- packages/process_run/tool/travis.dart | 19 --------------- 3 files changed, 23 insertions(+), 30 deletions(-) delete mode 100644 packages/process_run/tool/travis.dart diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index 1c83bfa..643c974 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -7,21 +7,32 @@ on: jobs: test: - name: Test on ${{ matrix.os }} / ${{ matrix.dart }} + name: Test on ${{ matrix.os }} / dart ${{ matrix.dart }} runs-on: ${{ matrix.os }} defaults: run: - working-directory: packages/process_run + working-directory: . strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - dart: [3.0.5, stable, beta, dev] + include: + - os: ubuntu-latest + dart: 3.0.5 + - os: ubuntu-latest + dart: stable + - os: ubuntu-latest + dart: beta + - os: ubuntu-latest + dart: dev + - os: windows-latest + dart: stable + - os: macos-latest + dart: stable steps: - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} - uses: actions/checkout@v3 - run: dart --version - - run: dart pub get - - run: dart run tool/run_ci.dart \ No newline at end of file + - run: dart pub global activate dev_build + - run: dart pub global run dev_build:run_ci \ No newline at end of file diff --git a/.github/workflows/run_ci_downgrade_analyze.yml b/.github/workflows/run_ci_downgrade_analyze.yml index 6f19237..e928bb9 100644 --- a/.github/workflows/run_ci_downgrade_analyze.yml +++ b/.github/workflows/run_ci_downgrade_analyze.yml @@ -8,7 +8,7 @@ on: jobs: test: - name: Test on ${{ matrix.os }} / ${{ matrix.dart }} + name: Test on ${{ matrix.os }} / dart ${{ matrix.dart }} runs-on: ${{ matrix.os }} defaults: run: @@ -16,13 +16,14 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest] - dart: [stable] + include: + - os: ubuntu-latest + dart: stable steps: - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} - run: dart --version - - run: dart pub global activate dev_test - - run: dart pub global run dev_test:run_ci --pub-downgrade --analyze --no-override --recursive + - run: dart pub global activate dev_build + - run: dart pub global run dev_build:run_ci --pub-downgrade --analyze --no-override --recursive diff --git a/packages/process_run/tool/travis.dart b/packages/process_run/tool/travis.dart deleted file mode 100644 index 78e1850..0000000 --- a/packages/process_run/tool/travis.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:process_run/shell.dart'; - -Future main() async { - var shell = Shell(); - await shell.run(''' -# Format -dart format --set-exit-if-changed -o none . - -# Analyze code -dart analyze --fatal-warnings --fatal-infos . - -# Run tests -pub run test -p vm -r expanded - -# Run tests using build_runner -pub run build_runner test -- -p vm -r expanded - -'''); -} From 9f8c83d72d3a3c7ded35d85501f70389237d88f7 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sun, 24 Dec 2023 10:12:19 +0100 Subject: [PATCH 071/150] [process_run] fix issue #101, properly propage errors in shell line controller. --- .../lib/src/lines_utils_common.dart | 2 ++ .../test/shell_lines_controller_test.dart | 32 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index 6d53396..da573e9 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -135,6 +135,8 @@ Stream shellStreamLines(Stream> stream, // Last one addCurrentLine(); ctlr.close(); + }, onError: (Object e, StackTrace st) { + ctlr.addError(e, st); }); }, onCancel: () { subscription?.cancel(); diff --git a/packages/process_run/test/shell_lines_controller_test.dart b/packages/process_run/test/shell_lines_controller_test.dart index 4531253..1aa90df 100644 --- a/packages/process_run/test/shell_lines_controller_test.dart +++ b/packages/process_run/test/shell_lines_controller_test.dart @@ -12,7 +12,8 @@ void main() { late ShellEnvironment env; setUpAll(() { env = ShellEnvironment() - ..aliases['streamer'] = 'dart run ${shellArgument(streamerScriptPath)}'; + ..aliases['streamer'] = 'dart run ${shellArgument(streamerScriptPath)}' + ..aliases['echo'] = 'dart run ${shellArgument(echoScriptPath)}'; }); test('stream all', () async { var ctlr = ShellLinesController(); @@ -45,5 +46,34 @@ void main() { // Should fail } }, timeout: const Timeout(Duration(milliseconds: 30000))); + test('addError', () async { + var ctlr = ShellLinesController(); + var completer = Completer(); + ctlr.stream.listen((event) { + fail('should not be called'); + }, onError: (Object e) { + expect(e, 'test'); + completer.complete(true); + }); + ctlr.sink.addError('test'); + + await completer.future; + ctlr.close(); + }); + test('shell error', () async { + var ctlr = ShellLinesController(); + var completer = Completer(); + ctlr.stream.listen((event) {}, onError: (Object e) { + var shellException = e as ShellException; + expect(shellException.result!.exitCode, 1); + //expect(e, 'test'); + completer.complete(true); + }); + var shell = Shell(stdout: ctlr.sink, environment: env); + await shell + .run('echo --exit-code 1') + .then((_) => ctlr.close(), onError: ctlr.sink.addError); + await completer.future; + }); }); } From cb68cc6b74e432f15d80394ecc84dc51490283c9 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sun, 24 Dec 2023 10:13:41 +0100 Subject: [PATCH 072/150] [process_run] v0.13.3+1 --- packages/process_run/CHANGELOG.md | 3 ++- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 943ee62..c6b2fac 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,7 +1,8 @@ -## 0.13.3 +## 0.13.3+1 * Fix finding `flutter` on windows in unit tests * Remove `charcode` dependency. +* Propage added errors in `ShellLinesController` ## 0.13.2 diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 84c5873..3e7c4cb 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.13.3 +version: 0.13.3+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 294ecb81050239c2d5781cf8b26a5aff5b1a3576 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 2 Jan 2024 17:57:31 +0100 Subject: [PATCH 073/150] [process_run] fix issue #19 no longer weirdly replace `\` by `\\` --- packages/process_run/lib/src/io/shell_words.dart | 2 +- packages/process_run/lib/src/shell_utils.dart | 5 ++--- packages/process_run/test/dartbin_test.dart | 2 +- packages/process_run/test/shell_test.dart | 6 +++--- packages/process_run/test/src_shell_utils_test.dart | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/process_run/lib/src/io/shell_words.dart b/packages/process_run/lib/src/io/shell_words.dart index bdc7cd0..c808499 100644 --- a/packages/process_run/lib/src/io/shell_words.dart +++ b/packages/process_run/lib/src/io/shell_words.dart @@ -21,7 +21,7 @@ import 'package:string_scanner/string_scanner.dart'; /// This will discard any comments at the end of [command]. /// /// Throws a [FormatException] if [command] isn't a valid shell command. -List shellSplit(String command) { +List shellSplitImpl(String command) { final scanner = StringScanner(command); final results = []; final token = StringBuffer(); diff --git a/packages/process_run/lib/src/shell_utils.dart b/packages/process_run/lib/src/shell_utils.dart index e1899cd..655399b 100644 --- a/packages/process_run/lib/src/shell_utils.dart +++ b/packages/process_run/lib/src/shell_utils.dart @@ -3,7 +3,7 @@ import 'dart:convert'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/constant.dart'; -import 'package:process_run/src/io/shell_words.dart' as io show shellSplit; +import 'package:process_run/src/io/shell_words.dart' as io show shellSplitImpl; import 'package:process_run/src/shell_environment.dart'; import 'bin/shell/import.dart'; @@ -207,8 +207,7 @@ bool fixRunInShell(bool? runInShell, String executable) { } /// Use io package shellSplit implementation -List shellSplit(String command) => - io.shellSplit(command.replaceAll(r'\', r'\\')); +List shellSplit(String command) => io.shellSplitImpl(command); /// Inverse of shell split String shellJoin(List parts) => diff --git a/packages/process_run/test/dartbin_test.dart b/packages/process_run/test/dartbin_test.dart index 93eeb21..d091038 100644 --- a/packages/process_run/test/dartbin_test.dart +++ b/packages/process_run/test/dartbin_test.dart @@ -56,7 +56,7 @@ void defineTests() { // Dart SDK version: 2.9.0-21.2.beta (beta) (Fri Jul 10 17:39:56 2020 +0200) on "linux_x64" // After 2.15.0 // Dart SDK version: 2.15.0-82.0.dev (dev) (Sat Sep 4 03:33:09 2021 -0700) on "linux_x64" - }); + }, skip: 'dart might not be in the path'); test('run', () async { final result = await Process.run(dartExecutable!, ['--version']); diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index b002f1d..a8cc504 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -18,7 +18,7 @@ import 'hex_utils.dart'; @Deprecated('Dev only, used when uncommenting debug = devTrue') bool devTrue = true; -//bool debug = devTrue; +// bool debug = devTrue; bool debug = false; // To set in both variable for a full empty environment @@ -147,7 +147,7 @@ dart example/echo.dart -o ${shellArgument(weirdText)} '''); - expect(results[0].stdout.toString().trim(), r'a/\bc/\d'); + expect(results[0].stdout.toString().trim(), r'a/bc/d'); expect(results[1].stdout.toString().trim(), r'a/\b c/\d'); expect(results.length, 2); }); @@ -399,7 +399,7 @@ dart current_dir.dart test('escape backslash', () async { var shell = Shell(verbose: debug); - var results = await shell.run('''echo "\\"'''); + var results = await shell.run(r'echo "\\"'); expect(results[0].stdout.toString().trim(), '\\'); }); test('others', () async { diff --git a/packages/process_run/test/src_shell_utils_test.dart b/packages/process_run/test/src_shell_utils_test.dart index c291dc0..337f99d 100644 --- a/packages/process_run/test/src_shell_utils_test.dart +++ b/packages/process_run/test/src_shell_utils_test.dart @@ -63,7 +63,7 @@ void main() { test('shellSplit', () { // We differ from io implementation - expect(shellSplit(r'\'), [r'\']); + expect(shellSplit(r'"\\"'), [r'\']); expect(shellSplit('Hello world'), ['Hello', 'world']); expect(shellSplit('"Hello world"'), ['Hello world']); expect(shellSplit("'Hello world'"), ['Hello world']); @@ -90,7 +90,7 @@ void main() { testSplitJoin('foo'); testSplitJoin('foo bar'); - testSplitJoin(r'\'); + // testSplitJoin(r'\'); testSplitJoin('"foo bar"'); testSplitJoin("'foo bar'", expected: '"foo bar"'); }); From eb21ac7d5f635d06685281cfaef0e47ebd6a2056 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 2 Jan 2024 17:59:18 +0100 Subject: [PATCH 074/150] [process_run] v0.14.0 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index c6b2fac..0eb6b63 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.14.0 + +* No longer replace `\` by `\\` before splitting arguments + ## 0.13.3+1 * Fix finding `flutter` on windows in unit tests diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 3e7c4cb..9800934 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.13.3+1 +version: 0.14.0 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From a0eb4560b6bfe3418f62aee72de7e65a3677df17 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 2 Jan 2024 18:47:42 +0100 Subject: [PATCH 075/150] fix backslash handling on windows --- .../process_run/lib/src/io/shell_words.dart | 101 ++++++++++++++++++ packages/process_run/lib/src/shell_utils.dart | 7 +- packages/process_run/test/echo_test.dart | 7 +- packages/process_run/test/shell_test.dart | 15 ++- .../test/src_shell_utils_test.dart | 6 +- 5 files changed, 129 insertions(+), 7 deletions(-) diff --git a/packages/process_run/lib/src/io/shell_words.dart b/packages/process_run/lib/src/io/shell_words.dart index c808499..a2b653b 100644 --- a/packages/process_run/lib/src/io/shell_words.dart +++ b/packages/process_run/lib/src/io/shell_words.dart @@ -136,6 +136,107 @@ List shellSplitImpl(String command) { return results; } +/// Splits [command] into tokens according to [the POSIX shell +/// specification][spec] slightly modified for windows. +/// +/// [spec]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/contents.html +/// +/// This returns the unquoted values of quoted tokens. For example, +/// `shellSplit('foo "bar baz"')` returns `["foo", "bar baz"]`. It does not +/// currently support here-documents. It does *not* treat dynamic features such +/// as parameter expansion specially. For example, `shellSplit("foo $(bar +/// baz)")` returns `["foo", "$(bar", "baz)"]`. +/// +/// This will discard any comments at the end of [command]. +/// +/// Throws a [FormatException] if [command] isn't a valid shell command. +List shellSplitWindowsImpl(String command) { + final scanner = StringScanner(command); + final results = []; + final token = StringBuffer(); + + // Whether a token is being parsed, as opposed to a separator character. This + // is different than just [token.isEmpty], because empty quoted tokens can + // exist. + var hasToken = false; + + while (!scanner.isDone) { + final next = scanner.readChar(); + switch (next) { + case charcodeBackslash: + // We don't escape backslashes in Windows paths. + hasToken = true; + token.writeCharCode(next); + break; + + case charcodeSingleQuote: + hasToken = true; + // Section 2.2.2: Enclosing characters in single-quotes ( '' ) shall + // preserve the literal value of each character within the + // single-quotes. A single-quote cannot occur within single-quotes. + final firstQuote = scanner.position - 1; + while (!scanner.scanChar(charcodeSingleQuote)) { + _checkUnmatchedQuote(scanner, firstQuote); + token.writeCharCode(scanner.readChar()); + } + break; + + case charcodeDoubleQuote: + hasToken = true; + // Section 2.2.3: Enclosing characters in double-quotes ( "" ) shall + // preserve the literal value of all characters within the + // double-quotes, with the exception of the characters backquote, + // , and . + // + // (Note that this code doesn't preserve special behavior of backquote + // or dollar sign within double quotes, since those are dynamic + // features.) + final firstQuote = scanner.position - 1; + while (!scanner.scanChar(charcodeDoubleQuote)) { + _checkUnmatchedQuote(scanner, firstQuote); + + // We don't escape backslashes in Windows paths. + + token.writeCharCode(scanner.readChar()); + } + break; + + case charcodeHash: + // Section 2.3: If the current character is a '#' [and the previous + // characters was not part of a word], it and all subsequent characters + // up to, but excluding, the next shall be discarded as a + // comment. The that ends the line is not considered part of + // the comment. + if (hasToken) { + token.writeCharCode(charcodeHash); + break; + } + + while (!scanner.isDone && scanner.peekChar() != charcodeLf) { + scanner.readChar(); + } + break; + + case charcodeSpace: + case charcodeTab: + case charcodeLf: + // ignore: invariant_booleans + if (hasToken) results.add(token.toString()); + hasToken = false; + token.clear(); + break; + + default: + hasToken = true; + token.writeCharCode(next); + break; + } + } + + if (hasToken) results.add(token.toString()); + return results; +} + /// Throws a [FormatException] if [scanner] is done indicating that a closing /// quote matching the one at position [openingQuote] is missing. void _checkUnmatchedQuote(StringScanner scanner, int openingQuote) { diff --git a/packages/process_run/lib/src/shell_utils.dart b/packages/process_run/lib/src/shell_utils.dart index 655399b..1f59fa5 100644 --- a/packages/process_run/lib/src/shell_utils.dart +++ b/packages/process_run/lib/src/shell_utils.dart @@ -3,7 +3,8 @@ import 'dart:convert'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/constant.dart'; -import 'package:process_run/src/io/shell_words.dart' as io show shellSplitImpl; +import 'package:process_run/src/io/shell_words.dart' as io + show shellSplitImpl, shellSplitWindowsImpl; import 'package:process_run/src/shell_environment.dart'; import 'bin/shell/import.dart'; @@ -207,7 +208,9 @@ bool fixRunInShell(bool? runInShell, String executable) { } /// Use io package shellSplit implementation -List shellSplit(String command) => io.shellSplitImpl(command); +List shellSplit(String command) => context.style == windows.style + ? io.shellSplitWindowsImpl(command) + : io.shellSplitImpl(command); /// Inverse of shell split String shellJoin(List parts) => diff --git a/packages/process_run/test/echo_test.dart b/packages/process_run/test/echo_test.dart index 20325a2..6ce3908 100644 --- a/packages/process_run/test/echo_test.dart +++ b/packages/process_run/test/echo_test.dart @@ -4,6 +4,7 @@ library process_run.echo_test; import 'dart:convert'; import 'dart:io'; +import 'package:path/path.dart'; import 'package:process_run/process_run.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/dartbin_impl.dart'; @@ -11,10 +12,14 @@ import 'package:test/test.dart'; import 'process_run_test_common.dart'; -var echo = '$resolvedDartExecutable run example/echo.dart'; +var echo = + '$resolvedDartExecutable run ${shellArgument(join("example", "echo.dart"))}'; void main() { group('echo', () { + test('run echo', () async { + await run('$echo --stdout test'); + }); Future runCheck( Object? Function(ProcessResult result) check, String executable, diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index a8cc504..b62b3e0 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -147,8 +147,13 @@ dart example/echo.dart -o ${shellArgument(weirdText)} '''); - expect(results[0].stdout.toString().trim(), r'a/bc/d'); - expect(results[1].stdout.toString().trim(), r'a/\b c/\d'); + if (Platform.isWindows) { + expect(results[0].stdout.toString().trim(), r'a/\bc/\d'); + expect(results[1].stdout.toString().trim(), r'a/\b c/\d'); + } else { + expect(results[0].stdout.toString().trim(), r'a/bc/d'); + expect(results[1].stdout.toString().trim(), r'a/\b c/\d'); + } expect(results.length, 2); }); test('dart', () async { @@ -400,7 +405,11 @@ dart current_dir.dart test('escape backslash', () async { var shell = Shell(verbose: debug); var results = await shell.run(r'echo "\\"'); - expect(results[0].stdout.toString().trim(), '\\'); + if (Platform.isWindows) { + expect(results[0].stdout.toString().trim(), r'\\'); + } else { + expect(results[0].stdout.toString().trim(), r'\'); + } }); test('others', () async { try { diff --git a/packages/process_run/test/src_shell_utils_test.dart b/packages/process_run/test/src_shell_utils_test.dart index 337f99d..67c022c 100644 --- a/packages/process_run/test/src_shell_utils_test.dart +++ b/packages/process_run/test/src_shell_utils_test.dart @@ -63,7 +63,11 @@ void main() { test('shellSplit', () { // We differ from io implementation - expect(shellSplit(r'"\\"'), [r'\']); + if (Platform.isWindows) { + expect(shellSplit(r'"\\"'), [r'\\']); + } else { + expect(shellSplit(r'"\\"'), [r'\']); + } expect(shellSplit('Hello world'), ['Hello', 'world']); expect(shellSplit('"Hello world"'), ['Hello world']); expect(shellSplit("'Hello world'"), ['Hello world']); From f9ee9136f762d124b5a81a87882610784902ef63 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 2 Jan 2024 18:56:48 +0100 Subject: [PATCH 076/150] [process_run] v0.14.0+1 --- packages/process_run/CHANGELOG.md | 4 +++- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 0eb6b63..befde83 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,6 +1,8 @@ -## 0.14.0 +## 0.14.0+1 * No longer replace `\` by `\\` before splitting arguments +* Fix backslash handling when splitting a command with a different behavior on Windows and Mac/Linux + (backslash is not an escape character on Windows) ## 0.13.3+1 diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 9800934..8e04d95 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.14.0 +version: 0.14.0+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 8a614749363fcf7b3c1b10b6263818354f9ea214 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 15 Jan 2024 11:09:44 +0100 Subject: [PATCH 077/150] work on #103, add runSync and runExecutableArgumentsSync both to global space and Shell class --- packages/process_run/example/demo_sync.dart | 17 ++ packages/process_run/lib/process_run.dart | 2 - packages/process_run/lib/shell.dart | 7 +- packages/process_run/lib/src/process_run.dart | 100 +++++++++ packages/process_run/lib/src/shell.dart | 202 +++++++++++++++++- .../process_run/lib/src/shell_common.dart | 50 +++-- packages/process_run/test/echo_test.dart | 9 + packages/process_run/test/shell_api_test.dart | 3 + .../process_run/test/shell_common_test.dart | 15 ++ packages/process_run/test/shell_run_test.dart | 10 + packages/process_run/test/shell_test.dart | 11 + 11 files changed, 395 insertions(+), 31 deletions(-) create mode 100755 packages/process_run/example/demo_sync.dart diff --git a/packages/process_run/example/demo_sync.dart b/packages/process_run/example/demo_sync.dart new file mode 100755 index 0000000..80bb01a --- /dev/null +++ b/packages/process_run/example/demo_sync.dart @@ -0,0 +1,17 @@ +import 'dart:io'; + +import 'package:process_run/process_run.dart'; + +void main() { + // Run the command + runExecutableArgumentsSync('echo', ['hello world']); + + // Stream the out to stdout + runExecutableArgumentsSync('echo', ['hello world']); + + // Calling dart + runExecutableArgumentsSync('dart', ['--version'], verbose: true); + + // stream the output to stderr + runExecutableArgumentsSync('dart', ['--version'], stderr: stderr); +} diff --git a/packages/process_run/lib/process_run.dart b/packages/process_run/lib/process_run.dart index 7a2e416..8f3759d 100644 --- a/packages/process_run/lib/process_run.dart +++ b/packages/process_run/lib/process_run.dart @@ -7,6 +7,4 @@ export 'package:process_run/src/shell_utils_common.dart' show argumentsToString, argumentToString; export 'shell.dart'; -export 'src/process_run.dart' - show runExecutableArguments, executableArgumentsToString; export 'which.dart' show which, whichSync; diff --git a/packages/process_run/lib/shell.dart b/packages/process_run/lib/shell.dart index 65ce319..6f9c509 100644 --- a/packages/process_run/lib/shell.dart +++ b/packages/process_run/lib/shell.dart @@ -55,9 +55,12 @@ export 'src/process_cmd.dart' /// Deprecated ProcessCmd; export 'src/process_run.dart' - show runExecutableArguments, executableArgumentsToString; + show + runExecutableArguments, + executableArgumentsToString, + runExecutableArgumentsSync; export 'src/prompt.dart' show promptConfirm, promptTerminate, prompt; -export 'src/shell.dart' show run, Shell, ShellException; +export 'src/shell.dart' show run, runSync, Shell, ShellException; export 'src/shell_environment.dart' show ShellEnvironment, diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index 9955640..35438a5 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -189,6 +189,106 @@ Future runExecutableArguments( return result; } +/// +/// if [commandVerbose] or [verbose] is true, display the command. +/// if [verbose] is true, stream stdout & stdin +/// +/// Compared to the async version, it is not possible to kill the spawn process nor to +/// feed any input. +ProcessResult runExecutableArgumentsSync( + String executable, List arguments, + {String? workingDirectory, + Map? environment, + bool includeParentEnvironment = true, + bool? runInShell, + Encoding? stdoutEncoding = systemEncoding, + Encoding? stderrEncoding = systemEncoding, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose}) { + if (verbose == true) { + commandVerbose = true; + stdout ??= io.stdout; + stderr ??= io.stderr; + } + + if (commandVerbose == true) { + utils.streamSinkWriteln(stdout ?? io.stdout, + '\$ ${executableArgumentsToString(executable, arguments)}', + encoding: stdoutEncoding); + } + + // Build our environment + var shellEnvironment = ShellEnvironment.full( + environment: environment, + includeParentEnvironment: includeParentEnvironment); + + // Default is the full command + var executableShortName = executable; + + // Find executable if needed, i.e. if it is only a name + if (basename(executable) == executable) { + // Try to find it in path or use it as is + executable = utils.findExecutableSync(executable, shellEnvironment.paths) ?? + executable; + } else { + // resolve locally + executable = utils.findExecutableSync(basename(executable), [ + join(workingDirectory ?? Directory.current.path, dirname(executable)) + ]) ?? + executable; + } + + // Fix runInShell on windows (force run in shell for non-.exe) + runInShell = utils.fixRunInShell(runInShell, executable); + + io.ProcessResult result; + try { + result = Process.runSync( + executable, + arguments, + environment: shellEnvironment, + includeParentEnvironment: false, + runInShell: runInShell, + workingDirectory: workingDirectory, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + ); + } catch (e) { + if (verbose == true) { + io.stderr.writeln(e); + io.stderr.writeln( + '\$ ${executableArgumentsToString(executableShortName, arguments)}'); + io.stderr.writeln( + 'workingDirectory: ${workingDirectory ?? Directory.current.path}'); + } + rethrow; + } + + List outputToIntList(dynamic data, Encoding? encoding) { + if (data is List) { + return data; + } else if (data is String && encoding != null) { + return encoding.encode(data); + } else { + throw 'Unexpected data type: ${data.runtimeType}'; + } + } + + if (stdout != null) { + var out = outputToIntList(result.stdout, stdoutEncoding); + stdout.add(out); + } + + if (stderr != null) { + var err = outputToIntList(result.stderr, stderrEncoding); + stderr.add(err); + } + + return result; +} + /// Command runner. not exported /// Execute a predefined ProcessCmd command diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 65322af..69312ed 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -3,11 +3,12 @@ import 'dart:io' as io; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; +import 'package:process_run/shell.dart' as impl; import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/platform/platform.dart'; import 'package:process_run/src/process_run.dart'; import 'package:process_run/src/shell_common.dart' - show ShellCore, ShellOptions, shellDebug; + show ShellCore, ShellCoreSync, ShellOptions, shellDebug; import 'package:process_run/src/shell_utils.dart'; import 'package:synchronized/synchronized.dart'; @@ -16,7 +17,7 @@ export 'shell_common.dart' show shellDebug; /// /// Run one or multiple plain text command(s). /// -/// Commands can be splitted by line. +/// Commands can be split by line. /// /// Commands can be on multiple line if ending with ' ^' or ' \'. /// @@ -68,6 +69,62 @@ Future> run( .run(script, onProcess: onProcess); } +/// +/// Run one or multiple plain text command(s). +/// +/// Commands can be split by line. +/// +/// Commands can be on multiple line if ending with ' ^' or ' \'. +/// +/// Returns a list of executed command line results. Verbose by default. +/// +/// +/// ```dart +/// await run('flutter build'); +/// await run('dart --version'); +/// await run(''' +/// dart --version +/// git status +/// '''); +/// +/// Compared to the async version, it is not possible to kill the spawn process nor to +/// feed any input. +/// ``` +List runSync( + String script, { + bool throwOnError = true, + String? workingDirectory, + Map? environment, + bool includeParentEnvironment = true, + bool? runInShell, + Encoding stdoutEncoding = systemEncoding, + Encoding stderrEncoding = systemEncoding, + StreamSink>? stdout, + StreamSink>? stderr, + bool verbose = true, + + // Default to true + bool? commandVerbose, + // Default to true if verbose is true + bool? commentVerbose, +}) { + return Shell( + throwOnError: throwOnError, + workingDirectory: workingDirectory, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdin: stdin, + stdout: stdout, + stderr: stderr, + verbose: verbose, + commandVerbose: commandVerbose, + commentVerbose: commentVerbose) + .runSync(script); +} + /// Multiplatform Shell utility to run a script with multiple commands. /// /// Extra path/env can be loaded using ~/.config/tekartik/process_run/env.yaml @@ -89,7 +146,7 @@ Future> run( /// /// A list of ProcessResult is returned /// -abstract class Shell implements ShellCore { +abstract class Shell implements ShellCore, ShellCoreSync { final ShellOptions _options; /// Incremental internal runId @@ -279,7 +336,7 @@ abstract class Shell implements ShellCore { /// /// Run one or multiple plain text command(s). /// - /// Commands can be splitted by line. + /// Commands can be split by line. /// /// Commands can be on multiple line if ending with ' ^' or ' \'. (note that \ /// must be escaped too so you might have to enter \\). @@ -329,6 +386,55 @@ abstract class Shell implements ShellCore { }); } + /// + /// Run one or multiple plain text command(s). + /// + /// Commands can be split by line. + /// + /// Commands can be on multiple line if ending with ' ^' or ' \'. (note that \ + /// must be escaped too so you might have to enter \\). + /// + /// Returns a list of executed command line results. + /// + /// [onProcess] is called for each started process. + /// + /// Compare to the async version, it is not possible to kill the spawn process nor to + /// feed any input. + /// + @override + List runSync( + String script, + ) { + var commands = scriptToCommands(script); + + var processResults = []; + for (var command in commands) { + // Display the comments + if (isLineComment(command!)) { + if (_options.commentVerbose) { + stdout.writeln(command); + } + continue; + } + var parts = shellSplit(command); + var executable = parts[0]; + var arguments = parts.sublist(1); + + // Find alias + var alias = _options.environment.aliases[executable]; + if (alias != null) { + // The alias itself should be split + parts = shellSplit(alias); + executable = parts[0]; + arguments = [...parts.sublist(1), ...arguments]; + } + var processResult = runExecutableArgumentsSync(executable, arguments); + processResults.add(processResult); + } + + return processResults; + } + final _runLock = Lock(); /// Run a single [executable] with [arguments], resolving the [executable] if needed. @@ -346,6 +452,24 @@ abstract class Shell implements ShellCore { }); } + /// Run a single [executable] with [arguments], resolving the [executable] if needed. + /// + /// Returns a process result (or throw if specified in the shell). + /// + /// [onProcess] is called for each started process. + @override + ProcessResult runExecutableArgumentsSync( + String executable, + List arguments, + ) { + var runId = ++_runId; + return _runExecutableArgumentsSync( + runId, + executable, + arguments, + ); + } + Future _runLocked(FutureOr Function(int runId) action) { // devPrint('Previous: ${_currentProcessToString()}'); var runId = ++_runId; @@ -373,6 +497,76 @@ abstract class Shell implements ShellCore { _currentProcessResultCompleter = null; } + /// Run a single [executable] with [arguments], resolving the [executable] if needed. + /// + /// Call onProcess upon process startup + /// + /// Returns a process result (or throw if specified in the shell). + ProcessResult _runExecutableArgumentsSync( + int runId, + String executable, + List arguments, + ) { + var executableFullPath = + findExecutableSync(executable, _userPaths) ?? executable; + var processCmd = ProcessCmd(executableFullPath, arguments); + try { + _clearPreviousContext(); + + ProcessResult? processResult; + + try { + if (shellDebug) { + print('$_runId: Before $processCmd'); + } + + processResult = impl.runExecutableArgumentsSync( + executableFullPath, arguments, + runInShell: _options.runInShell, + environment: _options.environment, + includeParentEnvironment: false, + stderrEncoding: _options.stderrEncoding ?? io.systemEncoding, + stdoutEncoding: _options.stdoutEncoding ?? io.systemEncoding, + workingDirectory: _options.workingDirectory); + } finally { + if (shellDebug) { + print( + '$_runId: After $executableFullPath exitCode ${processResult?.exitCode}'); + } + } + // devPrint('After $processCmd'); + if (_options.throwOnError && processResult.exitCode != 0) { + throw ShellException( + '$processCmd, exitCode ${processResult.exitCode}, workingDirectory: $_workingDirectoryPath', + processResult); + } + return processResult; + } on ProcessException catch (e) { + var stderr = _options.stderr ?? io.stderr; + void writeln([String? msg]) { + stderr.add(utf8.encode(msg ?? '')); + stderr.add(utf8.encode('\n')); + } + + var workingDirectory = + _options.workingDirectory ?? Directory.current.path; + + writeln(); + if (!Directory(workingDirectory).existsSync()) { + writeln('Missing working directory $workingDirectory'); + } else { + writeln(''' + Check that $executableFullPath exists + command: $processCmd'''); + } + writeln(); + + throw ShellException( + '$processCmd, error: $e, workingDirectory: $_workingDirectoryPath', + null); + } + } + /// Run a single [executable] with [arguments], resolving the [executable] if needed. /// /// Call onProcess upon process startup diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index 540f7c1..84dd379 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -36,28 +36,6 @@ var shellDebug = false; // devWarning(true); // false /// A list of ProcessResult is returned /// abstract class ShellCore { - /* - ShellCore( - {ShellOptions? options, - Map? environment, - - /// Compat, prefer options - bool? verbose, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - StreamSink>? stdout, - StreamSink>? stderr, - bool? runInShell}) => - shellContext.newShell( - options: options?.clone( - verbose: verbose, - stderrEncoding: stderrEncoding, - stdoutEncoding: stdoutEncoding, - runInShell: runInShell, - stdout: stdout, - stderr: stderr), - environment: environment);*/ - /// Kills the current running process. /// /// Returns `true` if the signal is successfully delivered to the process. @@ -116,6 +94,32 @@ abstract class ShellCore { ShellContext get context; } +abstract class ShellCoreSync { + /// + /// Run one or multiple plain text command(s). + /// + /// Commands can be split by line. + /// + /// Commands can be on multiple line if ending with ' ^' or ' \'. (note that \ + /// must be escaped too so you might have to enter \\). + /// + /// Returns a list of executed command line results. + /// + /// Compared to the async version, it is not possible to kill the spawn process nor to + /// feed any input. + /// + List runSync(String script); + + /// Run a single [executable] with [arguments], resolving the [executable] if needed. + /// + /// Returns a process result (or throw if specified in the shell). + /// + /// Compared to the async version, it is not possible to kill the spawn process nor to + /// feed any input. + ProcessResult runExecutableArgumentsSync( + String executable, List arguments); +} + /// Shell options. class ShellOptions { final bool _throwOnError; @@ -248,7 +252,7 @@ Future which(String command, } /// Default missing implementation. -mixin ShellMixin implements ShellCore { +mixin ShellMixin implements ShellCore, ShellCoreSync { // Set lazily after newShell; @override late ShellContext context; diff --git a/packages/process_run/test/echo_test.dart b/packages/process_run/test/echo_test.dart index 6ce3908..863693e 100644 --- a/packages/process_run/test/echo_test.dart +++ b/packages/process_run/test/echo_test.dart @@ -52,6 +52,15 @@ void main() { stderrEncoding: stderrEncoding, stdout: stdout); check(result); + result = runExecutableArgumentsSync(executable, arguments, + workingDirectory: workingDirectory, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdout: stdout); + check(result); } test('stdout', () async { diff --git a/packages/process_run/test/shell_api_test.dart b/packages/process_run/test/shell_api_test.dart index f6f58d7..9dfd5a4 100644 --- a/packages/process_run/test/shell_api_test.dart +++ b/packages/process_run/test/shell_api_test.dart @@ -36,6 +36,9 @@ void main() { promptTerminate; prompt; run; + runSync; + runExecutableArguments; + runExecutableArgumentsSync; Shell; ShellOptions; ShellException; diff --git a/packages/process_run/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart index 110dc5b..fffbc04 100644 --- a/packages/process_run/test/shell_common_test.dart +++ b/packages/process_run/test/shell_common_test.dart @@ -152,6 +152,21 @@ class ShellMock with ShellMixin implements Shell { throw UnimplementedError(); } + @override + ProcessResult runExecutableArgumentsSync( + String executable, + List arguments, + ) { + // TODO: implement runExecutableArguments + throw UnimplementedError(); + } + + @override + List runSync(String script) { + // TODO: implement runSync + throw UnimplementedError(); + } + @override late final ShellOptions options; } diff --git a/packages/process_run/test/shell_run_test.dart b/packages/process_run/test/shell_run_test.dart index cbb83a7..aaf6a24 100644 --- a/packages/process_run/test/shell_run_test.dart +++ b/packages/process_run/test/shell_run_test.dart @@ -45,6 +45,15 @@ void main() { verbose: false); }); + test('sync --version', () async { + var result = runSync('dart --version', + throwOnError: false, verbose: false, commandVerbose: true) + .first; + stdout.writeln('stdout: ${result.stdout.toString().trim()}'); + stdout.writeln('stderr: ${result.stderr.toString().trim()}'); + stdout.writeln('exitCode: ${result.exitCode}'); + }); + test('--version', () async { for (var bin in [ // 'dartdoc', deprecated @@ -63,6 +72,7 @@ void main() { stdout.writeln('exitCode: ${result.exitCode}'); } }); + test('dart compile', () async { var bin = 'build/native/info.exe'; await Directory(dirname(bin)).create(recursive: true); diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index b62b3e0..4cb1ebe 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -162,6 +162,12 @@ dart example/echo.dart -o ${shellArgument(weirdText)} expect(results.length, 1); expect(results.first.exitCode, 0); }); + test('sync dart', () async { + var shell = Shell(verbose: debug); + var results = shell.runSync('''dart --version'''); + expect(results.length, 1); + expect(results.first.exitCode, 0); + }); test('dart runExecutableArguments', () async { var shell = Shell(verbose: debug); @@ -585,6 +591,10 @@ _tekartik_dummy_app_that_does_not_exits (await sh.runExecutableArguments(dartExecutable!, ['--version'])) .stderr .toString()); + var resolvedVersionSync = parseDartBinVersionOutput( + (sh.runExecutableArgumentsSync(dartExecutable!, ['--version'])) + .stderr + .toString()); var whichVersion = parseDartBinVersionOutput( (await sh.runExecutableArguments(whichDart!, ['--version'])) .stderr @@ -595,6 +605,7 @@ _tekartik_dummy_app_that_does_not_exits .toString()); expect(version, resolvedVersion); expect(version, whichVersion); + expect(version, resolvedVersionSync); }); test('verbose non ascii char', () async { From 1fdda52bc028cc76949bfb5e345ae1670c60a154 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 15 Jan 2024 15:14:46 +0100 Subject: [PATCH 078/150] [process_run] v0.14.1 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/doc/shell.md | 23 +++++++++------------ packages/process_run/example/demo_sync.dart | 7 +++++++ packages/process_run/pubspec.yaml | 2 +- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index befde83..ed822f2 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.14.1 + +* add `runSync` and `runExecutableArgumentsSync` to global space and to `Shell` + ## 0.14.0+1 * No longer replace `\` by `\\` before splitting arguments diff --git a/packages/process_run/doc/shell.md b/packages/process_run/doc/shell.md index e7d45cb..5379121 100644 --- a/packages/process_run/doc/shell.md +++ b/packages/process_run/doc/shell.md @@ -41,23 +41,20 @@ await run('echo "Hello world"'); await run('echo ${shellArgument('Hello world')}'); ``` -### Changing directory +## Running the script in synchronous mode -You can pushd/popd a directory +The synchronous mode is useful for testing. It is not recommended for production use as +it is a synchronous call and will block until the child process terminates. -```dart -shell = shell.pushd('example'); - -await shell.run(''' - -# Listing directory in the example folder -dir - -'''); -shell = shell.popd(); +```dart +var shell = Shell(); +// This is a synchronous call and will block until the child process terminates. +var results = shell.runSync('echo "Hello world"'); +var result = results.first; +print('output: "${result.outText.trim()}" exitCode: ${result.exitCode}'); +// should display: output: "Hello world" exitCode: 0 ``` - ### Handling errors By default, `run` will throw an error if the `exitCode` is not 0. You can prevent that diff --git a/packages/process_run/example/demo_sync.dart b/packages/process_run/example/demo_sync.dart index 80bb01a..e3d80bd 100755 --- a/packages/process_run/example/demo_sync.dart +++ b/packages/process_run/example/demo_sync.dart @@ -3,6 +3,13 @@ import 'dart:io'; import 'package:process_run/process_run.dart'; void main() { + var shell = Shell(); + // This is a synchronous call and will block until the child process terminates. + var results = shell.runSync('echo "Hello world"'); + var result = results.first; + print('output: "${result.outText.trim()}" exitCode: ${result.exitCode}'); + // should display: output: "Hello world" exitCode: 0 + // Run the command runExecutableArgumentsSync('echo', ['hello world']); diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 8e04d95..a1f1a33 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.14.0+1 +version: 0.14.1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 35c74b3d89683355aba3cfebbcefb33516e7eba4 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 15 Jan 2024 15:20:08 +0100 Subject: [PATCH 079/150] Shell doc --- packages/process_run/doc/shell.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/process_run/doc/shell.md b/packages/process_run/doc/shell.md index 5379121..3ad5161 100644 --- a/packages/process_run/doc/shell.md +++ b/packages/process_run/doc/shell.md @@ -43,6 +43,9 @@ await run('echo ${shellArgument('Hello world')}'); ## Running the script in synchronous mode +`runSync` and `runExecutableArgumentsSync` are available since 0.14.1 in the global space and in the `Shell` class. +They are synchronous version of `run` and `runExecutableArguments` respectively with some limitations. + The synchronous mode is useful for testing. It is not recommended for production use as it is a synchronous call and will block until the child process terminates. @@ -55,6 +58,12 @@ print('output: "${result.outText.trim()}" exitCode: ${result.exitCode}'); // should display: output: "Hello world" exitCode: 0 ``` +**Warning**: +- You cannot feed any stdin to the child process. +- You cannot kill a synchronous child process. +- Available since 0.14.1 +- Recommended for testing only, it is a synchronous call and will block until the child process terminates. + ### Handling errors By default, `run` will throw an error if the `exitCode` is not 0. You can prevent that From 3d3ce7309acb1aa56857904a13bf3001598dcf9f Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 15 Jan 2024 18:16:11 +0100 Subject: [PATCH 080/150] doc: runSync --- packages/process_run/lib/src/shell.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 69312ed..5f7ee2a 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -80,9 +80,9 @@ Future> run( /// /// /// ```dart -/// await run('flutter build'); -/// await run('dart --version'); -/// await run(''' +/// runSync('flutter build'); +/// runSync('dart --version'); +/// runSync(''' /// dart --version /// git status /// '''); From c09ae3a60387f0313825586b12a0122655417382 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 15 Jan 2024 18:16:54 +0100 Subject: [PATCH 081/150] doc: runSync --- packages/process_run/lib/src/shell.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 5f7ee2a..0fa38eb 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -86,6 +86,7 @@ Future> run( /// dart --version /// git status /// '''); +/// ``` /// /// Compared to the async version, it is not possible to kill the spawn process nor to /// feed any input. From 7fe391be5b3f4266678cf7b3a2d3c124987f8851 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 15 Jan 2024 18:17:27 +0100 Subject: [PATCH 082/150] [process_run] v0.14.1+1 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index ed822f2..272e5f1 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.14.1 +## 0.14.1+1 * add `runSync` and `runExecutableArgumentsSync` to global space and to `Shell` diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index a1f1a33..4587402 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.14.1 +version: 0.14.1+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From ff9d30da45bd81268c2d5193b1342d23f618aa56 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 15 Jan 2024 18:37:52 +0100 Subject: [PATCH 083/150] [process_run] v0.14.1+2 doc --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/lib/src/shell.dart | 12 ++++-------- packages/process_run/lib/src/shell_common.dart | 8 ++++---- packages/process_run/pubspec.yaml | 2 +- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 272e5f1..c5a1a9c 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.14.1+1 +## 0.14.1+2 * add `runSync` and `runExecutableArgumentsSync` to global space and to `Shell` diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 0fa38eb..1758ffe 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -19,7 +19,7 @@ export 'shell_common.dart' show shellDebug; /// /// Commands can be split by line. /// -/// Commands can be on multiple line if ending with ' ^' or ' \'. +/// Commands can be on multiple line if ending with ` ^` or `` \``. /// /// Returns a list of executed command line results. Verbose by default. /// @@ -74,7 +74,7 @@ Future> run( /// /// Commands can be split by line. /// -/// Commands can be on multiple line if ending with ' ^' or ' \'. +/// Commands can be on multiple line if ending with ` ^` or `` \``. /// /// Returns a list of executed command line results. Verbose by default. /// @@ -339,8 +339,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// /// Commands can be split by line. /// - /// Commands can be on multiple line if ending with ' ^' or ' \'. (note that \ - /// must be escaped too so you might have to enter \\). + /// Commands can be on multiple line if ending with ` ^` or `` \``. /// /// Returns a list of executed command line results. /// @@ -392,13 +391,10 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// /// Commands can be split by line. /// - /// Commands can be on multiple line if ending with ' ^' or ' \'. (note that \ - /// must be escaped too so you might have to enter \\). + /// Commands can be on multiple line if ending with ` ^` or `` \``. /// /// Returns a list of executed command line results. /// - /// [onProcess] is called for each started process. - /// /// Compare to the async version, it is not possible to kill the spawn process nor to /// feed any input. /// diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index 84dd379..c6b27a6 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -48,8 +48,8 @@ abstract class ShellCore { /// /// Commands can be splitted by line. /// - /// Commands can be on multiple line if ending with ' ^' or ' \'. (note that \ - /// must be escaped too so you might have to enter \\). + /// Commands can be on multiple line if ending with ` ^` or `` \``. (note that ``\`` + /// must be escaped too so you might have to enter ``\\``). /// /// Returns a list of executed command line results. /// @@ -100,8 +100,8 @@ abstract class ShellCoreSync { /// /// Commands can be split by line. /// - /// Commands can be on multiple line if ending with ' ^' or ' \'. (note that \ - /// must be escaped too so you might have to enter \\). + /// Commands can be on multiple line if ending with ` ^` or `` \``. (note that ``\`` + /// must be escaped too so you might have to enter ``\\``). /// /// Returns a list of executed command line results. /// diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 4587402..f41dfa2 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.14.1+1 +version: 0.14.1+2 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 59218a8e1f4b8d66a530b38eea256630d8bdcf87 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 15 Jan 2024 18:40:41 +0100 Subject: [PATCH 084/150] [process_run] v0.14.1+3 doc --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/lib/src/shell.dart | 1 - packages/process_run/pubspec.yaml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index c5a1a9c..c2857e6 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.14.1+2 +## 0.14.1+3 * add `runSync` and `runExecutableArgumentsSync` to global space and to `Shell` diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 1758ffe..5994ef0 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -90,7 +90,6 @@ Future> run( /// /// Compared to the async version, it is not possible to kill the spawn process nor to /// feed any input. -/// ``` List runSync( String script, { bool throwOnError = true, diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index f41dfa2..96b9f74 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.14.1+2 +version: 0.14.1+3 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 8135dd39cf50c94f8b516e131220050bf55aabf1 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 24 Jan 2024 18:31:32 +0100 Subject: [PATCH 085/150] fix lints --- packages/process_run/analysis_options.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/process_run/analysis_options.yaml b/packages/process_run/analysis_options.yaml index 279d957..4b8852b 100644 --- a/packages/process_run/analysis_options.yaml +++ b/packages/process_run/analysis_options.yaml @@ -16,8 +16,6 @@ analyzer: errors: # treat missing required parameters as a warning (not a hint) missing_required_param: warning - # treat missing returns as a warning (not a hint) - missing_return: warning # allow having TODOs in the code todo: ignore From 057304ce12dec8e8f19936c9a1a44d4f7d84d7d8 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 21 Feb 2024 11:16:46 +0100 Subject: [PATCH 086/150] fix: work on #105 add noStdoutResult and noStdErrResult to ShellOptions to avoid out of memory for very long output --- packages/process_run/lib/src/process_run.dart | 17 +++- packages/process_run/lib/src/shell.dart | 59 +++++++----- .../process_run/lib/src/shell_common.dart | 95 ++++++++++++------- packages/process_run/test/shell_test.dart | 49 ++++++++++ 4 files changed, 162 insertions(+), 58 deletions(-) diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index 35438a5..a423628 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -18,6 +18,9 @@ export 'shell_utils_io.dart' show executableArgumentsToString; /// /// Optional [onProcess(process)] is called to allow killing the process. /// +/// If [noStdoutResult] is true, the result will not contain the stdout. +/// If [noStderrResult] is true, the result will not contain the stderr. +/// /// Don't mess-up with the input and output for now here. only use it for kill. Future runExecutableArguments( String executable, List arguments, @@ -32,6 +35,8 @@ Future runExecutableArguments( StreamSink>? stderr, bool? verbose, bool? commandVerbose, + bool? noStdoutResult, + bool? noStderrResult, void Function(Process process)? onProcess}) async { if (verbose == true) { commandVerbose = true; @@ -137,8 +142,12 @@ Future runExecutableArguments( return list; } - var out = streamToResult(outCtlr.stream, stdoutEncoding); - var err = streamToResult(errCtlr.stream, stderrEncoding); + var out = (noStdoutResult ?? false) + ? Future.value(null) + : streamToResult(outCtlr.stream, stdoutEncoding); + var err = (noStderrResult ?? false) + ? Future.value(null) + : streamToResult(errCtlr.stream, stderrEncoding); process.stdout.listen((List d) { if (stdout != null) { @@ -303,6 +312,8 @@ Future processCmdRun(ProcessCmd cmd, Stream>? stdin, StreamSink>? stdout, StreamSink>? stderr, + bool? noStdoutResult, + bool? noStderrResult, void Function(Process process)? onProcess}) async { if (verbose == true) { stdout ??= io.stdout; @@ -328,6 +339,8 @@ Future processCmdRun(ProcessCmd cmd, stdin: stdin, stdout: stdout, stderr: stderr, + noStdoutResult: noStdoutResult, + noStderrResult: noStderrResult, onProcess: onProcess); } catch (e) { if (verbose == true) { diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 5994ef0..1f46d87 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -2,8 +2,8 @@ import 'dart:convert'; import 'dart:io' as io; import 'package:path/path.dart'; -import 'package:process_run/shell.dart'; import 'package:process_run/shell.dart' as impl; +import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/platform/platform.dart'; import 'package:process_run/src/process_run.dart'; @@ -23,6 +23,8 @@ export 'shell_common.dart' show shellDebug; /// /// Returns a list of executed command line results. Verbose by default. /// +/// Prefer using [options] than the parameters. [options] overrides all other +/// parameters but [onProcess]. /// /// ```dart /// await run('flutter build'); @@ -50,6 +52,7 @@ Future> run( bool? commandVerbose, // Default to true if verbose is true bool? commentVerbose, + ShellOptions? options, void Function(Process process)? onProcess, }) { return Shell( @@ -65,7 +68,8 @@ Future> run( stderr: stderr, verbose: verbose, commandVerbose: commandVerbose, - commentVerbose: commentVerbose) + commentVerbose: commentVerbose, + options: options) .run(script, onProcess: onProcess); } @@ -107,6 +111,9 @@ List runSync( bool? commandVerbose, // Default to true if verbose is true bool? commentVerbose, + + /// Override all other options parameters + ShellOptions? options, }) { return Shell( throwOnError: throwOnError, @@ -121,7 +128,8 @@ List runSync( stderr: stderr, verbose: verbose, commandVerbose: commandVerbose, - commentVerbose: commentVerbose) + commentVerbose: commentVerbose, + options: options) .runSync(script); } @@ -181,6 +189,8 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// /// if [verbose] is not false or [commentVerbose] is true, it will display the /// comments as well + /// + /// [options] overrides all other parameters factory Shell( {bool throwOnError = true, String? workingDirectory, @@ -197,6 +207,8 @@ abstract class Shell implements ShellCore, ShellCoreSync { bool? commandVerbose, // Default to false bool? commentVerbose, + + /// Overrides all parameters ShellOptions? options}) { var shell = shellContext.newShell( options: options ?? @@ -227,26 +239,27 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// Create a new shell @Deprecated('Use clone with options') - Shell clone( - {bool? throwOnError, - String? workingDirectory, - // Don't change environment - @Deprecated('Don\'t change map') Map? environment, + Shell clone({ + bool? throwOnError, + String? workingDirectory, + // Don't change environment + @Deprecated('Don\'t change map') Map? environment, - /// Explicetely set e new environment + /// Explicetely set e new environment // ShellEnvironment? shellEnvironment, - @Deprecated('Don\'t change includeParentEnvironment') - // Don't change includeParentEnvironment - bool? includeParentEnvironment, - bool? runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose, - bool? commentVerbose}) { + @Deprecated('Don\'t change includeParentEnvironment') + // Don't change includeParentEnvironment + bool? includeParentEnvironment, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, + bool? commentVerbose, + }) { var localShellEnvironment = // Compat (environment is ShellEnvironment ? environment : null); @@ -601,7 +614,9 @@ abstract class Shell implements ShellCore, ShellCoreSync { commandVerbose: _options.commandVerbose, stderr: _options.stderr, stdin: _options.stdin, - stdout: _options.stdout, onProcess: (process) { + stdout: _options.stdout, + noStdoutResult: _options.noStdoutResult, + noStderrResult: _options.noStderrResult, onProcess: (process) { _currentProcess = process; _currentProcessCmd = processCmd; _currentProcessRunId = runId; diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index c6b27a6..1e2a984 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -121,6 +121,8 @@ abstract class ShellCoreSync { } /// Shell options. +/// + class ShellOptions { final bool _throwOnError; final String? _workingDirectory; @@ -134,6 +136,8 @@ class ShellOptions { final bool _verbose; final bool _commandVerbose; final bool _commentVerbose; + final bool? _noStdoutResult; + final bool? _noStderrResult; late final ShellEnvironment? _environment; @@ -164,24 +168,34 @@ class ShellOptions { /// default to true for non .exe files /// /// if [verbose] is not false or [commentVerbose] is true, it will display the - /// comments as well - ShellOptions( - {bool throwOnError = true, - String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool? runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool verbose = true, - // Default to true - bool? commandVerbose, - // Default to false - bool? commentVerbose}) - : _throwOnError = throwOnError, + /// comments as well. + /// + /// If [noStdoutResult] is true, stdout will be null in the ProcessResult result + /// of the run command (runSync will still contain it). + /// + /// If [noStderrResult] is true, stderr will be null in the ProcessResult result + /// of the run command (runSync will still contain it). + ShellOptions({ + bool throwOnError = true, + String? workingDirectory, + Map? environment, + bool includeParentEnvironment = true, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool verbose = true, + // Default to true + bool? commandVerbose, + // Default to false + bool? commentVerbose, + // Default to false + bool? noStdoutResult, + // Default to false + bool? noStderrResult, + }) : _throwOnError = throwOnError, _workingDirectory = workingDirectory, _runInShell = runInShell, _stdoutEncoding = stdoutEncoding, @@ -191,7 +205,9 @@ class ShellOptions { _stderr = stderr, _verbose = verbose, _commandVerbose = commandVerbose ?? verbose, - _commentVerbose = commentVerbose ?? false { + _commentVerbose = commentVerbose ?? false, + _noStderrResult = noStderrResult, + _noStdoutResult = noStdoutResult { _environment = ShellEnvironment.full( environment: environment, includeParentEnvironment: includeParentEnvironment); @@ -212,6 +228,12 @@ class ShellOptions { /// True if it should throw if an error occurred. bool get throwOnError => _throwOnError; + /// True if ProcessResult should not contain stdout + bool? get noStdoutResult => _noStdoutResult; + + /// True if ProcessResult should not contain stderr + bool? get noStderrResult => _noStderrResult; + /// Create a new shell ShellOptions clone( {bool? throwOnError, @@ -225,6 +247,8 @@ class ShellOptions { bool? verbose, bool? commandVerbose, bool? commentVerbose, + bool? noStdoutResult, + bool? noStderrResult, ShellEnvironment? shellEnvironment}) { return ShellOptions( verbose: verbose ?? _verbose, @@ -238,7 +262,9 @@ class ShellOptions { stdoutEncoding: stdoutEncoding ?? _stdoutEncoding, throwOnError: throwOnError ?? _throwOnError, workingDirectory: workingDirectory ?? _workingDirectory, - environment: shellEnvironment); + environment: shellEnvironment, + noStdoutResult: noStdoutResult ?? _noStdoutResult, + noStderrResult: noStderrResult ?? _noStderrResult); } } @@ -272,20 +298,21 @@ mixin ShellMixin implements ShellCore, ShellCoreSync { } @Deprecated('Use clone with options') - Shell clone( - {bool? throwOnError, - String? workingDirectory, - Map? environment, - bool? includeParentEnvironment, - bool? runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose, - bool? commentVerbose}) { + Shell clone({ + bool? throwOnError, + String? workingDirectory, + Map? environment, + bool? includeParentEnvironment, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, + bool? commentVerbose, + }) { return cloneWithOptions( ShellOptions( throwOnError: throwOnError ?? options.throwOnError, diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index 4cb1ebe..66909e2 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -105,7 +105,56 @@ dart example/echo.dart -o éà expect(results.length, 7); }); + // Compiled version + var echoExe = shellArgument(join('.local', 'example', 'echo.exe')); + Future ensureEchoExe() async { + if (!File(echoExe).existsSync()) { + await Directory(join('.local', 'example')).create(recursive: true); + await run( + 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o $echoExe'); + } + } + + test('noStdoutResult/noStderrResult', () async { + await ensureEchoExe(); + var options = ShellOptions(noStdoutResult: true, verbose: false); + var shell = Shell(options: options); + var script = '$echoExe -o Out -e Err'; + var result = (await shell.run(script)).first; + expect(result.stdout, isNull); + expect(result.stderr, 'Err'); + result = (await shell + .runExecutableArguments(echoExe, ['-o', 'Out', '-e', 'Err'])); + expect(result.stdout, isNull); + expect(result.stderr, 'Err'); + // Not valid for runSync + result = (shell.runSync(script)).first; + expect(result.stdout, 'Out'); + expect(result.stderr, 'Err'); + // Not valid for runExecutableArgumentsSync + result = (shell + .runExecutableArgumentsSync(echoExe, ['-o', 'Out', '-e', 'Err'])); + expect(result.stdout, 'Out'); + expect(result.stderr, 'Err'); + result = (await run(script, options: options)).first; + expect(result.stdout, isNull); + expect(result.stderr, 'Err'); + result = (runSync(script, options: options)).first; + // Not valid for runSync + expect(result.stdout, 'Out'); + expect(result.stderr, 'Err'); + options = ShellOptions(noStderrResult: true, verbose: false); + shell = Shell(options: options); + result = (await shell.run(script)).first; + expect(result.stdout, 'Out'); + expect(result.stderr, isNull); + result = (await run(script, options: options)).first; + expect(result.stdout, 'Out'); + expect(result.stderr, isNull); + }); + test('arguments utf8', () async { + await ensureEchoExe(); var shell = Shell(verbose: debug, stdoutEncoding: utf8); var results = await shell.run(''' dart example/echo.dart -o 你好 From d3c4947b388c71aa8c0693fdbe9435b809edc2be Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 21 Feb 2024 11:42:19 +0100 Subject: [PATCH 087/150] fix #105 add noStdoutResult and noStdErrResult to ShellOptions and runExecutableArguments to avoid out of memory for very long output --- packages/process_run/lib/src/process_cmd.dart | 4 +- packages/process_run/test/shell_test.dart | 116 ++++++++++-------- 2 files changed, 65 insertions(+), 55 deletions(-) diff --git a/packages/process_run/lib/src/process_cmd.dart b/packages/process_run/lib/src/process_cmd.dart index 74b8f22..2307089 100644 --- a/packages/process_run/lib/src/process_cmd.dart +++ b/packages/process_run/lib/src/process_cmd.dart @@ -11,8 +11,8 @@ class ProcessCmd { Map? environment; bool includeParentEnvironment; bool? runInShell; - Encoding? stdoutEncoding; - Encoding? stderrEncoding; + Encoding stdoutEncoding; + Encoding stderrEncoding; ProcessCmd(this.executable, this.arguments, {this.workingDirectory, diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index 66909e2..4112c1f 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -15,6 +15,17 @@ import 'package:test/test.dart'; import 'hex_utils.dart'; +// Compiled version of echo.dart +var echoExePath = join('.local', 'example', 'echo.exe'); +var echoExe = shellArgument(echoExePath); +Future ensureEchoExe() async { + if (!File(echoExe).existsSync()) { + await Directory(dirname(echoExePath)).create(recursive: true); + await run( + 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o $echoExe'); + } +} + @Deprecated('Dev only, used when uncommenting debug = devTrue') bool devTrue = true; @@ -78,18 +89,19 @@ void main() { }); test('arguments', () async { + await ensureEchoExe(); var shell = Shell(verbose: debug); var text = 'Hello world'; var results = await shell.run(''' # this will print 'Helloworld' -dart example/echo.dart -o Hello world -dart example/echo.dart -o $text +$echoExe -o Hello world +$echoExe -o $text # this will print 'Hello world' -dart example/echo.dart -o 'Hello world' -dart example/echo.dart -o 'Hello world' -dart example/echo.dart -o ${shellArgument(text)} -dart example/echo.dart -o 你好 -dart example/echo.dart -o éà +$echoExe -o 'Hello world' +$echoExe -o 'Hello world' +$echoExe -o ${shellArgument(text)} +$echoExe -o 你好 +$echoExe -o éà '''); expect(results[0].stdout.toString().trim(), 'Helloworld'); expect(results[1].stdout.toString().trim(), 'Helloworld'); @@ -105,16 +117,6 @@ dart example/echo.dart -o éà expect(results.length, 7); }); - // Compiled version - var echoExe = shellArgument(join('.local', 'example', 'echo.exe')); - Future ensureEchoExe() async { - if (!File(echoExe).existsSync()) { - await Directory(join('.local', 'example')).create(recursive: true); - await run( - 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o $echoExe'); - } - } - test('noStdoutResult/noStderrResult', () async { await ensureEchoExe(); var options = ShellOptions(noStdoutResult: true, verbose: false); @@ -139,8 +141,14 @@ dart example/echo.dart -o éà result = (await run(script, options: options)).first; expect(result.stdout, isNull); expect(result.stderr, 'Err'); - result = (runSync(script, options: options)).first; + result = (await runExecutableArguments( + echoExe, ['-o', 'Out', '-e', 'Err'], + noStdoutResult: true)); + expect(result.stdout, isNull); + expect(result.stderr, 'Err'); // Not valid for runSync + result = (runSync(script, options: options)).first; + expect(result.stdout, 'Out'); expect(result.stderr, 'Err'); options = ShellOptions(noStderrResult: true, verbose: false); @@ -157,42 +165,44 @@ dart example/echo.dart -o éà await ensureEchoExe(); var shell = Shell(verbose: debug, stdoutEncoding: utf8); var results = await shell.run(''' -dart example/echo.dart -o 你好 +$echoExe -o 你好 '''); expect(results.outLines.toList()[0], '你好'); expect(results.length, 1); }); test('outLines, errLines', () async { + await ensureEchoExe(); var shell = Shell(verbose: debug, runInShell: true); var results = await shell.run( - 'dart example/echo.dart --stdout-hex ${bytesToHex(utf8.encode('Hello\nWorld'))}'); + '$echoExe --stdout-hex ${bytesToHex(utf8.encode('Hello\nWorld'))}'); expect(results.outLines, ['Hello', 'World']); expect(results[0].outLines, ['Hello', 'World']); expect(results.errLines, isEmpty); - results = await shell.run('dart example/echo.dart -e Hello'); + results = await shell.run('$echoExe -e Hello'); expect(results.outLines, isEmpty); expect(results.errLines, ['Hello']); results = await shell.run(''' # This is a 2 commands file -dart example/echo.dart -o Hello +$echoExe -o Hello -dart example/echo.dart -e World +$echoExe -e World '''); expect(results.outLines, ['Hello']); expect(results.errLines, ['World']); }); test('backslash', () async { + await ensureEchoExe(); var shell = Shell(verbose: debug); var weirdText = r'a/\b c/\d'; var results = await shell.run(''' -dart example/echo.dart -o $weirdText -dart example/echo.dart -o ${shellArgument(weirdText)} +$echoExe -o $weirdText +$echoExe -o ${shellArgument(weirdText)} '''); @@ -236,11 +246,12 @@ dart example/echo.dart -o ${shellArgument(weirdText)} test('kill simple', () async { try { await () async { - var shell = Shell().cd('example'); - await shell.run('dart run echo.dart --version'); + await ensureEchoExe(); + var shell = Shell(); + await shell.run('$echoExe --version'); late Future future; try { - future = shell.run('dart run echo.dart --wait 30000'); + future = shell.run('$echoExe --wait 30000'); await future.timeout(const Duration(milliseconds: 2500)); fail('should fail'); } on TimeoutException catch (_) { @@ -263,12 +274,13 @@ dart example/echo.dart -o ${shellArgument(weirdText)} } }, timeout: const Timeout(Duration(seconds: 50))); test('kill complex', () async { + await ensureEchoExe(); try { await () async { - var shell = Shell().cd('example'); + var shell = Shell(); late Future future; try { - future = shell.run('dart echo.dart --wait 3000'); + future = shell.run('$echoExe --wait 3000'); await future.timeout(const Duration(milliseconds: 2000)); fail('should fail'); } on TimeoutException catch (_) { @@ -280,12 +292,12 @@ dart example/echo.dart -o ${shellArgument(weirdText)} await future; fail('should fail'); } on ShellException catch (_) { - // 2: ShellException(dart echo.dart --wait 3000, exitCode -15, workingDirectory: + // 2: ShellException($echoExe--wait 3000, exitCode -15, workingDirectory: // devPrint('2: $e'); } try { - var future = shell.run('dart echo.dart --wait 10000'); + var future = shell.run('$echoExe --wait 10000'); await Future.delayed(const Duration(milliseconds: 3000)); shell.kill(); await future.timeout(const Duration(milliseconds: 8000)); @@ -297,7 +309,7 @@ dart example/echo.dart -o ${shellArgument(weirdText)} try { // Killing before calling future = shell - .run('dart echo.dart --wait 9000') + .run('$echoExe --wait 9000') .timeout(const Duration(milliseconds: 7000)); shell.kill(); await future; @@ -315,26 +327,26 @@ dart example/echo.dart -o ${shellArgument(weirdText)} group('ShellLinesController', () { test('Shell Lines out', () async { + await ensureEchoExe(); var linesController = ShellLinesController(); - var shell = - Shell(stdout: linesController.sink, verbose: false).cd('example'); - await shell.run('dart echo.dart some_text'); + var shell = Shell(stdout: linesController.sink, verbose: false); + await shell.run('$echoExe some_text'); linesController.close(); expect(await linesController.stream.toList(), ['some_text']); linesController = ShellLinesController(); - shell = - Shell(stdout: linesController.sink, verbose: false).cd('example'); - await shell.run('dart echo.dart some_text1'); + shell = Shell(stdout: linesController.sink, verbose: false); + await shell.run('$echoExe some_text1'); await shell.run(''' - dart echo.dart some_text2 - dart echo.dart some_text3 + $echoExe some_text2 + $echoExe some_text3 '''); linesController.close(); expect(await linesController.stream.toList(), ['some_text1', 'some_text2', 'some_text3']); }); test('pause', () async { + await ensureEchoExe(); late ShellLinesController linesController; var lines = []; late Shell shell; @@ -344,8 +356,7 @@ dart example/echo.dart -o ${shellArgument(weirdText)} lines.clear(); subscription?.cancel(); linesController = ShellLinesController(); - shell = - Shell(stdout: linesController.sink, verbose: false).cd('example'); + shell = Shell(stdout: linesController.sink, verbose: false); lines.clear(); subscription = linesController.stream.listen((event) { // devPrint('line: $event'); @@ -354,25 +365,25 @@ dart example/echo.dart -o ${shellArgument(weirdText)} } init(); - await shell.run('dart echo.dart some_text'); + await shell.run('$echoExe some_text'); expect(lines, ['some_text']); init(); subscription?.pause(); - await shell.run('dart echo.dart some_text'); + await shell.run('$echoExe some_text'); expect(lines, isEmpty); init(); - await shell.run('dart echo.dart some_text1'); + await shell.run('$echoExe some_text1'); expect(lines, ['some_text1']); lines.clear(); subscription!.pause(); var count = 0; await shell.run(''' - dart echo.dart some_text2 - dart echo.dart some_text3 + $echoExe some_text2 + $echoExe some_text3 ''', onProcess: (process) { count++; // devPrint('onProcess ${process.pid} (paused: $paused)'); @@ -385,7 +396,7 @@ dart example/echo.dart -o ${shellArgument(weirdText)} lines.clear(); subscription!.resume(); await shell.run(''' - dart echo.dart some_text4 + $echoExe some_text4 '''); expect(lines.last, 'some_text4'); }); @@ -658,17 +669,16 @@ _tekartik_dummy_app_that_does_not_exits }); test('verbose non ascii char', () async { + await ensureEchoExe(); var controller = ShellLinesController(); var shell = Shell( stdout: controller.sink, verbose: true, - environment: ShellEnvironment() - ..aliases['echo'] = 'dart example/echo.dart -o'); + environment: ShellEnvironment()..aliases['echo'] = '$echoExe -o'); await shell.run('echo 你好é'); controller.close(); if (!Platform.isWindows) { - expect(await controller.stream.toList(), - ['\$ dart example/echo.dart -o 你好é', '你好é']); + expect(await controller.stream.toList(), ['\$ $echoExe -o 你好é', '你好é']); } }); From 9200e39d80fc83f53f3e4880c8b2cdf2d7d7df8c Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 21 Feb 2024 11:44:41 +0100 Subject: [PATCH 088/150] [process_run] v0.14.2 --- packages/process_run/CHANGELOG.md | 5 +++++ packages/process_run/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index c2857e6..bfb7b86 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.14.2 + +* add `noStdoutResult` and `noStderrResult` to `ShellOptions` and `runExecutableArguments` to avoid out of memory for + very long output + ## 0.14.1+3 * add `runSync` and `runExecutableArgumentsSync` to global space and to `Shell` diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 96b9f74..d1292f8 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.14.1+3 +version: 0.14.2 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 00479b939234fb1443279e62426d1febf15441eb Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 13 May 2024 09:45:46 +0200 Subject: [PATCH 089/150] fix lints --- .github/workflows/run_ci.yml | 2 -- packages/process_run/lib/src/flutterbin_cmd.dart | 2 +- packages/process_run/lib/src/process_cmd.dart | 2 +- packages/process_run/lib/src/process_run.dart | 2 +- packages/process_run/lib/src/shell.dart | 2 +- packages/process_run/lib/src/shell_utils_io.dart | 5 ++--- packages/process_run/test/process_cmd_test.dart | 2 +- packages/process_run/test/which_test.dart | 2 +- 8 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index 054ebcc..c52b788 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -16,8 +16,6 @@ jobs: fail-fast: false matrix: include: - - os: ubuntu-latest - dart: 3.0.5 - os: ubuntu-latest dart: stable - os: ubuntu-latest diff --git a/packages/process_run/lib/src/flutterbin_cmd.dart b/packages/process_run/lib/src/flutterbin_cmd.dart index 930c06a..f3fd8de 100644 --- a/packages/process_run/lib/src/flutterbin_cmd.dart +++ b/packages/process_run/lib/src/flutterbin_cmd.dart @@ -30,7 +30,7 @@ bool get isFlutterSupportedSync => flutterExecutablePath != null; class FlutterCmd extends ProcessCmd { // Somehow flutter requires runInShell on Linux, does not hurt on windows FlutterCmd(List arguments) - : super(flutterExecutablePath, arguments, runInShell: true); + : super(flutterExecutablePath!, arguments, runInShell: true); @override String toString() => executableArgumentsToString('flutter', arguments); diff --git a/packages/process_run/lib/src/process_cmd.dart b/packages/process_run/lib/src/process_cmd.dart index 2307089..aa73481 100644 --- a/packages/process_run/lib/src/process_cmd.dart +++ b/packages/process_run/lib/src/process_cmd.dart @@ -5,7 +5,7 @@ import 'package:collection/collection.dart'; import 'package:process_run/process_run.dart'; class ProcessCmd { - String? executable; + String executable; List arguments; String? workingDirectory; Map? environment; diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index a423628..5ba0da4 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -327,7 +327,7 @@ Future processCmdRun(ProcessCmd cmd, } try { - return await runExecutableArguments(cmd.executable!, cmd.arguments, + return await runExecutableArguments(cmd.executable, cmd.arguments, workingDirectory: cmd.workingDirectory, environment: cmd.environment, includeParentEnvironment: cmd.includeParentEnvironment, diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 1f46d87..bed95dc 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -700,7 +700,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { class _ProcessCmd extends ProcessCmd { final String executableShortName; - _ProcessCmd(String super.executable, super.arguments, + _ProcessCmd(super.executable, super.arguments, {required this.executableShortName}); @override diff --git a/packages/process_run/lib/src/shell_utils_io.dart b/packages/process_run/lib/src/shell_utils_io.dart index 438f97f..aa3359a 100644 --- a/packages/process_run/lib/src/shell_utils_io.dart +++ b/packages/process_run/lib/src/shell_utils_io.dart @@ -6,10 +6,9 @@ import 'package:path/path.dart'; import 'package:process_run/src/shell_utils.dart'; /// Convenient way to display a command -String executableArgumentsToString( - String? executable, List? arguments) { +String executableArgumentsToString(String executable, List? arguments) { final sb = StringBuffer(); - if (Platform.isWindows && (basename(executable!) == executable)) { + if (Platform.isWindows && (basename(executable) == executable)) { var ext = extension(executable); switch (ext) { case '.exe': diff --git a/packages/process_run/test/process_cmd_test.dart b/packages/process_run/test/process_cmd_test.dart index 0ff7c29..4a2af1e 100644 --- a/packages/process_run/test/process_cmd_test.dart +++ b/packages/process_run/test/process_cmd_test.dart @@ -36,7 +36,7 @@ void main() { expect(cmd1, isNot(cmd2)); }); test('dart_cmd', () async { - final result = await runCmd(ProcessCmd(dartExecutable, ['--version'])); + final result = await runCmd(ProcessCmd(dartExecutable!, ['--version'])); testDartVersionOutput(result); // 'Dart VM version: 1.7.0-dev.4.5 (Thu Oct 9 01:44:31 2014) on 'linux_x64'\n' }); diff --git a/packages/process_run/test/which_test.dart b/packages/process_run/test/which_test.dart index 2ceb913..d6cf7b2 100644 --- a/packages/process_run/test/which_test.dart +++ b/packages/process_run/test/which_test.dart @@ -18,7 +18,7 @@ void main() { var dartExecutable = whichSync('dart', environment: env); expect(dartExecutable, isNotNull); print(dartExecutable); - var cmd = ProcessCmd(dartExecutable, ['--version']); + var cmd = ProcessCmd(dartExecutable!, ['--version']); final result = await runCmd(cmd); testDartVersionOutput(result); }); From 910964e8f39d351c3e6525c30c87454ac3ea26e1 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 13 May 2024 09:46:08 +0200 Subject: [PATCH 090/150] fix lints --- packages/process_run/test/src/shell_impl_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/process_run/test/src/shell_impl_test.dart b/packages/process_run/test/src/shell_impl_test.dart index 4f189d0..f7077e4 100644 --- a/packages/process_run/test/src/shell_impl_test.dart +++ b/packages/process_run/test/src/shell_impl_test.dart @@ -1,4 +1,6 @@ @TestOn('vm') +library; + import 'dart:io'; import 'package:path/path.dart'; From 10b9a40a27ea11e8c1700cc78c6f33fb041486ce Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 29 Jun 2024 09:32:19 +0200 Subject: [PATCH 091/150] feat: add stdio lines grouper --- packages/process_run/analysis_options.yaml | 1 + .../example/shell_stdio_lines_grouper.dart | 24 ++ packages/process_run/lib/cmd_run.dart | 2 +- packages/process_run/lib/package/package.dart | 3 +- .../process_run/lib/src/bin/shell/dump.dart | 2 +- .../lib/src/bin/shell/env_alias_delete.dart | 2 +- .../lib/src/bin/shell/env_alias_get.dart | 3 +- .../lib/src/bin/shell/env_alias_set.dart | 2 +- .../lib/src/bin/shell/env_delete.dart | 3 +- .../lib/src/bin/shell/env_edit.dart | 3 +- .../lib/src/bin/shell/env_file_content.dart | 2 +- .../lib/src/bin/shell/env_path_delete.dart | 2 +- .../lib/src/bin/shell/env_path_get.dart | 3 +- .../lib/src/bin/shell/env_path_prepend.dart | 2 +- .../lib/src/bin/shell/env_var_delete.dart | 3 +- .../lib/src/bin/shell/env_var_get.dart | 3 +- .../lib/src/bin/shell/env_var_set.dart | 3 +- .../process_run/lib/src/bin/shell/import.dart | 3 +- .../lib/src/bin/shell/shell_bin_command.dart | 3 +- .../process_run/lib/src/common/dartbin.dart | 3 +- packages/process_run/lib/src/dartbin_cmd.dart | 2 +- .../process_run/lib/src/dartbin_impl.dart | 3 +- packages/process_run/lib/src/dev_cmd_run.dart | 2 +- .../lib/src/io/env_var_delete_io.dart | 2 +- .../lib/src/io/env_var_set_io.dart | 2 +- packages/process_run/lib/src/io/io.dart | 20 ++ .../process_run/lib/src/io/io_import.dart | 3 +- .../process_run/lib/src/io/shared_stdin.dart | 2 +- .../lib/src/platform/platform.dart | 1 + .../lib/src/platform/platform_common.dart | 16 ++ .../lib/src/platform/platform_io.dart | 9 +- .../lib/src/platform/platform_stub.dart | 23 +- packages/process_run/lib/src/process_cmd.dart | 2 +- packages/process_run/lib/src/process_run.dart | 4 +- packages/process_run/lib/src/prompt.dart | 3 +- .../process_run/lib/src/script_filename.dart | 2 +- packages/process_run/lib/src/shell.dart | 16 +- .../process_run/lib/src/shell_common.dart | 1 - .../lib/src/shell_context_common.dart | 40 ++++ .../process_run/lib/src/shell_context_io.dart | 4 +- .../process_run/lib/src/shell_utils_io.dart | 3 +- .../lib/src/stdio/platform/platform.dart | 1 + .../lib/src/stdio/platform/platform_io.dart | 7 + .../lib/src/stdio/platform/platform_stub.dart | 5 + .../lib/src/stdio/platform/shell_import.dart | 3 + .../lib/src/stdio/shell_streamer_io.dart | 50 ++++ packages/process_run/lib/src/stdio/stdio.dart | 222 ++++++++++++++++++ packages/process_run/lib/src/user_config.dart | 2 +- packages/process_run/lib/src/utils.dart | 2 +- packages/process_run/lib/stdio.dart | 1 + .../lib/utils/process_result_extension.dart | 2 +- packages/process_run/test/compile_test.dart | 47 +++- .../process_run/test/shell_common_test.dart | 24 +- .../test/shell_stdio_lines_grouper_test.dart | 51 ++++ .../process_run/test/src/compile_echo.dart | 20 ++ .../src/shell_output_lines_streamer_test.dart | 17 ++ 56 files changed, 572 insertions(+), 114 deletions(-) create mode 100644 packages/process_run/example/shell_stdio_lines_grouper.dart create mode 100644 packages/process_run/lib/src/io/io.dart create mode 100644 packages/process_run/lib/src/platform/platform_common.dart create mode 100644 packages/process_run/lib/src/stdio/platform/platform.dart create mode 100644 packages/process_run/lib/src/stdio/platform/platform_io.dart create mode 100644 packages/process_run/lib/src/stdio/platform/platform_stub.dart create mode 100644 packages/process_run/lib/src/stdio/platform/shell_import.dart create mode 100644 packages/process_run/lib/src/stdio/shell_streamer_io.dart create mode 100644 packages/process_run/lib/src/stdio/stdio.dart create mode 100644 packages/process_run/lib/stdio.dart create mode 100644 packages/process_run/test/shell_stdio_lines_grouper_test.dart create mode 100644 packages/process_run/test/src/compile_echo.dart create mode 100644 packages/process_run/test/src/shell_output_lines_streamer_test.dart diff --git a/packages/process_run/analysis_options.yaml b/packages/process_run/analysis_options.yaml index 4b8852b..828eba2 100644 --- a/packages/process_run/analysis_options.yaml +++ b/packages/process_run/analysis_options.yaml @@ -21,6 +21,7 @@ analyzer: linter: rules: + # - public_member_api_docs - always_declare_return_types - avoid_dynamic_calls - avoid_slow_async_io diff --git a/packages/process_run/example/shell_stdio_lines_grouper.dart b/packages/process_run/example/shell_stdio_lines_grouper.dart new file mode 100644 index 0000000..33efaee --- /dev/null +++ b/packages/process_run/example/shell_stdio_lines_grouper.dart @@ -0,0 +1,24 @@ +import 'package:process_run/shell.dart'; +import 'package:process_run/stdio.dart'; +import '../test/src/compile_echo.dart'; + +void main() async { + var echo = await compileEchoExample(); + + var options = ShellOptions( + verbose: true, environment: ShellEnvironment()..aliases['echo'] = echo); + + Future> printHello123Slow() async { + var shell = Shell(options: options); + return await shell.run(''' +echo --wait 100 --stdout hello1 --write-line +echo --wait 100 --stdout hello2 --write-line +'''); + } + + var stdio = shellStdioLinesGrouper; + await Future.wait>([ + stdio.runZoned(() => printHello123Slow()), + stdio.runZoned(() => printHello123Slow()) + ]); +} diff --git a/packages/process_run/lib/cmd_run.dart b/packages/process_run/lib/cmd_run.dart index abfde91..8ba8825 100644 --- a/packages/process_run/lib/cmd_run.dart +++ b/packages/process_run/lib/cmd_run.dart @@ -5,7 +5,7 @@ library process_run.cmd_run; /// Command runner /// import 'dart:async'; -import 'dart:io'; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/process_run.dart'; diff --git a/packages/process_run/lib/package/package.dart b/packages/process_run/lib/package/package.dart index 92c8136..ad94048 100644 --- a/packages/process_run/lib/package/package.dart +++ b/packages/process_run/lib/package/package.dart @@ -1,6 +1,5 @@ -import 'dart:io'; - import 'package:path/path.dart'; +import 'package:process_run/src/io/io.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; import 'package:yaml/yaml.dart'; diff --git a/packages/process_run/lib/src/bin/shell/dump.dart b/packages/process_run/lib/src/bin/shell/dump.dart index 47a4cf7..de8b5cf 100644 --- a/packages/process_run/lib/src/bin/shell/dump.dart +++ b/packages/process_run/lib/src/bin/shell/dump.dart @@ -1,4 +1,4 @@ -import 'dart:io'; +import 'package:process_run/src/io/io.dart'; void dumpStringMap(Map map) { var keys = map.keys.toList() diff --git a/packages/process_run/lib/src/bin/shell/env_alias_delete.dart b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart index 17fc017..7770058 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'dart:io'; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; class ShellEnvAliasDeleteCommand extends ShellEnvCommandBase { ShellEnvAliasDeleteCommand() diff --git a/packages/process_run/lib/src/bin/shell/env_alias_get.dart b/packages/process_run/lib/src/bin/shell/env_alias_get.dart index c88137a..deb2455 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_get.dart @@ -1,8 +1,7 @@ -import 'dart:io'; - import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; import 'dump.dart'; diff --git a/packages/process_run/lib/src/bin/shell/env_alias_set.dart b/packages/process_run/lib/src/bin/shell/env_alias_set.dart index 8a98e34..e1dab9c 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_set.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_set.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'dart:io'; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; class ShellEnvAliasSetCommand extends ShellEnvCommandBase { ShellEnvAliasSetCommand() diff --git a/packages/process_run/lib/src/bin/shell/env_delete.dart b/packages/process_run/lib/src/bin/shell/env_delete.dart index f9fd6f2..2f641e8 100644 --- a/packages/process_run/lib/src/bin/shell/env_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_delete.dart @@ -1,8 +1,7 @@ -import 'dart:io'; - import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/shell.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; import 'env.dart'; diff --git a/packages/process_run/lib/src/bin/shell/env_edit.dart b/packages/process_run/lib/src/bin/shell/env_edit.dart index d5311df..78f6adb 100644 --- a/packages/process_run/lib/src/bin/shell/env_edit.dart +++ b/packages/process_run/lib/src/bin/shell/env_edit.dart @@ -1,7 +1,6 @@ -import 'dart:io'; - import 'package:process_run/shell.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; import 'env.dart'; diff --git a/packages/process_run/lib/src/bin/shell/env_file_content.dart b/packages/process_run/lib/src/bin/shell/env_file_content.dart index 54fa815..31ebf6a 100644 --- a/packages/process_run/lib/src/bin/shell/env_file_content.dart +++ b/packages/process_run/lib/src/bin/shell/env_file_content.dart @@ -1,7 +1,7 @@ import 'dart:convert'; -import 'dart:io'; import 'package:process_run/src/characters.dart'; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/user_config.dart'; class FileContent { diff --git a/packages/process_run/lib/src/bin/shell/env_path_delete.dart b/packages/process_run/lib/src/bin/shell/env_path_delete.dart index 0364b3e..f8a0317 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_delete.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'dart:io'; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; class ShellEnvPathDeleteCommand extends ShellEnvCommandBase { ShellEnvPathDeleteCommand() diff --git a/packages/process_run/lib/src/bin/shell/env_path_get.dart b/packages/process_run/lib/src/bin/shell/env_path_get.dart index 8a8d27c..e5b44e9 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_get.dart @@ -1,9 +1,8 @@ -import 'dart:io'; - import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/dump.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; class ShellEnvPathGetCommand extends ShellEnvCommandBase { ShellEnvPathGetCommand() diff --git a/packages/process_run/lib/src/bin/shell/env_path_prepend.dart b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart index bca15c0..bc6948e 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_prepend.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'dart:io'; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; class ShellEnvPathPrependCommand extends ShellEnvCommandBase { ShellEnvPathPrependCommand() diff --git a/packages/process_run/lib/src/bin/shell/env_var_delete.dart b/packages/process_run/lib/src/bin/shell/env_var_delete.dart index 44e61b7..66bbf44 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_delete.dart @@ -1,9 +1,8 @@ -import 'dart:io'; - import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_var_delete_io.dart'; +import 'package:process_run/src/io/io.dart'; class ShellEnvVarDeleteCommand extends ShellEnvCommandBase { late final helper = ShellEnvVarDeleteIoHelper( diff --git a/packages/process_run/lib/src/bin/shell/env_var_get.dart b/packages/process_run/lib/src/bin/shell/env_var_get.dart index b5e6e85..d997765 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_get.dart @@ -1,8 +1,7 @@ -import 'dart:io'; - import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_var_get_io.dart'; +import 'package:process_run/src/io/io.dart'; import 'dump.dart'; diff --git a/packages/process_run/lib/src/bin/shell/env_var_set.dart b/packages/process_run/lib/src/bin/shell/env_var_set.dart index 62acb06..8890e24 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_set.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_set.dart @@ -1,9 +1,8 @@ -import 'dart:io'; - import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_var_set_io.dart'; +import 'package:process_run/src/io/io.dart'; class ShellEnvVarSetCommand extends ShellEnvCommandBase { late final helper = ShellEnvVarSetIoHelper( diff --git a/packages/process_run/lib/src/bin/shell/import.dart b/packages/process_run/lib/src/bin/shell/import.dart index b14e998..7a19cfa 100644 --- a/packages/process_run/lib/src/bin/shell/import.dart +++ b/packages/process_run/lib/src/bin/shell/import.dart @@ -1,7 +1,6 @@ -export 'dart:io'; - export 'package:meta/meta.dart'; export 'package:process_run/src/bin/shell/shell.dart'; export 'package:process_run/src/common/import.dart'; +export 'package:process_run/src/io/io.dart'; export 'shell_bin_command.dart'; diff --git a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart index 76f8f1b..e52c901 100644 --- a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart +++ b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart @@ -1,10 +1,9 @@ -import 'dart:io'; - // ignore: import_of_legacy_library_into_null_safe import 'package:args/args.dart'; import 'package:meta/meta.dart'; import 'package:process_run/src/bin/shell/shell.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/io/io.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; diff --git a/packages/process_run/lib/src/common/dartbin.dart b/packages/process_run/lib/src/common/dartbin.dart index f658455..6c21489 100644 --- a/packages/process_run/lib/src/common/dartbin.dart +++ b/packages/process_run/lib/src/common/dartbin.dart @@ -1,8 +1,7 @@ -import 'dart:io'; - import 'package:path/path.dart'; import 'package:process_run/src/dartbin_cmd.dart'; import 'package:process_run/src/dartbin_impl.dart'; +import 'package:process_run/src/io/io.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; diff --git a/packages/process_run/lib/src/dartbin_cmd.dart b/packages/process_run/lib/src/dartbin_cmd.dart index 1bdc284..e661907 100644 --- a/packages/process_run/lib/src/dartbin_cmd.dart +++ b/packages/process_run/lib/src/dartbin_cmd.dart @@ -1,8 +1,8 @@ import 'dart:convert'; -import 'dart:io'; import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/utils.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; diff --git a/packages/process_run/lib/src/dartbin_impl.dart b/packages/process_run/lib/src/dartbin_impl.dart index a7f378b..583d150 100644 --- a/packages/process_run/lib/src/dartbin_impl.dart +++ b/packages/process_run/lib/src/dartbin_impl.dart @@ -1,6 +1,5 @@ -import 'dart:io'; - import 'package:path/path.dart'; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/shell_utils.dart'; import 'package:process_run/src/user_config.dart'; diff --git a/packages/process_run/lib/src/dev_cmd_run.dart b/packages/process_run/lib/src/dev_cmd_run.dart index 6b26af4..561bb39 100644 --- a/packages/process_run/lib/src/dev_cmd_run.dart +++ b/packages/process_run/lib/src/dev_cmd_run.dart @@ -1,7 +1,7 @@ import 'dart:async'; -import 'dart:io'; import 'package:process_run/cmd_run.dart'; +import 'package:process_run/src/io/io.dart'; @Deprecated('Deb only, verbose') Future devRunCmd(ProcessCmd cmd, diff --git a/packages/process_run/lib/src/io/env_var_delete_io.dart b/packages/process_run/lib/src/io/env_var_delete_io.dart index a278251..f9c2253 100644 --- a/packages/process_run/lib/src/io/env_var_delete_io.dart +++ b/packages/process_run/lib/src/io/env_var_delete_io.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'dart:io'; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_io.dart'; +import 'package:process_run/src/io/io.dart'; class ShellEnvVarDeleteIoHelper extends ShellEnvIoHelper { ShellEnvVarDeleteIoHelper( diff --git a/packages/process_run/lib/src/io/env_var_set_io.dart b/packages/process_run/lib/src/io/env_var_set_io.dart index cd20ff7..e77dc92 100644 --- a/packages/process_run/lib/src/io/env_var_set_io.dart +++ b/packages/process_run/lib/src/io/env_var_set_io.dart @@ -1,10 +1,10 @@ import 'dart:convert'; -import 'dart:io'; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_io.dart'; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/shell_common.dart'; class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { diff --git a/packages/process_run/lib/src/io/io.dart b/packages/process_run/lib/src/io/io.dart new file mode 100644 index 0000000..ebf0d98 --- /dev/null +++ b/packages/process_run/lib/src/io/io.dart @@ -0,0 +1,20 @@ +import 'dart:io' as io; + +import 'package:process_run/src/stdio/stdio.dart'; + +export 'dart:io' hide stdout, stderr; + +export 'package:process_run/src/stdio/stdio.dart' + show ShellStdio, shellStdioLinesGrouper, ShellStdioExt; + +/// Global stdout +io.IOSink get stdout => shellStdioOrNull?.out ?? io.stdout; + +/// Global stderr +io.IOSink get stderr => shellStdioOrNull?.err ?? io.stderr; + +/// io stdout. +io.IOSink get ioStdout => io.stdout; + +/// io stdout. +io.IOSink get ioStderr => io.stderr; diff --git a/packages/process_run/lib/src/io/io_import.dart b/packages/process_run/lib/src/io/io_import.dart index be872dc..04e0b86 100644 --- a/packages/process_run/lib/src/io/io_import.dart +++ b/packages/process_run/lib/src/io/io_import.dart @@ -1 +1,2 @@ -export 'dart:io' show ProcessResult, Process, ProcessSignal; +export 'package:process_run/src/io/io.dart' + show ProcessResult, Process, ProcessSignal; diff --git a/packages/process_run/lib/src/io/shared_stdin.dart b/packages/process_run/lib/src/io/shared_stdin.dart index 21b733e..7572f29 100644 --- a/packages/process_run/lib/src/io/shared_stdin.dart +++ b/packages/process_run/lib/src/io/shared_stdin.dart @@ -4,9 +4,9 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io'; import 'package:meta/meta.dart'; +import 'package:process_run/src/io/io.dart'; /// A shared singleton instance of `dart:io`'s [stdin] stream. /// diff --git a/packages/process_run/lib/src/platform/platform.dart b/packages/process_run/lib/src/platform/platform.dart index e67cc23..6211174 100644 --- a/packages/process_run/lib/src/platform/platform.dart +++ b/packages/process_run/lib/src/platform/platform.dart @@ -1 +1,2 @@ +export 'platform_common.dart' show shellContext, clearShellContext; export 'platform_stub.dart' if (dart.library.io) 'platform_io.dart'; diff --git a/packages/process_run/lib/src/platform/platform_common.dart b/packages/process_run/lib/src/platform/platform_common.dart new file mode 100644 index 0000000..6841dcd --- /dev/null +++ b/packages/process_run/lib/src/platform/platform_common.dart @@ -0,0 +1,16 @@ +import 'package:meta/meta.dart'; +import 'package:process_run/src/shell_context_common.dart'; + +/// Global platform shell context, if any. +@internal +ShellContext? shellContextPlatformOrNull; + +/// Set shell context before use, default to io on io, in memory otherwise. +set shellContext(ShellContext shellContext) => + shellContextPlatformOrNull = shellContext; + +/// Internal use only. +@visibleForTesting +void clearShellContext() { + shellContextPlatformOrNull = null; +} diff --git a/packages/process_run/lib/src/platform/platform_io.dart b/packages/process_run/lib/src/platform/platform_io.dart index f91ce93..ee4763f 100644 --- a/packages/process_run/lib/src/platform/platform_io.dart +++ b/packages/process_run/lib/src/platform/platform_io.dart @@ -1,13 +1,12 @@ -import 'dart:io'; +import 'package:process_run/src/io/io.dart'; +import 'package:process_run/src/platform/platform_common.dart'; import 'package:process_run/src/shell_context_common.dart'; import 'package:process_run/src/shell_context_io.dart'; bool get platformIoIsWindows => Platform.isWindows; /// Global shell context -ShellContext shellContext = ShellContextIo(); +final shellContextIo = ShellContextIo(); -void clearShellContext() { - throw StateError('clearShellContext Not supported'); -} +ShellContext get shellContext => shellContextPlatformOrNull ??= shellContextIo; diff --git a/packages/process_run/lib/src/platform/platform_stub.dart b/packages/process_run/lib/src/platform/platform_stub.dart index c85a683..d1da5ca 100644 --- a/packages/process_run/lib/src/platform/platform_stub.dart +++ b/packages/process_run/lib/src/platform/platform_stub.dart @@ -1,24 +1,9 @@ -import 'package:process_run/src/bin/shell/import.dart'; +import 'package:process_run/src/platform/platform_common.dart'; import 'package:process_run/src/shell_context_common.dart'; /// Only true for IO windows bool get platformIoIsWindows => false; -ShellContext? _shellContext; - -/// Must be set before use -ShellContext get shellContext { - if (_shellContext == null) { - throw StateError('shellContext must be set before use'); - } - return _shellContext!; -} - -/// Set shell context before use -set shellContext(ShellContext shellContext) => _shellContext = shellContext; - -/// Internal use only. -@visibleForTesting -void clearShellContext() { - _shellContext = null; -} +/// Never null +ShellContext get shellContext => + shellContextPlatformOrNull ??= shellContextMemory; diff --git a/packages/process_run/lib/src/process_cmd.dart b/packages/process_run/lib/src/process_cmd.dart index aa73481..a9a1001 100644 --- a/packages/process_run/lib/src/process_cmd.dart +++ b/packages/process_run/lib/src/process_cmd.dart @@ -1,8 +1,8 @@ import 'dart:convert'; -import 'dart:io'; import 'package:collection/collection.dart'; import 'package:process_run/process_run.dart'; +import 'package:process_run/src/io/io.dart'; class ProcessCmd { String executable; diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index 5ba0da4..eed4472 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'dart:io' as io; -import 'dart:io'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; +import 'package:process_run/src/io/io.dart' as io; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/shell.dart'; import 'package:process_run/src/shell_utils.dart' as utils; import 'package:process_run/src/shell_utils.dart'; diff --git a/packages/process_run/lib/src/prompt.dart b/packages/process_run/lib/src/prompt.dart index c802bbf..d504688 100644 --- a/packages/process_run/lib/src/prompt.dart +++ b/packages/process_run/lib/src/prompt.dart @@ -1,7 +1,8 @@ import 'dart:convert'; -import 'dart:io'; import 'package:process_run/shell.dart'; +import 'package:process_run/src/io/io.dart'; + import 'shell_utils.dart'; /// Get text diff --git a/packages/process_run/lib/src/script_filename.dart b/packages/process_run/lib/src/script_filename.dart index 42a9069..8966326 100644 --- a/packages/process_run/lib/src/script_filename.dart +++ b/packages/process_run/lib/src/script_filename.dart @@ -1,4 +1,4 @@ -import 'dart:io'; +import 'package:process_run/src/io/io.dart'; /// 'flutter' => 'flutter.bat' (windows) or 'flutter' String getBashOrBatExecutableFilename(String command) { diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index bed95dc..633b6cd 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -1,10 +1,9 @@ import 'dart:convert'; -import 'dart:io' as io; -import 'package:path/path.dart'; import 'package:process_run/shell.dart' as impl; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/import.dart'; +import 'package:process_run/src/io/io.dart' as io; import 'package:process_run/src/platform/platform.dart'; import 'package:process_run/src/process_run.dart'; import 'package:process_run/src/shell_common.dart' @@ -14,6 +13,9 @@ import 'package:synchronized/synchronized.dart'; export 'shell_common.dart' show shellDebug; +/// Shell on process callback +typedef ShellOnProcessCallback = void Function(Process process); + /// /// Run one or multiple plain text command(s). /// @@ -53,7 +55,7 @@ Future> run( // Default to true if verbose is true bool? commentVerbose, ShellOptions? options, - void Function(Process process)? onProcess, + ShellOnProcessCallback? onProcess, }) { return Shell( throwOnError: throwOnError, @@ -287,8 +289,8 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// Create new shell at the given path @override Shell cd(String path) { - if (isRelative(path)) { - path = join(_workingDirectoryPath, path); + if (context.path.isRelative(path)) { + path = context.path.join(_workingDirectoryPath, path); } if (_options.commandVerbose) { streamSinkWriteln(_options.stdout ?? stdout, '\$ cd $path', @@ -359,7 +361,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// @override Future> run(String script, - {void Function(Process process)? onProcess}) { + {ShellOnProcessCallback? onProcess}) { // devPrint('Running $script'); return _runLocked((runId) async { var commands = scriptToCommands(script); @@ -584,6 +586,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { Future _lockedRunExecutableArguments( int runId, String executable, List arguments, {void Function(Process process)? onProcess}) { + /// Global process handler. try { _clearPreviousContext(); var completer = @@ -608,6 +611,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { if (shellDebug) { print('$_runId: Before $processCmd'); } + try { processResult = await processCmdRun(processCmd, verbose: _options.verbose, diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index 1e2a984..4c59383 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -279,7 +279,6 @@ Future which(String command, /// Default missing implementation. mixin ShellMixin implements ShellCore, ShellCoreSync { - // Set lazily after newShell; @override late ShellContext context; diff --git a/packages/process_run/lib/src/shell_context_common.dart b/packages/process_run/lib/src/shell_context_common.dart index ca3e478..1713c84 100644 --- a/packages/process_run/lib/src/shell_context_common.dart +++ b/packages/process_run/lib/src/shell_context_common.dart @@ -29,3 +29,43 @@ abstract class ShellContext { Map? environment, }); } + +mixin ShellContextMixin implements ShellContext { + @override + Encoding get encoding => + throw UnimplementedError('ShellContextMixin.encoding'); + @override + Shell newShell( + {ShellOptions? options, + Map? environment, + bool includeParentEnvironment = true}) { + throw UnimplementedError('ShellContext.newShell'); + } + + @override + ShellEnvironment newShellEnvironment({Map? environment}) { + throw UnimplementedError('ShellContext.newShellEnvironment'); + } + + @override + p.Context get path => throw UnimplementedError('ShellContext.path'); + + @override + ShellEnvironment get shellEnvironment => + throw UnimplementedError('ShellContext.shellEnvironment'); + + @override + Future which(String command, + {ShellEnvironment? environment, bool includeParentEnvironment = true}) { + throw UnimplementedError('ShellContext.which'); + } +} + +/// In memory shell context. +class ShellContextMemory with ShellContextMixin implements ShellContext { + @override + Encoding get encoding => utf8; +} + +/// In memory shell context. +final shellContextMemory = ShellContextMemory(); diff --git a/packages/process_run/lib/src/shell_context_io.dart b/packages/process_run/lib/src/shell_context_io.dart index 1727786..fc9c2fe 100644 --- a/packages/process_run/lib/src/shell_context_io.dart +++ b/packages/process_run/lib/src/shell_context_io.dart @@ -1,14 +1,14 @@ import 'dart:convert'; -import 'dart:io'; import 'package:path/path.dart' as p; import 'package:process_run/shell.dart' as ds; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/shell_common.dart'; import 'package:process_run/src/shell_common_io.dart'; import 'package:process_run/src/shell_context_common.dart'; import 'package:process_run/src/shell_environment.dart' as io; -class ShellContextIo implements ShellContext { +class ShellContextIo with ShellContextMixin implements ShellContext { @override ShellEnvironment get shellEnvironment => io.ShellEnvironment(environment: ds.shellEnvironment); diff --git a/packages/process_run/lib/src/shell_utils_io.dart b/packages/process_run/lib/src/shell_utils_io.dart index aa3359a..d2f0fed 100644 --- a/packages/process_run/lib/src/shell_utils_io.dart +++ b/packages/process_run/lib/src/shell_utils_io.dart @@ -1,8 +1,7 @@ library process_run.src.shell_utils_io; -import 'dart:io'; - import 'package:path/path.dart'; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/shell_utils.dart'; /// Convenient way to display a command diff --git a/packages/process_run/lib/src/stdio/platform/platform.dart b/packages/process_run/lib/src/stdio/platform/platform.dart new file mode 100644 index 0000000..e67cc23 --- /dev/null +++ b/packages/process_run/lib/src/stdio/platform/platform.dart @@ -0,0 +1 @@ +export 'platform_stub.dart' if (dart.library.io) 'platform_io.dart'; diff --git a/packages/process_run/lib/src/stdio/platform/platform_io.dart b/packages/process_run/lib/src/stdio/platform/platform_io.dart new file mode 100644 index 0000000..c79cce0 --- /dev/null +++ b/packages/process_run/lib/src/stdio/platform/platform_io.dart @@ -0,0 +1,7 @@ +import 'package:process_run/src/stdio/shell_streamer_io.dart'; + +export 'package:process_run/src/platform/platform.dart' show shellContext; + +class ShellOutputLinesStreamerPlatform extends ShellOutputLinesStreamerIo { + ShellOutputLinesStreamerPlatform({super.current}); +} diff --git a/packages/process_run/lib/src/stdio/platform/platform_stub.dart b/packages/process_run/lib/src/stdio/platform/platform_stub.dart new file mode 100644 index 0000000..4b46004 --- /dev/null +++ b/packages/process_run/lib/src/stdio/platform/platform_stub.dart @@ -0,0 +1,5 @@ +import 'package:process_run/src/stdio/stdio.dart'; + +class ShellOutputLinesStreamerPlatform extends ShellOutputLinesStreamerMemory { + ShellOutputLinesStreamerPlatform({super.current}); +} diff --git a/packages/process_run/lib/src/stdio/platform/shell_import.dart b/packages/process_run/lib/src/stdio/platform/shell_import.dart new file mode 100644 index 0000000..eabdc93 --- /dev/null +++ b/packages/process_run/lib/src/stdio/platform/shell_import.dart @@ -0,0 +1,3 @@ +export 'package:process_run/src/shell_common.dart'; +export 'package:process_run/src/shell_context_common.dart'; +export 'package:process_run/src/shell_environment.dart'; diff --git a/packages/process_run/lib/src/stdio/shell_streamer_io.dart b/packages/process_run/lib/src/stdio/shell_streamer_io.dart new file mode 100644 index 0000000..97ea6d1 --- /dev/null +++ b/packages/process_run/lib/src/stdio/shell_streamer_io.dart @@ -0,0 +1,50 @@ +import 'package:process_run/src/io/io.dart' as io; + +import 'package:process_run/src/stdio/stdio.dart'; + +/// Stdio streamer. +class ShellOutputLinesStreamerIo + with ShellOutputLinesStreamerMixin + implements ShellOutputLinesStreamer { + void log(String message) { + if (current) { + io.stdout.writeln(message); + } else { + lines.add(StdioStreamLine(StdioStreamType.out, message)); + } + } + + void error(String message) { + if (current) { + io.stderr.writeln(message); + } else { + lines.add(StdioStreamLine(StdioStreamType.err, message)); + } + } + + /// Stdio streamer.could become true at any moment! + ShellOutputLinesStreamerIo({bool? current = false}) { + this.current = current; + outController.stream.listen((line) { + log(line); + }); + errController.stream.listen((line) { + error(line); + }); + } + + /// Close. + @override + void close() { + mixinDispose(); + if (!current) { + for (var line in lines) { + if (line.type == StdioStreamType.out) { + io.stdout.writeln(line.line); + } else { + io.stderr.writeln(line.line); + } + } + } + } +} diff --git a/packages/process_run/lib/src/stdio/stdio.dart b/packages/process_run/lib/src/stdio/stdio.dart new file mode 100644 index 0000000..562b764 --- /dev/null +++ b/packages/process_run/lib/src/stdio/stdio.dart @@ -0,0 +1,222 @@ +import 'dart:async' as async; +import 'dart:convert'; +import 'dart:core' as core; +import 'dart:core'; + +import 'package:process_run/shell.dart'; +import 'package:process_run/src/bin/shell/import.dart'; +import 'package:process_run/src/stdio/platform/platform.dart'; + +class ShellStdioLinesGrouperIOSink implements IOSink { + bool get _isErr => type == StdioStreamType.err; + late final IOSink ioSink = _isErr ? ioStderr : ioStdout; + final StdioStreamType type; + + @override + Encoding get encoding => ioSink.encoding; + + ShellStdioLinesGrouperIOSink(this.type); + + @override + void add(core.List data) { + var currentZoneId = _shellStdioLinesGrouper.currentZoneId; + var zoneId = _shellStdioLinesGrouper.zoneId; + + var isCurrent = currentZoneId == zoneId; + + var streamer = _shellStdioLinesGrouper.streamers[zoneId] ??= + ShellOutputLinesStreamerPlatform(current: isCurrent); + // devPrint('[$zoneId/$currentZoneId] Adding data ${encoding.decode(data).trim()}'); + var sink = _isErr ? streamer.err : streamer.out; + sink.add(data); + } + + @override + void addError(core.Object error, [core.StackTrace? stackTrace]) { + ioSink.addError(error, stackTrace); + } + + @override + async.Future addStream(async.Stream> stream) async { + await for (var data in stream) { + add(data); + } + } + + @override + async.Future close() async { + await ioSink.close(); + } + + @override + async.Future get done async { + return ioSink.done; + } + + @override + async.Future flush() async { + // await ioSink.flush(); + } + + @override + void write(core.Object? object) { + add(encoding.encode(object?.toString() ?? '')); + } + + @override + void writeAll(core.Iterable objects, [core.String separator = '']) { + write(objects.join(separator)); + } + + @override + void writeCharCode(core.int charCode) { + write(String.fromCharCode(charCode)); + } + + @override + void writeln([core.Object? object = '']) { + write('$object\n'); + } + + @override + set encoding(Encoding encoding) { + throw core.UnsupportedError('ShellStdioIOSink encoding is read only'); + } +} + +/// Group in zones. +class _ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { + int? currentZoneId; + final streamers = {}; + + @override + late final out = ShellStdioLinesGrouperIOSink(StdioStreamType.out); + + @override + late final err = ShellStdioLinesGrouperIOSink(StdioStreamType.err); +} + +final _shellStdioLinesGrouper = _ShellStdioLinesGrouper(); +ShellStdio get shellStdioLinesGrouper => _shellStdioLinesGrouper; + +const _stdio = #tekartik_shell_stdio; +const _id = #tekartik_shell_stdio_id; + +/// Shell stdio interface, default value for stdout, stderr +abstract class ShellStdio { + /// Stdout. + IOSink get out; + + /// Stderr. + IOSink get err; +} + +mixin ShellStdioMixin implements ShellStdio {} + +int _zoneId = 0; +int _nextZoneId() => ++_zoneId; +int _inZoneCount = 0; + +extension ShellStdioExt on ShellStdio { + Future runZoned(Future Function() action) async { + var zoneId = _nextZoneId(); + try { + _inZoneCount++; + return await async + .runZoned(action, zoneValues: {_stdio: this, _id: zoneId}); + } finally { + _inZoneCount--; + var streamer = _shellStdioLinesGrouper.streamers[zoneId]; + streamer?.close(); + } + } +} + +extension ShellStdioExtPrv on ShellStdio { + /// Only valid in a zone. + int get zoneId => Zone.current[_id] as int; +} + +/// Overriden shell stdio if any. +ShellStdio? get shellStdioOrNull => + _inZoneCount > 0 ? Zone.current[_stdio] as ShellStdio? : null; + +/// Stream type. +enum StdioStreamType { + /// Out + out, + + /// Err + err +} + +/// Stdio stream line. +class StdioStreamLine { + /// Stream type. + final StdioStreamType type; + + /// Line. + final String line; + + /// Stdio stream line. + StdioStreamLine(this.type, this.line); +} + +class ShellOutputLinesStreamerMemory with ShellOutputLinesStreamerMixin { + ShellOutputLinesStreamerMemory({bool? current = false}) { + this.current = current; + } +} + +mixin ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { + @override + StreamSink> get err => outController.sink; + + @override + StreamSink> get out => outController.sink; + + /// Current. + bool get current => _current ?? false; + + bool? _current; + + set current(bool? current) { + _current = current; + } + + /// Lines. + var lines = []; + + /// Out. + final outController = ShellLinesController(); + + /// Err. + final errController = ShellLinesController(); + + void mixinDispose() { + outController.close(); + errController.close(); + } + + @override + void close() { + mixinDispose(); + } +} + +/// Stdio streamer. +abstract class ShellOutputLinesStreamer { + /// Out stream sink + StreamSink> get out; + + /// Err stream sink + StreamSink> get err; + + /// default is io version. + factory ShellOutputLinesStreamer({bool? current = false}) { + return ShellOutputLinesStreamerPlatform(current: current); + } + + /// Close the streamer. + void close(); +} diff --git a/packages/process_run/lib/src/user_config.dart b/packages/process_run/lib/src/user_config.dart index c262191..fc99212 100644 --- a/packages/process_run/lib/src/user_config.dart +++ b/packages/process_run/lib/src/user_config.dart @@ -1,4 +1,3 @@ -import 'dart:io'; import 'dart:math'; import 'package:collection/collection.dart'; @@ -7,6 +6,7 @@ import 'package:path/path.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/dartbin_impl.dart'; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/script_filename.dart'; import 'package:process_run/src/shell_utils.dart'; import 'package:yaml/yaml.dart'; diff --git a/packages/process_run/lib/src/utils.dart b/packages/process_run/lib/src/utils.dart index ff87d8f..640924f 100644 --- a/packages/process_run/lib/src/utils.dart +++ b/packages/process_run/lib/src/utils.dart @@ -1,5 +1,5 @@ import 'dart:convert'; -import 'dart:io'; +import 'package:process_run/src/io/io.dart'; String getShellCmdBinFileName(String command) => '$command${Platform.isWindows ? '.bat' : ''}'; diff --git a/packages/process_run/lib/stdio.dart b/packages/process_run/lib/stdio.dart new file mode 100644 index 0000000..43ca6dc --- /dev/null +++ b/packages/process_run/lib/stdio.dart @@ -0,0 +1 @@ +export 'src/io/io.dart'; diff --git a/packages/process_run/lib/utils/process_result_extension.dart b/packages/process_run/lib/utils/process_result_extension.dart index f06537a..c633e67 100644 --- a/packages/process_run/lib/utils/process_result_extension.dart +++ b/packages/process_run/lib/utils/process_result_extension.dart @@ -1,5 +1,5 @@ import 'dart:convert'; -import 'dart:io'; +import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/lines_utils.dart'; diff --git a/packages/process_run/test/compile_test.dart b/packages/process_run/test/compile_test.dart index 50dea73..5a2acc8 100644 --- a/packages/process_run/test/compile_test.dart +++ b/packages/process_run/test/compile_test.dart @@ -7,23 +7,48 @@ import 'package:path/path.dart'; import 'package:process_run/shell_run.dart'; import 'package:test/test.dart'; +import 'src/compile_echo.dart'; + void main() { test('compile and run exe', () async { - var folder = - Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); - var exeExtension = Platform.isWindows ? '.exe' : ''; - var echoExePath = join('build', folder, 'process_run_echo$exeExtension'); + var echoExePath = await compileEchoExample(); var echoExeDir = dirname(echoExePath); var echoExeName = basename(echoExePath); - var shell = Shell(verbose: false); - if (!File(echoExePath).existsSync()) { - Directory(echoExeDir).createSync(recursive: true); - await shell.run( - 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o ${shellArgument(echoExePath)}'); - } + + // Try path access + var lines = (await Shell(verbose: false) + .run('${shellArgument(echoExePath)} --stdout test')) + .outLines; + expect(lines, ['test']); + + // Try using alias + lines = (await Shell( + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echoExePath) + .run('echo --stdout test')) + .outLines; + expect(lines, ['test']); + + // Try using alias in options + var options = ShellOptions( + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echoExePath); + lines = (await Shell(options: options).run('echo --stdout test')).outLines; + expect(lines, ['test']); + // Try using alias + lines = (await Shell( + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echoExePath) + .run(''' +echo --stdout test1 +echo --stdout test2 + ''')) + .outLines; + expect(lines, ['test1', 'test2']); + // Try relative access var exePathShell = Shell(workingDirectory: echoExeDir, verbose: false); - var lines = (await exePathShell + lines = (await exePathShell .run('${shellArgument(join('.', echoExeName))} --stdout test')) .outLines; expect(lines, ['test']); diff --git a/packages/process_run/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart index fffbc04..9f783df 100644 --- a/packages/process_run/test/shell_common_test.dart +++ b/packages/process_run/test/shell_common_test.dart @@ -1,10 +1,8 @@ library process_run.test.shell_common_api_test; import 'dart:async'; -import 'dart:convert'; import 'dart:io'; -import 'package:path/src/context.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/env_utils.dart'; import 'package:process_run/src/platform/platform.dart'; @@ -13,11 +11,7 @@ import 'package:process_run/src/shell_context_common.dart'; import 'package:process_run/src/shell_environment_common.dart'; import 'package:test/test.dart'; -class ShellContextMock implements ShellContext { - @override - // TODO: implement encoding - Encoding get encoding => throw UnimplementedError(); - +class ShellContextMock with ShellContextMixin implements ShellContext { @override Shell newShell( {ShellOptions? options, @@ -26,24 +20,8 @@ class ShellContextMock implements ShellContext { return ShellMock(options: options, context: this); } - @override - ShellEnvironment newShellEnvironment({Map? environment}) { - // TODO: implement newShellEnvironment - throw UnimplementedError(); - } - - @override - Context get path => throw UnimplementedError(); - @override final ShellEnvironment shellEnvironment = ShellEnvironmentMock(); - - @override - Future which(String command, - {ShellEnvironment? environment, bool includeParentEnvironment = true}) { - // TODO: implement which - throw UnimplementedError(); - } } class ShellEnvironmentMock extends ShellEnvironmentBase diff --git a/packages/process_run/test/shell_stdio_lines_grouper_test.dart b/packages/process_run/test/shell_stdio_lines_grouper_test.dart new file mode 100644 index 0000000..08ba083 --- /dev/null +++ b/packages/process_run/test/shell_stdio_lines_grouper_test.dart @@ -0,0 +1,51 @@ +@TestOn('vm') +library; + +import 'package:process_run/process_run.dart'; +import 'package:process_run/stdio.dart'; +import 'package:test/test.dart'; + +import 'src/compile_echo.dart'; + +void main() { + group('shell_stdio_lines_grouper', () { + test('hello123', () async { + var echo = await compileEchoExample(); + + var options = ShellOptions( + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echo); + var lines = + (await Shell(options: options).run('echo --stdout test')).outLines; + expect(lines, ['test']); + /* + var env = ShellEnvironment() + // ..aliases['echo'] = 'dart run ${shellArgument(echoScriptPath)}'; + ..aliases['echo'] = echo; + + var options = ShellOptions(environment: env); + */ + var shell = Shell(options: options); + + await shell.run('echo --stdout hello1'); + + /* + var options = ShellOptions(verbose: true, environment: env); + */ + Future> printHello123Slow() async { + var shell = Shell(options: options); + return await shell.run(''' +echo --wait 100 --stdout hello1 +echo --wait 100 --stdout hello2 +'''); + } + + // await printHello123Slow(); + + var stdio = shellStdioLinesGrouper; + await Future.wait>( + [stdio.runZoned(() => printHello123Slow()), printHello123Slow()]); + }); + test('ok', () {}); + }); +} diff --git a/packages/process_run/test/src/compile_echo.dart b/packages/process_run/test/src/compile_echo.dart new file mode 100644 index 0000000..6b8f873 --- /dev/null +++ b/packages/process_run/test/src/compile_echo.dart @@ -0,0 +1,20 @@ +import 'dart:io'; + +import 'package:path/path.dart'; +import 'package:process_run/shell.dart'; + +/// Return the executable path. +Future compileEchoExample() async { + var folder = + Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); + var exeExtension = Platform.isWindows ? '.exe' : ''; + var echoExePath = join('build', folder, 'process_run_echo$exeExtension'); + var echoExeDir = dirname(echoExePath); + var shell = Shell(verbose: false); + if (!File(echoExePath).existsSync()) { + Directory(echoExeDir).createSync(recursive: true); + await shell.run( + 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o ${shellArgument(echoExePath)}'); + } + return echoExePath; +} diff --git a/packages/process_run/test/src/shell_output_lines_streamer_test.dart b/packages/process_run/test/src/shell_output_lines_streamer_test.dart new file mode 100644 index 0000000..cd4fafb --- /dev/null +++ b/packages/process_run/test/src/shell_output_lines_streamer_test.dart @@ -0,0 +1,17 @@ +import 'dart:convert'; + +import 'package:process_run/src/stdio/stdio.dart'; +import 'package:test/test.dart'; + +void main() { + group('shell_stdio', () { + test('StdioStream', () { + // ignore: unused_local_variable + var shellStreamer = ShellOutputLinesStreamer(); + shellStreamer.out.add(utf8.encode('hi')); + shellStreamer.err.add(utf8.encode('error')); + + shellStreamer.close(); + }); + }); +} From 6384efbaa7d88d0c3d61c4ca39b3d5a505e77921 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 29 Jun 2024 09:34:42 +0200 Subject: [PATCH 092/150] [process_run] v1.0.0-0 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index bfb7b86..7226969 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.0-0 + +* add `ShellStdio` and `shellStdioLinesGrouper` to allow grouping stdout and stderr lines by zones. + ## 0.14.2 * add `noStdoutResult` and `noStderrResult` to `ShellOptions` and `runExecutableArguments` to avoid out of memory for diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index d1292f8..547cb9a 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 0.14.2 +version: 1.0.0-0 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From fd5f67839cb11d93b916bc993fb119d6cd6956f8 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 29 Jun 2024 09:48:29 +0200 Subject: [PATCH 093/150] fix unit test --- packages/process_run/test/shell_common_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/process_run/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart index 9f783df..4b4dc3f 100644 --- a/packages/process_run/test/shell_common_test.dart +++ b/packages/process_run/test/shell_common_test.dart @@ -186,7 +186,7 @@ void main() { if (isRunningAsJavascript) { fail('should fail'); } - } on StateError catch (e) { + } catch (e) { if (!isRunningAsJavascript) { rethrow; } From 26128b665608c21835cd07de7a0a6cc782b22a3b Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 29 Jun 2024 12:05:18 +0200 Subject: [PATCH 094/150] [process_run] v1.0.0-1 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/example/echo.dart | 4 +- .../example/shell_stdio_lines_grouper.dart | 14 +- .../lib/src/lines_utils_common.dart | 5 +- .../lib/src/stdio/platform/platform_io.dart | 2 +- .../lib/src/stdio/platform/platform_stub.dart | 2 +- .../lib/src/stdio/shell_streamer_io.dart | 15 +- packages/process_run/lib/src/stdio/stdio.dart | 134 ++++++++++++------ packages/process_run/pubspec.yaml | 2 +- .../test/shell_stdio_lines_grouper_test.dart | 26 +++- packages/process_run/test/src/stdio_test.dart | 12 ++ 11 files changed, 159 insertions(+), 59 deletions(-) create mode 100644 packages/process_run/test/src/stdio_test.dart diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 7226969..30691f3 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.0-0 +## 1.0.0-1 * add `ShellStdio` and `shellStdioLinesGrouper` to allow grouping stdout and stderr lines by zones. diff --git a/packages/process_run/example/echo.dart b/packages/process_run/example/echo.dart index 3a54c44..e47d575 100755 --- a/packages/process_run/example/echo.dart +++ b/packages/process_run/example/echo.dart @@ -139,14 +139,14 @@ Future main(List arguments) async { if (stderrText != null) { stderr.write(stderrText); if (writeLine!) { - stdout.writeln(); + stderr.writeln(); } } final stderrHexTest = argsResult['stderr-hex'] as String?; if (stderrHexTest != null) { stderr.add(hexToBytes(stderrHexTest)); if (writeLine!) { - stdout.writeln(); + stderr.writeln(); } } diff --git a/packages/process_run/example/shell_stdio_lines_grouper.dart b/packages/process_run/example/shell_stdio_lines_grouper.dart index 33efaee..f6d52b4 100644 --- a/packages/process_run/example/shell_stdio_lines_grouper.dart +++ b/packages/process_run/example/shell_stdio_lines_grouper.dart @@ -8,17 +8,21 @@ void main() async { var options = ShellOptions( verbose: true, environment: ShellEnvironment()..aliases['echo'] = echo); - Future> printHello123Slow() async { + Future printHello12345Slow() async { var shell = Shell(options: options); - return await shell.run(''' + + await shell.run(''' echo --wait 100 --stdout hello1 --write-line echo --wait 100 --stdout hello2 --write-line +echo --wait 100 --stderr hello3 --write-line '''); + stdout.writeln('hello4'); + stderr.writeln('hello5'); } var stdio = shellStdioLinesGrouper; - await Future.wait>([ - stdio.runZoned(() => printHello123Slow()), - stdio.runZoned(() => printHello123Slow()) + await Future.wait([ + stdio.runZoned(() => printHello12345Slow()), + stdio.runZoned(() => printHello12345Slow()) ]); } diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index da573e9..52c93a1 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -33,9 +33,12 @@ class ShellLinesController { ShellLinesController({Encoding? encoding}) { this.encoding = encoding ?? shellContext.encoding; - _controller = StreamController>(); + // Must be sync! + _controller = StreamController>(sync: true); } + Future get done => _controller.done; + /// Write a string with the specified encoding. void write(String message) => streamSinkWrite(sink, message, encoding: encoding); diff --git a/packages/process_run/lib/src/stdio/platform/platform_io.dart b/packages/process_run/lib/src/stdio/platform/platform_io.dart index c79cce0..ded7ffe 100644 --- a/packages/process_run/lib/src/stdio/platform/platform_io.dart +++ b/packages/process_run/lib/src/stdio/platform/platform_io.dart @@ -3,5 +3,5 @@ import 'package:process_run/src/stdio/shell_streamer_io.dart'; export 'package:process_run/src/platform/platform.dart' show shellContext; class ShellOutputLinesStreamerPlatform extends ShellOutputLinesStreamerIo { - ShellOutputLinesStreamerPlatform({super.current}); + ShellOutputLinesStreamerPlatform({super.current, super.stdout, super.stderr}); } diff --git a/packages/process_run/lib/src/stdio/platform/platform_stub.dart b/packages/process_run/lib/src/stdio/platform/platform_stub.dart index 4b46004..68f1728 100644 --- a/packages/process_run/lib/src/stdio/platform/platform_stub.dart +++ b/packages/process_run/lib/src/stdio/platform/platform_stub.dart @@ -1,5 +1,5 @@ import 'package:process_run/src/stdio/stdio.dart'; class ShellOutputLinesStreamerPlatform extends ShellOutputLinesStreamerMemory { - ShellOutputLinesStreamerPlatform({super.current}); + ShellOutputLinesStreamerPlatform({super.current, super.stdout, super.stderr}); } diff --git a/packages/process_run/lib/src/stdio/shell_streamer_io.dart b/packages/process_run/lib/src/stdio/shell_streamer_io.dart index 97ea6d1..e617cc0 100644 --- a/packages/process_run/lib/src/stdio/shell_streamer_io.dart +++ b/packages/process_run/lib/src/stdio/shell_streamer_io.dart @@ -6,9 +6,11 @@ import 'package:process_run/src/stdio/stdio.dart'; class ShellOutputLinesStreamerIo with ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { + late final io.IOSink stdout; + late final io.IOSink stderr; void log(String message) { if (current) { - io.stdout.writeln(message); + stdout.writeln(message); } else { lines.add(StdioStreamLine(StdioStreamType.out, message)); } @@ -16,14 +18,17 @@ class ShellOutputLinesStreamerIo void error(String message) { if (current) { - io.stderr.writeln(message); + stderr.writeln(message); } else { lines.add(StdioStreamLine(StdioStreamType.err, message)); } } /// Stdio streamer.could become true at any moment! - ShellOutputLinesStreamerIo({bool? current = false}) { + ShellOutputLinesStreamerIo( + {bool? current = false, io.IOSink? stdout, io.IOSink? stderr}) { + this.stdout = stdout ?? io.ioStdout; + this.stderr = stderr ?? io.ioStderr; this.current = current; outController.stream.listen((line) { log(line); @@ -40,9 +45,9 @@ class ShellOutputLinesStreamerIo if (!current) { for (var line in lines) { if (line.type == StdioStreamType.out) { - io.stdout.writeln(line.line); + stdout.writeln(line.line); } else { - io.stderr.writeln(line.line); + stderr.writeln(line.line); } } } diff --git a/packages/process_run/lib/src/stdio/stdio.dart b/packages/process_run/lib/src/stdio/stdio.dart index 562b764..7ac048e 100644 --- a/packages/process_run/lib/src/stdio/stdio.dart +++ b/packages/process_run/lib/src/stdio/stdio.dart @@ -5,30 +5,58 @@ import 'dart:core'; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/import.dart'; +import 'package:process_run/src/io/io.dart' as io; import 'package:process_run/src/stdio/platform/platform.dart'; -class ShellStdioLinesGrouperIOSink implements IOSink { - bool get _isErr => type == StdioStreamType.err; - late final IOSink ioSink = _isErr ? ioStderr : ioStdout; +class InMemoryIOSink with IOSinkMixin implements IOSink { + @override final StdioStreamType type; + var data = >[]; + Iterable get lines => + LineSplitter.split(encoding.decode(data.expand((e) => e).toList())); + InMemoryIOSink(this.type); + + @override + void add(core.List data) { + this.data.add(data); + } + + @override + String toString() => 'InMemoryIOSink($type)'; +} + +mixin IOSinkMixin implements IOSink { + bool get _isErr => type == StdioStreamType.err; + late final IOSink ioSinkDelegate = _isErr ? ioStderr : ioStdout; + StdioStreamType get type; + IOSink get ioSink => ioSinkDelegate; @override Encoding get encoding => ioSink.encoding; - ShellStdioLinesGrouperIOSink(this.type); + @override + void write(core.Object? object) { + add(encoding.encode(object?.toString() ?? '')); + } @override - void add(core.List data) { - var currentZoneId = _shellStdioLinesGrouper.currentZoneId; - var zoneId = _shellStdioLinesGrouper.zoneId; + void writeAll(core.Iterable objects, [core.String separator = '']) { + write(objects.join(separator)); + } - var isCurrent = currentZoneId == zoneId; + @override + void writeCharCode(core.int charCode) { + write(String.fromCharCode(charCode)); + } - var streamer = _shellStdioLinesGrouper.streamers[zoneId] ??= - ShellOutputLinesStreamerPlatform(current: isCurrent); - // devPrint('[$zoneId/$currentZoneId] Adding data ${encoding.decode(data).trim()}'); - var sink = _isErr ? streamer.err : streamer.out; - sink.add(data); + @override + void writeln([core.Object? object = '']) { + write('$object\n'); + } + + @override + set encoding(Encoding encoding) { + throw core.UnsupportedError('ShellStdioIOSink encoding is read only'); } @override @@ -55,48 +83,58 @@ class ShellStdioLinesGrouperIOSink implements IOSink { @override async.Future flush() async { - // await ioSink.flush(); + await ioSink.flush(); } +} +class ShellStdioLinesGrouperIOSink with IOSinkMixin implements IOSink { + final ShellStdioLinesGrouper grouper; @override - void write(core.Object? object) { - add(encoding.encode(object?.toString() ?? '')); - } - + final StdioStreamType type; @override - void writeAll(core.Iterable objects, [core.String separator = '']) { - write(objects.join(separator)); + late final IOSink ioSink; + ShellStdioLinesGrouperIOSink(this.grouper, this.type, {IOSink? ioSink}) { + this.ioSink = ioSink ?? super.ioSink; } @override - void writeCharCode(core.int charCode) { - write(String.fromCharCode(charCode)); - } + void add(core.List data) { + var currentZoneId = _shellStdioLinesGrouper.currentZoneId; + var zoneId = _shellStdioLinesGrouper.zoneId; - @override - void writeln([core.Object? object = '']) { - write('$object\n'); - } + var isCurrent = currentZoneId == zoneId; - @override - set encoding(Encoding encoding) { - throw core.UnsupportedError('ShellStdioIOSink encoding is read only'); + var streamer = _shellStdioLinesGrouper.streamers[zoneId] ??= + ShellOutputLinesStreamer( + current: isCurrent, stdout: grouper.stdout, stderr: grouper.stderr); + // devPrint('[$zoneId/$currentZoneId] Adding data ${encoding.decode(data).trim()}'); + var sink = _isErr ? streamer.err : streamer.out; + sink.add(data); } } /// Group in zones. -class _ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { +class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { + /// Overriden mainly for testing. + final IOSink? stdout; + + /// Overriden mainly for testing. + final IOSink? stderr; int? currentZoneId; final streamers = {}; + ShellStdioLinesGrouper({this.stdout, this.stderr}); + @override - late final out = ShellStdioLinesGrouperIOSink(StdioStreamType.out); + late final out = + ShellStdioLinesGrouperIOSink(this, StdioStreamType.out, ioSink: stdout); @override - late final err = ShellStdioLinesGrouperIOSink(StdioStreamType.err); + late final err = + ShellStdioLinesGrouperIOSink(this, StdioStreamType.err, ioSink: stderr); } -final _shellStdioLinesGrouper = _ShellStdioLinesGrouper(); +final _shellStdioLinesGrouper = ShellStdioLinesGrouper(); ShellStdio get shellStdioLinesGrouper => _shellStdioLinesGrouper; const _stdio = #tekartik_shell_stdio; @@ -127,7 +165,10 @@ extension ShellStdioExt on ShellStdio { } finally { _inZoneCount--; var streamer = _shellStdioLinesGrouper.streamers[zoneId]; - streamer?.close(); + if (streamer != null) { + await Future.value(); // await streamer.done; + streamer.close(); + } } } } @@ -163,17 +204,20 @@ class StdioStreamLine { } class ShellOutputLinesStreamerMemory with ShellOutputLinesStreamerMixin { - ShellOutputLinesStreamerMemory({bool? current = false}) { + //late final io.IOSink stdout; + //late final io.IOSink stderr; + ShellOutputLinesStreamerMemory( + {bool? current = false, io.IOSink? stdout, io.IOSink? stderr}) { this.current = current; } } mixin ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { @override - StreamSink> get err => outController.sink; + StreamSink> get out => outController.sink; @override - StreamSink> get out => outController.sink; + StreamSink> get err => errController.sink; /// Current. bool get current => _current ?? false; @@ -198,6 +242,11 @@ mixin ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { errController.close(); } + @override + Future get done async { + await Future.wait([outController.done, errController.done]); + } + @override void close() { mixinDispose(); @@ -213,10 +262,15 @@ abstract class ShellOutputLinesStreamer { StreamSink> get err; /// default is io version. - factory ShellOutputLinesStreamer({bool? current = false}) { - return ShellOutputLinesStreamerPlatform(current: current); + factory ShellOutputLinesStreamer( + {bool? current = false, io.IOSink? stdout, io.IOSink? stderr}) { + return ShellOutputLinesStreamerPlatform( + current: current, stdout: stdout, stderr: stderr); } + /// Wait for the streamer to be done. + Future get done; + /// Close the streamer. void close(); } diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 547cb9a..5268ab1 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.0.0-0 +version: 1.0.0-1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run diff --git a/packages/process_run/test/shell_stdio_lines_grouper_test.dart b/packages/process_run/test/shell_stdio_lines_grouper_test.dart index 08ba083..383ca0b 100644 --- a/packages/process_run/test/shell_stdio_lines_grouper_test.dart +++ b/packages/process_run/test/shell_stdio_lines_grouper_test.dart @@ -2,6 +2,7 @@ library; import 'package:process_run/process_run.dart'; +import 'package:process_run/src/stdio/stdio.dart'; import 'package:process_run/stdio.dart'; import 'package:test/test.dart'; @@ -9,7 +10,7 @@ import 'src/compile_echo.dart'; void main() { group('shell_stdio_lines_grouper', () { - test('hello123', () async { + test('hello12', () async { var echo = await compileEchoExample(); var options = ShellOptions( @@ -45,7 +46,28 @@ echo --wait 100 --stdout hello2 var stdio = shellStdioLinesGrouper; await Future.wait>( [stdio.runZoned(() => printHello123Slow()), printHello123Slow()]); + + var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); + var isMemoryStdout = InMemoryIOSink(StdioStreamType.out); + stdio = ShellStdioLinesGrouper( + stderr: inMemoryStderr, stdout: isMemoryStdout); + await Future.wait>( + [stdio.runZoned(() => printHello123Slow()), printHello123Slow()]); + // Not working yet + // expect(isMemoryStdout.lines, ['hello1', 'hello2', 'hello1', 'hello2', 'hello1', 'hello2']); + }); + test('in memory stdout/stderr', () async { + var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); + var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); + var stdio = ShellStdioLinesGrouper( + stderr: inMemoryStderr, stdout: inMemoryStdout); + await stdio.runZoned(() async { + stdout.writeln('test1'); + stderr.writeln('test2'); + stdout.writeln('test3'); + }); + expect(inMemoryStdout.lines, ['test1', 'test3']); + expect(inMemoryStderr.lines, ['test2']); }); - test('ok', () {}); }); } diff --git a/packages/process_run/test/src/stdio_test.dart b/packages/process_run/test/src/stdio_test.dart new file mode 100644 index 0000000..9d46797 --- /dev/null +++ b/packages/process_run/test/src/stdio_test.dart @@ -0,0 +1,12 @@ +import 'package:process_run/src/stdio/stdio.dart'; +import 'package:test/test.dart'; + +void main() { + group('IOSink', () { + test('memory', () { + var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); + inMemoryStdout.writeln('test'); + expect(inMemoryStdout.lines, ['test']); + }); + }); +} From 891dfcf713fdf205b1b8fea6bbf2e66a2aec7576 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 29 Jun 2024 12:15:14 +0200 Subject: [PATCH 095/150] [process_run] v1.0.0 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/lib/src/bin/shell/shell.dart | 4 ++-- packages/process_run/lib/src/version.dart | 2 ++ packages/process_run/pubspec.yaml | 4 ++-- packages/process_run/tool/pre_publish.dart | 5 +++++ 5 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 packages/process_run/lib/src/version.dart create mode 100644 packages/process_run/tool/pre_publish.dart diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 30691f3..2f6a911 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.0-1 +## 1.0.0 * add `ShellStdio` and `shellStdioLinesGrouper` to allow grouping stdout and stderr lines by zones. diff --git a/packages/process_run/lib/src/bin/shell/shell.dart b/packages/process_run/lib/src/bin/shell/shell.dart index 4a961f6..92ad9d9 100644 --- a/packages/process_run/lib/src/bin/shell/shell.dart +++ b/packages/process_run/lib/src/bin/shell/shell.dart @@ -1,12 +1,12 @@ import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/run.dart'; -// ignore: import_of_legacy_library_into_null_safe +import 'package:process_run/src/version.dart'; import 'package:pub_semver/pub_semver.dart'; import 'env.dart'; import 'import.dart'; -Version shellBinVersion = Version(0, 2, 0); +Version shellBinVersion = Version.parse(packageVersion); const flagHelp = 'help'; const flagInfo = 'info'; diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart new file mode 100644 index 0000000..526cd53 --- /dev/null +++ b/packages/process_run/lib/src/version.dart @@ -0,0 +1,2 @@ +// Generated code. Do not modify. +const packageVersion = '1.0.0'; diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 5268ab1..6e5b406 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.0.0-1 +version: 1.0.0 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run @@ -22,7 +22,7 @@ dev_dependencies: async: '>=2.5.0' build_runner: '>=1.11.2' build_test: '>=1.3.7' - + build_version: '>=2.0.0' executables: # Shell helper ds: shell diff --git a/packages/process_run/tool/pre_publish.dart b/packages/process_run/tool/pre_publish.dart new file mode 100644 index 0000000..ddcdedb --- /dev/null +++ b/packages/process_run/tool/pre_publish.dart @@ -0,0 +1,5 @@ +import 'package:process_run/shell.dart'; + +void main() async { + await run('dart pub run build_runner build --delete-conflicting-outputs'); +} From 348f2b5ca8655c1470f8b046cc9e55be85338d6e Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 29 Jun 2024 12:21:57 +0200 Subject: [PATCH 096/150] [process_run] v1.0.0+1 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/pubspec.yaml | 2 +- packages/process_run/test/src/stdio_test.dart | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 2f6a911..59edcc7 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.0 +## 1.0.0+1 * add `ShellStdio` and `shellStdioLinesGrouper` to allow grouping stdout and stderr lines by zones. diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 6e5b406..eb25984 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.0.0 +version: 1.0.0+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run diff --git a/packages/process_run/test/src/stdio_test.dart b/packages/process_run/test/src/stdio_test.dart index 9d46797..678527e 100644 --- a/packages/process_run/test/src/stdio_test.dart +++ b/packages/process_run/test/src/stdio_test.dart @@ -1,3 +1,6 @@ +@TestOn('vm') +library; + import 'package:process_run/src/stdio/stdio.dart'; import 'package:test/test.dart'; From c573b39135a9794f47c74c1eba68e881e1279f46 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 23 Jul 2024 17:28:13 +0200 Subject: [PATCH 097/150] [process_run] fix lines grouper and CRLF vs CR vs LF handling --- .../lib/src/lines_utils_common.dart | 136 ++++++++++-------- .../{test => lib/src/utils}/hex_utils.dart | 0 .../test/shell_stdio_lines_grouper_test.dart | 41 ++++++ packages/process_run/test/shell_test.dart | 3 +- 4 files changed, 119 insertions(+), 61 deletions(-) rename packages/process_run/{test => lib/src/utils}/hex_utils.dart (100%) diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index 52c93a1..425b8dc 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -66,8 +66,8 @@ Stream shellStreamLines(Stream> stream, encoding ??= shellContext.encoding; StreamSubscription? subscription; List? currentLine; - const endOfLine = 10; - const lineFeed = 13; + const lineFeed = 10; // \n LF + const carriageReturn = 13; // \r CR late StreamController ctlr; // devPrint('listen (paused: $paused)'); @@ -75,11 +75,11 @@ Stream shellStreamLines(Stream> stream, if (subscription?.isPaused ?? false) { // Do nothing, current line is discarded } else { - if (currentLine?.isNotEmpty ?? false) { + if (currentLine != null) { try { ctlr.add(encoding!.decode(currentLine!)); } catch (_) { -// Ignore nad encoded line + // Ignore bad encoding print('ignoring: $currentLine'); } } @@ -87,63 +87,81 @@ Stream shellStreamLines(Stream> stream, currentLine = null; } - ctlr = StreamController(onPause: () { - if (shellDebug) { - print('onPause (paused: ${subscription?.isPaused})'); - } - // Last one - addCurrentLine(); - subscription?.pause(); - }, onResume: () { - // devPrint('onResume (paused: $paused)'); - if (subscription?.isPaused ?? false) { - subscription?.resume(); - } - }, onListen: () { - void addToCurrentLine(List data) { - if (currentLine == null) { - currentLine = data; - } else { - var newCurrentLine = Uint8List(currentLine!.length + data.length); - newCurrentLine.setAll(0, currentLine!); - newCurrentLine.setAll(currentLine!.length, data); - currentLine = newCurrentLine; - } - } + ctlr = StreamController( + onPause: () { + if (shellDebug) { + print('onPause (paused: ${subscription?.isPaused})'); + } + // Last one + addCurrentLine(); + subscription?.pause(); + }, + onResume: () { + // devPrint('onResume (paused: $paused)'); + if (subscription?.isPaused ?? false) { + subscription?.resume(); + } + }, + onListen: () { + void addToCurrentLine(List data) { + if (currentLine == null) { + currentLine = data; + } else { + var newCurrentLine = Uint8List(currentLine!.length + data.length); + newCurrentLine.setAll(0, currentLine!); + newCurrentLine.setAll(currentLine!.length, data); + currentLine = newCurrentLine; + } + } + + var lastWasCR = false; + subscription = stream.listen((data) { + var paused = subscription?.isPaused ?? false; + // devPrint('read $data (paused: $paused)'); + if (paused) { + return; + } + // look for \n (10) + var start = 0; + + for (var i = 0; i < data.length; i++) { + var byte = data[i]; + if (byte == lineFeed || byte == carriageReturn) { + if (byte == lineFeed) { + // Ignore CRLF + if (lastWasCR) { + lastWasCR = false; + start = i + 1; + continue; + } + } else { + lastWasCR = true; + } + addToCurrentLine(data.sublist(start, i)); + addCurrentLine(); - subscription = stream.listen((data) { - // var _w; - // print('read $data'); - var paused = subscription?.isPaused ?? false; - // devPrint('read $data (paused: $paused)'); - if (paused) { - return; - } - // look for \n (10) - var start = 0; - for (var i = 0; i < data.length; i++) { - var byte = data[i]; - if (byte == endOfLine || byte == lineFeed) { - addToCurrentLine(data.sublist(start, i)); - addCurrentLine(); // Skip it - start = i + 1; - } - } - // Store last current line - if (data.length > start) { - addToCurrentLine(data.sublist(start, data.length)); - } - }, onDone: () { - // Last one - addCurrentLine(); - ctlr.close(); - }, onError: (Object e, StackTrace st) { - ctlr.addError(e, st); - }); - }, onCancel: () { - subscription?.cancel(); - }); + start = i + 1; + } else { + lastWasCR = false; + } + } + // Store last current line + if (data.length > start) { + addToCurrentLine(data.sublist(start, data.length)); + } + }, onDone: () { + // Last one + addCurrentLine(); + ctlr.close(); + }, onError: (Object e, StackTrace st) { + ctlr.addError(e, st); + }); + }, + onCancel: () { + subscription?.cancel(); + }, + sync: true); return ctlr.stream; } diff --git a/packages/process_run/test/hex_utils.dart b/packages/process_run/lib/src/utils/hex_utils.dart similarity index 100% rename from packages/process_run/test/hex_utils.dart rename to packages/process_run/lib/src/utils/hex_utils.dart diff --git a/packages/process_run/test/shell_stdio_lines_grouper_test.dart b/packages/process_run/test/shell_stdio_lines_grouper_test.dart index 383ca0b..108f971 100644 --- a/packages/process_run/test/shell_stdio_lines_grouper_test.dart +++ b/packages/process_run/test/shell_stdio_lines_grouper_test.dart @@ -69,5 +69,46 @@ echo --wait 100 --stdout hello2 expect(inMemoryStdout.lines, ['test1', 'test3']); expect(inMemoryStderr.lines, ['test2']); }); + + test('empty lines', () async { + var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); + var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); + var stdio = ShellStdioLinesGrouper( + stderr: inMemoryStderr, stdout: inMemoryStdout); + await stdio.runZoned(() async { + stdout.writeln('test1'); + stdout.writeln(''); + stdout.writeln('test2'); + }); + expect(inMemoryStdout.lines, ['test1', '', 'test2']); + }); + + test('CRLF', () async { + var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); + var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); + var stdio = ShellStdioLinesGrouper( + stderr: inMemoryStderr, stdout: inMemoryStdout); + await stdio.runZoned(() async { + stdout.write('test1\r\n'); + stdout.write('test2\r'); + stdout.write('test3\n'); + stdout.writeln('test4'); + }); + expect(inMemoryStdout.lines, ['test1', 'test2', 'test3', 'test4']); + }); + + test('last lines', () async { + var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); + var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); + var stdio = ShellStdioLinesGrouper( + stderr: inMemoryStderr, stdout: inMemoryStdout); + await stdio.runZoned(() async { + stdout.writeln('test1'); + stdout.writeln(''); + stdout.write('test'); + stdout.write('2'); + }); + expect(inMemoryStdout.lines, ['test1', '', 'test2']); + }); }); } diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index 4112c1f..7e1ad01 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -10,11 +10,10 @@ import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/dartbin_cmd.dart' show parseDartBinVersionOutput; +import 'package:process_run/src/utils/hex_utils.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; -import 'hex_utils.dart'; - // Compiled version of echo.dart var echoExePath = join('.local', 'example', 'echo.exe'); var echoExe = shellArgument(echoExePath); From fc231da4cfadd8f953927df87abb7699fa68eff6 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 23 Jul 2024 17:28:51 +0200 Subject: [PATCH 098/150] [process_run] v1.0.0+2 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 59edcc7..a474ba6 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.0+1 +## 1.0.0+2 * add `ShellStdio` and `shellStdioLinesGrouper` to allow grouping stdout and stderr lines by zones. diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index eb25984..4455b31 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.0.0+1 +version: 1.0.0+2 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From e31696aad119b47ae2e1eb7c8f49b7ef19c16ce9 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 24 Jul 2024 11:37:44 +0200 Subject: [PATCH 099/150] fix shell options clone for environment --- packages/process_run/lib/src/shell_common.dart | 2 +- .../test/shell_environment_test.dart | 8 ++++++++ .../process_run/test/shell_options_test.dart | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 packages/process_run/test/shell_options_test.dart diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index 4c59383..8d75176 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -262,7 +262,7 @@ class ShellOptions { stdoutEncoding: stdoutEncoding ?? _stdoutEncoding, throwOnError: throwOnError ?? _throwOnError, workingDirectory: workingDirectory ?? _workingDirectory, - environment: shellEnvironment, + environment: shellEnvironment ?? _environment, noStdoutResult: noStdoutResult ?? _noStdoutResult, noStderrResult: noStderrResult ?? _noStderrResult); } diff --git a/packages/process_run/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart index 74f0740..98affd0 100644 --- a/packages/process_run/test/shell_environment_test.dart +++ b/packages/process_run/test/shell_environment_test.dart @@ -319,6 +319,14 @@ void main() { shellEnvironment = prevEnv; } }); + + test('cd', () async { + var env = ShellEnvironment()..aliases['cd_alias'] = 'cd'; + var shell = Shell(environment: env); + expect(shell.options.environment.aliases['cd_alias'], 'cd'); + shell = shell.cd('test'); + expect(shell.options.environment.aliases['cd_alias'], 'cd'); + }); } /// Better with non verbose shell. diff --git a/packages/process_run/test/shell_options_test.dart b/packages/process_run/test/shell_options_test.dart new file mode 100644 index 0000000..5786d2b --- /dev/null +++ b/packages/process_run/test/shell_options_test.dart @@ -0,0 +1,18 @@ +@TestOn('vm') +library; + +import 'package:process_run/shell.dart'; +import 'package:test/test.dart'; + +void main() { + group('shell_options', () { + test('clone', () async { + var env = ShellEnvironment()..aliases['clone_alias'] = 'clone'; + var shellOptions = ShellOptions(environment: env); + + expect(shellOptions.environment.aliases['clone_alias'], 'clone'); + shellOptions = shellOptions.clone(); + expect(shellOptions.environment.aliases['clone_alias'], 'clone'); + }); + }); +} From 24610d5c19db2c9aabb5088cd964659d65abf8b4 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 24 Jul 2024 11:38:35 +0200 Subject: [PATCH 100/150] [process_run] v1.0.0+3 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index a474ba6..fd26cc7 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.0+2 +## 1.0.0+3 * add `ShellStdio` and `shellStdioLinesGrouper` to allow grouping stdout and stderr lines by zones. diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 4455b31..43ee791 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.0.0+2 +version: 1.0.0+3 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From ecae7709f2987d7229a3906ab5898ec31aae7fc7 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 25 Jul 2024 10:51:41 +0200 Subject: [PATCH 101/150] [process_run] remove deprecated command and start using api doc lint rule --- packages/process_run/analysis_options.yaml | 2 +- .../process_run/bin/analysis_options.yaml | 8 ++++ .../process_run/example/analysis_options.yaml | 8 ++++ packages/process_run/lib/cmd_run.dart | 7 --- .../process_run/lib/src/bin/shell/dump.dart | 2 + .../process_run/lib/src/bin/shell/env.dart | 11 ++++- .../lib/src/bin/shell/env_alias.dart | 4 +- .../lib/src/bin/shell/env_alias_delete.dart | 2 + .../lib/src/bin/shell/env_alias_dump.dart | 2 + .../lib/src/bin/shell/env_alias_get.dart | 2 + .../lib/src/bin/shell/env_alias_set.dart | 2 + .../lib/src/bin/shell/env_delete.dart | 2 + .../lib/src/bin/shell/env_edit.dart | 2 + .../lib/src/bin/shell/env_file_content.dart | 16 +++++++ .../lib/src/bin/shell/env_path.dart | 2 + .../lib/src/bin/shell/env_path_delete.dart | 2 + .../lib/src/bin/shell/env_path_dump.dart | 2 + .../lib/src/bin/shell/env_path_get.dart | 2 + .../lib/src/bin/shell/env_path_prepend.dart | 2 + .../lib/src/bin/shell/env_var.dart | 4 +- .../lib/src/bin/shell/env_var_delete.dart | 6 ++- .../lib/src/bin/shell/env_var_dump.dart | 2 + .../lib/src/bin/shell/env_var_get.dart | 6 ++- .../lib/src/bin/shell/env_var_set.dart | 6 ++- .../process_run/lib/src/bin/shell/run.dart | 5 +- .../process_run/lib/src/bin/shell/shell.dart | 37 ++++++++++++++- .../lib/src/bin/shell/shell_bin_command.dart | 22 +++++++-- .../process_run/lib/src/build_runner.dart | 2 + .../process_run/lib/src/common/dartbin.dart | 2 + .../process_run/lib/src/common/dev_utils.dart | 13 ++++- packages/process_run/lib/src/dartbin_cmd.dart | 35 +------------- packages/process_run/lib/src/user_config.dart | 2 + packages/process_run/lib/src/utils.dart | 2 + .../process_run/lib/src/utils/hex_utils.dart | 2 + packages/process_run/lib/src/version.dart | 2 +- .../process_run/test/analysis_options.yaml | 8 ++++ .../process_run/test/cmd_run_api_test.dart | 7 --- .../process_run/test/dartbin_cmd_test.dart | 17 ------- .../test/dartbin_cmd_verbose_test_.dart | 22 --------- packages/process_run/test/dartdevc_test.dart | 46 ------------------ packages/process_run/test/dartdoc_test.dart | 47 ------------------- packages/process_run/test/dartfmt_test.dart | 30 ------------ .../process_run/tool/analysis_options.yaml | 8 ++++ 43 files changed, 184 insertions(+), 229 deletions(-) create mode 100644 packages/process_run/bin/analysis_options.yaml create mode 100644 packages/process_run/example/analysis_options.yaml create mode 100644 packages/process_run/test/analysis_options.yaml delete mode 100644 packages/process_run/test/dartdevc_test.dart delete mode 100644 packages/process_run/test/dartdoc_test.dart delete mode 100644 packages/process_run/test/dartfmt_test.dart create mode 100644 packages/process_run/tool/analysis_options.yaml diff --git a/packages/process_run/analysis_options.yaml b/packages/process_run/analysis_options.yaml index 828eba2..7cfc53c 100644 --- a/packages/process_run/analysis_options.yaml +++ b/packages/process_run/analysis_options.yaml @@ -21,7 +21,7 @@ analyzer: linter: rules: - # - public_member_api_docs + - public_member_api_docs - always_declare_return_types - avoid_dynamic_calls - avoid_slow_async_io diff --git a/packages/process_run/bin/analysis_options.yaml b/packages/process_run/bin/analysis_options.yaml new file mode 100644 index 0000000..bb0d2a1 --- /dev/null +++ b/packages/process_run/bin/analysis_options.yaml @@ -0,0 +1,8 @@ +# Defines a default set of lint rules enforced for +# projects at Google. For details and rationale, +# see https://github.com/dart-lang/pedantic#enabled-lints. +include: ../analysis_options.yaml + +linter: + rules: + public_member_api_docs: false diff --git a/packages/process_run/example/analysis_options.yaml b/packages/process_run/example/analysis_options.yaml new file mode 100644 index 0000000..bb0d2a1 --- /dev/null +++ b/packages/process_run/example/analysis_options.yaml @@ -0,0 +1,8 @@ +# Defines a default set of lint rules enforced for +# projects at Google. For details and rationale, +# see https://github.com/dart-lang/pedantic#enabled-lints. +include: ../analysis_options.yaml + +linter: + rules: + public_member_api_docs: false diff --git a/packages/process_run/lib/cmd_run.dart b/packages/process_run/lib/cmd_run.dart index 8ba8825..bf94b7a 100644 --- a/packages/process_run/lib/cmd_run.dart +++ b/packages/process_run/lib/cmd_run.dart @@ -43,14 +43,7 @@ export 'process_run.dart' export 'src/build_runner.dart' show PbrCmd; export 'src/dartbin_cmd.dart' show - // ignore: deprecated_member_use_from_same_package - Dart2JsCmd, DartCmd, - DartDocCmd, // ignore: deprecated_member_use_from_same_package - DartFmtCmd, // ignore: deprecated_member_use_from_same_package - DartDevcCmd, - // ignore: deprecated_member_use_from_same_package - DartAnalyzerCmd, PubCmd, PubGlobalRunCmd, PubRunCmd, diff --git a/packages/process_run/lib/src/bin/shell/dump.dart b/packages/process_run/lib/src/bin/shell/dump.dart index de8b5cf..d0ce1f9 100644 --- a/packages/process_run/lib/src/bin/shell/dump.dart +++ b/packages/process_run/lib/src/bin/shell/dump.dart @@ -1,5 +1,6 @@ import 'package:process_run/src/io/io.dart'; +/// Dump a string map void dumpStringMap(Map map) { var keys = map.keys.toList() ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); @@ -9,6 +10,7 @@ void dumpStringMap(Map map) { } } +/// Dump a string list void dumpStringList(List list) { for (var item in list) { stdout.writeln('$item'); diff --git a/packages/process_run/lib/src/bin/shell/env.dart b/packages/process_run/lib/src/bin/shell/env.dart index ad5ab9c..cddc36a 100644 --- a/packages/process_run/lib/src/bin/shell/env.dart +++ b/packages/process_run/lib/src/bin/shell/env.dart @@ -15,7 +15,9 @@ import 'env_path.dart'; import 'env_var.dart'; import 'import.dart'; +/// Shell env command base class ShellEnvCommandBase extends ShellBinCommand { + /// Shell env command base ShellEnvCommandBase({required super.name, super.description}) { parser.addFlag(flagLocal, abbr: 'l', help: 'Use local env', negatable: false, defaultsTo: true); @@ -23,14 +25,17 @@ class ShellEnvCommandBase extends ShellBinCommand { abbr: 'u', help: 'Use user env instead of local env', negatable: false); } + /// Local env bool get local { final user = results[flagUser] as bool; final local = !user; return local; } + /// Local/User label String get label => local ? 'local' : 'user'; + /// Read or Create the env file content Future envFileReadOrCreate({bool write = false}) async { var fileContent = EnvFileContent(_envFilePath!); if (!await fileContent.read()) { @@ -42,6 +47,7 @@ class ShellEnvCommandBase extends ShellBinCommand { return fileContent; } + /// Env file path String? get envFilePath => _envFilePath; String? get _envFilePath => local @@ -50,6 +56,7 @@ class ShellEnvCommandBase extends ShellBinCommand { List? _sampleFileContent; + /// Sample file content List get sampleFileContent => _sampleFileContent ??= () { var content = local ? ''' @@ -92,10 +99,12 @@ class ShellEnvCommandBase extends ShellBinCommand { }(); } +/// Shell env command class ShellEnvCommand extends ShellEnvCommandBase { + /// Shell env command ShellEnvCommand() : super( - name: 'env', + name: commandEnv, description: 'Manipulate local and global env vars, paths and aliases') { addCommand(ShellEnvVarCommand()); diff --git a/packages/process_run/lib/src/bin/shell/env_alias.dart b/packages/process_run/lib/src/bin/shell/env_alias.dart index 899b0e7..7805157 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias.dart @@ -5,9 +5,11 @@ import 'env_alias_delete.dart'; import 'env_alias_get.dart'; import 'import.dart'; +/// Alias operations class ShellEnvAliasCommand extends ShellBinCommand { + /// Alias operations ShellEnvAliasCommand() - : super(name: 'alias', description: 'Alias operations') { + : super(name: commandEnvAliases, description: 'Alias operations') { addCommand(ShellEnvAliasDumpCommand()); addCommand(ShellEnvAliasSetCommand()); addCommand(ShellEnvAliasGetCommand()); diff --git a/packages/process_run/lib/src/bin/shell/env_alias_delete.dart b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart index 7770058..eff2a17 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart @@ -5,7 +5,9 @@ import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/io.dart'; +/// Shell env alias delete command. class ShellEnvAliasDeleteCommand extends ShellEnvCommandBase { + /// Shell env alias delete command. ShellEnvAliasDeleteCommand() : super( name: 'delete', diff --git a/packages/process_run/lib/src/bin/shell/env_alias_dump.dart b/packages/process_run/lib/src/bin/shell/env_alias_dump.dart index 1c60bb0..2e203d8 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_dump.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_dump.dart @@ -3,7 +3,9 @@ import 'package:process_run/src/utils.dart'; import 'import.dart'; +/// Shell env alias dump command. class ShellEnvAliasDumpCommand extends ShellBinCommand { + /// Shell env alias dump command. ShellEnvAliasDumpCommand() : super(name: 'dump', description: 'Dump process_run aliases'); diff --git a/packages/process_run/lib/src/bin/shell/env_alias_get.dart b/packages/process_run/lib/src/bin/shell/env_alias_get.dart index deb2455..9cc6d50 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_get.dart @@ -5,7 +5,9 @@ import 'package:process_run/src/io/io.dart'; import 'dump.dart'; +/// Shell env alias get command. class ShellEnvAliasGetCommand extends ShellEnvCommandBase { + /// Shell env alias get command. ShellEnvAliasGetCommand() : super( name: 'get', diff --git a/packages/process_run/lib/src/bin/shell/env_alias_set.dart b/packages/process_run/lib/src/bin/shell/env_alias_set.dart index e1dab9c..26e5fef 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_set.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_set.dart @@ -5,7 +5,9 @@ import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/io.dart'; +/// Shell env alias set command. class ShellEnvAliasSetCommand extends ShellEnvCommandBase { + /// Shell env alias set command. ShellEnvAliasSetCommand() : super( name: 'set', diff --git a/packages/process_run/lib/src/bin/shell/env_delete.dart b/packages/process_run/lib/src/bin/shell/env_delete.dart index 2f641e8..7e7257f 100644 --- a/packages/process_run/lib/src/bin/shell/env_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_delete.dart @@ -5,7 +5,9 @@ import 'package:process_run/src/io/io.dart'; import 'env.dart'; +/// Shell env delete command. class ShellEnvDeleteCommand extends ShellEnvCommandBase { + /// Shell env delete command. ShellEnvDeleteCommand() : super(name: 'delete', description: 'Delete the environment file') { parser.addFlag(flagForce, diff --git a/packages/process_run/lib/src/bin/shell/env_edit.dart b/packages/process_run/lib/src/bin/shell/env_edit.dart index 78f6adb..58bcda3 100644 --- a/packages/process_run/lib/src/bin/shell/env_edit.dart +++ b/packages/process_run/lib/src/bin/shell/env_edit.dart @@ -4,7 +4,9 @@ import 'package:process_run/src/io/io.dart'; import 'env.dart'; +/// Shell env edit command. class ShellEnvEditCommand extends ShellEnvCommandBase { + /// Shell env edit command. ShellEnvEditCommand() : super(name: 'edit', description: 'Edit the environment file'); diff --git a/packages/process_run/lib/src/bin/shell/env_file_content.dart b/packages/process_run/lib/src/bin/shell/env_file_content.dart index 31ebf6a..31ab86f 100644 --- a/packages/process_run/lib/src/bin/shell/env_file_content.dart +++ b/packages/process_run/lib/src/bin/shell/env_file_content.dart @@ -4,13 +4,17 @@ import 'package:process_run/src/characters.dart'; import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/user_config.dart'; +/// File content helper class FileContent { + /// io file late File file; + /// File content helper FileContent(String path) { file = File(path); } + /// Read the file Future read() async { try { lines = LineSplitter.split(await file.readAsString()).toList(); @@ -21,6 +25,7 @@ class FileContent { } } + /// Find the index of the top level key int indexOfTopLevelKey(List supportedKeys) { for (var key in supportedKeys) { for (var i = 0; i < lines!.length; i++) { @@ -35,12 +40,14 @@ class FileContent { return -1; } + /// Write the file Future write() async { var content = lines!.join(Platform.isWindows ? '\r\n' : '\n'); await file.parent.create(recursive: true); await file.writeAsString(content, flush: true); } + /// Check if the list is a top level key static bool isTopLevelKey(String line) { if (startsWithWhitespace(line)) { return false; @@ -92,29 +99,38 @@ class FileContent { return modified; } + /// lines List? lines; } +/// Env file content helper class EnvFileContent extends FileContent { + /// Env file content helper EnvFileContent(super.path); + /// add an alias bool addAlias(String alias, String command) => writeKeyValue(userConfigAliasKeys, alias, value: command); + /// delete an alias bool deleteAlias(String alias) => writeKeyValue(userConfigAliasKeys, alias, delete: true); + /// add a variable bool addVar(String key, String value) => writeKeyValue(userConfigVarKeys, key, value: value); + /// delete a variable bool deleteVar(String key) => writeKeyValue(userConfigVarKeys, key, delete: true); /// Put the paths at the top bool prependPaths(List paths) => writePaths(paths); + /// Delete the paths bool deletePaths(List paths) => writePaths(paths, delete: true); + /// Write paths bool writePaths(List paths, {bool delete = false}) { // Remove alias header var index = indexOfTopLevelKey(userConfigPathKeys); diff --git a/packages/process_run/lib/src/bin/shell/env_path.dart b/packages/process_run/lib/src/bin/shell/env_path.dart index d2b2eb6..3771637 100644 --- a/packages/process_run/lib/src/bin/shell/env_path.dart +++ b/packages/process_run/lib/src/bin/shell/env_path.dart @@ -5,7 +5,9 @@ import 'env_path_delete.dart'; import 'env_path_get.dart'; import 'import.dart'; +/// Path operations class ShellEnvPathCommand extends ShellBinCommand { + /// Path operations ShellEnvPathCommand() : super(name: 'path', description: 'Path operations') { addCommand(ShellEnvPathDumpCommand()); addCommand(ShellEnvPathPrependCommand()); diff --git a/packages/process_run/lib/src/bin/shell/env_path_delete.dart b/packages/process_run/lib/src/bin/shell/env_path_delete.dart index f8a0317..010c62a 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_delete.dart @@ -5,7 +5,9 @@ import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/io.dart'; +/// Shell env path delete command. class ShellEnvPathDeleteCommand extends ShellEnvCommandBase { + /// Shell env path delete command. ShellEnvPathDeleteCommand() : super( name: 'delete', diff --git a/packages/process_run/lib/src/bin/shell/env_path_dump.dart b/packages/process_run/lib/src/bin/shell/env_path_dump.dart index 342e430..30e3af6 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_dump.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_dump.dart @@ -3,7 +3,9 @@ import 'package:process_run/src/bin/shell/dump.dart'; import 'import.dart'; +/// Shell env path dump command. class ShellEnvPathDumpCommand extends ShellBinCommand { + /// Shell env path dump command. ShellEnvPathDumpCommand() : super(name: 'dump', description: 'Dump process_run paths'); diff --git a/packages/process_run/lib/src/bin/shell/env_path_get.dart b/packages/process_run/lib/src/bin/shell/env_path_get.dart index e5b44e9..15d628a 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_get.dart @@ -4,7 +4,9 @@ import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/io.dart'; +/// Shell env path get command. class ShellEnvPathGetCommand extends ShellEnvCommandBase { + /// Shell env path get command. ShellEnvPathGetCommand() : super( name: 'get', diff --git a/packages/process_run/lib/src/bin/shell/env_path_prepend.dart b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart index bc6948e..1f08a91 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_prepend.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart @@ -5,7 +5,9 @@ import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/io.dart'; +/// Shell env path prepend command. class ShellEnvPathPrependCommand extends ShellEnvCommandBase { + /// Shell env path prepend command. ShellEnvPathPrependCommand() : super( name: 'prepend', diff --git a/packages/process_run/lib/src/bin/shell/env_var.dart b/packages/process_run/lib/src/bin/shell/env_var.dart index b0b5558..3e43bdd 100644 --- a/packages/process_run/lib/src/bin/shell/env_var.dart +++ b/packages/process_run/lib/src/bin/shell/env_var.dart @@ -5,10 +5,12 @@ import 'env_var_get.dart'; import 'env_var_set.dart'; import 'import.dart'; +/// Shell env var command. class ShellEnvVarCommand extends ShellBinCommand { + /// Shell env var command. ShellEnvVarCommand() : super( - name: 'var', + name: commandEnvVar, description: 'Manipulate local and global env variables') { addCommand(ShellEnvVarDumpCommand()); addCommand(ShellEnvVarSetCommand()); diff --git a/packages/process_run/lib/src/bin/shell/env_var_delete.dart b/packages/process_run/lib/src/bin/shell/env_var_delete.dart index 66bbf44..599dee2 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_delete.dart @@ -4,10 +4,12 @@ import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_var_delete_io.dart'; import 'package:process_run/src/io/io.dart'; +/// Delete an environment variable from a user/local config file class ShellEnvVarDeleteCommand extends ShellEnvCommandBase { - late final helper = ShellEnvVarDeleteIoHelper( + late final _helper = ShellEnvVarDeleteIoHelper( shell: Shell(), local: local, verbose: verbose ?? false); + /// Delete an environment variable from a user/local config file ShellEnvVarDeleteCommand() : super( name: 'delete', @@ -28,7 +30,7 @@ class ShellEnvVarDeleteCommand extends ShellEnvCommandBase { stderr.writeln('At least 1 arguments expected'); exit(1); } else { - await helper.deleteMulti(rest); + await _helper.deleteMulti(rest); return true; } } diff --git a/packages/process_run/lib/src/bin/shell/env_var_dump.dart b/packages/process_run/lib/src/bin/shell/env_var_dump.dart index 9c8d99e..4424f04 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_dump.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_dump.dart @@ -2,7 +2,9 @@ import 'package:process_run/shell.dart'; import 'import.dart'; +/// Dump environment variable class ShellEnvVarDumpCommand extends ShellBinCommand { + /// Dump environment variable ShellEnvVarDumpCommand() : super(name: 'dump', description: 'Dump environment variable'); diff --git a/packages/process_run/lib/src/bin/shell/env_var_get.dart b/packages/process_run/lib/src/bin/shell/env_var_get.dart index d997765..85692cf 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_get.dart @@ -5,9 +5,11 @@ import 'package:process_run/src/io/io.dart'; import 'dump.dart'; +/// Get an environment variable from a user/local config file class ShellEnvVarGetCommand extends ShellEnvCommandBase { - late final helper = ShellEnvVarGetIoHelper(); + late final _helper = ShellEnvVarGetIoHelper(); + /// Get an environment variable from a user/local config file ShellEnvVarGetCommand() : super( name: 'get', @@ -30,7 +32,7 @@ class ShellEnvVarGetCommand extends ShellEnvCommandBase { stderr.writeln('At least 1 arguments expected'); exit(1); } else { - var map = helper.getMulti(rest); + var map = _helper.getMulti(rest); if (map.isEmpty) { stdout.writeln('not found'); } else { diff --git a/packages/process_run/lib/src/bin/shell/env_var_set.dart b/packages/process_run/lib/src/bin/shell/env_var_set.dart index 8890e24..0347fb4 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_set.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_set.dart @@ -4,10 +4,12 @@ import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_var_set_io.dart'; import 'package:process_run/src/io/io.dart'; +/// Set an environment variable in a user/local config file class ShellEnvVarSetCommand extends ShellEnvCommandBase { - late final helper = ShellEnvVarSetIoHelper( + late final _helper = ShellEnvVarSetIoHelper( shell: Shell(), local: local, verbose: verbose ?? false); + /// Set an environment variable in a user/local config file ShellEnvVarSetCommand() : super( name: 'set', @@ -29,7 +31,7 @@ class ShellEnvVarSetCommand extends ShellEnvCommandBase { } else { var name = rest[0]; var value = rest.sublist(1).join(' '); - await helper.setValue(name, value); + await _helper.setValue(name, value); return true; } diff --git a/packages/process_run/lib/src/bin/shell/run.dart b/packages/process_run/lib/src/bin/shell/run.dart index 722d19b..bb99011 100644 --- a/packages/process_run/lib/src/bin/shell/run.dart +++ b/packages/process_run/lib/src/bin/shell/run.dart @@ -4,11 +4,12 @@ import 'package:process_run/src/user_config.dart'; import 'import.dart'; -/// pub run process_run:shell edit-env +/// pub run process_run:shell run class ShellRunCommand extends ShellBinCommand { + /// pub run process_run:shell run ShellRunCommand() : super( - name: 'run', description: 'Run a command using user environment') { + name: commandRun, description: 'Run a command using user environment') { parser.addFlag(flagInfo, abbr: 'i', help: 'display info', negatable: false); } diff --git a/packages/process_run/lib/src/bin/shell/shell.dart b/packages/process_run/lib/src/bin/shell/shell.dart index 92ad9d9..fa8e8d8 100644 --- a/packages/process_run/lib/src/bin/shell/shell.dart +++ b/packages/process_run/lib/src/bin/shell/shell.dart @@ -6,32 +6,64 @@ import 'package:pub_semver/pub_semver.dart'; import 'env.dart'; import 'import.dart'; +/// The shell bin version Version shellBinVersion = Version.parse(packageVersion); +/// Help flag const flagHelp = 'help'; + +/// Info flag const flagInfo = 'info'; + +/// Local flag const flagLocal = 'local'; + +/// User flag const flagUser = 'user'; -// Force an action + +/// Force an action const flagForce = 'force'; + +/// Delete flag const flagDelete = 'delete'; + +/// Verbose flag const flagVerbose = 'verbose'; + +/// Version flag const flagVersion = 'version'; +/// Command edit-env const commandEdit = 'edit-env'; + +/// Command run const commandRun = 'run'; + +/// Command env const commandEnv = 'env'; +/// Command env edit const commandEnvEdit = 'edit'; + +/// Command env var const commandEnvVar = 'var'; + +/// Command env var dump const commandEnvVarDump = 'dump'; + +/// Command env path const commandEnvPath = 'path'; + +/// Command env aliases const commandEnvAliases = 'alias'; +/// Script shortcut String get script => 'ds'; +/// Main shell command class MainShellCommand extends ShellBinCommand { - MainShellCommand() : super(name: 'ds', version: shellBinVersion) { + /// Main shell command + MainShellCommand() : super(name: script, version: shellBinVersion) { addCommand(ShellEnvCommand()); addCommand(ShellRunCommand()); } @@ -77,6 +109,7 @@ ds env edit } } +/// Main shell command final mainCommand = MainShellCommand(); /// diff --git a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart index e52c901..d4b5420 100644 --- a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart +++ b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart @@ -7,29 +7,36 @@ import 'package:process_run/src/io/io.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; +/// Shell command base class class ShellBinCommand { - // Optional parent + /// Optional parent ShellBinCommand? parent; + + /// Name of the command String name; + /// Default parser ArgParser get parser => _parser ??= ArgParser(allowTrailingOptions: false); FutureOr Function()? _onRun; ArgParser? _parser; + + /// Parser results late ArgResults results; bool? _verbose; - // Set before run + /// Set before run bool? get verbose => _verbose ??= parent?.verbose; String? _description; + /// Description of the command String? get description => _description; Version? _version; + /// Version of the command Version? get version => _version ??= parent?.version; - // name - // description + /// print the name and description void printNameDescription() { stdout.writeln('$name${parent != null ? '' : ' ${version.toString()}'}'); if (description != null) { @@ -37,6 +44,7 @@ class ShellBinCommand { } } + /// Print the usage void printUsage() { printNameDescription(); stdout.writeln(); @@ -54,6 +62,7 @@ class ShellBinCommand { stdout.writeln(); } + /// Print the base usage void printBaseUsage() { printNameDescription(); if (_commands.isNotEmpty) { @@ -65,6 +74,7 @@ class ShellBinCommand { } } + /// Parse the arguments ArgResults parse(List arguments) { // Add missing common commands parser.addFlag(flagVersion, @@ -74,6 +84,7 @@ class ShellBinCommand { return results = parser.parse(arguments); } + /// Parse and run the command @nonVirtual FutureOr parseAndRun(List arguments) { parse(arguments); @@ -82,6 +93,7 @@ class ShellBinCommand { final _commands = {}; + /// Shell bin command ShellBinCommand( {required this.name, Version? version, @@ -98,6 +110,7 @@ class ShellBinCommand { parser.addFlag(flagHelp, abbr: 'h', help: 'Usage help', negatable: false); } + /// Add a command void addCommand(ShellBinCommand command) { parser.addCommand(command.name, command.parser); _commands[command.name] = command; @@ -118,6 +131,7 @@ class ShellBinCommand { /// Get a flag bool? getFlag(String name) => results[name] as bool?; + /// Run @nonVirtual FutureOr run() async { // Handle version first diff --git a/packages/process_run/lib/src/build_runner.dart b/packages/process_run/lib/src/build_runner.dart index 4a162d2..67cdf7a 100644 --- a/packages/process_run/lib/src/build_runner.dart +++ b/packages/process_run/lib/src/build_runner.dart @@ -1,5 +1,7 @@ import 'package:process_run/cmd_run.dart'; +/// Run the build_runner command class PbrCmd extends PubRunCmd { + /// Run the build_runner command PbrCmd(List arguments) : super('build_runner', arguments); } diff --git a/packages/process_run/lib/src/common/dartbin.dart b/packages/process_run/lib/src/common/dartbin.dart index 6c21489..bf05d62 100644 --- a/packages/process_run/lib/src/common/dartbin.dart +++ b/packages/process_run/lib/src/common/dartbin.dart @@ -10,8 +10,10 @@ import 'package:pub_semver/pub_semver.dart'; /// String? get dartExecutable => resolvedDartExecutable; +/// Get dart bin directory path String get dartSdkBinDirPath => dirname(dartExecutable!); +/// Get dart sdk directory path String get dartSdkDirPath => dirname(dartSdkBinDirPath); Version? _dartVersion; diff --git a/packages/process_run/lib/src/common/dev_utils.dart b/packages/process_run/lib/src/common/dev_utils.dart index 24e34da..b7ce25f 100644 --- a/packages/process_run/lib/src/common/dev_utils.dart +++ b/packages/process_run/lib/src/common/dev_utils.dart @@ -1,6 +1,8 @@ /// Development helpers to generate warning in code library; +import 'package:meta/meta.dart'; + void _devPrint(Object object) { if (_devPrintEnabled) { print(object); @@ -13,6 +15,8 @@ bool _devPrintEnabled = true; set devPrintEnabled(bool enabled) => _devPrintEnabled = enabled; @Deprecated('Dev only') + +/// Print only in dev mode void devPrint(Object? object) { if (_devPrintEnabled) { print(object); @@ -20,6 +24,8 @@ void devPrint(Object? object) { } @Deprecated('Dev only') + +/// Warning in dev mode T devWarning(T t) => t; void _devError([Object? msg]) { @@ -36,11 +42,16 @@ void _devError([Object? msg]) { } @Deprecated('Dev only') + +/// Error in dev mode void devError([String? msg]) => _devError(msg); -// exported for testing +/// exported for testing +@visibleForTesting void debugDevPrint(Object object) => _devPrint(object); +/// exported for testing +@visibleForTesting void debugDevError(Object object) => _devError(object); set debugDevPrintEnabled(bool enabled) => _devPrintEnabled = enabled; diff --git a/packages/process_run/lib/src/dartbin_cmd.dart b/packages/process_run/lib/src/dartbin_cmd.dart index e661907..2ae5a80 100644 --- a/packages/process_run/lib/src/dartbin_cmd.dart +++ b/packages/process_run/lib/src/dartbin_cmd.dart @@ -9,6 +9,7 @@ import 'package:pub_semver/pub_semver.dart'; import 'common/import.dart'; +/// dart bin file name String dartBinFileName = 'dart${Platform.isWindows ? '.exe' : ''}'; /// Call dart executable @@ -16,42 +17,10 @@ String dartBinFileName = 'dart${Platform.isWindows ? '.exe' : ''}'; /// To prevent 'Observatory server failed to start after 1 tries' when /// running from an idea use: includeParentEnvironment = false class DartCmd extends _DartBinCmd { + /// Call dart executable DartCmd(List arguments) : super(dartBinFileName, arguments); } -/// dartfmt command -@Deprecated('dartfmt is deprecated itself, use dart format') -class DartFmtCmd extends DartCmd { - DartFmtCmd(List arguments) : super(['format', ...arguments]); -} - -/// dartanalyzer -@Deprecated('dartanalyzer is deprecated itself, use dart analyze') -class DartAnalyzerCmd extends _DartBinCmd { - DartAnalyzerCmd(List arguments) - : super(getShellCmdBinFileName('dartanalyzer'), arguments); -} - -/// dart2js -@Deprecated('Use dart compile js') -class Dart2JsCmd extends _DartBinCmd { - Dart2JsCmd(List arguments) - : super(getShellCmdBinFileName('dart2js'), arguments); -} - -/// dartdoc -@Deprecated('dartfmt is deprecated itself, user dart doc') -class DartDocCmd extends _DartBinCmd { - DartDocCmd(List arguments) - : super(getShellCmdBinFileName('dartdoc'), arguments); -} - -/// dartdevc -class DartDevcCmd extends _DartBinCmd { - DartDevcCmd(List arguments) - : super(getShellCmdBinFileName('dartdevc'), arguments); -} - /// pub class PubCmd extends DartCmd { PubCmd(List arguments) : super(['pub', ...arguments]); diff --git a/packages/process_run/lib/src/user_config.dart b/packages/process_run/lib/src/user_config.dart index fc99212..c7395c4 100644 --- a/packages/process_run/lib/src/user_config.dart +++ b/packages/process_run/lib/src/user_config.dart @@ -97,6 +97,7 @@ class EnvFileConfig { final Map vars; final Map aliases; + /// Env file config EnvFileConfig(List? paths, Map? vars, Map? aliases) : paths = paths ?? [], @@ -276,6 +277,7 @@ void userLoadEnvFile(String path) { } // private +/// Update userPaths and userEnvironment void userLoadConfigMap(Map map) { userLoadEnvFileConfig(loadFromMap(map)); } diff --git a/packages/process_run/lib/src/utils.dart b/packages/process_run/lib/src/utils.dart index 640924f..7a25d03 100644 --- a/packages/process_run/lib/src/utils.dart +++ b/packages/process_run/lib/src/utils.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'package:process_run/src/io/io.dart'; +/// Get the shell command file name String getShellCmdBinFileName(String command) => '$command${Platform.isWindows ? '.bat' : ''}'; @@ -8,6 +9,7 @@ String getShellCmdBinFileName(String command) => // [data] can be map a list // if it is a string, it will try to parse it first // +/// Convert data to pretty json String? jsonPretty(dynamic data) { if (data is String) { dynamic parsed = jsonDecode(data); diff --git a/packages/process_run/lib/src/utils/hex_utils.dart b/packages/process_run/lib/src/utils/hex_utils.dart index a110c82..8cad44f 100644 --- a/packages/process_run/lib/src/utils/hex_utils.dart +++ b/packages/process_run/lib/src/utils/hex_utils.dart @@ -32,10 +32,12 @@ int _hex2CodeUint8(int value) { return _hexCodeUint4(value); } +/// Convert a byte to a hex string String byteToHex(int value) { return String.fromCharCodes([_hex1CodeUint8(value), _hex2CodeUint8(value)]); } +/// Convert a list of bytes to a hex string String bytesToHex(List bytes) { final sb = StringBuffer(); for (final byte in bytes) { diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index 526cd53..a1cb014 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '1.0.0'; +const packageVersion = '1.0.0+3'; diff --git a/packages/process_run/test/analysis_options.yaml b/packages/process_run/test/analysis_options.yaml new file mode 100644 index 0000000..bb0d2a1 --- /dev/null +++ b/packages/process_run/test/analysis_options.yaml @@ -0,0 +1,8 @@ +# Defines a default set of lint rules enforced for +# projects at Google. For details and rationale, +# see https://github.com/dart-lang/pedantic#enabled-lints. +include: ../analysis_options.yaml + +linter: + rules: + public_member_api_docs: false diff --git a/packages/process_run/test/cmd_run_api_test.dart b/packages/process_run/test/cmd_run_api_test.dart index 224eab3..26a4188 100644 --- a/packages/process_run/test/cmd_run_api_test.dart +++ b/packages/process_run/test/cmd_run_api_test.dart @@ -34,14 +34,7 @@ void main() { argumentsToString; argumentToString; PbrCmd; - // ignore: deprecated_member_use_from_same_package - Dart2JsCmd; DartCmd; - DartDocCmd; // ignore: deprecated_member_use_from_same_package - DartFmtCmd; // ignore: deprecated_member_use_from_same_package - DartDevcCmd; - // ignore: deprecated_member_use_from_same_package - DartAnalyzerCmd; PubCmd; PubGlobalRunCmd; PubRunCmd; diff --git a/packages/process_run/test/dartbin_cmd_test.dart b/packages/process_run/test/dartbin_cmd_test.dart index ffc48b5..e1033f7 100644 --- a/packages/process_run/test/dartbin_cmd_test.dart +++ b/packages/process_run/test/dartbin_cmd_test.dart @@ -26,29 +26,12 @@ void main() { }); test('others', () async { expect((await runCmd(DartCmd(['--help']))).exitCode, 0); - var exitCode = (await runCmd( - DartFmtCmd(// ignore: deprecated_member_use_from_same_package - ['--help']))) - .exitCode; - if (!Platform.isWindows) { - // Somehow the exit code is 1 on windows - expect(exitCode, 0); - } - // expect((await runCmd(DartAnalyzerCmd(['--help']))).exitCode, 0); - // expect((await runCmd(DartDevcCmd(['--help']))).exitCode, 0); expect((await runCmd(PubCmd(['--help']))).exitCode, 0); //expect((await runCmd(DartDevkCmd(['--help']))).exitCode, 0); }); test('toString', () { expect(PubCmd(['--help']).toString(), 'dart pub --help'); - // expect(DartDocCmd(['--help']).toString(), 'dartdoc --help'); - // ignore: deprecated_member_use_from_same_package - expect(Dart2JsCmd(['--help']).toString(), 'dart2js --help'); - // expect(DartDevcCmd(['--help']).toString(), 'dartdevc --help'); - //expect(DartAnalyzerCmd(['--help']).toString(), 'dartanalyzer --help'); - expect(DartFmtCmd(// ignore: deprecated_member_use_from_same_package - ['--help']).toString(), 'dart format --help'); expect(DartCmd(['--help']).toString(), 'dart --help'); }); diff --git a/packages/process_run/test/dartbin_cmd_verbose_test_.dart b/packages/process_run/test/dartbin_cmd_verbose_test_.dart index a8f4814..4ddc43d 100644 --- a/packages/process_run/test/dartbin_cmd_verbose_test_.dart +++ b/packages/process_run/test/dartbin_cmd_verbose_test_.dart @@ -2,34 +2,12 @@ library process_run.dartbin_cmd_verbose_test; import 'package:process_run/cmd_run.dart' show runCmd; -import 'package:process_run/shell.dart'; import 'package:process_run/src/dartbin_cmd.dart'; -import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; void main() { group('dartbin_cmd_verbose', () { test('all', () async { - expect( - (await runCmd( - DartFmtCmd(// ignore: deprecated_member_use_from_same_package - ['--help']), - verbose: true)) - .exitCode, - 0); - - // To remove once dart stable hits 2.17.0 - if (dartVersion < Version(2, 17, 0, pre: '0')) { - expect( - // ignore: deprecated_member_use_from_same_package - (await runCmd(Dart2JsCmd(['--help']), verbose: true)).exitCode, - 0); - expect( - // ignore: deprecated_member_use_from_same_package - (await runCmd(DartDocCmd(['--help']), verbose: true)).exitCode, - 0); - } - expect((await runCmd(PubCmd(['--help']), verbose: true)).exitCode, 0); }); }); diff --git a/packages/process_run/test/dartdevc_test.dart b/packages/process_run/test/dartdevc_test.dart deleted file mode 100644 index 84b18a5..0000000 --- a/packages/process_run/test/dartdevc_test.dart +++ /dev/null @@ -1,46 +0,0 @@ -@TestOn('vm') -library process_run.dartdevc_test; - -import 'dart:io'; - -import 'package:path/path.dart'; -import 'package:process_run/cmd_run.dart'; -import 'package:test/test.dart'; - -import 'process_run_test_common.dart'; - -void main() => defineTests(); - -void defineTests() { - group('dartdevc', () { - test('help', () async { - final result = await runCmd(DartDevcCmd(['--help'])); - expect(result.stdout, contains('Usage: dartdevc')); - expect(result.exitCode, 0); - }); - test('version', () async { - final result = await runCmd(DartDevcCmd(['--version'])); - expect(result.stdout, contains('dartdevc')); - expect(result.exitCode, 0); - }); - test('build', () async { - // from dartdevc: exec '$DART' --packages='$BIN_DIR/snapshots/resources/dartdevc/.packages' '$SNAPSHOT' '$@' - - var destination = join(testDir, 'dartdevc_build', 'main.js'); - - // delete dir if any - try { - await Directory(dirname(destination)).create(recursive: true); - } catch (_) {} - - final result = await runCmd( - DartDevcCmd( - ['-o', destination, join(projectTop, 'test', 'data', 'main.dart')]), - //verbose: true - ); - //expect(result.stdout, contains('dartdevc')); - expect(result.exitCode, 0); - //}, skip: 'failed on SDK 1.19.0'); - fixed in 1.19.1 - }); - }, skip: true); -} diff --git a/packages/process_run/test/dartdoc_test.dart b/packages/process_run/test/dartdoc_test.dart deleted file mode 100644 index 025d43d..0000000 --- a/packages/process_run/test/dartdoc_test.dart +++ /dev/null @@ -1,47 +0,0 @@ -@TestOn('vm') -library process_run.dartdoc_test; - -import 'dart:mirrors'; - -import 'package:path/path.dart'; -import 'package:process_run/cmd_run.dart'; -import 'package:test/test.dart'; - -String getScriptPath(Type type) => - (reflectClass(type).owner as LibraryMirror).uri.toFilePath(); - -class Script { - static String get path => getScriptPath(Script); -} - -String projectTop = dirname(dirname(Script.path)); -String testOut = join(projectTop, '.dart_tool', 'process_run', 'test'); - -void main() => defineTests(); - -void defineTests() { - group('dartdoc', () { - test('help', () async { - // ignore: deprecated_member_use_from_same_package - final result = await runCmd(DartDocCmd(['--help'])); - expect(result.stdout, contains('--version')); - expect(result.exitCode, 0); - }); - test('version', () async { - // ignore: deprecated_member_use_from_same_package - final result = await runCmd(DartDocCmd(['--version'])); - expect(result.stdout, contains('dartdoc')); - expect(result.exitCode, 0); - }); - test('build', () async { - // from dartdoc: exec '$DART' --packages='$BIN_DIR/snapshots/resources/dartdoc/.packages' '$SNAPSHOT' '$@' - - final result = await runCmd( - // ignore: deprecated_member_use_from_same_package - DartDocCmd(['--output', join(testOut, 'dartdoc_build')])); - //expect(result.stdout, contains('dartdoc')); - expect(result.exitCode, 0); - //}, skip: 'failed on SDK 1.19.0'); - fixed in 1.19.1 - }, timeout: const Timeout(Duration(minutes: 2))); - }, skip: 'Deprecated'); -} diff --git a/packages/process_run/test/dartfmt_test.dart b/packages/process_run/test/dartfmt_test.dart deleted file mode 100644 index 46c02c5..0000000 --- a/packages/process_run/test/dartfmt_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -@TestOn('vm') -library process_run.dartfmt_test; - -import 'package:process_run/cmd_run.dart'; -// ignore: import_of_legacy_library_into_null_safe -import 'package:pub_semver/pub_semver.dart'; -import 'package:test/test.dart'; - -void main() => defineTests(); - -void defineTests() { - group('dartfmt', () { - test('help', () async { - var result = await runCmd( - DartFmtCmd(// ignore: deprecated_member_use_from_same_package - ['--help'])); - expect(result.exitCode, 0); - expect(result.stdout, contains('Usage:')); - expect(result.stdout, contains('dartfmt')); - - // The raw version is displayed - result = await runCmd( - DartFmtCmd(// ignore: deprecated_member_use_from_same_package - ['--version'])); - var version = Version.parse((result.stdout as String).trim()); - expect(version, greaterThan(Version(1, 0, 0))); - expect(result.exitCode, 0); - }); - }, skip: 'Deprecated'); -} diff --git a/packages/process_run/tool/analysis_options.yaml b/packages/process_run/tool/analysis_options.yaml new file mode 100644 index 0000000..bb0d2a1 --- /dev/null +++ b/packages/process_run/tool/analysis_options.yaml @@ -0,0 +1,8 @@ +# Defines a default set of lint rules enforced for +# projects at Google. For details and rationale, +# see https://github.com/dart-lang/pedantic#enabled-lints. +include: ../analysis_options.yaml + +linter: + rules: + public_member_api_docs: false From 266e4adcf8c63427681531f01b5952cb545ee356 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 25 Jul 2024 11:10:01 +0200 Subject: [PATCH 102/150] [process_run] fix api doc lint rule --- packages/process_run/analysis_options.yaml | 2 + packages/process_run/lib/src/dartbin_cmd.dart | 13 +++-- .../process_run/lib/src/dartbin_impl.dart | 8 +++- packages/process_run/lib/src/dev_cmd_run.dart | 2 + .../process_run/lib/src/flutterbin_cmd.dart | 16 +++++-- packages/process_run/lib/src/io/env_io.dart | 11 +++++ .../lib/src/io/env_var_delete_io.dart | 3 ++ .../lib/src/io/env_var_get_io.dart | 4 ++ .../lib/src/io/env_var_set_io.dart | 2 + .../process_run/lib/src/io/shared_stdin.dart | 1 + .../lib/src/lines_utils_common.dart | 4 ++ .../lib/src/platform/platform_io.dart | 2 + packages/process_run/lib/src/process_cmd.dart | 38 ++++++++------- packages/process_run/lib/src/shell.dart | 47 ++----------------- .../process_run/lib/src/shell_common.dart | 37 +-------------- .../process_run/lib/src/shell_common_io.dart | 5 ++ .../lib/src/shell_context_common.dart | 2 + .../process_run/lib/src/shell_context_io.dart | 1 + packages/process_run/lib/src/shell_utils.dart | 2 + .../lib/src/shell_utils_common.dart | 7 +++ packages/process_run/lib/src/user_config.dart | 22 +++++++-- .../process_run/lib/src/utils/hex_utils.dart | 3 +- packages/process_run/lib/src/webdev.dart | 2 + packages/process_run/lib/src/which.dart | 1 + .../process_run/test/dartbin_cmd_test.dart | 2 - .../process_run/test/shell_common_test.dart | 9 ---- packages/process_run/test/shell_test.dart | 6 --- 27 files changed, 121 insertions(+), 131 deletions(-) diff --git a/packages/process_run/analysis_options.yaml b/packages/process_run/analysis_options.yaml index 7cfc53c..918853f 100644 --- a/packages/process_run/analysis_options.yaml +++ b/packages/process_run/analysis_options.yaml @@ -10,6 +10,8 @@ include: package:lints/recommended.yaml # See the configuration guide for more # https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer analyzer: + exclude: + - lib/src/version.dart language: strict-casts: true strict-inference: true diff --git a/packages/process_run/lib/src/dartbin_cmd.dart b/packages/process_run/lib/src/dartbin_cmd.dart index 2ae5a80..8f9698a 100644 --- a/packages/process_run/lib/src/dartbin_cmd.dart +++ b/packages/process_run/lib/src/dartbin_cmd.dart @@ -3,7 +3,6 @@ import 'dart:convert'; import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/src/io/io.dart'; -import 'package:process_run/src/utils.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; @@ -23,15 +22,10 @@ class DartCmd extends _DartBinCmd { /// pub class PubCmd extends DartCmd { + /// Call pub executable PubCmd(List arguments) : super(['pub', ...arguments]); } -@Deprecated('Not supported anymore') -class DartDevkCmd extends _DartBinCmd { - DartDevkCmd(List arguments) - : super(getShellCmdBinFileName('dartdevk'), arguments); -} - class _DartBinCmd extends ProcessCmd { final String binName; @@ -42,10 +36,12 @@ class _DartBinCmd extends ProcessCmd { String toString() => executableArgumentsToString(binName, arguments); } +/// pub run class PubRunCmd extends PubCmd { final String _command; final List _arguments; + /// Call pub run PubRunCmd(this._command, this._arguments) : super(['run', _command, ..._arguments]); @@ -53,10 +49,12 @@ class PubRunCmd extends PubCmd { String toString() => executableArgumentsToString(_command, _arguments); } +/// pub global run class PubGlobalRunCmd extends PubCmd { final String _command; final List _arguments; + /// Call pub global run PubGlobalRunCmd(this._command, this._arguments) : super(['global', 'run', _command, ..._arguments]); @@ -64,6 +62,7 @@ class PubGlobalRunCmd extends PubCmd { String toString() => executableArgumentsToString(_command, _arguments); } +/// Parse the text from Platform.version Version parsePlatformVersion(String text) { return Version.parse(text.split(' ').first); } diff --git a/packages/process_run/lib/src/dartbin_impl.dart b/packages/process_run/lib/src/dartbin_impl.dart index 583d150..e8fec33 100644 --- a/packages/process_run/lib/src/dartbin_impl.dart +++ b/packages/process_run/lib/src/dartbin_impl.dart @@ -1,3 +1,4 @@ +import 'package:meta/meta.dart'; import 'package:path/path.dart'; import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/shell_utils.dart'; @@ -5,12 +6,16 @@ import 'package:process_run/src/user_config.dart'; bool _dartExecutableLock = false; +/// Force using the which command to find dart executable (debug only) +@visibleForTesting var debugDartExecutableForceWhich = false; +/// find dart executable String? findDartExecutableSync(List paths) { return findExecutableSync('dart', paths); } +/// Resolve dart executable from environment String? resolveDartExecutable({Map? environment}) { if (!_dartExecutableLock) { _dartExecutableLock = true; @@ -33,7 +38,7 @@ String? resolveDartExecutable({Map? environment}) { } } -// Find dart in the cache dir +/// Find dart in the cache dir of flutter String? findFlutterDartExecutableSync(String path) { return findDartExecutableSync([join(path, 'cache', 'dart-sdk', 'bin')]); } @@ -54,6 +59,7 @@ String? get resolvedDartExecutable => _resolvedDartExecutable ??= () { String? _platformResolvedExecutable; +/// resolved executable from platform String? get platformResolvedExecutable { if (!debugDartExecutableForceWhich) { return _platformResolvedExecutable ??= () { diff --git a/packages/process_run/lib/src/dev_cmd_run.dart b/packages/process_run/lib/src/dev_cmd_run.dart index 561bb39..90d31cd 100644 --- a/packages/process_run/lib/src/dev_cmd_run.dart +++ b/packages/process_run/lib/src/dev_cmd_run.dart @@ -4,6 +4,8 @@ import 'package:process_run/cmd_run.dart'; import 'package:process_run/src/io/io.dart'; @Deprecated('Deb only, verbose') + +/// dev only run command Future devRunCmd(ProcessCmd cmd, {bool? verbose, bool? commandVerbose, diff --git a/packages/process_run/lib/src/flutterbin_cmd.dart b/packages/process_run/lib/src/flutterbin_cmd.dart index f3fd8de..f707952 100644 --- a/packages/process_run/lib/src/flutterbin_cmd.dart +++ b/packages/process_run/lib/src/flutterbin_cmd.dart @@ -19,8 +19,11 @@ set flutterExecutablePath(String? path) { } @Deprecated('Dev only') + +/// Flutter command ProcessCmd flutterCmd(List arguments) => FlutterCmd(arguments); +/// true if flutter is supported bool get isFlutterSupported => isFlutterSupportedSync; /// true if flutter is supported @@ -28,7 +31,7 @@ bool get isFlutterSupportedSync => flutterExecutablePath != null; /// build a flutter command class FlutterCmd extends ProcessCmd { - // Somehow flutter requires runInShell on Linux, does not hurt on windows + /// Somehow flutter requires runInShell on Linux, does not hurt on windows FlutterCmd(List arguments) : super(flutterExecutablePath!, arguments, runInShell: true); @@ -36,7 +39,7 @@ class FlutterCmd extends ProcessCmd { String toString() => executableArgumentsToString('flutter', arguments); } -// to deprecate +/// to deprecate, get flutter bin version Future getFlutterVersion() => getFlutterBinVersion(); /// Get flutter version. @@ -53,13 +56,16 @@ Future getFlutterBinChannel() async => FlutterBinInfo? _flutterBinInfo; +/// Get flutter bin info Future getFlutterBinInfo() async => _flutterBinInfo ??= await _getFlutterBinInfo(); /// Parse flutter information abstract class FlutterBinInfo { + /// Channel (dev, beta, master, stable) String? get channel; + /// Version Version? get version; /// First line is sufficient @@ -95,20 +101,20 @@ abstract class FlutterBinInfo { } } if (version != null || channel != null) { - return FlutterBinInfoImpl(version: version, channel: channel); + return _FlutterBinInfoImpl(version: version, channel: channel); } return null; } } -class FlutterBinInfoImpl implements FlutterBinInfo { +class _FlutterBinInfoImpl implements FlutterBinInfo { @override final String? channel; @override final Version? version; - FlutterBinInfoImpl({this.channel, this.version}); + _FlutterBinInfoImpl({this.channel, this.version}); } /// Get flutter info. diff --git a/packages/process_run/lib/src/io/env_io.dart b/packages/process_run/lib/src/io/env_io.dart index 3e4b55c..0464afe 100644 --- a/packages/process_run/lib/src/io/env_io.dart +++ b/packages/process_run/lib/src/io/env_io.dart @@ -4,16 +4,25 @@ import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env_file_content.dart'; import 'package:process_run/src/user_config.dart'; +/// Helper to read and write the environment file class ShellEnvIoHelper { + /// Shell final Shell shell; + + /// Local or user final bool local; + + /// Verbose final bool verbose; + /// Create a helper ShellEnvIoHelper( {required this.shell, required this.local, required this.verbose}); + /// Label String get label => local ? 'local' : 'user'; + /// Read or create the environment file Future envFileReadOrCreate({bool write = false}) async { var fileContent = EnvFileContent(_envFilePath!); if (!await fileContent.read()) { @@ -25,6 +34,7 @@ class ShellEnvIoHelper { return fileContent; } + /// Get the environment file path String? get envFilePath => _envFilePath; String? get _envFilePath => local @@ -33,6 +43,7 @@ class ShellEnvIoHelper { List? _sampleFileContent; + /// Sample file content List get sampleFileContent => _sampleFileContent ??= () { var content = local ? ''' diff --git a/packages/process_run/lib/src/io/env_var_delete_io.dart b/packages/process_run/lib/src/io/env_var_delete_io.dart index f9c2253..e0a33e2 100644 --- a/packages/process_run/lib/src/io/env_var_delete_io.dart +++ b/packages/process_run/lib/src/io/env_var_delete_io.dart @@ -5,10 +5,13 @@ import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_io.dart'; import 'package:process_run/src/io/io.dart'; +/// Helper to delete environment variables class ShellEnvVarDeleteIoHelper extends ShellEnvIoHelper { + /// Helper to delete environment variables ShellEnvVarDeleteIoHelper( {required super.shell, required super.local, required super.verbose}); + /// delete multiple environment variables Future deleteMulti(List keys) async { var fileContent = await envFileReadOrCreate(); var modified = false; diff --git a/packages/process_run/lib/src/io/env_var_get_io.dart b/packages/process_run/lib/src/io/env_var_get_io.dart index 63ef105..9ef3d06 100644 --- a/packages/process_run/lib/src/io/env_var_get_io.dart +++ b/packages/process_run/lib/src/io/env_var_get_io.dart @@ -1,8 +1,11 @@ import 'package:process_run/shell.dart'; +/// Helper to get environment variables class ShellEnvVarGetIoHelper { + /// Helper to get environment variables ShellEnvVarGetIoHelper(); + /// get multiple environment variables Map getMulti(List keys) { Map map = ShellEnvironment().vars; map = Map.from(map) @@ -10,6 +13,7 @@ class ShellEnvVarGetIoHelper { return map; } + /// get a single environment variable String? get(String key) { var value = ShellEnvironment().vars[key]; return value; diff --git a/packages/process_run/lib/src/io/env_var_set_io.dart b/packages/process_run/lib/src/io/env_var_set_io.dart index e77dc92..01fb353 100644 --- a/packages/process_run/lib/src/io/env_var_set_io.dart +++ b/packages/process_run/lib/src/io/env_var_set_io.dart @@ -7,11 +7,13 @@ import 'package:process_run/src/io/env_io.dart'; import 'package:process_run/src/io/io.dart'; import 'package:process_run/src/shell_common.dart'; +/// Helper to set environment variables class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { /// Local should be true by default ShellEnvVarSetIoHelper( {required super.shell, required super.local, super.verbose = true}); + /// Set a single environment variable Future setValue(String name, String? value) async { if (verbose) { stdout.writeln('file $label: $envFilePath'); diff --git a/packages/process_run/lib/src/io/shared_stdin.dart b/packages/process_run/lib/src/io/shared_stdin.dart index 7572f29..398bf2c 100644 --- a/packages/process_run/lib/src/io/shared_stdin.dart +++ b/packages/process_run/lib/src/io/shared_stdin.dart @@ -33,6 +33,7 @@ class SharedStdIn extends Stream> { var _terminated = false; final Stream> _originalStream; + /// Creates a new [SharedStdIn] instance. SharedStdIn([Stream>? stream]) : _originalStream = stream ?? stdin; /// Returns a future that completes with the next line. diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index 425b8dc..28f590b 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -28,15 +28,18 @@ import 'common/import.dart'; /// } /// ``` class ShellLinesController { + /// Encoding to use late final Encoding encoding; late StreamController> _controller; + /// Create a shell lines controller. ShellLinesController({Encoding? encoding}) { this.encoding = encoding ?? shellContext.encoding; // Must be sync! _controller = StreamController>(sync: true); } + /// Future when done Future get done => _controller.done; /// Write a string with the specified encoding. @@ -55,6 +58,7 @@ class ShellLinesController { _controller.close(); } + /// Write a line. void writeln(String message) { write('$message\n'); } diff --git a/packages/process_run/lib/src/platform/platform_io.dart b/packages/process_run/lib/src/platform/platform_io.dart index ee4763f..e917259 100644 --- a/packages/process_run/lib/src/platform/platform_io.dart +++ b/packages/process_run/lib/src/platform/platform_io.dart @@ -4,9 +4,11 @@ import 'package:process_run/src/platform/platform_common.dart'; import 'package:process_run/src/shell_context_common.dart'; import 'package:process_run/src/shell_context_io.dart'; +/// true if we are on windows bool get platformIoIsWindows => Platform.isWindows; /// Global shell context final shellContextIo = ShellContextIo(); +/// Get the global shell context ShellContext get shellContext => shellContextPlatformOrNull ??= shellContextIo; diff --git a/packages/process_run/lib/src/process_cmd.dart b/packages/process_run/lib/src/process_cmd.dart index a9a1001..0466e76 100644 --- a/packages/process_run/lib/src/process_cmd.dart +++ b/packages/process_run/lib/src/process_cmd.dart @@ -4,16 +4,33 @@ import 'package:collection/collection.dart'; import 'package:process_run/process_run.dart'; import 'package:process_run/src/io/io.dart'; +/// Process command class ProcessCmd { + /// Executable String executable; + + /// Arguments List arguments; + + /// Working directory String? workingDirectory; + + /// Environment Map? environment; + + /// Include parent environment bool includeParentEnvironment; + + /// Run in shell bool? runInShell; + + /// Standard output encoding Encoding stdoutEncoding; + + /// Standard error encoding Encoding stderrEncoding; + /// Process command ProcessCmd(this.executable, this.arguments, {this.workingDirectory, this.environment, @@ -22,6 +39,7 @@ class ProcessCmd { this.stdoutEncoding = systemEncoding, this.stderrEncoding = systemEncoding}); + /// Clone ProcessCmd clone() => ProcessCmd(executable, arguments, workingDirectory: workingDirectory, environment: environment, @@ -46,24 +64,6 @@ class ProcessCmd { String toString() => executableArgumentsToString(executable, arguments); } -// Use ProcessCmd instead -@Deprecated('Use ProcessCmd instead') -ProcessCmd processCmd(String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool? runInShell, - Encoding stdoutEncoding = systemEncoding, - Encoding stderrEncoding = systemEncoding}) { - return ProcessCmd(executable, arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding); -} - bool _isNotEmpty(Object? stdout) { if (stdout is List) { return stdout.isNotEmpty; @@ -73,6 +73,7 @@ bool _isNotEmpty(Object? stdout) { return (stdout != null); } +/// Process result debug string String processResultToDebugString(ProcessResult result) { final sb = StringBuffer(); sb.writeln('exitCode: ${result.exitCode}'); @@ -85,6 +86,7 @@ String processResultToDebugString(ProcessResult result) { return sb.toString(); } +/// Process command debug string String processCmdToDebugString(ProcessCmd cmd) { final sb = StringBuffer(); if (cmd.workingDirectory != null) { diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 633b6cd..b3d79b8 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -239,49 +239,6 @@ abstract class Shell implements ShellCore, ShellCoreSync { @override ShellOptions get options => _options; - /// Create a new shell - @Deprecated('Use clone with options') - Shell clone({ - bool? throwOnError, - String? workingDirectory, - // Don't change environment - @Deprecated('Don\'t change map') Map? environment, - - /// Explicetely set e new environment -// ShellEnvironment? shellEnvironment, - @Deprecated('Don\'t change includeParentEnvironment') - // Don't change includeParentEnvironment - bool? includeParentEnvironment, - bool? runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose, - bool? commentVerbose, - }) { - var localShellEnvironment = - // Compat - (environment is ShellEnvironment ? environment : null); - return Shell( - options: options.clone( - throwOnError: throwOnError, - workingDirectory: workingDirectory, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding, - stdin: stdin, - stderr: stderr, - stdout: stdout, - commentVerbose: commentVerbose, - commandVerbose: commandVerbose, - shellEnvironment: localShellEnvironment, - verbose: verbose, - )); - } - /// non null String get _workingDirectoryPath => _options.workingDirectory ?? Directory.current.path; @@ -714,9 +671,13 @@ class _ProcessCmd extends ProcessCmd { /// Exception thrown in exitCode != 0 and throwOnError is true class ShellException implements Exception { + /// Process result final ProcessResult? result; + + /// Exception message final String message; + /// Shell exception ShellException(this.message, this.result); @override diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index 8d75176..8920f59 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -12,6 +12,7 @@ export 'package:process_run/shell.dart' export 'io/io_import.dart' show ProcessResult, Process, ProcessSignal; +/// shell debug flag (dev only) var shellDebug = false; // devWarning(true); // false /// Multiplatform Shell utility to run a script with multiple commands. @@ -94,6 +95,7 @@ abstract class ShellCore { ShellContext get context; } +/// Sync version of [ShellCore]. abstract class ShellCoreSync { /// /// Run one or multiple plain text command(s). @@ -295,39 +297,4 @@ mixin ShellMixin implements ShellCore, ShellCoreSync { var shell = context.newShell(options: options); return shell; } - - @Deprecated('Use clone with options') - Shell clone({ - bool? throwOnError, - String? workingDirectory, - Map? environment, - bool? includeParentEnvironment, - bool? runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose, - bool? commentVerbose, - }) { - return cloneWithOptions( - ShellOptions( - throwOnError: throwOnError ?? options.throwOnError, - workingDirectory: workingDirectory ?? options.workingDirectory, - environment: environment ?? options.environment, - includeParentEnvironment: includeParentEnvironment ?? true, - runInShell: runInShell ?? options.runInShell, - stdoutEncoding: stdoutEncoding ?? options.stdoutEncoding, - stderrEncoding: stderrEncoding ?? options.stderrEncoding, - stdin: stdin ?? options.stdin, - stdout: stdout ?? options.stdout, - stderr: stderr ?? options.stderr, - verbose: verbose ?? options.verbose, - commandVerbose: commandVerbose ?? options.commandVerbose, - commentVerbose: commentVerbose ?? options.commentVerbose, - ), - ); - } } diff --git a/packages/process_run/lib/src/shell_common_io.dart b/packages/process_run/lib/src/shell_common_io.dart index 45d364e..59f931c 100644 --- a/packages/process_run/lib/src/shell_common_io.dart +++ b/packages/process_run/lib/src/shell_common_io.dart @@ -3,7 +3,9 @@ import 'package:process_run/src/io/env_var_set_io.dart'; import 'shell_common.dart'; +/// Shell implementation using io. class ShellIo extends Shell with ShellMixin { + /// Shell implementation using io. ShellIo({ required ShellOptions options, }) : super.implWithOptions(options); @@ -18,9 +20,12 @@ class ShellIo extends Shell with ShellMixin { } } +/// Shell exception io class ShellExceptionIo implements ShellException { + /// implementation final io.ShellException impl; + /// Shell exception io ShellExceptionIo(this.impl); @override diff --git a/packages/process_run/lib/src/shell_context_common.dart b/packages/process_run/lib/src/shell_context_common.dart index 1713c84..4409917 100644 --- a/packages/process_run/lib/src/shell_context_common.dart +++ b/packages/process_run/lib/src/shell_context_common.dart @@ -25,11 +25,13 @@ abstract class ShellContext { @Deprecated('Use options') Map? environment, @Deprecated('Use options') bool includeParentEnvironment = true}); + /// New shell environment ShellEnvironment newShellEnvironment({ Map? environment, }); } +/// Shell context mixin mixin ShellContextMixin implements ShellContext { @override Encoding get encoding => diff --git a/packages/process_run/lib/src/shell_context_io.dart b/packages/process_run/lib/src/shell_context_io.dart index fc9c2fe..b75422d 100644 --- a/packages/process_run/lib/src/shell_context_io.dart +++ b/packages/process_run/lib/src/shell_context_io.dart @@ -8,6 +8,7 @@ import 'package:process_run/src/shell_common_io.dart'; import 'package:process_run/src/shell_context_common.dart'; import 'package:process_run/src/shell_environment.dart' as io; +/// Shell context io class ShellContextIo with ShellContextMixin implements ShellContext { @override ShellEnvironment get shellEnvironment => diff --git a/packages/process_run/lib/src/shell_utils.dart b/packages/process_run/lib/src/shell_utils.dart index 1f59fa5..6fb2ead 100644 --- a/packages/process_run/lib/src/shell_utils.dart +++ b/packages/process_run/lib/src/shell_utils.dart @@ -186,6 +186,7 @@ List? _windowsPathExts; List get windowsPathExts => _windowsPathExts ??= environmentGetWindowsPathExt(platformEnvironment) ?? windowsDefaultPathExt; +/// Get the PATHEXT environment variable (windows) List? environmentGetWindowsPathExt( Map platformEnvironment) => platformEnvironment['PATHEXT'] @@ -308,6 +309,7 @@ List? _platformEnvironmentPaths; List get platformEnvironmentPaths => _platformEnvironmentPaths ??= _getEnvironmentPaths(platformEnvironment); +/// Get environment paths List getEnvironmentPaths([Map? environment]) { if (environment == null) { return platformEnvironmentPaths; diff --git a/packages/process_run/lib/src/shell_utils_common.dart b/packages/process_run/lib/src/shell_utils_common.dart index 979f269..1d25f6d 100644 --- a/packages/process_run/lib/src/shell_utils_common.dart +++ b/packages/process_run/lib/src/shell_utils_common.dart @@ -8,12 +8,19 @@ import 'package:process_run/src/platform/platform.dart'; import 'characters.dart'; import 'shell_utils.dart' as shell_utils; +/// windows common executable extensions const windowsDefaultPathExt = ['.exe', '.bat', '.cmd', '.com']; +/// windows env path separator const String windowsEnvPathSeparator = ';'; + +/// posix env path separator const String posixEnvPathSeparator = ':'; + +/// env path key const envPathKey = 'PATH'; +/// Get the env path separator String get envPathSeparator => platformIoIsWindows ? windowsEnvPathSeparator : posixEnvPathSeparator; diff --git a/packages/process_run/lib/src/user_config.dart b/packages/process_run/lib/src/user_config.dart index c7395c4..ea39d3c 100644 --- a/packages/process_run/lib/src/user_config.dart +++ b/packages/process_run/lib/src/user_config.dart @@ -22,6 +22,7 @@ var userConfigVarKeys = ['var', 'vars']; /// Supported alias keys var userConfigAliasKeys = ['alias', 'aliases']; +/// User config. class UserConfig { /// never null final Map vars; @@ -32,6 +33,7 @@ class UserConfig { /// never null final Map aliases; + /// User config UserConfig( {Map? vars, List? paths, @@ -45,8 +47,10 @@ class UserConfig { '${vars.length} vars ${paths.length} paths ${aliases.length} aliases'; } +/// User config UserConfig? _userConfig; +/// Get the user config UserConfig get userConfig => _userConfig ?? () { @@ -85,16 +89,24 @@ Map get userEnvironment => ShellEnvironment.empty() ..aliases.addAll(userConfig.aliases) ..paths.addAll(userConfig.paths); -// Test only @protected + +/// Reset user config +@visibleForTesting void resetUserConfig() { shellEnvironment = null; _userConfig = null; } +/// Env file config class EnvFileConfig { + /// paths final List paths; + + /// vars final Map vars; + + /// aliases final Map aliases; /// Env file config @@ -110,9 +122,11 @@ class EnvFileConfig { /// Has vars, paths or aliases. bool get isNotEmpty => !isEmpty; + /// Debug map Map toDebugMap() => {'paths': paths, 'vars': vars, 'aliases': aliases}; + /// Load from path Future loadFromPath(String path) async { return _loadFromPath(path); } @@ -291,6 +305,7 @@ void userLoadEnv( } // private +/// load user env file config void userLoadEnvFileConfig(EnvFileConfig envFileConfig) { var config = userConfig; var paths = List.from(config.paths); @@ -390,7 +405,7 @@ UserConfig getUserConfig(Map? environment) { paths: shEnv.paths, vars: shEnv.vars, aliases: shEnv.aliases); } -// Fix environment with global settings and current dart sdk +/// get users paths List getUserPaths(Map environment) => getUserConfig(environment).paths; @@ -412,6 +427,5 @@ String getLocalEnvFilePath([Map? environment]) { return join(Directory.current.path, subDir); } +/// Default location of the local env file final localEnvFilePathDefault = joinAll(['.local', 'ds_env.yaml']); -final localEnvFilePathDefaultOld = - joinAll(['.dart_tool', 'process_run', 'env.yaml']); diff --git a/packages/process_run/lib/src/utils/hex_utils.dart b/packages/process_run/lib/src/utils/hex_utils.dart index 8cad44f..55b7b06 100644 --- a/packages/process_run/lib/src/utils/hex_utils.dart +++ b/packages/process_run/lib/src/utils/hex_utils.dart @@ -46,7 +46,8 @@ String bytesToHex(List bytes) { return sb.toString(); } -// It safely ignores non hex data so it can contain spaces or line feed +/// Convert a hex string to a list of bytes +/// It safely ignores non hex data so it can contain spaces or line feed List hexToBytes(String text) { final bytes = []; int? firstNibble; diff --git a/packages/process_run/lib/src/webdev.dart b/packages/process_run/lib/src/webdev.dart index 89cbed0..23f5606 100644 --- a/packages/process_run/lib/src/webdev.dart +++ b/packages/process_run/lib/src/webdev.dart @@ -1,5 +1,7 @@ import 'package:process_run/cmd_run.dart'; +/// webdev command class WebDevCmd extends PubGlobalRunCmd { + /// webdev command WebDevCmd(List arguments) : super('webdev', arguments); } diff --git a/packages/process_run/lib/src/which.dart b/packages/process_run/lib/src/which.dart index 74b2246..ecb7459 100644 --- a/packages/process_run/lib/src/which.dart +++ b/packages/process_run/lib/src/which.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:path/path.dart'; import 'package:process_run/src/shell_environment.dart'; +/// Find the command according to the [paths] or env variables (`PATH`) Future which(String command, {@Deprecated('Use environment') Map? env, Map? environment, diff --git a/packages/process_run/test/dartbin_cmd_test.dart b/packages/process_run/test/dartbin_cmd_test.dart index e1033f7..4898660 100644 --- a/packages/process_run/test/dartbin_cmd_test.dart +++ b/packages/process_run/test/dartbin_cmd_test.dart @@ -3,8 +3,6 @@ library process_run.dartbin_cmd_test; import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; -import 'package:process_run/src/bin/shell/import.dart'; -// ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; diff --git a/packages/process_run/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart index 4b4dc3f..b07058b 100644 --- a/packages/process_run/test/shell_common_test.dart +++ b/packages/process_run/test/shell_common_test.dart @@ -211,14 +211,5 @@ void main() { expect(shell.path, 'a/b'); expect(shell.options.workingDirectory, 'a/b'); }); - test('clone', () async { - // ignore: deprecated_member_use_from_same_package - var shell = ShellMock().clone( - workingDirectory: 'a/b', - environment: {}, - includeParentEnvironment: false); - expect(shell.path, 'a/b'); - expect(shell.options.workingDirectory, 'a/b'); - }); }); } diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index 7e1ad01..582e4f2 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -728,10 +728,4 @@ _tekartik_dummy_app_that_does_not_exits expect(shell.path, 'a/b'); expect(shell.options.workingDirectory, 'a/b'); }); - test('clone', () async { - // ignore: deprecated_member_use_from_same_package - var shell = Shell().clone(workingDirectory: 'a/b'); - expect(shell.path, 'a/b'); - expect(shell.options.workingDirectory, 'a/b'); - }); } From f3e831947e966194fd0eb60303832190c5e3595f Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 25 Jul 2024 14:05:26 +0200 Subject: [PATCH 103/150] [process_run] shellLinesGrouper --- .github/dependabot.yml | 7 +- packages/process_run/dart_test.yaml | 1 + .../process_run/lib/src/api/shell_common.dart | 11 +- .../process_run/lib/src/bin/shell/run.dart | 3 +- packages/process_run/lib/src/env_utils.dart | 3 + .../lib/src/io/env_var_set_io.dart | 1 - .../lib/src/lines_utils_common.dart | 2 + .../lib/src/mixin/shell_common.dart | 2 +- .../src/process_result_common_extension.dart | 7 +- .../process_run/lib/src/shell_common.dart | 6 - .../process_run/lib/src/shell_common_io.dart | 3 +- .../lib/src/shell_context_common.dart | 2 + .../process_run/lib/src/shell_context_io.dart | 2 +- .../lib/src/shell_environment_common.dart | 10 +- .../lib/src/stdio/platform/platform_io.dart | 4 +- .../lib/src/stdio/platform/platform_stub.dart | 4 +- .../lib/src/stdio/shell_streamer_io.dart | 50 ++++++--- packages/process_run/lib/src/stdio/stdio.dart | 104 +++++++++++++----- packages/process_run/test/echo_test.dart | 27 ++++- packages/process_run/test/shell_api_test.dart | 34 +++--- .../process_run/test/shell_import_test.dart | 11 ++ .../test/shell_stdio_lines_grouper_test.dart | 2 +- .../process_run/test/src/compile_echo.dart | 4 +- packages/process_run_test/.gitignore | 4 + packages/process_run_test/README.md | 1 + .../process_run_test/analysis_options.yaml | 30 +++++ .../example/raw_stdout_example.dart | 17 +++ .../example/stderr_lines_grouper_example.dart | 18 +++ .../example/stdio_lines_grouper_example.dart | 23 ++++ .../example/stdout_lines_grouper_example.dart | 24 ++++ packages/process_run_test/pubspec.yaml | 19 ++++ 31 files changed, 338 insertions(+), 98 deletions(-) create mode 100644 packages/process_run/test/shell_import_test.dart create mode 100644 packages/process_run_test/.gitignore create mode 100644 packages/process_run_test/README.md create mode 100644 packages/process_run_test/analysis_options.yaml create mode 100644 packages/process_run_test/example/raw_stdout_example.dart create mode 100644 packages/process_run_test/example/stderr_lines_grouper_example.dart create mode 100644 packages/process_run_test/example/stdio_lines_grouper_example.dart create mode 100644 packages/process_run_test/example/stdout_lines_grouper_example.dart create mode 100644 packages/process_run_test/pubspec.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 44fa5c2..313bbaf 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,14 +3,17 @@ version: 2 enable-beta-ecosystems: true + updates: - package-ecosystem: "pub" directory: "packages/process_run" schedule: interval: "monthly" + - package-ecosystem: "pub" + directory: "packages/process_run_test" + schedule: + interval: "monthly" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" - labels: - - autosubmit diff --git a/packages/process_run/dart_test.yaml b/packages/process_run/dart_test.yaml index b3e203d..9ad53d5 100644 --- a/packages/process_run/dart_test.yaml +++ b/packages/process_run/dart_test.yaml @@ -1,4 +1,5 @@ platforms: - vm - node + - chrome concurrency: 1 \ No newline at end of file diff --git a/packages/process_run/lib/src/api/shell_common.dart b/packages/process_run/lib/src/api/shell_common.dart index ce3dd6a..a2a73f5 100644 --- a/packages/process_run/lib/src/api/shell_common.dart +++ b/packages/process_run/lib/src/api/shell_common.dart @@ -5,14 +5,7 @@ export 'package:process_run/src/process_result_common_extension.dart' ProcessRunProcessResultsExt, ProcessRunProcessResultExt, ProcessRunProcessExt; -export 'package:process_run/src/shell_common.dart' - show - Process, - ProcessResult, - ProcessSignal, - ShellOptions, - Shell, - ShellException; +export 'package:process_run/src/shell_common.dart' show ShellOptions; export 'package:process_run/src/shell_environment_common.dart' show shellEnvironment, @@ -22,3 +15,5 @@ export 'package:process_run/src/shell_environment_common.dart' ShellEnvironmentPaths; export 'package:process_run/src/shell_utils_common.dart' show shellArgument, shellArguments; +export 'package:process_run/stdio.dart' + show Process, ProcessResult, ProcessSignal; diff --git a/packages/process_run/lib/src/bin/shell/run.dart b/packages/process_run/lib/src/bin/shell/run.dart index bb99011..d4ef729 100644 --- a/packages/process_run/lib/src/bin/shell/run.dart +++ b/packages/process_run/lib/src/bin/shell/run.dart @@ -9,7 +9,8 @@ class ShellRunCommand extends ShellBinCommand { /// pub run process_run:shell run ShellRunCommand() : super( - name: commandRun, description: 'Run a command using user environment') { + name: commandRun, + description: 'Run a command using user environment') { parser.addFlag(flagInfo, abbr: 'i', help: 'display info', negatable: false); } diff --git a/packages/process_run/lib/src/env_utils.dart b/packages/process_run/lib/src/env_utils.dart index 905cf44..e88a3d6 100644 --- a/packages/process_run/lib/src/env_utils.dart +++ b/packages/process_run/lib/src/env_utils.dart @@ -21,3 +21,6 @@ bool get isDebug => !isRelease; /// Special runtime trick to known whether we are in the javascript world const isRunningAsJavascript = identical(1, 1.0); + +/// Borrowed from flutter (isRunningAsJavascript is false in wasm) +const bool kDartIsWeb = bool.fromEnvironment('dart.library.js_util'); diff --git a/packages/process_run/lib/src/io/env_var_set_io.dart b/packages/process_run/lib/src/io/env_var_set_io.dart index 01fb353..d736234 100644 --- a/packages/process_run/lib/src/io/env_var_set_io.dart +++ b/packages/process_run/lib/src/io/env_var_set_io.dart @@ -5,7 +5,6 @@ import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/common/import.dart'; import 'package:process_run/src/io/env_io.dart'; import 'package:process_run/src/io/io.dart'; -import 'package:process_run/src/shell_common.dart'; /// Helper to set environment variables class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index 28f590b..9891de6 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -155,6 +155,7 @@ Stream shellStreamLines(Stream> stream, addToCurrentLine(data.sublist(start, data.length)); } }, onDone: () { + // devPrint('onDone'); // Last one addCurrentLine(); ctlr.close(); @@ -163,6 +164,7 @@ Stream shellStreamLines(Stream> stream, }); }, onCancel: () { + // devPrint('onCancel'); subscription?.cancel(); }, sync: true); diff --git a/packages/process_run/lib/src/mixin/shell_common.dart b/packages/process_run/lib/src/mixin/shell_common.dart index 7689ec8..b0d56b7 100644 --- a/packages/process_run/lib/src/mixin/shell_common.dart +++ b/packages/process_run/lib/src/mixin/shell_common.dart @@ -1,4 +1,4 @@ -export 'package:process_run/src/shell_common.dart' show Shell; +export 'package:process_run/src/shell.dart' show Shell; export 'package:process_run/src/shell_environment_common.dart' show ShellEnvironmentPaths, diff --git a/packages/process_run/lib/src/process_result_common_extension.dart b/packages/process_run/lib/src/process_result_common_extension.dart index 24d854f..c20b16e 100644 --- a/packages/process_run/lib/src/process_result_common_extension.dart +++ b/packages/process_run/lib/src/process_result_common_extension.dart @@ -1,7 +1,6 @@ import 'dart:convert'; -import 'package:process_run/src/shell_common.dart'; - +import 'bin/shell/import.dart'; import 'lines_utils.dart'; /// run response helper. @@ -44,8 +43,8 @@ extension ProcessRunProcessResultExt on ProcessResult { /// Process helper. extension ProcessRunProcessExt on Process { /// Out lines stream - Stream get outLines => shellStreamLines(stdout); + Stream get outLines => shellStreamLines(this.stdout); /// Err lines stream - Stream get errLines => shellStreamLines(stderr); + Stream get errLines => shellStreamLines(this.stderr); } diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index 8920f59..8869811 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -7,11 +7,6 @@ import 'package:process_run/src/shell_context_common.dart'; import 'io/io_import.dart' show ProcessResult, Process, ProcessSignal; -export 'package:process_run/shell.dart' - show Shell, ShellException, ShellEnvironment; - -export 'io/io_import.dart' show ProcessResult, Process, ProcessSignal; - /// shell debug flag (dev only) var shellDebug = false; // devWarning(true); // false @@ -124,7 +119,6 @@ abstract class ShellCoreSync { /// Shell options. /// - class ShellOptions { final bool _throwOnError; final String? _workingDirectory; diff --git a/packages/process_run/lib/src/shell_common_io.dart b/packages/process_run/lib/src/shell_common_io.dart index 59f931c..934fd90 100644 --- a/packages/process_run/lib/src/shell_common_io.dart +++ b/packages/process_run/lib/src/shell_common_io.dart @@ -1,6 +1,7 @@ import 'package:process_run/shell.dart' as io; import 'package:process_run/src/io/env_var_set_io.dart'; - +import 'package:process_run/src/shell.dart'; +import 'bin/shell/import.dart'; import 'shell_common.dart'; /// Shell implementation using io. diff --git a/packages/process_run/lib/src/shell_context_common.dart b/packages/process_run/lib/src/shell_context_common.dart index 4409917..334e704 100644 --- a/packages/process_run/lib/src/shell_context_common.dart +++ b/packages/process_run/lib/src/shell_context_common.dart @@ -1,7 +1,9 @@ import 'dart:convert'; import 'package:path/path.dart' as p; +import 'package:process_run/src/shell.dart'; import 'package:process_run/src/shell_common.dart'; +import 'package:process_run/src/shell_environment.dart'; /// abstract shell context abstract class ShellContext { diff --git a/packages/process_run/lib/src/shell_context_io.dart b/packages/process_run/lib/src/shell_context_io.dart index b75422d..e0cd5a3 100644 --- a/packages/process_run/lib/src/shell_context_io.dart +++ b/packages/process_run/lib/src/shell_context_io.dart @@ -2,8 +2,8 @@ import 'dart:convert'; import 'package:path/path.dart' as p; import 'package:process_run/shell.dart' as ds; +import 'package:process_run/shell.dart'; import 'package:process_run/src/io/io.dart'; -import 'package:process_run/src/shell_common.dart'; import 'package:process_run/src/shell_common_io.dart'; import 'package:process_run/src/shell_context_common.dart'; import 'package:process_run/src/shell_environment.dart' as io; diff --git a/packages/process_run/lib/src/shell_environment_common.dart b/packages/process_run/lib/src/shell_environment_common.dart index 2d9191f..ee43fc2 100644 --- a/packages/process_run/lib/src/shell_environment_common.dart +++ b/packages/process_run/lib/src/shell_environment_common.dart @@ -1,12 +1,14 @@ import 'dart:collection'; import 'package:collection/collection.dart'; -import 'package:process_run/shell.dart'; +//import 'package:process_run/shell.dart'; import 'package:process_run/src/platform/platform.dart'; -import 'package:process_run/src/shell_utils_common.dart'; +import 'package:process_run/src/shell_environment.dart'; //import 'package:process_run/shell.dart'; //import 'package:process_run/src/common/import.dart'; -//import 'package:process_run/src/shell_utils.dart'; +import 'package:process_run/src/shell_utils.dart'; +import 'package:process_run/src/shell_utils_common.dart'; + export 'package:process_run/shell.dart' show ShellEnvironment; /// Shell environment ordered paths helper. Changes the PATH variable @@ -365,7 +367,7 @@ abstract class ShellEnvironmentCore with MapMixin { /// `paths` and `vars` key Map toJson(); - /* +/* /// Create a new shell environment from the current shellEnvironment. /// /// Defaults create a full parent environment. diff --git a/packages/process_run/lib/src/stdio/platform/platform_io.dart b/packages/process_run/lib/src/stdio/platform/platform_io.dart index ded7ffe..c38a04f 100644 --- a/packages/process_run/lib/src/stdio/platform/platform_io.dart +++ b/packages/process_run/lib/src/stdio/platform/platform_io.dart @@ -2,6 +2,8 @@ import 'package:process_run/src/stdio/shell_streamer_io.dart'; export 'package:process_run/src/platform/platform.dart' show shellContext; +/// Shell streamer platform implementation. class ShellOutputLinesStreamerPlatform extends ShellOutputLinesStreamerIo { - ShellOutputLinesStreamerPlatform({super.current, super.stdout, super.stderr}); + /// Shell streamer platform implementation. + ShellOutputLinesStreamerPlatform({super.stdout, super.stderr}); } diff --git a/packages/process_run/lib/src/stdio/platform/platform_stub.dart b/packages/process_run/lib/src/stdio/platform/platform_stub.dart index 68f1728..cd2359c 100644 --- a/packages/process_run/lib/src/stdio/platform/platform_stub.dart +++ b/packages/process_run/lib/src/stdio/platform/platform_stub.dart @@ -1,5 +1,7 @@ import 'package:process_run/src/stdio/stdio.dart'; +/// Shell streamer platform implementation. class ShellOutputLinesStreamerPlatform extends ShellOutputLinesStreamerMemory { - ShellOutputLinesStreamerPlatform({super.current, super.stdout, super.stderr}); + /// Shell streamer platform implementation. + ShellOutputLinesStreamerPlatform({super.stdout, super.stderr}); } diff --git a/packages/process_run/lib/src/stdio/shell_streamer_io.dart b/packages/process_run/lib/src/stdio/shell_streamer_io.dart index e617cc0..2da8d9c 100644 --- a/packages/process_run/lib/src/stdio/shell_streamer_io.dart +++ b/packages/process_run/lib/src/stdio/shell_streamer_io.dart @@ -6,30 +6,44 @@ import 'package:process_run/src/stdio/stdio.dart'; class ShellOutputLinesStreamerIo with ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { - late final io.IOSink stdout; - late final io.IOSink stderr; + /// stdout. + late final io.IOSink _stdout; + + /// stderr. + late final io.IOSink _stderr; + + /// Log an info message. void log(String message) { if (current) { - stdout.writeln(message); + _stdout.writeln(message); } else { lines.add(StdioStreamLine(StdioStreamType.out, message)); } } + @override + set current(bool current) { + if (this.current != current) { + super.current = current; + if (current == true) { + _dumpExisting(); + } + } + } + + /// Log an error message. void error(String message) { if (current) { - stderr.writeln(message); + _stderr.writeln(message); } else { lines.add(StdioStreamLine(StdioStreamType.err, message)); } } /// Stdio streamer.could become true at any moment! - ShellOutputLinesStreamerIo( - {bool? current = false, io.IOSink? stdout, io.IOSink? stderr}) { - this.stdout = stdout ?? io.ioStdout; - this.stderr = stderr ?? io.ioStderr; - this.current = current; + ShellOutputLinesStreamerIo({io.IOSink? stdout, io.IOSink? stderr}) { + _stdout = stdout ?? io.ioStdout; + _stderr = stderr ?? io.ioStderr; outController.stream.listen((line) { log(line); }); @@ -38,18 +52,22 @@ class ShellOutputLinesStreamerIo }); } + void _dumpExisting() { + for (var line in lines) { + if (line.type == StdioStreamType.out) { + _stdout.writeln(line.line); + } else { + _stderr.writeln(line.line); + } + } + } + /// Close. @override void close() { mixinDispose(); if (!current) { - for (var line in lines) { - if (line.type == StdioStreamType.out) { - stdout.writeln(line.line); - } else { - stderr.writeln(line.line); - } - } + _dumpExisting(); } } } diff --git a/packages/process_run/lib/src/stdio/stdio.dart b/packages/process_run/lib/src/stdio/stdio.dart index 7ac048e..db3c84d 100644 --- a/packages/process_run/lib/src/stdio/stdio.dart +++ b/packages/process_run/lib/src/stdio/stdio.dart @@ -8,13 +8,19 @@ import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/io/io.dart' as io; import 'package:process_run/src/stdio/platform/platform.dart'; +/// In memory implementation of [IOSink] class InMemoryIOSink with IOSinkMixin implements IOSink { @override final StdioStreamType type; + /// Data var data = >[]; + + /// Lines Iterable get lines => LineSplitter.split(encoding.decode(data.expand((e) => e).toList())); + + /// In memory implementation of [IOSink] InMemoryIOSink(this.type); @override @@ -26,10 +32,17 @@ class InMemoryIOSink with IOSinkMixin implements IOSink { String toString() => 'InMemoryIOSink($type)'; } +/// Mixin for [IOSink] mixin IOSinkMixin implements IOSink { bool get _isErr => type == StdioStreamType.err; + + /// Delegate late final IOSink ioSinkDelegate = _isErr ? ioStderr : ioStdout; + + /// sink type StdioStreamType get type; + + /// io sink IOSink get ioSink => ioSinkDelegate; @override Encoding get encoding => ioSink.encoding; @@ -87,32 +100,41 @@ mixin IOSinkMixin implements IOSink { } } +/// Shell stdio lines grouper implementation of [IOSink] class ShellStdioLinesGrouperIOSink with IOSinkMixin implements IOSink { + /// grouper final ShellStdioLinesGrouper grouper; @override final StdioStreamType type; @override late final IOSink ioSink; + + /// Shell stdio lines grouper implementation of [IOSink] ShellStdioLinesGrouperIOSink(this.grouper, this.type, {IOSink? ioSink}) { this.ioSink = ioSink ?? super.ioSink; } @override void add(core.List data) { - var currentZoneId = _shellStdioLinesGrouper.currentZoneId; - var zoneId = _shellStdioLinesGrouper.zoneId; + var zoneId = grouper.zoneId; + var currentZoneId = grouper.currentZoneId ??= zoneId; var isCurrent = currentZoneId == zoneId; - var streamer = _shellStdioLinesGrouper.streamers[zoneId] ??= - ShellOutputLinesStreamer( - current: isCurrent, stdout: grouper.stdout, stderr: grouper.stderr); + var streamer = grouper.streamers[zoneId] ??= ShellOutputLinesStreamer( + current: isCurrent, stdout: grouper.stdout, stderr: grouper.stderr); + streamer.current = isCurrent; // devPrint('[$zoneId/$currentZoneId] Adding data ${encoding.decode(data).trim()}'); var sink = _isErr ? streamer.err : streamer.out; sink.add(data); } } +/// Global zone id. +int _zoneId = 0; +int _nextZoneId() => ++_zoneId; +int _inZoneCount = 0; + /// Group in zones. class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { /// Overriden mainly for testing. @@ -120,9 +142,14 @@ class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { /// Overriden mainly for testing. final IOSink? stderr; + + /// Current zone id int? currentZoneId; + + /// Streamers final streamers = {}; + /// Group in zones. ShellStdioLinesGrouper({this.stdout, this.stderr}); @override @@ -135,6 +162,10 @@ class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { } final _shellStdioLinesGrouper = ShellStdioLinesGrouper(); + +/// Shell stdio lines grouper. +/// +/// Use runZoned to group Shell and stdio output and error ShellStdio get shellStdioLinesGrouper => _shellStdioLinesGrouper; const _stdio = #tekartik_shell_stdio; @@ -149,31 +180,44 @@ abstract class ShellStdio { IOSink get err; } +/// Shell stdio mixin. mixin ShellStdioMixin implements ShellStdio {} -int _zoneId = 0; -int _nextZoneId() => ++_zoneId; -int _inZoneCount = 0; - +/// Shell stdio extension. extension ShellStdioExt on ShellStdio { + /// Run in a zone, grouping lines Future runZoned(Future Function() action) async { var zoneId = _nextZoneId(); try { _inZoneCount++; - return await async - .runZoned(action, zoneValues: {_stdio: this, _id: zoneId}); + return await async.runZoned(() async { + try { + return await action(); + } finally { + //devPrint('[$zoneId] Closing streamer'); + var streamer = self.streamers[zoneId]; + // devPrint('[$zoneId] Closing streamer $streamer'); + if (streamer != null) { + await Future.value(); + // await streamer.done; handing + streamer.close(); + } + if (self.currentZoneId == zoneId) { + self.currentZoneId = null; + } + } + }, zoneValues: {_stdio: this, _id: zoneId}); } finally { _inZoneCount--; - var streamer = _shellStdioLinesGrouper.streamers[zoneId]; - if (streamer != null) { - await Future.value(); // await streamer.done; - streamer.close(); - } } } } +/// Shell stdio extension private. extension ShellStdioExtPrv on ShellStdio { + /// Casted to private implementation. + ShellStdioLinesGrouper get self => this as ShellStdioLinesGrouper; + /// Only valid in a zone. int get zoneId => Zone.current[_id] as int; } @@ -203,15 +247,13 @@ class StdioStreamLine { StdioStreamLine(this.type, this.line); } +/// Memory implementation of [ShellOutputLinesStreamer] class ShellOutputLinesStreamerMemory with ShellOutputLinesStreamerMixin { - //late final io.IOSink stdout; - //late final io.IOSink stderr; - ShellOutputLinesStreamerMemory( - {bool? current = false, io.IOSink? stdout, io.IOSink? stderr}) { - this.current = current; - } + /// Memory implementation of [ShellOutputLinesStreamer] + ShellOutputLinesStreamerMemory({io.IOSink? stdout, io.IOSink? stderr}); } +/// Mixin for [ShellOutputLinesStreamer] mixin ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { @override StreamSink> get out => outController.sink; @@ -220,11 +262,13 @@ mixin ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { StreamSink> get err => errController.sink; /// Current. - bool get current => _current ?? false; + @override + bool get current => _current; - bool? _current; + var _current = false; - set current(bool? current) { + @override + set current(bool current) { _current = current; } @@ -237,6 +281,7 @@ mixin ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { /// Err. final errController = ShellLinesController(); + /// Dispose. void mixinDispose() { outController.close(); errController.close(); @@ -264,10 +309,15 @@ abstract class ShellOutputLinesStreamer { /// default is io version. factory ShellOutputLinesStreamer( {bool? current = false, io.IOSink? stdout, io.IOSink? stderr}) { - return ShellOutputLinesStreamerPlatform( - current: current, stdout: stdout, stderr: stderr); + return ShellOutputLinesStreamerPlatform(stdout: stdout, stderr: stderr); } + /// Get the current state. + bool get current; + + /// Set the current state. + set current(bool current); + /// Wait for the streamer to be done. Future get done; diff --git a/packages/process_run/test/echo_test.dart b/packages/process_run/test/echo_test.dart index 863693e..cfd4b7c 100644 --- a/packages/process_run/test/echo_test.dart +++ b/packages/process_run/test/echo_test.dart @@ -71,6 +71,13 @@ void main() { expect(result.exitCode, 0); } + void checkOutWriteLine(ProcessResult result) { + expect(result.stderr, ''); + expect(result.stdout, 'out\n'); + expect(result.pid, isNotNull); + expect(result.exitCode, 0); + } + void checkEmpty(ProcessResult result) { expect(result.stderr, ''); expect(result.stdout, ''); @@ -81,6 +88,8 @@ void main() { await runCheck( checkOut, dartExecutable!, [echoScriptPath, '--stdout', 'out']); await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); + await runCheck(checkOutWriteLine, dartExecutable!, + [echoScriptPath, '--stdout', 'out', '--write-line']); }); test('stdout_bin', () async { @@ -135,6 +144,13 @@ void main() { expect(result.exitCode, 0); } + void checkErrWriteLine(ProcessResult result) { + expect(result.stderr, 'err\n'); + expect(result.stdout, ''); + expect(result.pid, isNotNull); + expect(result.exitCode, 0); + } + void checkEmpty(ProcessResult result) { expect(result.stderr, ''); expect(result.stdout, ''); @@ -143,8 +159,15 @@ void main() { } await runCheck( - checkErr, dartExecutable!, [echoScriptPath, '--stderr', 'err'], - stdout: stdout); + checkErr, + dartExecutable!, + [echoScriptPath, '--stderr', 'err'], + ); + await runCheck( + checkErrWriteLine, + dartExecutable!, + [echoScriptPath, '--stderr', 'err', '--write-line'], + ); await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); }); diff --git a/packages/process_run/test/shell_api_test.dart b/packages/process_run/test/shell_api_test.dart index 9dfd5a4..f219ded 100644 --- a/packages/process_run/test/shell_api_test.dart +++ b/packages/process_run/test/shell_api_test.dart @@ -1,37 +1,35 @@ -@TestOn('vm') -library process_run.test.shell_api_test; - import 'package:process_run/shell.dart'; +import 'package:process_run/src/env_utils.dart' show kDartIsWeb; import 'package:test/test.dart'; void main() { group('shell_api_test', () { test('public', () { // ignore_for_file: unnecessary_statements - sharedStdIn; - dartVersion; - dartChannel; - dartExecutable; + if (!kDartIsWeb) { + sharedStdIn; + dartVersion; + dartChannel; + dartExecutable; - userHomePath; - userAppDataPath; + userHomePath; + userAppDataPath; + shellEnvironment; + platformEnvironment; + userPaths; + userEnvironment; + isFlutterSupportedSync; + isFlutterSupported; + } shellArgument; - shellEnvironment; - platformEnvironment; shellArguments; shellExecutableArguments; - userPaths; - userEnvironment; userLoadEnvFile; userLoadEnv; - getFlutterBinVersion; getFlutterBinChannel; - isFlutterSupported; - isFlutterSupportedSync; ShellLinesController; shellStreamLines; - promptConfirm; promptTerminate; prompt; @@ -51,12 +49,10 @@ void main() { ProcessRunProcessResultsExt(null)?.outText; ProcessRunProcessResultExt(null)?.outText; ProcessRunProcessExt(null)?.outLines; - // process_cmd ProcessCmd; processResultToDebugString; processCmdToDebugString; - // shell_utils stringToArguments; }); diff --git a/packages/process_run/test/shell_import_test.dart b/packages/process_run/test/shell_import_test.dart new file mode 100644 index 0000000..e85af85 --- /dev/null +++ b/packages/process_run/test/shell_import_test.dart @@ -0,0 +1,11 @@ +import 'package:process_run/shell.dart'; +import 'package:test/test.dart'; + +void main() { + group('Shell import', () { + test('public', () { + // ignore: unnecessary_statements + ShellOptions; + }); + }); +} diff --git a/packages/process_run/test/shell_stdio_lines_grouper_test.dart b/packages/process_run/test/shell_stdio_lines_grouper_test.dart index 108f971..1cbc1f2 100644 --- a/packages/process_run/test/shell_stdio_lines_grouper_test.dart +++ b/packages/process_run/test/shell_stdio_lines_grouper_test.dart @@ -2,8 +2,8 @@ library; import 'package:process_run/process_run.dart'; +import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/stdio/stdio.dart'; -import 'package:process_run/stdio.dart'; import 'package:test/test.dart'; import 'src/compile_echo.dart'; diff --git a/packages/process_run/test/src/compile_echo.dart b/packages/process_run/test/src/compile_echo.dart index 6b8f873..1a9736a 100644 --- a/packages/process_run/test/src/compile_echo.dart +++ b/packages/process_run/test/src/compile_echo.dart @@ -4,14 +4,14 @@ import 'package:path/path.dart'; import 'package:process_run/shell.dart'; /// Return the executable path. -Future compileEchoExample() async { +Future compileEchoExample({bool force = false}) async { var folder = Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); var exeExtension = Platform.isWindows ? '.exe' : ''; var echoExePath = join('build', folder, 'process_run_echo$exeExtension'); var echoExeDir = dirname(echoExePath); var shell = Shell(verbose: false); - if (!File(echoExePath).existsSync()) { + if (!File(echoExePath).existsSync() || force) { Directory(echoExeDir).createSync(recursive: true); await shell.run( 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o ${shellArgument(echoExePath)}'); diff --git a/packages/process_run_test/.gitignore b/packages/process_run_test/.gitignore new file mode 100644 index 0000000..790fe65 --- /dev/null +++ b/packages/process_run_test/.gitignore @@ -0,0 +1,4 @@ +# https://dart.dev/guides/libraries/private-files +# Created by `dart pub` +.dart_tool/ +/pubspec.lock diff --git a/packages/process_run_test/README.md b/packages/process_run_test/README.md new file mode 100644 index 0000000..c2bc24d --- /dev/null +++ b/packages/process_run_test/README.md @@ -0,0 +1 @@ +# Process run tests diff --git a/packages/process_run_test/analysis_options.yaml b/packages/process_run_test/analysis_options.yaml new file mode 100644 index 0000000..dee8927 --- /dev/null +++ b/packages/process_run_test/analysis_options.yaml @@ -0,0 +1,30 @@ +# This file configures the static analysis results for your project (errors, +# warnings, and lints). +# +# This enables the 'recommended' set of lints from `package:lints`. +# This set helps identify many issues that may lead to problems when running +# or consuming Dart code, and enforces writing Dart using a single, idiomatic +# style and format. +# +# If you want a smaller set of lints you can change this to specify +# 'package:lints/core.yaml'. These are just the most critical lints +# (the recommended set includes the core lints). +# The core lints are also what is used by pub.dev for scoring packages. + +include: package:lints/recommended.yaml + +# Uncomment the following section to specify additional rules. + +# linter: +# rules: +# - camel_case_types + +# analyzer: +# exclude: +# - path/to/excluded/files/** + +# For more information about the core and recommended set of lints, see +# https://dart.dev/go/core-lints + +# For additional information about configuring this file, see +# https://dart.dev/guides/language/analysis-options diff --git a/packages/process_run_test/example/raw_stdout_example.dart b/packages/process_run_test/example/raw_stdout_example.dart new file mode 100644 index 0000000..031164e --- /dev/null +++ b/packages/process_run_test/example/raw_stdout_example.dart @@ -0,0 +1,17 @@ +import 'dart:io'; + +void writeCount(int count) { + stdout.writeln('Counting to $count'); + for (var i = 0; i < count; i++) { + if (i.isEven) { + stderr.writeln('Error: ${i + 1}'); + } else { + stdout.writeln('Info: ${i + 1}'); + } + } +} + +Future main() async { + writeCount(2); + writeCount(10); +} diff --git a/packages/process_run_test/example/stderr_lines_grouper_example.dart b/packages/process_run_test/example/stderr_lines_grouper_example.dart new file mode 100644 index 0000000..fb27688 --- /dev/null +++ b/packages/process_run_test/example/stderr_lines_grouper_example.dart @@ -0,0 +1,18 @@ +import 'package:process_run/stdio.dart'; + +Future writeCount(int count) async { + stderr.writeln('Counting to $count'); + for (var i = 0; i < count; i++) { + stderr.writeln('${i + 1}'); + await Future.delayed(Duration(milliseconds: 500)); + } +} + +Future main() async { + shellStdioLinesGrouper.runZoned(() async { + await writeCount(2); + }); + shellStdioLinesGrouper.runZoned(() async { + await writeCount(10); + }); +} diff --git a/packages/process_run_test/example/stdio_lines_grouper_example.dart b/packages/process_run_test/example/stdio_lines_grouper_example.dart new file mode 100644 index 0000000..7c87168 --- /dev/null +++ b/packages/process_run_test/example/stdio_lines_grouper_example.dart @@ -0,0 +1,23 @@ +import 'package:process_run/stdio.dart'; + +Future writeCount(int count) async { + stdout.writeln('Counting to $count'); + for (var i = 0; i < count; i++) { + if (i.isEven) { + stderr.writeln('Error: ${i + 1}'); + } else { + stdout.writeln('Info: ${i + 1}'); + } + await Future.delayed(Duration(milliseconds: 500)); + } +} + +Future main() async { + shellStdioLinesGrouper.runZoned(() async { + await writeCount(4); + }); + + shellStdioLinesGrouper.runZoned(() async { + await writeCount(10); + }); +} diff --git a/packages/process_run_test/example/stdout_lines_grouper_example.dart b/packages/process_run_test/example/stdout_lines_grouper_example.dart new file mode 100644 index 0000000..8c95557 --- /dev/null +++ b/packages/process_run_test/example/stdout_lines_grouper_example.dart @@ -0,0 +1,24 @@ +import 'package:process_run/stdio.dart'; + +Future writeCount(int count) async { + stdout.writeln('Counting to $count'); + for (var i = 0; i < count; i++) { + stdout.writeln('${i + 1}'); + await Future.delayed(Duration(milliseconds: 500)); + } +} + +Future main() async { + shellStdioLinesGrouper.runZoned(() async { + await writeCount(2); + }); + shellStdioLinesGrouper.runZoned(() async { + await writeCount(1); + }); + shellStdioLinesGrouper.runZoned(() async { + await writeCount(3); + }); + shellStdioLinesGrouper.runZoned(() async { + await writeCount(10); + }); +} diff --git a/packages/process_run_test/pubspec.yaml b/packages/process_run_test/pubspec.yaml new file mode 100644 index 0000000..511105c --- /dev/null +++ b/packages/process_run_test/pubspec.yaml @@ -0,0 +1,19 @@ +name: process_run_test +description: Process run example and tests +version: 1.0.0 +publish_to: none + +environment: + sdk: ^3.4.4 + +# Add regular dependencies here. +dependencies: + process_run: '>=1.0.0+3' + +dev_dependencies: + lints: '>=4.0.0' + test: '>=1.24.0' + +dependency_overrides: + process_run: + path: ../process_run \ No newline at end of file From 87497873c968e3f49d91f6aa15c4629dc21620ad Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 25 Jul 2024 14:08:58 +0200 Subject: [PATCH 104/150] [process_run] v1.0.1 --- packages/process_run/CHANGELOG.md | 4 ++++ .../process_run/lib/src/bin/shell/shell_bin_command.dart | 1 - packages/process_run/lib/src/dev_cmd_run.dart | 3 +-- packages/process_run/lib/src/shell_context_common.dart | 7 +++---- packages/process_run/lib/src/version.dart | 2 +- packages/process_run/lib/src/which.dart | 9 ++------- packages/process_run/pubspec.yaml | 2 +- 7 files changed, 12 insertions(+), 16 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index fd26cc7..ef92fbc 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.1 + +* Remove deprecated methods + ## 1.0.0+3 * add `ShellStdio` and `shellStdioLinesGrouper` to allow grouping stdout and stderr lines by zones. diff --git a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart index d4b5420..97979ba 100644 --- a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart +++ b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart @@ -99,7 +99,6 @@ class ShellBinCommand { Version? version, ArgParser? parser, ShellBinCommand? parent, - @Deprecated('Do no user') FutureOr Function()? onRun, String? description}) { _onRun = onRun; _parser = parser; diff --git a/packages/process_run/lib/src/dev_cmd_run.dart b/packages/process_run/lib/src/dev_cmd_run.dart index 90d31cd..89f4430 100644 --- a/packages/process_run/lib/src/dev_cmd_run.dart +++ b/packages/process_run/lib/src/dev_cmd_run.dart @@ -3,9 +3,8 @@ import 'dart:async'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/src/io/io.dart'; -@Deprecated('Deb only, verbose') - /// dev only run command +@Deprecated('Dev only, verbose') Future devRunCmd(ProcessCmd cmd, {bool? verbose, bool? commandVerbose, diff --git a/packages/process_run/lib/src/shell_context_common.dart b/packages/process_run/lib/src/shell_context_common.dart index 334e704..e04ad65 100644 --- a/packages/process_run/lib/src/shell_context_common.dart +++ b/packages/process_run/lib/src/shell_context_common.dart @@ -22,10 +22,9 @@ abstract class ShellContext { /// New shell must set itself as a shell Context, shell environement is /// no longer relevent. - Shell newShell( - {ShellOptions? options, - @Deprecated('Use options') Map? environment, - @Deprecated('Use options') bool includeParentEnvironment = true}); + Shell newShell({ + ShellOptions? options, + }); /// New shell environment ShellEnvironment newShellEnvironment({ diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index a1cb014..92a0d66 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '1.0.0+3'; +const packageVersion = '1.0.1'; diff --git a/packages/process_run/lib/src/which.dart b/packages/process_run/lib/src/which.dart index ecb7459..dc74909 100644 --- a/packages/process_run/lib/src/which.dart +++ b/packages/process_run/lib/src/which.dart @@ -5,21 +5,16 @@ import 'package:process_run/src/shell_environment.dart'; /// Find the command according to the [paths] or env variables (`PATH`) Future which(String command, - {@Deprecated('Use environment') Map? env, - Map? environment, + {Map? environment, bool includeParentEnvironment = true}) async { return whichSync(command, - // ignore: deprecated_member_use, deprecated_member_use_from_same_package - env: env, environment: environment, includeParentEnvironment: includeParentEnvironment); } /// Find the command according to the [paths] or env variables (`PATH`) String? whichSync(String command, - {@Deprecated('Use environment') Map? env, - Map? environment, - bool includeParentEnvironment = true}) { + {Map? environment, bool includeParentEnvironment = true}) { // only valid for single commands if (basename(command) != command) { return null; diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 43ee791..668592c 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.0.0+3 +version: 1.0.1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 8af392d6a0ae3d72062ae9e8228d4ee79c79f020 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 25 Jul 2024 15:28:17 +0200 Subject: [PATCH 105/150] [process_run] fix lines grouper ordering --- .../lib/src/stdio/shell_streamer_io.dart | 9 +- packages/process_run/lib/src/stdio/stdio.dart | 95 ++++++++++++------- .../src/shell_output_lines_streamer_test.dart | 2 + ...art => stdout_lines_grouper_example1.dart} | 5 +- .../stdout_lines_grouper_example2.dart | 20 ++++ 5 files changed, 89 insertions(+), 42 deletions(-) rename packages/process_run_test/example/{stdout_lines_grouper_example.dart => stdout_lines_grouper_example1.dart} (83%) create mode 100644 packages/process_run_test/example/stdout_lines_grouper_example2.dart diff --git a/packages/process_run/lib/src/stdio/shell_streamer_io.dart b/packages/process_run/lib/src/stdio/shell_streamer_io.dart index 2da8d9c..a8bb8bc 100644 --- a/packages/process_run/lib/src/stdio/shell_streamer_io.dart +++ b/packages/process_run/lib/src/stdio/shell_streamer_io.dart @@ -26,7 +26,7 @@ class ShellOutputLinesStreamerIo if (this.current != current) { super.current = current; if (current == true) { - _dumpExisting(); + dump(); } } } @@ -52,7 +52,9 @@ class ShellOutputLinesStreamerIo }); } - void _dumpExisting() { + // No effect by default (in memory), overriden on io. + @override + void dump() { for (var line in lines) { if (line.type == StdioStreamType.out) { _stdout.writeln(line.line); @@ -66,8 +68,5 @@ class ShellOutputLinesStreamerIo @override void close() { mixinDispose(); - if (!current) { - _dumpExisting(); - } } } diff --git a/packages/process_run/lib/src/stdio/stdio.dart b/packages/process_run/lib/src/stdio/stdio.dart index db3c84d..53cf068 100644 --- a/packages/process_run/lib/src/stdio/stdio.dart +++ b/packages/process_run/lib/src/stdio/stdio.dart @@ -8,6 +8,10 @@ import 'package:process_run/src/bin/shell/import.dart'; import 'package:process_run/src/io/io.dart' as io; import 'package:process_run/src/stdio/platform/platform.dart'; +// var _debugLinesGrouper = devWarning(true); +const _debugLinesGrouper = false; +var _log = print; + /// In memory implementation of [IOSink] class InMemoryIOSink with IOSinkMixin implements IOSink { @override @@ -117,13 +121,8 @@ class ShellStdioLinesGrouperIOSink with IOSinkMixin implements IOSink { @override void add(core.List data) { var zoneId = grouper.zoneId; - var currentZoneId = grouper.currentZoneId ??= zoneId; - - var isCurrent = currentZoneId == zoneId; - var streamer = grouper.streamers[zoneId] ??= ShellOutputLinesStreamer( - current: isCurrent, stdout: grouper.stdout, stderr: grouper.stderr); - streamer.current = isCurrent; + stdout: grouper.stdout, stderr: grouper.stderr); // devPrint('[$zoneId/$currentZoneId] Adding data ${encoding.decode(data).trim()}'); var sink = _isErr ? streamer.err : streamer.out; sink.add(data); @@ -149,6 +148,9 @@ class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { /// Streamers final streamers = {}; + /// Ordered streamer ids + final streamerZoneIds = []; + /// Group in zones. ShellStdioLinesGrouper({this.stdout, this.stderr}); @@ -159,6 +161,50 @@ class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { @override late final err = ShellStdioLinesGrouperIOSink(this, StdioStreamType.err, ioSink: stderr); + + void _setCurrent() { + if (_debugLinesGrouper) { + _log('_setCurrent $currentZoneId $streamerZoneIds'); + } + if (currentZoneId == null) { + var firstZoneId = streamerZoneIds.firstOrNull; + if (firstZoneId != null) { + streamers[firstZoneId]?.current = true; + currentZoneId = firstZoneId; + if (_debugLinesGrouper) { + _log('_setCurrent new $currentZoneId'); + } + } + } + } + + /// Run in a zone, grouping lines + Future _runZonedImpl(Future Function() action) async { + var zoneId = _nextZoneId(); + streamers[zoneId] = + ShellOutputLinesStreamer(stdout: stdout, stderr: stderr); + streamerZoneIds.add(zoneId); + _setCurrent(); + + try { + _inZoneCount++; + return await async.runZoned(() async { + try { + return await action(); + } finally { + var streamer = streamers[zoneId]; + streamer?.close(); + if (currentZoneId == zoneId) { + streamerZoneIds.remove(zoneId); + currentZoneId = null; + } + _setCurrent(); + } + }, zoneValues: {_stdio: this, _id: zoneId}); + } finally { + _inZoneCount--; + } + } } final _shellStdioLinesGrouper = ShellStdioLinesGrouper(); @@ -186,31 +232,8 @@ mixin ShellStdioMixin implements ShellStdio {} /// Shell stdio extension. extension ShellStdioExt on ShellStdio { /// Run in a zone, grouping lines - Future runZoned(Future Function() action) async { - var zoneId = _nextZoneId(); - try { - _inZoneCount++; - return await async.runZoned(() async { - try { - return await action(); - } finally { - //devPrint('[$zoneId] Closing streamer'); - var streamer = self.streamers[zoneId]; - // devPrint('[$zoneId] Closing streamer $streamer'); - if (streamer != null) { - await Future.value(); - // await streamer.done; handing - streamer.close(); - } - if (self.currentZoneId == zoneId) { - self.currentZoneId = null; - } - } - }, zoneValues: {_stdio: this, _id: zoneId}); - } finally { - _inZoneCount--; - } - } + Future runZoned(Future Function() action) => + self._runZonedImpl(action); } /// Shell stdio extension private. @@ -251,6 +274,10 @@ class StdioStreamLine { class ShellOutputLinesStreamerMemory with ShellOutputLinesStreamerMixin { /// Memory implementation of [ShellOutputLinesStreamer] ShellOutputLinesStreamerMemory({io.IOSink? stdout, io.IOSink? stderr}); + + // No effect by default (in memory), overriden on io. + @override + void dump() {} } /// Mixin for [ShellOutputLinesStreamer] @@ -307,8 +334,7 @@ abstract class ShellOutputLinesStreamer { StreamSink> get err; /// default is io version. - factory ShellOutputLinesStreamer( - {bool? current = false, io.IOSink? stdout, io.IOSink? stderr}) { + factory ShellOutputLinesStreamer({io.IOSink? stdout, io.IOSink? stderr}) { return ShellOutputLinesStreamerPlatform(stdout: stdout, stderr: stderr); } @@ -321,6 +347,9 @@ abstract class ShellOutputLinesStreamer { /// Wait for the streamer to be done. Future get done; + /// Dump existing lines. + void dump(); + /// Close the streamer. void close(); } diff --git a/packages/process_run/test/src/shell_output_lines_streamer_test.dart b/packages/process_run/test/src/shell_output_lines_streamer_test.dart index cd4fafb..b6c14b2 100644 --- a/packages/process_run/test/src/shell_output_lines_streamer_test.dart +++ b/packages/process_run/test/src/shell_output_lines_streamer_test.dart @@ -10,7 +10,9 @@ void main() { var shellStreamer = ShellOutputLinesStreamer(); shellStreamer.out.add(utf8.encode('hi')); shellStreamer.err.add(utf8.encode('error')); + shellStreamer.out.add(utf8.encode('ho')); + shellStreamer.dump(); shellStreamer.close(); }); }); diff --git a/packages/process_run_test/example/stdout_lines_grouper_example.dart b/packages/process_run_test/example/stdout_lines_grouper_example1.dart similarity index 83% rename from packages/process_run_test/example/stdout_lines_grouper_example.dart rename to packages/process_run_test/example/stdout_lines_grouper_example1.dart index 8c95557..4032514 100644 --- a/packages/process_run_test/example/stdout_lines_grouper_example.dart +++ b/packages/process_run_test/example/stdout_lines_grouper_example1.dart @@ -13,10 +13,7 @@ Future main() async { await writeCount(2); }); shellStdioLinesGrouper.runZoned(() async { - await writeCount(1); - }); - shellStdioLinesGrouper.runZoned(() async { - await writeCount(3); + await writeCount(5); }); shellStdioLinesGrouper.runZoned(() async { await writeCount(10); diff --git a/packages/process_run_test/example/stdout_lines_grouper_example2.dart b/packages/process_run_test/example/stdout_lines_grouper_example2.dart new file mode 100644 index 0000000..b6592df --- /dev/null +++ b/packages/process_run_test/example/stdout_lines_grouper_example2.dart @@ -0,0 +1,20 @@ +import 'package:process_run/stdio.dart'; + +Future writeCount(int count) async { + stdout.writeln('Counting to $count'); + for (var i = 0; i < count; i++) { + stdout.writeln('${i + 1}'); + await Future.delayed(Duration(milliseconds: 500)); + } +} + +Future main() async { + shellStdioLinesGrouper.runZoned(() async { + await Future.delayed(Duration(milliseconds: 500)); + await writeCount(2); + }); + shellStdioLinesGrouper.runZoned(() async { + await Future.delayed(Duration(milliseconds: 250)); + await writeCount(1); + }); +} From bdf756b36c00a27c89d22162358a5acbf3181c56 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 25 Jul 2024 16:00:53 +0200 Subject: [PATCH 106/150] [process_run] fix lines grouper ordering --- packages/process_run/CHANGELOG.md | 2 +- .../lib/src/lines_utils_common.dart | 3 ++ packages/process_run/lib/src/stdio/stdio.dart | 50 +++++++++++++------ packages/process_run/pubspec.yaml | 4 +- .../test/shell_stdio_lines_grouper_test.dart | 42 ++++++++++++++++ .../stdout_lines_grouper_example1.dart | 1 + .../stdout_lines_grouper_example2.dart | 1 + .../stdout_lines_grouper_example3.dart | 24 +++++++++ 8 files changed, 110 insertions(+), 17 deletions(-) create mode 100644 packages/process_run_test/example/stdout_lines_grouper_example3.dart diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index ef92fbc..e5ddefe 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.1 +## 1.0.1+1 * Remove deprecated methods diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index 9891de6..d101df8 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -53,6 +53,9 @@ class ShellLinesController { Stream get stream => shellStreamLines(_controller.stream, encoding: encoding); + /// True if the controller is closed. + bool get isClosed => _controller.isClosed; + /// Dispose the controller. void close() { _controller.close(); diff --git a/packages/process_run/lib/src/stdio/stdio.dart b/packages/process_run/lib/src/stdio/stdio.dart index 53cf068..0c3d55a 100644 --- a/packages/process_run/lib/src/stdio/stdio.dart +++ b/packages/process_run/lib/src/stdio/stdio.dart @@ -166,15 +166,34 @@ class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { if (_debugLinesGrouper) { _log('_setCurrent $currentZoneId $streamerZoneIds'); } - if (currentZoneId == null) { - var firstZoneId = streamerZoneIds.firstOrNull; - if (firstZoneId != null) { - streamers[firstZoneId]?.current = true; - currentZoneId = firstZoneId; - if (_debugLinesGrouper) { - _log('_setCurrent new $currentZoneId'); - } + while (true) { + var nextZoneId = streamerZoneIds.firstOrNull; + var zoneId = currentZoneId ?? nextZoneId; + if (zoneId == null) { + break; + } + var streamer = streamers[zoneId]!; + streamer.current = true; + if (_debugLinesGrouper) { + _log('_setCurrent new $zoneId'); + } + if (streamer.isClosed) { + streamerZoneIds.remove(zoneId); + streamers.remove(zoneId); + } else { + break; } + /* + if (currentZoneId == null) { + var firstZoneId = streamerZoneIds.firstOrNull; + if (firstZoneId != null) { + streamers[firstZoneId]?.current = true; + currentZoneId = firstZoneId; + if (_debugLinesGrouper) { + _log('_setCurrent new $currentZoneId'); + } + } + }*/ } } @@ -192,12 +211,8 @@ class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { try { return await action(); } finally { - var streamer = streamers[zoneId]; - streamer?.close(); - if (currentZoneId == zoneId) { - streamerZoneIds.remove(zoneId); - currentZoneId = null; - } + var streamer = streamers[zoneId]!; + streamer.close(); _setCurrent(); } }, zoneValues: {_stdio: this, _id: zoneId}); @@ -308,6 +323,10 @@ mixin ShellOutputLinesStreamerMixin implements ShellOutputLinesStreamer { /// Err. final errController = ShellLinesController(); + /// True if the streamer is closed. + @override + bool get isClosed => outController.isClosed; + /// Dispose. void mixinDispose() { outController.close(); @@ -341,6 +360,9 @@ abstract class ShellOutputLinesStreamer { /// Get the current state. bool get current; + /// true if the streamer is closed + bool get isClosed; + /// Set the current state. set current(bool current); diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 668592c..ee2f780 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,10 +1,10 @@ name: process_run -version: 1.0.1 +version: 1.0.1+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run environment: - sdk: '>=3.0.0 <4.0.0' + sdk: ^3.4.0 dependencies: path: '>=1.8.0 <3.0.0' diff --git a/packages/process_run/test/shell_stdio_lines_grouper_test.dart b/packages/process_run/test/shell_stdio_lines_grouper_test.dart index 1cbc1f2..793726b 100644 --- a/packages/process_run/test/shell_stdio_lines_grouper_test.dart +++ b/packages/process_run/test/shell_stdio_lines_grouper_test.dart @@ -110,5 +110,47 @@ echo --wait 100 --stdout hello2 }); expect(inMemoryStdout.lines, ['test1', '', 'test2']); }); + + test('last done before first', () async { + var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); + var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); + var stdio = ShellStdioLinesGrouper( + stderr: inMemoryStderr, stdout: inMemoryStdout); + var futures = []; + futures.add(stdio.runZoned(() async { + await Future.delayed(const Duration(milliseconds: 100)); + stdout.writeln('test1'); + })); + futures.add(stdio.runZoned(() async { + await Future.delayed(const Duration(milliseconds: 5)); + stdout.writeln('test2'); + })); + futures.add(stdio.runZoned(() async { + stdout.writeln('test3'); + })); + await Future.wait(futures); + expect(inMemoryStdout.lines, ['test1', 'test2', 'test3']); + }); + + test('first done before last', () async { + var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); + var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); + var stdio = ShellStdioLinesGrouper( + stderr: inMemoryStderr, stdout: inMemoryStdout); + var futures = []; + futures.add(stdio.runZoned(() async { + stdout.writeln('test1'); + })); + futures.add(stdio.runZoned(() async { + await Future.delayed(const Duration(milliseconds: 5)); + stdout.writeln('test2'); + })); + futures.add(stdio.runZoned(() async { + await Future.delayed(const Duration(milliseconds: 100)); + stdout.writeln('test3'); + })); + await Future.wait(futures); + expect(inMemoryStdout.lines, ['test1', 'test2', 'test3']); + }); }); } diff --git a/packages/process_run_test/example/stdout_lines_grouper_example1.dart b/packages/process_run_test/example/stdout_lines_grouper_example1.dart index 4032514..0669c42 100644 --- a/packages/process_run_test/example/stdout_lines_grouper_example1.dart +++ b/packages/process_run_test/example/stdout_lines_grouper_example1.dart @@ -9,6 +9,7 @@ Future writeCount(int count) async { } Future main() async { + stdout.writeln('Counting 2,5,10'); shellStdioLinesGrouper.runZoned(() async { await writeCount(2); }); diff --git a/packages/process_run_test/example/stdout_lines_grouper_example2.dart b/packages/process_run_test/example/stdout_lines_grouper_example2.dart index b6592df..17971d3 100644 --- a/packages/process_run_test/example/stdout_lines_grouper_example2.dart +++ b/packages/process_run_test/example/stdout_lines_grouper_example2.dart @@ -9,6 +9,7 @@ Future writeCount(int count) async { } Future main() async { + stdout.writeln('Counting 2,1'); shellStdioLinesGrouper.runZoned(() async { await Future.delayed(Duration(milliseconds: 500)); await writeCount(2); diff --git a/packages/process_run_test/example/stdout_lines_grouper_example3.dart b/packages/process_run_test/example/stdout_lines_grouper_example3.dart new file mode 100644 index 0000000..40308f7 --- /dev/null +++ b/packages/process_run_test/example/stdout_lines_grouper_example3.dart @@ -0,0 +1,24 @@ +import 'package:process_run/stdio.dart'; + +Future writeCount(int count) async { + stdout.writeln('Counting to $count'); + for (var i = 0; i < count; i++) { + stdout.writeln('${i + 1}'); + await Future.delayed(Duration(milliseconds: 500)); + } +} + +Future main() async { + stdout.writeln('Counting 5,1,3'); + shellStdioLinesGrouper.runZoned(() async { + await Future.delayed(Duration(milliseconds: 500)); + await writeCount(5); + }); + shellStdioLinesGrouper.runZoned(() async { + await Future.delayed(Duration(milliseconds: 250)); + await writeCount(1); + }); + shellStdioLinesGrouper.runZoned(() async { + await writeCount(3); + }); +} From 598a3d25b4d6b4909ed6a26bb35bed0c37464be1 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 25 Jul 2024 16:22:17 +0200 Subject: [PATCH 107/150] [process_run] v1.1.0 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index e5ddefe..d6d08af 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.0.1+1 +## 1.1.0 * Remove deprecated methods diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index ee2f780..8ff54a1 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.0.1+1 +version: 1.1.0 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 3dfd2200135425a40911c0987cd5b96689d7b8ee Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 10 Aug 2024 08:31:30 +0200 Subject: [PATCH 108/150] auto tkfix --- packages/process_run/pubspec.yaml | 2 +- packages/process_run_test/pubspec.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 8ff54a1..f4d5519 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -4,7 +4,7 @@ description: Process run helpers for Linux/Win/Mac and which like feature for fi homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run environment: - sdk: ^3.4.0 + sdk: ^3.5.0 dependencies: path: '>=1.8.0 <3.0.0' diff --git a/packages/process_run_test/pubspec.yaml b/packages/process_run_test/pubspec.yaml index 511105c..b730021 100644 --- a/packages/process_run_test/pubspec.yaml +++ b/packages/process_run_test/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.0.0 publish_to: none environment: - sdk: ^3.4.4 + sdk: ^3.5.0 # Add regular dependencies here. dependencies: @@ -16,4 +16,4 @@ dev_dependencies: dependency_overrides: process_run: - path: ../process_run \ No newline at end of file + path: ../process_run From 7dc8aeea15b1335db05046968b87a489357945e7 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 15 Aug 2024 16:03:03 +0200 Subject: [PATCH 109/150] fix lints --- packages/process_run/analysis_options.yaml | 15 +++++++++++++-- .../process_run/example/dart_bin_version.dart | 5 +++-- packages/process_run/example/demo_sync.dart | 3 ++- .../example/flutter_bin_version.dart | 5 +++-- packages/process_run/example/info.dart | 9 +++++---- packages/process_run/example/my_script.dart | 4 +++- .../process_run/example/no_env_user_paths.dart | 3 ++- packages/process_run/example/prompt.dart | 5 +++-- .../process_run/example/shell/shell_common.dart | 2 ++ packages/process_run/example/streamer.dart | 1 + packages/process_run/example/user_paths.dart | 2 +- .../lib/src/bin/shell/env_delete.dart | 2 +- .../process_run/lib/src/bin/shell/env_edit.dart | 4 ++-- packages/process_run/lib/src/bin/shell/run.dart | 2 +- .../process_run/lib/src/common/dev_utils.dart | 7 +++++-- .../process_run/lib/src/lines_utils_common.dart | 2 ++ packages/process_run/lib/src/process_run.dart | 3 +++ packages/process_run/lib/src/shell.dart | 9 +++++++++ .../lib/src/stdio/shell_streamer_io.dart | 2 +- packages/process_run/test/dart_doc_test.dart | 2 ++ packages/process_run/test/dartbin_test.dart | 2 ++ packages/process_run/test/data/main.dart | 2 ++ .../process_run/test/process_run_in_test2_.dart | 2 ++ .../process_run/test/process_run_in_test_.dart | 2 ++ packages/process_run/test/process_run_test.dart | 2 ++ .../process_run/test/shell_common_test.dart | 2 ++ .../test/shell_environment_test.dart | 2 ++ packages/process_run/test/shell_run_test.dart | 2 ++ packages/process_run/test/shell_test.dart | 2 ++ packages/process_run/test/which_test.dart | 2 ++ .../process_run/tool/manual_test_prompt.dart | 2 ++ packages/process_run/tool/run_ci.dart | 17 ----------------- packages/process_run/tool/tag.dart | 4 ++-- 33 files changed, 88 insertions(+), 42 deletions(-) delete mode 100644 packages/process_run/tool/run_ci.dart diff --git a/packages/process_run/analysis_options.yaml b/packages/process_run/analysis_options.yaml index 918853f..ec5c087 100644 --- a/packages/process_run/analysis_options.yaml +++ b/packages/process_run/analysis_options.yaml @@ -23,21 +23,32 @@ analyzer: linter: rules: - - public_member_api_docs - always_declare_return_types - avoid_dynamic_calls + - avoid_print - avoid_slow_async_io - cancel_subscriptions + - deprecated_member_use_from_same_package - directives_ordering + - implicit_reopen + - invalid_case_patterns + - invalid_runtime_check_with_js_interop_types + - iterable_contains_unrelated_type + - list_remove_unrelated_type - no_adjacent_strings_in_list + - no_literal_bool_comparisons + - no_self_assignments - omit_local_variable_types - package_api_docs + - package_prefixed_library_names - prefer_const_constructors + - prefer_const_literals_to_create_immutables + - prefer_if_elements_to_conditional_expressions - prefer_single_quotes + - public_member_api_docs - sort_child_properties_last - test_types_in_equals - throw_in_finally - unawaited_futures - - unnecessary_null_aware_assignments - unnecessary_statements - unsafe_html diff --git a/packages/process_run/example/dart_bin_version.dart b/packages/process_run/example/dart_bin_version.dart index e8795c3..1c0ce8e 100644 --- a/packages/process_run/example/dart_bin_version.dart +++ b/packages/process_run/example/dart_bin_version.dart @@ -2,10 +2,11 @@ import 'dart:async'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; +import 'package:process_run/stdio.dart'; Future main() async { - print('dart: ${await which('dart')}'); + stdout.writeln('dart: ${await which('dart')}'); var dartBinVersion = await getDartBinVersion(); - print('dartBinVersion: $dartBinVersion'); + stdout.writeln('dartBinVersion: $dartBinVersion'); await Shell().run('dart --version'); } diff --git a/packages/process_run/example/demo_sync.dart b/packages/process_run/example/demo_sync.dart index e3d80bd..be91ee3 100755 --- a/packages/process_run/example/demo_sync.dart +++ b/packages/process_run/example/demo_sync.dart @@ -7,7 +7,8 @@ void main() { // This is a synchronous call and will block until the child process terminates. var results = shell.runSync('echo "Hello world"'); var result = results.first; - print('output: "${result.outText.trim()}" exitCode: ${result.exitCode}'); + stdout.writeln( + 'output: "${result.outText.trim()}" exitCode: ${result.exitCode}'); // should display: output: "Hello world" exitCode: 0 // Run the command diff --git a/packages/process_run/example/flutter_bin_version.dart b/packages/process_run/example/flutter_bin_version.dart index e240c14..6d91fa6 100644 --- a/packages/process_run/example/flutter_bin_version.dart +++ b/packages/process_run/example/flutter_bin_version.dart @@ -1,10 +1,11 @@ import 'dart:async'; import 'package:process_run/cmd_run.dart'; +import 'package:process_run/stdio.dart'; import 'package:process_run/which.dart'; Future main() async { - print('flutter: ${await which('flutter')}'); + stdout.writeln('flutter: ${await which('flutter')}'); var flutterBinVersion = await getFlutterBinVersion(); - print('flutterBinVersion: $flutterBinVersion'); + stdout.writeln('flutterBinVersion: $flutterBinVersion'); } diff --git a/packages/process_run/example/info.dart b/packages/process_run/example/info.dart index d577f4f..a19da8c 100644 --- a/packages/process_run/example/info.dart +++ b/packages/process_run/example/info.dart @@ -2,11 +2,12 @@ import 'dart:async'; import 'package:process_run/cmd_run.dart' show flutterExecutablePath; import 'package:process_run/shell.dart'; +import 'package:process_run/stdio.dart'; Future main() async { - print('dartExecutable: $dartExecutable'); - print('flutterExecutablePath: $flutterExecutablePath'); - print('which(\'dart\'): ${await which('dart')}'); - print('which(\'flutter\'): ${await which('flutter')}'); + stdout.writeln('dartExecutable: $dartExecutable'); + stdout.writeln('flutterExecutablePath: $flutterExecutablePath'); + stdout.writeln('which(\'dart\'): ${await which('dart')}'); + stdout.writeln('which(\'flutter\'): ${await which('flutter')}'); await run('dart --version'); } diff --git a/packages/process_run/example/my_script.dart b/packages/process_run/example/my_script.dart index 42d600b..951b978 100644 --- a/packages/process_run/example/my_script.dart +++ b/packages/process_run/example/my_script.dart @@ -1,3 +1,5 @@ +import 'package:process_run/stdio.dart'; + void main(List arguments) { - print(arguments); + stdout.writeln(arguments); } diff --git a/packages/process_run/example/no_env_user_paths.dart b/packages/process_run/example/no_env_user_paths.dart index e62ad20..968f265 100644 --- a/packages/process_run/example/no_env_user_paths.dart +++ b/packages/process_run/example/no_env_user_paths.dart @@ -1,10 +1,11 @@ import 'dart:async'; import 'package:process_run/src/user_config.dart'; +import 'package:process_run/stdio.dart'; Future main() async { var userPaths = getUserPaths({}); for (var path in userPaths) { - print(path); + stdout.writeln(path); } } diff --git a/packages/process_run/example/prompt.dart b/packages/process_run/example/prompt.dart index 143e99f..e0fdaec 100755 --- a/packages/process_run/example/prompt.dart +++ b/packages/process_run/example/prompt.dart @@ -2,9 +2,10 @@ import 'dart:async'; import 'package:process_run/shell_run.dart'; import 'package:process_run/src/prompt.dart'; +import 'package:process_run/stdio.dart'; Future main() async { - print(await prompt('Enter your name')); - print(await promptConfirm('Action')); + stdout.writeln(await prompt('Enter your name')); + stdout.writeln(await promptConfirm('Action')); await promptTerminate(); } diff --git a/packages/process_run/example/shell/shell_common.dart b/packages/process_run/example/shell/shell_common.dart index 344b854..035c620 100644 --- a/packages/process_run/example/shell/shell_common.dart +++ b/packages/process_run/example/shell/shell_common.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'package:process_run/shell.dart'; Future main() async { diff --git a/packages/process_run/example/streamer.dart b/packages/process_run/example/streamer.dart index 07d7598..44b9aac 100755 --- a/packages/process_run/example/streamer.dart +++ b/packages/process_run/example/streamer.dart @@ -87,6 +87,7 @@ Future main(List arguments) async { await Future.delayed(Duration(microseconds: delay)); } index++; + // ignore: avoid_print print('[$index]'); } diff --git a/packages/process_run/example/user_paths.dart b/packages/process_run/example/user_paths.dart index a49a8d5..4451459 100644 --- a/packages/process_run/example/user_paths.dart +++ b/packages/process_run/example/user_paths.dart @@ -6,6 +6,6 @@ import 'package:process_run/src/user_config.dart'; Future main() async { var userPaths = getUserPaths(Platform.environment); for (var path in userPaths) { - print(path); + stdout.writeln(path); } } diff --git a/packages/process_run/lib/src/bin/shell/env_delete.dart b/packages/process_run/lib/src/bin/shell/env_delete.dart index 7e7257f..16b9af4 100644 --- a/packages/process_run/lib/src/bin/shell/env_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_delete.dart @@ -18,7 +18,7 @@ class ShellEnvDeleteCommand extends ShellEnvCommandBase { FutureOr onRun() async { var path = envFilePath; if (verbose!) { - print('envFilePath: $path'); + stdout.writeln('envFilePath: $path'); } var force = getFlag(flagForce)!; diff --git a/packages/process_run/lib/src/bin/shell/env_edit.dart b/packages/process_run/lib/src/bin/shell/env_edit.dart index 58bcda3..a4c3a5b 100644 --- a/packages/process_run/lib/src/bin/shell/env_edit.dart +++ b/packages/process_run/lib/src/bin/shell/env_edit.dart @@ -13,7 +13,7 @@ class ShellEnvEditCommand extends ShellEnvCommandBase { @override FutureOr onRun() async { if (verbose!) { - print('envFilePath: $envFilePath'); + stdout.writeln('envFilePath: $envFilePath'); } await envFileReadOrCreate(write: true); @@ -41,7 +41,7 @@ class ShellEnvEditCommand extends ShellEnvCommandBase { await doRun('vi ${shellArgument(envFilePath!)}'); return true; } - print('no editor found'); + stdout.writeln('no editor found'); return false; } } diff --git a/packages/process_run/lib/src/bin/shell/run.dart b/packages/process_run/lib/src/bin/shell/run.dart index d4ef729..2001a80 100644 --- a/packages/process_run/lib/src/bin/shell/run.dart +++ b/packages/process_run/lib/src/bin/shell/run.dart @@ -64,7 +64,7 @@ class ShellRunCommand extends ShellBinCommand { exit(1); } if (verbose!) { - print('command: $command'); + stdout.writeln('command: $command'); } await run(command); return true; diff --git a/packages/process_run/lib/src/common/dev_utils.dart b/packages/process_run/lib/src/common/dev_utils.dart index b7ce25f..9c977eb 100644 --- a/packages/process_run/lib/src/common/dev_utils.dart +++ b/packages/process_run/lib/src/common/dev_utils.dart @@ -5,6 +5,7 @@ import 'package:meta/meta.dart'; void _devPrint(Object object) { if (_devPrintEnabled) { + // ignore: avoid_print print(object); } } @@ -14,11 +15,11 @@ bool _devPrintEnabled = true; @Deprecated('Dev only') set devPrintEnabled(bool enabled) => _devPrintEnabled = enabled; -@Deprecated('Dev only') - /// Print only in dev mode +@Deprecated('Dev only') void devPrint(Object? object) { if (_devPrintEnabled) { + // ignore: avoid_print print(object); } } @@ -34,7 +35,9 @@ void _devError([Object? msg]) { throw UnsupportedError('$msg'); } catch (e, st) { if (_devPrintEnabled) { + // ignore: avoid_print print('# ERROR $msg'); + // ignore: avoid_print print(st); } rethrow; diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index d101df8..c84b303 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -87,6 +87,7 @@ Stream shellStreamLines(Stream> stream, ctlr.add(encoding!.decode(currentLine!)); } catch (_) { // Ignore bad encoding + // ignore: avoid_print print('ignoring: $currentLine'); } } @@ -97,6 +98,7 @@ Stream shellStreamLines(Stream> stream, ctlr = StreamController( onPause: () { if (shellDebug) { + // ignore: avoid_print print('onPause (paused: ${subscription?.isPaused})'); } // Last one diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index eed4472..9582149 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -82,6 +82,7 @@ Future runExecutableArguments( includeParentEnvironment: false, runInShell: runInShell); if (shellDebug) { + // ignore: avoid_print print('process: ${process.pid}'); } if (onProcess != null) { @@ -92,8 +93,10 @@ Future runExecutableArguments( () async { try { var exitCode = await process.exitCode; + // ignore: avoid_print print('process: ${process.pid} exitCode $exitCode'); } catch (e) { + // ignore: avoid_print print('process: ${process.pid} Error $e waiting exit code'); } }(); diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index b3d79b8..602c881 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -455,6 +455,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { void _clearPreviousContext() { if (shellDebug) { + // ignore: avoid_print print( 'Clear previous context ${_currentProcessResultCompleter?.isCompleted}'); } @@ -485,6 +486,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { try { if (shellDebug) { + // ignore: avoid_print print('$_runId: Before $processCmd'); } @@ -498,6 +500,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { workingDirectory: _options.workingDirectory); } finally { if (shellDebug) { + // ignore: avoid_print print( '$_runId: After $executableFullPath exitCode ${processResult?.exitCode}'); } @@ -566,6 +569,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { try { // devPrint(_options.environment.keys.where((element) => element.contains('TEKARTIK'))); if (shellDebug) { + // ignore: avoid_print print('$_runId: Before $processCmd'); } @@ -582,6 +586,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { _currentProcessCmd = processCmd; _currentProcessRunId = runId; if (shellDebug) { + // ignore: avoid_print print('onProcess ${_currentProcessToString()}'); } if (onProcess != null) { @@ -589,6 +594,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { } if (_killedRunId >= _runId) { if (shellDebug) { + // ignore: avoid_print print('shell was killed'); } _kill(); @@ -597,6 +603,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { }); } finally { if (shellDebug) { + // ignore: avoid_print print( '$_runId: After $processCmd exitCode ${processResult?.exitCode}'); } @@ -637,6 +644,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { run().then((value) { if (shellDebug) { + // ignore: avoid_print print('$runId: done'); } if (!completer.isCompleted) { @@ -644,6 +652,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { } }).catchError((Object e) { if (shellDebug) { + // ignore: avoid_print print('$runId: error $e'); } if (!completer.isCompleted) { diff --git a/packages/process_run/lib/src/stdio/shell_streamer_io.dart b/packages/process_run/lib/src/stdio/shell_streamer_io.dart index a8bb8bc..13dc3a4 100644 --- a/packages/process_run/lib/src/stdio/shell_streamer_io.dart +++ b/packages/process_run/lib/src/stdio/shell_streamer_io.dart @@ -25,7 +25,7 @@ class ShellOutputLinesStreamerIo set current(bool current) { if (this.current != current) { super.current = current; - if (current == true) { + if (current) { dump(); } } diff --git a/packages/process_run/test/dart_doc_test.dart b/packages/process_run/test/dart_doc_test.dart index 2196c81..0ba4180 100644 --- a/packages/process_run/test/dart_doc_test.dart +++ b/packages/process_run/test/dart_doc_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.dartdoc_test; diff --git a/packages/process_run/test/dartbin_test.dart b/packages/process_run/test/dartbin_test.dart index d091038..5b55550 100644 --- a/packages/process_run/test/dartbin_test.dart +++ b/packages/process_run/test/dartbin_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.dartbin_test; diff --git a/packages/process_run/test/data/main.dart b/packages/process_run/test/data/main.dart index 25bea67..f3a8d74 100644 --- a/packages/process_run/test/data/main.dart +++ b/packages/process_run/test/data/main.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + void main() { print('Hello'); } diff --git a/packages/process_run/test/process_run_in_test2_.dart b/packages/process_run/test/process_run_in_test2_.dart index 71ae10e..4425968 100644 --- a/packages/process_run/test/process_run_in_test2_.dart +++ b/packages/process_run/test/process_run_in_test2_.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.process_run_in_test2_; diff --git a/packages/process_run/test/process_run_in_test_.dart b/packages/process_run/test/process_run_in_test_.dart index 2a09b6a..e273e35 100644 --- a/packages/process_run/test/process_run_in_test_.dart +++ b/packages/process_run/test/process_run_in_test_.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.process_run_in_test; diff --git a/packages/process_run/test/process_run_test.dart b/packages/process_run/test/process_run_test.dart index 84de687..cdd4874 100644 --- a/packages/process_run/test/process_run_test.dart +++ b/packages/process_run/test/process_run_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.process_run_test; diff --git a/packages/process_run/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart index b07058b..5c38d96 100644 --- a/packages/process_run/test/shell_common_test.dart +++ b/packages/process_run/test/shell_common_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + library process_run.test.shell_common_api_test; import 'dart:async'; diff --git a/packages/process_run/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart index 98affd0..4604261 100644 --- a/packages/process_run/test/shell_environment_test.dart +++ b/packages/process_run/test/shell_environment_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.test.shell_environment_test; diff --git a/packages/process_run/test/shell_run_test.dart b/packages/process_run/test/shell_run_test.dart index aaf6a24..c220053 100644 --- a/packages/process_run/test/shell_run_test.dart +++ b/packages/process_run/test/shell_run_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.test.shell_run_test; diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index 582e4f2..b709c6e 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.test.shell_test; diff --git a/packages/process_run/test/which_test.dart b/packages/process_run/test/which_test.dart index d6cf7b2..98e6870 100644 --- a/packages/process_run/test/which_test.dart +++ b/packages/process_run/test/which_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + @TestOn('vm') library process_run.which_test; diff --git a/packages/process_run/tool/manual_test_prompt.dart b/packages/process_run/tool/manual_test_prompt.dart index 57f5110..71cbed0 100644 --- a/packages/process_run/tool/manual_test_prompt.dart +++ b/packages/process_run/tool/manual_test_prompt.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'dart:async'; import 'dart:io'; diff --git a/packages/process_run/tool/run_ci.dart b/packages/process_run/tool/run_ci.dart deleted file mode 100644 index 0085485..0000000 --- a/packages/process_run/tool/run_ci.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'dart:io'; - -import 'package:process_run/shell.dart'; - -Future main() async { - var shell = Shell(); - - print(Platform.operatingSystem); - print(Platform.version); - await shell.run(''' -# Analyze code & format -dart format --set-exit-if-changed bin example lib test tool -dart analyze --fatal-infos --fatal-warnings . -# Run tests -dart test -'''); -} diff --git a/packages/process_run/tool/tag.dart b/packages/process_run/tool/tag.dart index 8535efd..ab73785 100644 --- a/packages/process_run/tool/tag.dart +++ b/packages/process_run/tool/tag.dart @@ -6,8 +6,8 @@ import 'package:process_run/shell.dart'; Future main() async { var shell = Shell(); var version = await getPackageVersion(); - print('Version $version'); - print('Tap anything or CTRL-C: $version'); + stdout.writeln('Version $version'); + stdout.writeln('Tap anything or CTRL-C: $version'); await stdin.first; await shell.run(''' From c41a02bb39396899f2305b42e8774461b837df21 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 21 Aug 2024 11:40:45 +0200 Subject: [PATCH 110/150] [process_run] v1.2.0-0 export ShellBinCommand --- .gitignore | 7 ++- packages/process_run/CHANGELOG.md | 5 ++ packages/process_run/lib/process_run.dart | 2 +- .../process_run/lib/src/bin/shell/env.dart | 11 +++- .../lib/src/bin/shell/env_alias_delete.dart | 6 +-- .../lib/src/bin/shell/env_alias_set.dart | 4 +- .../lib/src/bin/shell/env_delete.dart | 4 +- .../lib/src/bin/shell/env_edit.dart | 2 +- .../lib/src/bin/shell/env_info.dart | 42 +++++++++++++++ .../lib/src/bin/shell/env_path.dart | 3 +- .../lib/src/bin/shell/env_path_delete.dart | 4 +- .../lib/src/bin/shell/env_path_get.dart | 2 +- .../lib/src/bin/shell/env_path_prepend.dart | 4 +- .../lib/src/bin/shell/env_var_delete.dart | 4 +- .../lib/src/bin/shell/env_var_set.dart | 4 +- .../process_run/lib/src/bin/shell/run.dart | 2 +- .../lib/src/bin/shell/shell_bin_command.dart | 27 ++++++---- .../lib/utils/shell_bin_command.dart | 1 + packages/process_run/pubspec.yaml | 2 +- .../test/bin/compiled_bin_shell_test.dart | 54 +++++++++++++++++++ .../test/shell_bin_command_test.dart | 16 ++++++ .../process_run/test/src/compile_shell.dart | 20 +++++++ 22 files changed, 193 insertions(+), 33 deletions(-) create mode 100644 packages/process_run/lib/src/bin/shell/env_info.dart create mode 100644 packages/process_run/lib/utils/shell_bin_command.dart create mode 100644 packages/process_run/test/bin/compiled_bin_shell_test.dart create mode 100644 packages/process_run/test/shell_bin_command_test.dart create mode 100644 packages/process_run/test/src/compile_shell.dart diff --git a/.gitignore b/.gitignore index 65808c3..3b21e8b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,9 @@ *.iml # Local files -.local/ \ No newline at end of file +.local/ + +# Workaround for analyser issue, allow project at root +/pubspec.lock +/pubspec.yaml +/.dart_tool/ diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index d6d08af..703f57f 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.2.0-0 + +* Export ShellBinCommand +* requires dart 3.5 + ## 1.1.0 * Remove deprecated methods diff --git a/packages/process_run/lib/process_run.dart b/packages/process_run/lib/process_run.dart index 8f3759d..c2a38f9 100644 --- a/packages/process_run/lib/process_run.dart +++ b/packages/process_run/lib/process_run.dart @@ -4,7 +4,7 @@ library; export 'package:process_run/src/shell_utils_common.dart' - show argumentsToString, argumentToString; + show argumentsToString, argumentToString, stringToArguments; export 'shell.dart'; export 'which.dart' show which, whichSync; diff --git a/packages/process_run/lib/src/bin/shell/env.dart b/packages/process_run/lib/src/bin/shell/env.dart index cddc36a..e2927ea 100644 --- a/packages/process_run/lib/src/bin/shell/env.dart +++ b/packages/process_run/lib/src/bin/shell/env.dart @@ -11,6 +11,7 @@ import 'package:process_run/src/user_config.dart'; import 'env_alias.dart'; import 'env_delete.dart'; import 'env_file_content.dart'; +import 'env_info.dart'; import 'env_path.dart'; import 'env_var.dart'; import 'import.dart'; @@ -27,7 +28,13 @@ class ShellEnvCommandBase extends ShellBinCommand { /// Local env bool get local { - final user = results[flagUser] as bool; + if (!results.wasParsed(flagUser)) { + var parent = this.parent; + if (parent is ShellEnvCommandBase) { + return parent.local; + } + } + final user = results.flag(flagUser); final local = !user; return local; } @@ -113,6 +120,8 @@ class ShellEnvCommand extends ShellEnvCommandBase { addCommand(ShellEnvAliasCommand()); addCommand(ShellEnvPathCommand()); + addCommand(ShellEnvInfoCommand()); + parser.addFlag(flagInfo, abbr: 'i', help: 'display info', negatable: false); } diff --git a/packages/process_run/lib/src/bin/shell/env_alias_delete.dart b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart index eff2a17..f71c1bf 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart @@ -27,7 +27,7 @@ class ShellEnvAliasDeleteCommand extends ShellEnvCommandBase { stderr.writeln('At least 1 arguments expected'); exit(1); } else { - if (verbose!) { + if (verbose) { stdout.writeln('file $label: $envFilePath'); stdout.writeln('before: ${jsonEncode(ShellEnvironment().aliases)}'); } @@ -38,7 +38,7 @@ class ShellEnvAliasDeleteCommand extends ShellEnvCommandBase { modified = fileContent.deleteAlias(name) || modified; } if (modified) { - if (verbose!) { + if (verbose) { stdout.writeln('writing file'); } await fileContent.write(); @@ -46,7 +46,7 @@ class ShellEnvAliasDeleteCommand extends ShellEnvCommandBase { // Force reload shellEnvironment = null; - if (verbose!) { + if (verbose) { stdout.writeln('After: ${jsonEncode(ShellEnvironment().vars)}'); } return true; diff --git a/packages/process_run/lib/src/bin/shell/env_alias_set.dart b/packages/process_run/lib/src/bin/shell/env_alias_set.dart index 26e5fef..9ace091 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_set.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_set.dart @@ -27,7 +27,7 @@ class ShellEnvAliasSetCommand extends ShellEnvCommandBase { stderr.writeln('At least 2 arguments expected'); exit(1); } else { - if (verbose!) { + if (verbose) { stdout.writeln('file $label: $envFilePath'); stdout.writeln('before: ${jsonEncode(ShellEnvironment().aliases)}'); } @@ -39,7 +39,7 @@ class ShellEnvAliasSetCommand extends ShellEnvCommandBase { } // Force reload shellEnvironment = null; - if (verbose!) { + if (verbose) { stdout.writeln('After: ${jsonEncode(ShellEnvironment().aliases)}'); } return true; diff --git a/packages/process_run/lib/src/bin/shell/env_delete.dart b/packages/process_run/lib/src/bin/shell/env_delete.dart index 16b9af4..cf3a1f3 100644 --- a/packages/process_run/lib/src/bin/shell/env_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_delete.dart @@ -17,10 +17,10 @@ class ShellEnvDeleteCommand extends ShellEnvCommandBase { @override FutureOr onRun() async { var path = envFilePath; - if (verbose!) { + if (verbose) { stdout.writeln('envFilePath: $path'); } - var force = getFlag(flagForce)!; + var force = getFlag(flagForce); if (force || await promptConfirm('Confirm that you want to delete file ($label)')) { diff --git a/packages/process_run/lib/src/bin/shell/env_edit.dart b/packages/process_run/lib/src/bin/shell/env_edit.dart index a4c3a5b..32c04dd 100644 --- a/packages/process_run/lib/src/bin/shell/env_edit.dart +++ b/packages/process_run/lib/src/bin/shell/env_edit.dart @@ -12,7 +12,7 @@ class ShellEnvEditCommand extends ShellEnvCommandBase { @override FutureOr onRun() async { - if (verbose!) { + if (verbose) { stdout.writeln('envFilePath: $envFilePath'); } await envFileReadOrCreate(write: true); diff --git a/packages/process_run/lib/src/bin/shell/env_info.dart b/packages/process_run/lib/src/bin/shell/env_info.dart new file mode 100644 index 0000000..2856e2d --- /dev/null +++ b/packages/process_run/lib/src/bin/shell/env_info.dart @@ -0,0 +1,42 @@ +import 'package:path/path.dart'; +import 'package:process_run/src/user_config.dart'; + +import 'import.dart'; + +/// pub run process_run:shell run +class ShellEnvInfoCommand extends ShellBinCommand { + /// pub run process_run:shell run + ShellEnvInfoCommand() + : super(name: 'info', description: 'Display environment info'); + + @override + void printUsage() { + stdout.writeln('Run a command'); + stdout.writeln(); + stdout.writeln('Usage: $script env info'); + stdout.writeln(' Environment information'); + + super.printUsage(); + } + + @override + FutureOr onRun() async { + void displayInfo(String title, String path) { + var config = loadFromPath(path); + stdout.writeln('# $title'); + stdout.writeln('file: ${relative(path, from: Directory.current.path)}'); + stdout.writeln('vars: ${config.vars}'); + stdout.writeln('paths: ${config.paths}'); + } + + displayInfo('user_env', getUserEnvFilePath()!); + displayInfo('local_env', getLocalEnvFilePath()); + + return true; + } +} + +/// Direct shell env Alias dump run helper for testing. +Future main(List arguments) async { + await ShellEnvInfoCommand().parseAndRun(arguments); +} diff --git a/packages/process_run/lib/src/bin/shell/env_path.dart b/packages/process_run/lib/src/bin/shell/env_path.dart index 3771637..932213b 100644 --- a/packages/process_run/lib/src/bin/shell/env_path.dart +++ b/packages/process_run/lib/src/bin/shell/env_path.dart @@ -1,12 +1,13 @@ import 'package:process_run/src/bin/shell/env_path_dump.dart'; import 'package:process_run/src/bin/shell/env_path_prepend.dart'; +import 'env.dart'; import 'env_path_delete.dart'; import 'env_path_get.dart'; import 'import.dart'; /// Path operations -class ShellEnvPathCommand extends ShellBinCommand { +class ShellEnvPathCommand extends ShellEnvCommandBase { /// Path operations ShellEnvPathCommand() : super(name: 'path', description: 'Path operations') { addCommand(ShellEnvPathDumpCommand()); diff --git a/packages/process_run/lib/src/bin/shell/env_path_delete.dart b/packages/process_run/lib/src/bin/shell/env_path_delete.dart index 010c62a..5b73d49 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_delete.dart @@ -27,7 +27,7 @@ class ShellEnvPathDeleteCommand extends ShellEnvCommandBase { stderr.writeln('At least 1 path argument expected'); exit(1); } else { - if (verbose!) { + if (verbose) { stdout.writeln('File $label: $envFilePath'); stdout.writeln('before: ${jsonEncode(ShellEnvironment().paths)}'); } @@ -37,7 +37,7 @@ class ShellEnvPathDeleteCommand extends ShellEnvCommandBase { } // Force reload shellEnvironment = null; - if (verbose!) { + if (verbose) { stdout.writeln('After: ${jsonEncode(ShellEnvironment().paths)}'); } return true; diff --git a/packages/process_run/lib/src/bin/shell/env_path_get.dart b/packages/process_run/lib/src/bin/shell/env_path_get.dart index 15d628a..07ce82b 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_get.dart @@ -31,7 +31,7 @@ class ShellEnvPathGetCommand extends ShellEnvCommandBase { stderr.writeln('At least 1 path argument expected'); exit(1); } else { - if (verbose!) { + if (verbose) { stdout.writeln('File $label: $envFilePath'); } dumpStringList(ShellEnvironment() diff --git a/packages/process_run/lib/src/bin/shell/env_path_prepend.dart b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart index 1f08a91..d7b051f 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_prepend.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart @@ -27,7 +27,7 @@ class ShellEnvPathPrependCommand extends ShellEnvCommandBase { stderr.writeln('At least 1 path argument expected'); exit(1); } else { - if (verbose!) { + if (verbose) { stdout.writeln('before: ${jsonEncode(ShellEnvironment().paths)}'); } var fileContent = await envFileReadOrCreate(); @@ -36,7 +36,7 @@ class ShellEnvPathPrependCommand extends ShellEnvCommandBase { } // Force reload shellEnvironment = null; - if (verbose!) { + if (verbose) { stdout.writeln('After: ${jsonEncode(ShellEnvironment().paths)}'); } return true; diff --git a/packages/process_run/lib/src/bin/shell/env_var_delete.dart b/packages/process_run/lib/src/bin/shell/env_var_delete.dart index 599dee2..5bc4043 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_delete.dart @@ -6,8 +6,8 @@ import 'package:process_run/src/io/io.dart'; /// Delete an environment variable from a user/local config file class ShellEnvVarDeleteCommand extends ShellEnvCommandBase { - late final _helper = ShellEnvVarDeleteIoHelper( - shell: Shell(), local: local, verbose: verbose ?? false); + late final _helper = + ShellEnvVarDeleteIoHelper(shell: Shell(), local: local, verbose: verbose); /// Delete an environment variable from a user/local config file ShellEnvVarDeleteCommand() diff --git a/packages/process_run/lib/src/bin/shell/env_var_set.dart b/packages/process_run/lib/src/bin/shell/env_var_set.dart index 0347fb4..19c78be 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_set.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_set.dart @@ -6,8 +6,8 @@ import 'package:process_run/src/io/io.dart'; /// Set an environment variable in a user/local config file class ShellEnvVarSetCommand extends ShellEnvCommandBase { - late final _helper = ShellEnvVarSetIoHelper( - shell: Shell(), local: local, verbose: verbose ?? false); + late final _helper = + ShellEnvVarSetIoHelper(shell: Shell(), local: local, verbose: verbose); /// Set an environment variable in a user/local config file ShellEnvVarSetCommand() diff --git a/packages/process_run/lib/src/bin/shell/run.dart b/packages/process_run/lib/src/bin/shell/run.dart index 2001a80..4537cbe 100644 --- a/packages/process_run/lib/src/bin/shell/run.dart +++ b/packages/process_run/lib/src/bin/shell/run.dart @@ -63,7 +63,7 @@ class ShellRunCommand extends ShellBinCommand { if (command == null) { exit(1); } - if (verbose!) { + if (verbose) { stdout.writeln('command: $command'); } await run(command); diff --git a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart index 97979ba..30621df 100644 --- a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart +++ b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart @@ -25,7 +25,7 @@ class ShellBinCommand { bool? _verbose; /// Set before run - bool? get verbose => _verbose ??= parent?.verbose; + bool get verbose => _verbose ??= parent?.verbose ?? false; String? _description; @@ -76,12 +76,12 @@ class ShellBinCommand { /// Parse the arguments ArgResults parse(List arguments) { - // Add missing common commands - parser.addFlag(flagVersion, - help: 'Print the command version', negatable: false); - parser.addFlag(flagVerbose, - abbr: 'v', help: 'Verbose mode', negatable: false); - return results = parser.parse(arguments); + results = parser.parse(arguments); + if (parent == null) { + // Handle verbose + _verbose = getFlag(flagVerbose); + } + return results; } /// Parse and run the command @@ -100,12 +100,19 @@ class ShellBinCommand { ArgParser? parser, ShellBinCommand? parent, String? description}) { - _onRun = onRun; + //_onRun = onRun; _parser = parser; _description = description; _version = version; // read or create parser = this.parser; + // Add missing common commands + if (parent == null) { + parser.addFlag(flagVersion, + help: 'Print the command version', negatable: false); + parser.addFlag(flagVerbose, + abbr: 'v', help: 'Verbose mode', negatable: false); + } parser.addFlag(flagHelp, abbr: 'h', help: 'Usage help', negatable: false); } @@ -128,7 +135,7 @@ class ShellBinCommand { } /// Get a flag - bool? getFlag(String name) => results[name] as bool?; + bool getFlag(String name) => results.flag(name); /// Run @nonVirtual @@ -138,7 +145,7 @@ class ShellBinCommand { // Handle verbose _verbose = getFlag(flagVerbose); - final hasVersion = getFlag(flagVersion)!; + final hasVersion = getFlag(flagVersion); if (hasVersion) { stdout.writeln(version); return true; diff --git a/packages/process_run/lib/utils/shell_bin_command.dart b/packages/process_run/lib/utils/shell_bin_command.dart new file mode 100644 index 0000000..ecdc330 --- /dev/null +++ b/packages/process_run/lib/utils/shell_bin_command.dart @@ -0,0 +1 @@ +export 'package:process_run/src/mixin/shell_bin.dart'; diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index f4d5519..a7749df 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.1.0 +version: 1.2.0-0 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run diff --git a/packages/process_run/test/bin/compiled_bin_shell_test.dart b/packages/process_run/test/bin/compiled_bin_shell_test.dart new file mode 100644 index 0000000..aaccfb6 --- /dev/null +++ b/packages/process_run/test/bin/compiled_bin_shell_test.dart @@ -0,0 +1,54 @@ +@TestOn('vm') +library process_run.test.bin.shell_bin_test; + +import 'package:process_run/shell.dart'; +import 'package:process_run/src/bin/shell/import.dart'; +import 'package:pub_semver/pub_semver.dart'; +import 'package:test/test.dart'; + +import '../src/compile_shell.dart'; + +void main() { + late Shell shell; + group('compiled_bin_shell', () { + setUpAll(() async { + var dsExePath = await compileShellBin(force: false); + shell = Shell( + environment: ShellEnvironment()..aliases['ds'] = dsExePath, + verbose: false); + }); + test('version', () async { + var output = (await shell.run('ds --version')).outText.trim(); + await shell.run('ds env edit -h'); + expect(Version.parse(output), shellBinVersion); + }); + group('env', () { + group('path', () { + test('user prepend', () async { + var dummyPath = 'dummyUserPathPrepend'; + await shell.run('ds env --user path delete $dummyPath'); + var lines = (await shell.run('ds env --user path dump')).outLines; + expect(lines, isNot(contains(dummyPath))); + await shell.run('ds env --user path prepend $dummyPath'); + lines = (await shell.run('ds env --user path dump')).outLines; + expect(lines, contains(dummyPath)); + await shell.run('ds env --user path delete $dummyPath'); + lines = (await shell.run('ds env --user path dump')).outLines; + expect(lines, isNot(contains(dummyPath))); + }); + test('local prepend', () async { + var dummyPath = 'dummyLocalPathPrepend'; + await shell.run('ds env --user path delete $dummyPath'); + var lines = (await shell.run('ds env --user path dump')).outLines; + expect(lines, isNot(contains(dummyPath))); + await shell.run('ds env --user path prepend $dummyPath'); + lines = (await shell.run('ds env --user path dump')).outLines; + expect(lines, contains(dummyPath)); + await shell.run('ds env --user path delete $dummyPath'); + lines = (await shell.run('ds env --user path dump')).outLines; + expect(lines, isNot(contains(dummyPath))); + }); + }); + }); + }); +} diff --git a/packages/process_run/test/shell_bin_command_test.dart b/packages/process_run/test/shell_bin_command_test.dart new file mode 100644 index 0000000..0f9535e --- /dev/null +++ b/packages/process_run/test/shell_bin_command_test.dart @@ -0,0 +1,16 @@ +@TestOn('vm') +library; + +import 'package:process_run/utils/shell_bin_command.dart'; +import 'package:test/test.dart'; + +void main() { + test('basic', () { + var cmd = ShellBinCommand(name: 'test'); + expect(cmd.name, 'test'); + cmd.parse(['--verbose']); + expect(cmd.verbose, isTrue); + cmd.parse([]); + expect(cmd.verbose, isFalse); + }); +} diff --git a/packages/process_run/test/src/compile_shell.dart b/packages/process_run/test/src/compile_shell.dart new file mode 100644 index 0000000..5bf8ef3 --- /dev/null +++ b/packages/process_run/test/src/compile_shell.dart @@ -0,0 +1,20 @@ +import 'dart:io'; + +import 'package:path/path.dart'; +import 'package:process_run/shell.dart'; + +/// Return the executable path. +Future compileShellBin({bool force = false}) async { + var folder = + Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); + var exeExtension = Platform.isWindows ? '.exe' : ''; + var dsExePath = join('build', folder, 'ds$exeExtension'); + var dsExeDir = dirname(dsExePath); + var shell = Shell(verbose: false); + if (!File(dsExePath).existsSync() || force) { + Directory(dsExeDir).createSync(recursive: true); + await shell.run( + 'dart compile exe ${shellArgument(join('bin', 'shell.dart'))} -o ${shellArgument(dsExePath)}'); + } + return dsExePath; +} From 441c159c196363ab80c8ac2568941ba1fa8917d9 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 21 Aug 2024 11:46:51 +0200 Subject: [PATCH 111/150] [process_run] fix deps --- packages/process_run/lib/src/version.dart | 2 +- packages/process_run/pubspec.yaml | 28 +++++++++++------------ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index 92a0d66..eaaae42 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '1.0.1'; +const packageVersion = '1.2.0-0'; diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index a7749df..0affef8 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -7,22 +7,22 @@ environment: sdk: ^3.5.0 dependencies: - path: '>=1.8.0 <3.0.0' - collection: '>=1.15.0 <3.0.0' - string_scanner: '>=1.1.0 <3.0.0' - yaml: '>=3.0.0 <5.0.0' - meta: '>=1.3.0 <3.0.0' - args: '>=2.0.0 <4.0.0' - pub_semver: '>=2.0.0 <4.0.0' - synchronized: '>=3.0.0 <5.0.0' + path: ">=1.8.0 <3.0.0" + collection: ">=1.17.0 <3.0.0" + string_scanner: ">=1.1.0 <3.0.0" + yaml: ">=3.0.0 <5.0.0" + meta: ">=1.14.0 <3.0.0" + args: ">=2.5.0 <4.0.0" + pub_semver: ">=2.0.0 <4.0.0" + synchronized: ">=3.0.0 <5.0.0" dev_dependencies: - lints: '>=1.0.1' - test: '>=1.16.2' - async: '>=2.5.0' - build_runner: '>=1.11.2' - build_test: '>=1.3.7' - build_version: '>=2.0.0' + lints: ">=4.0.0" + test: ">=1.25.8" + async: ">=2.11.0" + build_runner: ">=2.4.12" + build_test: ">=2.2.2" + build_version: ">=2.1.1" executables: # Shell helper ds: shell From 5ab508259c7f56b5e330e3151d616952d9e060ff Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 21 Aug 2024 11:56:31 +0200 Subject: [PATCH 112/150] [process_run] v1.2.0 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/lib/src/version.dart | 2 +- packages/process_run/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 703f57f..bc1f12e 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.2.0-0 +## 1.2.0 * Export ShellBinCommand * requires dart 3.5 diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index eaaae42..cf971dd 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,2 +1,2 @@ // Generated code. Do not modify. -const packageVersion = '1.2.0-0'; +const packageVersion = '1.2.0'; diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 0affef8..9165361 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.0-0 +version: 1.2.0 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From b6fd80c455d918a8a52ceea9a9dff78f5460230b Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 26 Sep 2024 11:41:55 +0200 Subject: [PATCH 113/150] fix lints --- packages/process_run/lib/cmd_run.dart | 2 +- packages/process_run/lib/dartbin.dart | 2 +- packages/process_run/lib/shell.dart | 2 +- packages/process_run/lib/src/shell_utils_common.dart | 2 +- packages/process_run/lib/src/shell_utils_io.dart | 2 +- packages/process_run/test/bin/bin_shell_test.dart | 2 +- packages/process_run/test/bin/compiled_bin_shell_test.dart | 2 +- packages/process_run/test/build_runner_test.dart | 2 +- packages/process_run/test/cmd_run_api_test.dart | 2 +- packages/process_run/test/cmd_run_exception_test.dart | 2 +- packages/process_run/test/cmd_run_test.dart | 2 +- packages/process_run/test/compile_test.dart | 2 +- packages/process_run/test/dart_compile_js_test.dart | 2 +- packages/process_run/test/dart_doc_test.dart | 2 +- packages/process_run/test/dartbin_api_test.dart | 2 +- packages/process_run/test/dartbin_cmd_test.dart | 2 +- packages/process_run/test/dartbin_cmd_verbose_test_.dart | 2 +- packages/process_run/test/dartbin_test.dart | 2 +- packages/process_run/test/doc_test.dart | 2 +- packages/process_run/test/echo_test.dart | 2 +- packages/process_run/test/flutterbin_cmd_test.dart | 2 +- packages/process_run/test/flutterbin_impl_test.dart | 2 +- packages/process_run/test/package_test.dart | 2 +- packages/process_run/test/process_cmd_api_test.dart | 2 +- packages/process_run/test/process_cmd_test.dart | 2 +- packages/process_run/test/process_run_in_test2_.dart | 2 +- packages/process_run/test/process_run_in_test_.dart | 2 +- packages/process_run/test/process_run_out_test_.dart | 2 +- packages/process_run/test/process_run_test.dart | 2 +- packages/process_run/test/pub_test.dart | 2 +- packages/process_run/test/shell_common_api_test.dart | 2 +- packages/process_run/test/shell_common_test.dart | 2 +- packages/process_run/test/shell_environment_test.dart | 2 +- packages/process_run/test/shell_lines_controller_test.dart | 2 +- packages/process_run/test/shell_run_test.dart | 2 +- packages/process_run/test/shell_test.dart | 2 +- packages/process_run/test/src_dartbin_cmd_test.dart | 2 +- packages/process_run/test/src_shell_test.dart | 2 +- packages/process_run/test/src_shell_utils_test.dart | 2 +- packages/process_run/test/src_user_config_test.dart | 2 +- packages/process_run/test/which_test.dart | 2 +- 41 files changed, 41 insertions(+), 41 deletions(-) diff --git a/packages/process_run/lib/cmd_run.dart b/packages/process_run/lib/cmd_run.dart index bf94b7a..47a9565 100644 --- a/packages/process_run/lib/cmd_run.dart +++ b/packages/process_run/lib/cmd_run.dart @@ -1,5 +1,5 @@ /// Prefer using shell -library process_run.cmd_run; +library; /// /// Command runner diff --git a/packages/process_run/lib/dartbin.dart b/packages/process_run/lib/dartbin.dart index 17a52de..cfa9126 100644 --- a/packages/process_run/lib/dartbin.dart +++ b/packages/process_run/lib/dartbin.dart @@ -7,7 +7,7 @@ /// {@canonicalFor dartbin.dartChannel} /// {@canonicalFor dartbin.dartExecutable} /// {@canonicalFor dartbin.dartVersion} -library process_run.dartbin; +library; export 'package:process_run/src/flutterbin_cmd.dart' show diff --git a/packages/process_run/lib/shell.dart b/packages/process_run/lib/shell.dart index 6f9c509..3dcc23e 100644 --- a/packages/process_run/lib/shell.dart +++ b/packages/process_run/lib/shell.dart @@ -11,7 +11,7 @@ /// {@canonicalFor shell_utils.userHomePath} /// {@canonicalFor user_config.userPaths} /// {@canonicalFor process_run.runExecutableArguments} -library process_run.shell; +library; export 'package:process_run/dartbin.dart' show diff --git a/packages/process_run/lib/src/shell_utils_common.dart b/packages/process_run/lib/src/shell_utils_common.dart index 1d25f6d..32bbf60 100644 --- a/packages/process_run/lib/src/shell_utils_common.dart +++ b/packages/process_run/lib/src/shell_utils_common.dart @@ -1,4 +1,4 @@ -library process_run.src.shell_utils_common; +library; import 'dart:async'; import 'dart:convert'; diff --git a/packages/process_run/lib/src/shell_utils_io.dart b/packages/process_run/lib/src/shell_utils_io.dart index d2f0fed..2264a31 100644 --- a/packages/process_run/lib/src/shell_utils_io.dart +++ b/packages/process_run/lib/src/shell_utils_io.dart @@ -1,4 +1,4 @@ -library process_run.src.shell_utils_io; +library; import 'package:path/path.dart'; import 'package:process_run/src/io/io.dart'; diff --git a/packages/process_run/test/bin/bin_shell_test.dart b/packages/process_run/test/bin/bin_shell_test.dart index 5b1a330..c9a8688 100644 --- a/packages/process_run/test/bin/bin_shell_test.dart +++ b/packages/process_run/test/bin/bin_shell_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.test.bin.shell_bin_test; +library; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/env_file_content.dart'; diff --git a/packages/process_run/test/bin/compiled_bin_shell_test.dart b/packages/process_run/test/bin/compiled_bin_shell_test.dart index aaccfb6..ff8e749 100644 --- a/packages/process_run/test/bin/compiled_bin_shell_test.dart +++ b/packages/process_run/test/bin/compiled_bin_shell_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.test.bin.shell_bin_test; +library; import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/import.dart'; diff --git a/packages/process_run/test/build_runner_test.dart b/packages/process_run/test/build_runner_test.dart index 0c6bea5..5845684 100644 --- a/packages/process_run/test/build_runner_test.dart +++ b/packages/process_run/test/build_runner_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.dartfmt_test; +library; import 'package:process_run/cmd_run.dart'; import 'package:test/test.dart'; diff --git a/packages/process_run/test/cmd_run_api_test.dart b/packages/process_run/test/cmd_run_api_test.dart index 26a4188..57d0e91 100644 --- a/packages/process_run/test/cmd_run_api_test.dart +++ b/packages/process_run/test/cmd_run_api_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.test.cmd_run_api_test; +library; import 'package:process_run/cmd_run.dart'; import 'package:test/test.dart'; diff --git a/packages/process_run/test/cmd_run_exception_test.dart b/packages/process_run/test/cmd_run_exception_test.dart index e60a10b..2872aa0 100644 --- a/packages/process_run/test/cmd_run_exception_test.dart +++ b/packages/process_run/test/cmd_run_exception_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.cmd_run_exception_test; +library; import 'dart:io'; diff --git a/packages/process_run/test/cmd_run_test.dart b/packages/process_run/test/cmd_run_test.dart index a1ce250..dfdce65 100644 --- a/packages/process_run/test/cmd_run_test.dart +++ b/packages/process_run/test/cmd_run_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.cmd_run_test; +library; import 'dart:io'; diff --git a/packages/process_run/test/compile_test.dart b/packages/process_run/test/compile_test.dart index 5a2acc8..92843a2 100644 --- a/packages/process_run/test/compile_test.dart +++ b/packages/process_run/test/compile_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run_test_windows_test; +library; import 'dart:io'; diff --git a/packages/process_run/test/dart_compile_js_test.dart b/packages/process_run/test/dart_compile_js_test.dart index a60453d..ee894df 100644 --- a/packages/process_run/test/dart_compile_js_test.dart +++ b/packages/process_run/test/dart_compile_js_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.dart2js_test; +library; import 'dart:io'; import 'dart:mirrors'; diff --git a/packages/process_run/test/dart_doc_test.dart b/packages/process_run/test/dart_doc_test.dart index 0ba4180..b57a829 100644 --- a/packages/process_run/test/dart_doc_test.dart +++ b/packages/process_run/test/dart_doc_test.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.dartdoc_test; +library; import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; diff --git a/packages/process_run/test/dartbin_api_test.dart b/packages/process_run/test/dartbin_api_test.dart index 5926df1..6b73401 100644 --- a/packages/process_run/test/dartbin_api_test.dart +++ b/packages/process_run/test/dartbin_api_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.dartbin_api_test; +library; import 'package:process_run/dartbin.dart'; import 'package:test/test.dart'; diff --git a/packages/process_run/test/dartbin_cmd_test.dart b/packages/process_run/test/dartbin_cmd_test.dart index 4898660..ef8e79e 100644 --- a/packages/process_run/test/dartbin_cmd_test.dart +++ b/packages/process_run/test/dartbin_cmd_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.dartbin_cmd_test; +library; import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; diff --git a/packages/process_run/test/dartbin_cmd_verbose_test_.dart b/packages/process_run/test/dartbin_cmd_verbose_test_.dart index 4ddc43d..4d01749 100644 --- a/packages/process_run/test/dartbin_cmd_verbose_test_.dart +++ b/packages/process_run/test/dartbin_cmd_verbose_test_.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.dartbin_cmd_verbose_test; +library; import 'package:process_run/cmd_run.dart' show runCmd; import 'package:process_run/src/dartbin_cmd.dart'; diff --git a/packages/process_run/test/dartbin_test.dart b/packages/process_run/test/dartbin_test.dart index 5b55550..ff92261 100644 --- a/packages/process_run/test/dartbin_test.dart +++ b/packages/process_run/test/dartbin_test.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.dartbin_test; +library; import 'dart:io'; diff --git a/packages/process_run/test/doc_test.dart b/packages/process_run/test/doc_test.dart index c593964..cc86328 100644 --- a/packages/process_run/test/doc_test.dart +++ b/packages/process_run/test/doc_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.doc_test; +library; import 'package:process_run/shell_run.dart'; import 'package:test/test.dart'; diff --git a/packages/process_run/test/echo_test.dart b/packages/process_run/test/echo_test.dart index cfd4b7c..25a5948 100644 --- a/packages/process_run/test/echo_test.dart +++ b/packages/process_run/test/echo_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.echo_test; +library; import 'dart:convert'; import 'dart:io'; diff --git a/packages/process_run/test/flutterbin_cmd_test.dart b/packages/process_run/test/flutterbin_cmd_test.dart index 738a4c3..9f09ea4 100644 --- a/packages/process_run/test/flutterbin_cmd_test.dart +++ b/packages/process_run/test/flutterbin_cmd_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.flutterbin_cmd_test; +library; import 'dart:io'; diff --git a/packages/process_run/test/flutterbin_impl_test.dart b/packages/process_run/test/flutterbin_impl_test.dart index 447e43b..b780d99 100644 --- a/packages/process_run/test/flutterbin_impl_test.dart +++ b/packages/process_run/test/flutterbin_impl_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.flutterbin_cmd_test; +library; import 'package:process_run/src/flutterbin_cmd.dart'; // ignore: import_of_legacy_library_into_null_safe diff --git a/packages/process_run/test/package_test.dart b/packages/process_run/test/package_test.dart index bb865f6..5180480 100644 --- a/packages/process_run/test/package_test.dart +++ b/packages/process_run/test/package_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.pub_test; +library; import 'package:path/path.dart'; import 'package:process_run/package/package.dart'; diff --git a/packages/process_run/test/process_cmd_api_test.dart b/packages/process_run/test/process_cmd_api_test.dart index f167023..d9874e0 100644 --- a/packages/process_run/test/process_cmd_api_test.dart +++ b/packages/process_run/test/process_cmd_api_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.test.process_cmd_api_test; +library; import 'package:process_run/process_cmd.dart'; import 'package:test/test.dart'; diff --git a/packages/process_run/test/process_cmd_test.dart b/packages/process_run/test/process_cmd_test.dart index 4a2af1e..6598886 100644 --- a/packages/process_run/test/process_cmd_test.dart +++ b/packages/process_run/test/process_cmd_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.process_cmd_test; +library; import 'dart:convert'; import 'dart:io'; diff --git a/packages/process_run/test/process_run_in_test2_.dart b/packages/process_run/test/process_run_in_test2_.dart index 4425968..baf92f2 100644 --- a/packages/process_run/test/process_run_in_test2_.dart +++ b/packages/process_run/test/process_run_in_test2_.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.process_run_in_test2_; +library; import 'dart:async'; diff --git a/packages/process_run/test/process_run_in_test_.dart b/packages/process_run/test/process_run_in_test_.dart index e273e35..f12f2d1 100644 --- a/packages/process_run/test/process_run_in_test_.dart +++ b/packages/process_run/test/process_run_in_test_.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.process_run_in_test; +library; import 'package:process_run/process_run.dart'; import 'package:test/test.dart'; diff --git a/packages/process_run/test/process_run_out_test_.dart b/packages/process_run/test/process_run_out_test_.dart index 0502210..2523bbe 100644 --- a/packages/process_run/test/process_run_out_test_.dart +++ b/packages/process_run/test/process_run_out_test_.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.process_run_out_test; +library; import 'dart:io'; diff --git a/packages/process_run/test/process_run_test.dart b/packages/process_run/test/process_run_test.dart index cdd4874..2020875 100644 --- a/packages/process_run/test/process_run_test.dart +++ b/packages/process_run/test/process_run_test.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.process_run_test; +library; import 'dart:async'; import 'dart:convert'; diff --git a/packages/process_run/test/pub_test.dart b/packages/process_run/test/pub_test.dart index 39035d0..2f9eaf3 100644 --- a/packages/process_run/test/pub_test.dart +++ b/packages/process_run/test/pub_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.pub_test; +library; import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; diff --git a/packages/process_run/test/shell_common_api_test.dart b/packages/process_run/test/shell_common_api_test.dart index 15bc3ab..f3a7a5e 100644 --- a/packages/process_run/test/shell_common_api_test.dart +++ b/packages/process_run/test/shell_common_api_test.dart @@ -1,4 +1,4 @@ -library process_run.test.shell_common_api_test; +library; import 'package:process_run/src/mixin/shell_common.dart'; import 'package:test/test.dart'; diff --git a/packages/process_run/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart index 5c38d96..2396bf5 100644 --- a/packages/process_run/test/shell_common_test.dart +++ b/packages/process_run/test/shell_common_test.dart @@ -1,6 +1,6 @@ // ignore_for_file: avoid_print -library process_run.test.shell_common_api_test; +library; import 'dart:async'; import 'dart:io'; diff --git a/packages/process_run/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart index 4604261..01b06a1 100644 --- a/packages/process_run/test/shell_environment_test.dart +++ b/packages/process_run/test/shell_environment_test.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.test.shell_environment_test; +library; import 'dart:convert'; import 'dart:io'; diff --git a/packages/process_run/test/shell_lines_controller_test.dart b/packages/process_run/test/shell_lines_controller_test.dart index 1aa90df..4bf5acd 100644 --- a/packages/process_run/test/shell_lines_controller_test.dart +++ b/packages/process_run/test/shell_lines_controller_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.test.shell_test; +library; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/import.dart'; diff --git a/packages/process_run/test/shell_run_test.dart b/packages/process_run/test/shell_run_test.dart index c220053..1875a1d 100644 --- a/packages/process_run/test/shell_run_test.dart +++ b/packages/process_run/test/shell_run_test.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.test.shell_run_test; +library; import 'dart:io'; diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index b709c6e..fb5c0cf 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.test.shell_test; +library; import 'dart:convert'; import 'dart:io'; diff --git a/packages/process_run/test/src_dartbin_cmd_test.dart b/packages/process_run/test/src_dartbin_cmd_test.dart index c5d2bf1..8ce15c4 100644 --- a/packages/process_run/test/src_dartbin_cmd_test.dart +++ b/packages/process_run/test/src_dartbin_cmd_test.dart @@ -1,6 +1,6 @@ // TODO non vm //@TestOn('vm') -library process_run.test.src_dart_bin_cmd_test; +library; import 'package:process_run/dartbin.dart'; import 'package:process_run/src/dartbin_cmd.dart' diff --git a/packages/process_run/test/src_shell_test.dart b/packages/process_run/test/src_shell_test.dart index bbd000b..70afda5 100644 --- a/packages/process_run/test/src_shell_test.dart +++ b/packages/process_run/test/src_shell_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.test.src_shell_test; +library; import 'package:test/test.dart'; diff --git a/packages/process_run/test/src_shell_utils_test.dart b/packages/process_run/test/src_shell_utils_test.dart index 67c022c..1caa227 100644 --- a/packages/process_run/test/src_shell_utils_test.dart +++ b/packages/process_run/test/src_shell_utils_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.test.src_shell_utils_test; +library; import 'dart:convert'; diff --git a/packages/process_run/test/src_user_config_test.dart b/packages/process_run/test/src_user_config_test.dart index 878b4f3..498f614 100644 --- a/packages/process_run/test/src_user_config_test.dart +++ b/packages/process_run/test/src_user_config_test.dart @@ -1,5 +1,5 @@ @TestOn('vm') -library process_run.test.src_user_config_test; +library; import 'dart:io'; diff --git a/packages/process_run/test/which_test.dart b/packages/process_run/test/which_test.dart index 98e6870..f51893f 100644 --- a/packages/process_run/test/which_test.dart +++ b/packages/process_run/test/which_test.dart @@ -1,7 +1,7 @@ // ignore_for_file: avoid_print @TestOn('vm') -library process_run.which_test; +library; import 'dart:io'; From e7db6704a3b8a175a06c400fbdebde9f931400ea Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 27 Sep 2024 12:30:47 +0200 Subject: [PATCH 114/150] [process_run] v1.2.0+1 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index bc1f12e..ee3fdba 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.2.0 +## 1.2.0+1 * Export ShellBinCommand * requires dart 3.5 diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 9165361..7c8ac6c 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.0 +version: 1.2.0+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 2b7063af585cae00efe67733f492aeac18139a61 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 30 Sep 2024 17:32:45 +0200 Subject: [PATCH 115/150] [process_run] expand working directory to absolute --- packages/process_run/lib/src/process_run.dart | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index 9582149..14b3f67 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -103,11 +103,11 @@ Future runExecutableArguments( } } catch (e) { if (verbose == true) { - io.stderr.writeln(e); - io.stderr.writeln( - '\$ ${executableArgumentsToString(executableShortName, arguments)}'); - io.stderr.writeln( - 'workingDirectory: ${workingDirectory ?? Directory.current.path}'); + dumpException( + executable: executableShortName, + arguments: arguments, + exception: e, + workingDirectory: workingDirectory); } rethrow; } @@ -269,11 +269,11 @@ ProcessResult runExecutableArgumentsSync( ); } catch (e) { if (verbose == true) { - io.stderr.writeln(e); - io.stderr.writeln( - '\$ ${executableArgumentsToString(executableShortName, arguments)}'); - io.stderr.writeln( - 'workingDirectory: ${workingDirectory ?? Directory.current.path}'); + dumpException( + executable: executableShortName, + arguments: arguments, + exception: e, + workingDirectory: workingDirectory); } rethrow; } @@ -347,11 +347,24 @@ Future processCmdRun(ProcessCmd cmd, onProcess: onProcess); } catch (e) { if (verbose == true) { - io.stderr.writeln(e); - io.stderr.writeln('\$ $cmd'); - io.stderr.writeln( - 'workingDirectory: ${cmd.workingDirectory ?? Directory.current.path}'); + dumpException( + executable: cmd.executable, + arguments: cmd.arguments, + exception: e, + workingDirectory: cmd.workingDirectory); } rethrow; } } + +/// Dump the exception to stderr +void dumpException( + {required String executable, + required List arguments, + required Object exception, + String? workingDirectory}) { + io.stderr.writeln(exception); + io.stderr.writeln('\$ ${executableArgumentsToString(executable, arguments)}'); + io.stderr.writeln( + 'workingDirectory: ${normalize(absolute(workingDirectory ?? Directory.current.path))}'); +} From d14995d89cf36957f2c523320d66849db7068c37 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 30 Sep 2024 17:35:47 +0200 Subject: [PATCH 116/150] [process_run] remove version generation (use external tool) --- packages/process_run/lib/src/bin/shell/shell.dart | 3 +-- packages/process_run/lib/src/version.dart | 9 +++++++-- packages/process_run/tool/pre_publish.dart | 5 ----- 3 files changed, 8 insertions(+), 9 deletions(-) delete mode 100644 packages/process_run/tool/pre_publish.dart diff --git a/packages/process_run/lib/src/bin/shell/shell.dart b/packages/process_run/lib/src/bin/shell/shell.dart index fa8e8d8..37e1cec 100644 --- a/packages/process_run/lib/src/bin/shell/shell.dart +++ b/packages/process_run/lib/src/bin/shell/shell.dart @@ -1,13 +1,12 @@ import 'package:process_run/shell.dart'; import 'package:process_run/src/bin/shell/run.dart'; import 'package:process_run/src/version.dart'; -import 'package:pub_semver/pub_semver.dart'; import 'env.dart'; import 'import.dart'; /// The shell bin version -Version shellBinVersion = Version.parse(packageVersion); +final shellBinVersion = packageVersion; /// Help flag const flagHelp = 'help'; diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index cf971dd..c001308 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,2 +1,7 @@ -// Generated code. Do not modify. -const packageVersion = '1.2.0'; +import 'package:pub_semver/pub_semver.dart'; + +/// Package version text +const packageVersionText = '1.2.0+1'; + +/// Package version +final packageVersion = Version.parse(packageVersionText); diff --git a/packages/process_run/tool/pre_publish.dart b/packages/process_run/tool/pre_publish.dart deleted file mode 100644 index ddcdedb..0000000 --- a/packages/process_run/tool/pre_publish.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:process_run/shell.dart'; - -void main() async { - await run('dart pub run build_runner build --delete-conflicting-outputs'); -} From e1bde3c9873140ec0a32a76e31433cd8496613ec Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 30 Sep 2024 17:36:54 +0200 Subject: [PATCH 117/150] [process_run] v1.2.0+2 --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/lib/src/version.dart | 2 +- packages/process_run/pubspec.yaml | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index ee3fdba..a0f3619 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.2.0+1 +## 1.2.0+2 * Export ShellBinCommand * requires dart 3.5 diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index c001308..a529e36 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,7 +1,7 @@ import 'package:pub_semver/pub_semver.dart'; /// Package version text -const packageVersionText = '1.2.0+1'; +const packageVersionText = '1.2.0+2'; /// Package version final packageVersion = Version.parse(packageVersionText); diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 7c8ac6c..bd4f339 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.0+1 +version: 1.2.0+2 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run @@ -20,9 +20,7 @@ dev_dependencies: lints: ">=4.0.0" test: ">=1.25.8" async: ">=2.11.0" - build_runner: ">=2.4.12" - build_test: ">=2.2.2" - build_version: ">=2.1.1" + executables: # Shell helper ds: shell From 2437100e9a3a758599f6e14448feb7de549ee61d Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 30 Sep 2024 18:04:00 +0200 Subject: [PATCH 118/150] [process_run] v1.2.0+3 fix tests --- packages/process_run/CHANGELOG.md | 2 +- packages/process_run/pubspec.yaml | 2 +- .../process_run/test/build_runner_test.dart | 17 ----------------- .../process_run/test/src/compile_shell.dart | 14 ++++++++++++++ 4 files changed, 16 insertions(+), 19 deletions(-) delete mode 100644 packages/process_run/test/build_runner_test.dart diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index a0f3619..085de0d 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.2.0+2 +## 1.2.0+3 * Export ShellBinCommand * requires dart 3.5 diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index bd4f339..d189275 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.0+2 +version: 1.2.0+3 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run diff --git a/packages/process_run/test/build_runner_test.dart b/packages/process_run/test/build_runner_test.dart deleted file mode 100644 index 5845684..0000000 --- a/packages/process_run/test/build_runner_test.dart +++ /dev/null @@ -1,17 +0,0 @@ -@TestOn('vm') -library; - -import 'package:process_run/cmd_run.dart'; -import 'package:test/test.dart'; - -void main() => defineTests(); - -void defineTests() { - group('pbr', () { - test('help', () async { - final result = await runCmd(PbrCmd(['--help'])); - expect(result.exitCode, 0); - expect(result.stdout, contains('Usage: build_runner')); - }); - }); -} diff --git a/packages/process_run/test/src/compile_shell.dart b/packages/process_run/test/src/compile_shell.dart index 5bf8ef3..1e4ac16 100644 --- a/packages/process_run/test/src/compile_shell.dart +++ b/packages/process_run/test/src/compile_shell.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; +import 'package:process_run/src/bin/shell/shell.dart'; +import 'package:pub_semver/pub_semver.dart'; /// Return the executable path. Future compileShellBin({bool force = false}) async { @@ -11,6 +13,18 @@ Future compileShellBin({bool force = false}) async { var dsExePath = join('build', folder, 'ds$exeExtension'); var dsExeDir = dirname(dsExePath); var shell = Shell(verbose: false); + if (File(dsExePath).existsSync()) { + try { + var output = (await shell.run('$dsExePath --version')).outText.trim(); + if (Version.parse(output) != shellBinVersion) { + force = true; + } + } catch (_) { + // ignore + force = true; + } + } + if (!File(dsExePath).existsSync() || force) { Directory(dsExeDir).createSync(recursive: true); await shell.run( From c48ffe2c885f0d8f1483c969eed07419684aee8b Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 9 Oct 2024 10:28:46 +0200 Subject: [PATCH 119/150] feat: add binaryStream to ShellLinesController --- packages/process_run/lib/src/lines_utils_common.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index c84b303..3c2527f 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -7,7 +7,9 @@ import 'package:process_run/src/shell_utils_common.dart'; import 'common/import.dart'; -/// Basic shell lines controller. +/// Basic bi-directionnal shell lines controller. +/// +/// Use either sink for stdout/stderr or binaryStream for stdin /// /// Usage: /// ```dart @@ -56,6 +58,9 @@ class ShellLinesController { /// True if the controller is closed. bool get isClosed => _controller.isClosed; + /// The binary stream to listen to, that can be passed to stdin + Stream> get binaryStream => _controller.stream; + /// Dispose the controller. void close() { _controller.close(); From 9069edbfdc8f5395a2ab2baa8222f379dbcfe73b Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 9 Oct 2024 11:09:00 +0200 Subject: [PATCH 120/150] [process_run] feat: add binaryStream to ShellLinesController to allow using it in stdin --- packages/process_run/example/echo.dart | 29 ++++++------ packages/process_run/example/streamer.dart | 9 +++- .../test/shell_lines_controller_test.dart | 28 ++++++++++-- .../process_run/test/src/compile_echo.dart | 26 ++++++++++- .../test/src/compile_streamer.dart | 45 +++++++++++++++++++ 5 files changed, 117 insertions(+), 20 deletions(-) create mode 100644 packages/process_run/test/src/compile_streamer.dart diff --git a/packages/process_run/example/echo.dart b/packages/process_run/example/echo.dart index e47d575..2387748 100755 --- a/packages/process_run/example/echo.dart +++ b/packages/process_run/example/echo.dart @@ -9,6 +9,7 @@ import 'package:args/args.dart'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/version.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; @@ -70,10 +71,15 @@ Future main(List arguments) async { return int.tryParse(value?.toString() ?? ''); } - final help = argsResult['help'] as bool; - final verbose = argsResult['verbose'] as bool?; + final help = argsResult.flag('help'); + final version = argsResult.flag('version'); final wait = parseInt(argsResult['wait']); - final writeLine = argsResult['write-line'] as bool?; + final writeLine = argsResult.flag('write-line'); + + if (version) { + stdout.write(packageVersion); + return; + } if (wait != null) { await Future.delayed(Duration(milliseconds: wait)); @@ -106,16 +112,11 @@ Future main(List arguments) async { // handle stdin if asked for it if (argsResult['stdin'] as bool) { - // devPrint('reading stdin $stdin'); - if (verbose!) { - //stderr.writeln('stdin $stdin'); - //stderr.writeln('stdin ${await stdin..isEmpty}'); - } final lineSync = stdin.readLineSync(); if (lineSync != null) { stdout.write(lineSync); } - if (writeLine!) { + if (writeLine) { stdout.writeln(); } } @@ -123,14 +124,14 @@ Future main(List arguments) async { final outputText = argsResult['stdout'] as String?; if (outputText != null) { stdout.write(outputText); - if (writeLine!) { + if (writeLine) { stdout.writeln(); } } final hexOutputText = argsResult['stdout-hex'] as String?; if (hexOutputText != null) { stdout.add(hexToBytes(hexOutputText)); - if (writeLine!) { + if (writeLine) { stdout.writeln(); } } @@ -138,14 +139,14 @@ Future main(List arguments) async { final stderrText = argsResult['stderr'] as String?; if (stderrText != null) { stderr.write(stderrText); - if (writeLine!) { + if (writeLine) { stderr.writeln(); } } final stderrHexTest = argsResult['stderr-hex'] as String?; if (stderrHexTest != null) { stderr.add(hexToBytes(stderrHexTest)); - if (writeLine!) { + if (writeLine) { stderr.writeln(); } } @@ -153,7 +154,7 @@ Future main(List arguments) async { final envVar = argsResult['stdout-env'] as String?; if (envVar != null) { stdout.write(Platform.environment[envVar] ?? ''); - if (writeLine!) { + if (writeLine) { stdout.writeln(); } } diff --git a/packages/process_run/example/streamer.dart b/packages/process_run/example/streamer.dart index 44b9aac..98a0aa7 100755 --- a/packages/process_run/example/streamer.dart +++ b/packages/process_run/example/streamer.dart @@ -7,6 +7,7 @@ import 'dart:io'; import 'package:args/args.dart'; import 'package:path/path.dart'; import 'package:process_run/src/common/import.dart'; +import 'package:process_run/src/version.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; @@ -51,10 +52,11 @@ Future main(List arguments) async { return int.tryParse(value?.toString() ?? ''); } - final help = argsResult['help'] as bool; + final help = argsResult.flag('help'); final count = parseInt(argsResult['count']); final delay = parseInt(argsResult[udelayOption]); final timeout = parseInt(argsResult['timeout']); + final version = argsResult.flag('version'); void printUsage() { stdout.writeln('Streamer utility'); @@ -68,6 +70,11 @@ Future main(List arguments) async { stdout.writeln(parser.usage); } + if (version) { + stdout.write(packageVersion); + return; + } + if (help) { printUsage(); return; diff --git a/packages/process_run/test/shell_lines_controller_test.dart b/packages/process_run/test/shell_lines_controller_test.dart index 4bf5acd..f42ee47 100644 --- a/packages/process_run/test/shell_lines_controller_test.dart +++ b/packages/process_run/test/shell_lines_controller_test.dart @@ -5,15 +5,16 @@ import 'package:process_run/shell.dart'; import 'package:process_run/src/common/import.dart'; import 'package:test/test.dart'; -import 'process_run_test_common.dart'; +import 'src/compile_echo.dart'; +import 'src/compile_streamer.dart'; void main() { group('ShellLinesController', () { late ShellEnvironment env; - setUpAll(() { + setUpAll(() async { env = ShellEnvironment() - ..aliases['streamer'] = 'dart run ${shellArgument(streamerScriptPath)}' - ..aliases['echo'] = 'dart run ${shellArgument(echoScriptPath)}'; + ..aliases['streamer'] = await compileStreamerExample() + ..aliases['echo'] = await compileEchoExample(); }); test('stream all', () async { var ctlr = ShellLinesController(); @@ -75,5 +76,24 @@ void main() { .then((_) => ctlr.close(), onError: ctlr.sink.addError); await completer.future; }); + test('shell stdin', () async { + var ctlr = ShellLinesController(); + var inputController = ShellLinesController(); + var completer = Completer(); + ctlr.stream.listen((event) { + if (event == 'stdin_done') { + completer.complete(true); + } + }); + var shell = Shell( + stdout: ctlr.sink, + stdin: inputController.binaryStream, + environment: env); + var done = shell.run('echo --stdin --write-line --verbose'); + inputController.writeln('stdin_done'); + inputController.close(); + await completer.future; + await done; + }); }); } diff --git a/packages/process_run/test/src/compile_echo.dart b/packages/process_run/test/src/compile_echo.dart index 1a9736a..dd816df 100644 --- a/packages/process_run/test/src/compile_echo.dart +++ b/packages/process_run/test/src/compile_echo.dart @@ -2,6 +2,10 @@ import 'dart:io'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; +import 'package:process_run/src/version.dart'; +import 'package:pub_semver/pub_semver.dart'; + +var _echoVersionOk = false; /// Return the executable path. Future compileEchoExample({bool force = false}) async { @@ -11,7 +15,27 @@ Future compileEchoExample({bool force = false}) async { var echoExePath = join('build', folder, 'process_run_echo$exeExtension'); var echoExeDir = dirname(echoExePath); var shell = Shell(verbose: false); - if (!File(echoExePath).existsSync() || force) { + var file = File(echoExePath); + var needCompile = force || !file.existsSync(); + + if (!needCompile && _echoVersionOk) { + return echoExePath; + } + if (!needCompile && file.existsSync()) { + try { + var version = Version.parse( + (await shell.run('$echoExePath --version')).outText.trim()); + if (version != packageVersion) { + needCompile = true; + } else { + _echoVersionOk = true; + return echoExePath; + } + } catch (_) { + needCompile = true; + } + } + if (needCompile) { Directory(echoExeDir).createSync(recursive: true); await shell.run( 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o ${shellArgument(echoExePath)}'); diff --git a/packages/process_run/test/src/compile_streamer.dart b/packages/process_run/test/src/compile_streamer.dart new file mode 100644 index 0000000..e07800e --- /dev/null +++ b/packages/process_run/test/src/compile_streamer.dart @@ -0,0 +1,45 @@ +import 'dart:io'; + +import 'package:path/path.dart'; +import 'package:process_run/shell.dart'; +import 'package:process_run/src/version.dart'; +import 'package:pub_semver/pub_semver.dart'; + +var _streamerVersionOk = false; + +/// Return the executable path. +Future compileStreamerExample({bool force = false}) async { + var folder = + Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); + var exeExtension = Platform.isWindows ? '.exe' : ''; + var exe = join('build', folder, 'process_run_streamer$exeExtension'); + var exeDir = dirname(exe); + + var shell = Shell(verbose: false); + var file = File(exe); + + var needCompile = force || !file.existsSync(); + if (!needCompile && _streamerVersionOk) { + return exe; + } + if (!needCompile && file.existsSync()) { + try { + var version = + Version.parse((await shell.run('$exe --version')).outText.trim()); + if (version != packageVersion) { + needCompile = true; + } else { + _streamerVersionOk = true; + return exe; + } + } catch (_) { + needCompile = true; + } + } + if (needCompile) { + Directory(exeDir).createSync(recursive: true); + await shell.run( + 'dart compile exe ${shellArgument(join('example', 'streamer.dart'))} -o ${shellArgument(exe)}'); + } + return exe; +} From adff193cffb45da56a24c3ae3171e787e1ceef74 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 9 Oct 2024 11:10:50 +0200 Subject: [PATCH 121/150] [process_run] v1.2.1 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/lib/src/version.dart | 2 +- packages/process_run/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 085de0d..abad2fb 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.1 + +* Add `ShellLinesController.binaryStream` to allow processing binary data and allow using it for stdin. +* ## 1.2.0+3 * Export ShellBinCommand diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index a529e36..a9c43eb 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,7 +1,7 @@ import 'package:pub_semver/pub_semver.dart'; /// Package version text -const packageVersionText = '1.2.0+2'; +const packageVersionText = '1.2.1'; /// Package version final packageVersion = Version.parse(packageVersionText); diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index d189275..d78e809 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.0+3 +version: 1.2.1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 9e3fa658bb52ae981547a0d7eddde47855e16a05 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 9 Oct 2024 11:27:27 +0200 Subject: [PATCH 122/150] chore changelog typo --- packages/process_run/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index abad2fb..c704e31 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,7 +1,7 @@ ## 1.2.1 * Add `ShellLinesController.binaryStream` to allow processing binary data and allow using it for stdin. -* + ## 1.2.0+3 * Export ShellBinCommand From 957f6d9b4a0899f39c876b28a618deb128daab71 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sat, 12 Oct 2024 02:02:03 +0200 Subject: [PATCH 123/150] test: toJson --- packages/process_run/test/shell_environment_test.dart | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/process_run/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart index 01b06a1..f0b4277 100644 --- a/packages/process_run/test/shell_environment_test.dart +++ b/packages/process_run/test/shell_environment_test.dart @@ -249,6 +249,12 @@ void main() { 'vars': {'VAR1': 'var1'}, 'aliases': {'alias1': 'command1'} }); + var jsonText = jsonEncode(basicEnv.toJson()); + expect(jsonDecode(jsonText), basicEnv.toJson()); + + var env = ShellEnvironment(); + jsonText = jsonEncode(env.toJson()); + expect(jsonDecode(jsonText), env.toJson()); }); test('fromJson', () async { expect( From af38dc61426c6537653c72c126bcffc63447f1e0 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 22 Oct 2024 09:06:56 +0200 Subject: [PATCH 124/150] [process_run] v1.2.1+1 fix user flag handling in ds executable --- packages/process_run/CHANGELOG.md | 3 ++- .../process_run/lib/src/bin/shell/env.dart | 21 +++++++++++-------- .../lib/src/bin/shell/env_var.dart | 3 ++- packages/process_run/lib/src/version.dart | 2 +- packages/process_run/pubspec.yaml | 2 +- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index c704e31..8772ba8 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,6 +1,7 @@ -## 1.2.1 +## 1.2.1+1 * Add `ShellLinesController.binaryStream` to allow processing binary data and allow using it for stdin. +* Fix `--user` flag handling in `ds` executable. ## 1.2.0+3 diff --git a/packages/process_run/lib/src/bin/shell/env.dart b/packages/process_run/lib/src/bin/shell/env.dart index e2927ea..80b8e10 100644 --- a/packages/process_run/lib/src/bin/shell/env.dart +++ b/packages/process_run/lib/src/bin/shell/env.dart @@ -26,17 +26,20 @@ class ShellEnvCommandBase extends ShellBinCommand { abbr: 'u', help: 'Use user env instead of local env', negatable: false); } - /// Local env + /// Local env (default) bool get local { - if (!results.wasParsed(flagUser)) { - var parent = this.parent; - if (parent is ShellEnvCommandBase) { - return parent.local; - } + if (results.wasParsed(flagUser)) { + final user = results.flag(flagUser); + return !user; + } + if (results.wasParsed(flagLocal)) { + return results.flag(flagLocal); + } + var parent = this.parent; + if (parent is ShellEnvCommandBase) { + return parent.local; } - final user = results.flag(flagUser); - final local = !user; - return local; + return true; } /// Local/User label diff --git a/packages/process_run/lib/src/bin/shell/env_var.dart b/packages/process_run/lib/src/bin/shell/env_var.dart index 3e43bdd..4301eda 100644 --- a/packages/process_run/lib/src/bin/shell/env_var.dart +++ b/packages/process_run/lib/src/bin/shell/env_var.dart @@ -1,3 +1,4 @@ +import 'package:process_run/src/bin/shell/env.dart'; import 'package:process_run/src/bin/shell/env_var_delete.dart'; import 'package:process_run/src/bin/shell/env_var_dump.dart'; @@ -6,7 +7,7 @@ import 'env_var_set.dart'; import 'import.dart'; /// Shell env var command. -class ShellEnvVarCommand extends ShellBinCommand { +class ShellEnvVarCommand extends ShellEnvCommandBase { /// Shell env var command. ShellEnvVarCommand() : super( diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index a9c43eb..5ea494a 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,7 +1,7 @@ import 'package:pub_semver/pub_semver.dart'; /// Package version text -const packageVersionText = '1.2.1'; +const packageVersionText = '1.2.1+1'; /// Package version final packageVersion = Version.parse(packageVersionText); diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index d78e809..aea6eb9 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.1 +version: 1.2.1+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 1c54a865df5ba583dc3210a7a0c5f91db7206392 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 25 Oct 2024 13:41:50 +0200 Subject: [PATCH 125/150] feat: Shell.kill kill all chidren when using sigkill on linux --- packages/process_run/lib/src/shell.dart | 23 ++++++++++++++++++--- packages/process_run/test/shell_test.dart | 25 +++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 602c881..bbf67b4 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -292,9 +292,26 @@ abstract class Shell implements ShellCore, ShellCoreSync { bool _kill() { if (_currentProcess != null) { - io.stderr.writeln('killing $_killedRunId, ${_currentProcessToString()}'); - var result = _currentProcess!.kill(_killedProcessSignal); - _clearPreviousContext(); + bool result; + try { + io.stderr.writeln( + 'killing $_killedRunId, ${_currentProcessToString()} signal $_killedProcessSignal'); + + /// Workaround for linux when using sigkill to kill the children processes too + if (io.Platform.isLinux && + _killedProcessSignal == ProcessSignal.sigkill) { + /// Kill the children + var pid = _currentProcess!.pid; + // Kill children process + runExecutableArgumentsSync('pkill', ['-P', '$pid']); + } + + /// kill the parent process + result = _currentProcess!.kill(_killedProcessSignal); + _clearPreviousContext(); + } catch (_) { + result = false; + } return result; } else if (_currentProcessResultCompleter != null) { _clearPreviousContext(); diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index fb5c0cf..3e4deb2 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -274,6 +274,31 @@ $echoExe -o ${shellArgument(weirdText)} stderr.writeln('Allowed: could happen on CI'); } }, timeout: const Timeout(Duration(seconds: 50))); + + test('kill SIGKILL', () async { + try { + await () async { + await ensureEchoExe(); + var shell = Shell(); + await shell.run('$echoExe --version'); + late Future future; + try { + future = shell.run('$echoExe --wait 30000'); + } on TimeoutException catch (_) {} + try { + shell.kill(ProcessSignal.sigkill); + await future; + fail('should fail'); + } on ShellException catch (_) { + // 2: ShellException(dart echo.dart --wait 3000, exitCode -15, workingDirectory: + } + }() + .timeout(const Duration(seconds: 30)); + } on TimeoutException catch (e) { + stderr.writeln('TimeOutException $e'); + stderr.writeln('Allowed: could happen on CI'); + } + }, timeout: const Timeout(Duration(seconds: 50))); test('kill complex', () async { await ensureEchoExe(); try { From 7fee41093e8a8792cde6935ff549dcd136eb2ec1 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 25 Oct 2024 13:43:24 +0200 Subject: [PATCH 126/150] feat: Shell.kill kill all chidren when using sigkill on linux --- packages/process_run/lib/src/shell.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index bbf67b4..daab41b 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -300,10 +300,12 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// Workaround for linux when using sigkill to kill the children processes too if (io.Platform.isLinux && _killedProcessSignal == ProcessSignal.sigkill) { - /// Kill the children - var pid = _currentProcess!.pid; - // Kill children process - runExecutableArgumentsSync('pkill', ['-P', '$pid']); + try { + /// Kill the children + var pid = _currentProcess!.pid; + // Kill children process + runExecutableArgumentsSync('pkill', ['-P', '$pid']); + } catch (_) {} } /// kill the parent process From f2bd2e98690f3a60ec4e91ff6608a8fba0b91265 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 25 Oct 2024 14:40:06 +0200 Subject: [PATCH 127/150] [process_run] v1.2.2-0 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/lib/src/version.dart | 2 +- packages/process_run/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 8772ba8..672e05b 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.2-0 + +* Special kill behavior on linux when using sigkill (kills all children too) + ## 1.2.1+1 * Add `ShellLinesController.binaryStream` to allow processing binary data and allow using it for stdin. diff --git a/packages/process_run/lib/src/version.dart b/packages/process_run/lib/src/version.dart index 5ea494a..8655e71 100644 --- a/packages/process_run/lib/src/version.dart +++ b/packages/process_run/lib/src/version.dart @@ -1,7 +1,7 @@ import 'package:pub_semver/pub_semver.dart'; /// Package version text -const packageVersionText = '1.2.1+1'; +const packageVersionText = '1.2.2-0'; /// Package version final packageVersion = Version.parse(packageVersionText); diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index aea6eb9..d0fc72c 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.1+1 +version: 1.2.2-0 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 38da516fb1156376d3e04ec20b664ece1ffdb24a Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 29 Oct 2024 12:08:17 +0100 Subject: [PATCH 128/150] use pkill on MacOS too when using ProcessSignal.sigkill --- packages/process_run/lib/src/shell.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index daab41b..d4eabd1 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -298,7 +298,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { 'killing $_killedRunId, ${_currentProcessToString()} signal $_killedProcessSignal'); /// Workaround for linux when using sigkill to kill the children processes too - if (io.Platform.isLinux && + if ((io.Platform.isLinux || io.Platform.isMacOS) && _killedProcessSignal == ProcessSignal.sigkill) { try { /// Kill the children From 830089d3c41e4f07cb3d72be3b0db8dbbd9e81ec Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 29 Oct 2024 15:12:14 +0100 Subject: [PATCH 129/150] feat: when sigkill is used use taskkill on Windows --- packages/process_run/doc/shell.md | 11 ++++++- packages/process_run/lib/src/shell.dart | 38 ++++++++++++++++++------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/packages/process_run/doc/shell.md b/packages/process_run/doc/shell.md index 3ad5161..d3d7072 100644 --- a/packages/process_run/doc/shell.md +++ b/packages/process_run/doc/shell.md @@ -96,7 +96,7 @@ $ alias ds='dart pub global run process_run:shell' ### Helper -`ShellLinesController` allows listeninging line from a command line script. +`ShellLinesController` allows listening line from a command line script. ```dart var controller = ShellLinesController(); @@ -202,3 +202,12 @@ Then run your commands via `osascript` like so: ``` That will prompt for the user to type his password and then will run the script. + +### Killing a shell + +You can kill a shell using the `kill()` method. It will kill the shell and all its spawn children. +By default its uses `ProcessSignal.sigterm` signal. You can specify a different signal using the `signal` parameter. + +A special trick is made when `ProcessSignal.sigkill` used as it will force killing all children processes on Windows (taskkill), MacOS and Linux (pkill). +As I was experiencing with `dhttpd`, killing the process was not really killing the server so using `sigkill` (and so taskkill and pkill) was properly +killing the server. diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index d4eabd1..7c48c47 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -297,19 +297,35 @@ abstract class Shell implements ShellCore, ShellCoreSync { io.stderr.writeln( 'killing $_killedRunId, ${_currentProcessToString()} signal $_killedProcessSignal'); - /// Workaround for linux when using sigkill to kill the children processes too - if ((io.Platform.isLinux || io.Platform.isMacOS) && - _killedProcessSignal == ProcessSignal.sigkill) { - try { - /// Kill the children - var pid = _currentProcess!.pid; - // Kill children process - runExecutableArgumentsSync('pkill', ['-P', '$pid']); - } catch (_) {} + if (_killedProcessSignal == ProcessSignal.sigkill) { + var pid = _currentProcess!.pid; + + /// Workaround when using sigkill to kill the children processes too + if (io.Platform.isLinux || io.Platform.isMacOS) { + try { + /// Kill the children + runExecutableArgumentsSync('pkill', ['-P', '$pid']); + } catch (_) {} + } else if (io.Platform.isWindows) { + try { + /// Kill the children + var pid = _currentProcess!.pid; + // Kill children process + // /pid Specifies the process ID of the process to be terminated. + // /f Specifies that processes be forcefully ended. This parameter is ignored for remote processes; all remote processes are forcefully ended. + // /t Ends the specified process and any child processes started by it. + runExecutableArgumentsSync( + 'taskkill', ['/t', '/f', '/pid', '$pid']); + } catch (_) {} + } } - /// kill the parent process - result = _currentProcess!.kill(_killedProcessSignal); + try { + /// kill the parent process + result = _currentProcess!.kill(_killedProcessSignal); + } catch (_) { + result = false; + } _clearPreviousContext(); } catch (_) { result = false; From 82891182540df65b637939971f58996b83bc6906 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 29 Oct 2024 15:17:32 +0100 Subject: [PATCH 130/150] [process_run] v1.2.2 --- packages/process_run/CHANGELOG.md | 4 ++-- packages/process_run/lib/src/shell.dart | 1 - packages/process_run/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 672e05b..33c41d2 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,6 +1,6 @@ -## 1.2.2-0 +## 1.2.2 -* Special kill behavior on linux when using sigkill (kills all children too) +* Special kill behavior on linux, mac and windows when using sigkill (kills all children too) ## 1.2.1+1 diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 7c48c47..1f60639 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -309,7 +309,6 @@ abstract class Shell implements ShellCore, ShellCoreSync { } else if (io.Platform.isWindows) { try { /// Kill the children - var pid = _currentProcess!.pid; // Kill children process // /pid Specifies the process ID of the process to be terminated. // /f Specifies that processes be forcefully ended. This parameter is ignored for remote processes; all remote processes are forcefully ended. diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index d0fc72c..10043f2 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.2-0 +version: 1.2.2 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From 2f66de0ae3d8624f43e4684a12e8979c78ba8ee9 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 29 Oct 2024 15:29:04 +0100 Subject: [PATCH 131/150] add lints remove deprecated package_api_docs --- packages/process_run/analysis_options.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/process_run/analysis_options.yaml b/packages/process_run/analysis_options.yaml index ec5c087..8a22fa0 100644 --- a/packages/process_run/analysis_options.yaml +++ b/packages/process_run/analysis_options.yaml @@ -25,6 +25,7 @@ linter: rules: - always_declare_return_types - avoid_dynamic_calls + - avoid_null_checks_in_equality_operators - avoid_print - avoid_slow_async_io - cancel_subscriptions @@ -32,14 +33,12 @@ linter: - directives_ordering - implicit_reopen - invalid_case_patterns - - invalid_runtime_check_with_js_interop_types - iterable_contains_unrelated_type - list_remove_unrelated_type - no_adjacent_strings_in_list - no_literal_bool_comparisons - no_self_assignments - omit_local_variable_types - - package_api_docs - package_prefixed_library_names - prefer_const_constructors - prefer_const_literals_to_create_immutables @@ -50,5 +49,6 @@ linter: - test_types_in_equals - throw_in_finally - unawaited_futures + - unintended_html_in_doc_comment - unnecessary_statements - - unsafe_html + - unsafe_html \ No newline at end of file From cbbbf0577f62bb224d9689cb557cf80a236f26d9 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 2 Dec 2024 01:19:03 +0100 Subject: [PATCH 132/150] feat: export ShellOnProcessCallback --- packages/process_run/lib/shell.dart | 3 ++- packages/process_run/lib/src/process_run.dart | 4 ++-- packages/process_run/lib/src/shell.dart | 4 ++-- packages/process_run/lib/src/shell_common.dart | 6 +++--- packages/process_run/test/shell_api_test.dart | 6 ++++++ packages/process_run/test/shell_common_test.dart | 4 ++-- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/packages/process_run/lib/shell.dart b/packages/process_run/lib/shell.dart index 3dcc23e..505fd67 100644 --- a/packages/process_run/lib/shell.dart +++ b/packages/process_run/lib/shell.dart @@ -60,7 +60,8 @@ export 'src/process_run.dart' executableArgumentsToString, runExecutableArgumentsSync; export 'src/prompt.dart' show promptConfirm, promptTerminate, prompt; -export 'src/shell.dart' show run, runSync, Shell, ShellException; +export 'src/shell.dart' + show run, runSync, Shell, ShellException, ShellOnProcessCallback; export 'src/shell_environment.dart' show ShellEnvironment, diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index 14b3f67..68d29cc 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -37,7 +37,7 @@ Future runExecutableArguments( bool? commandVerbose, bool? noStdoutResult, bool? noStderrResult, - void Function(Process process)? onProcess}) async { + ShellOnProcessCallback? onProcess}) async { if (verbose == true) { commandVerbose = true; stdout ??= io.stdout; @@ -317,7 +317,7 @@ Future processCmdRun(ProcessCmd cmd, StreamSink>? stderr, bool? noStdoutResult, bool? noStderrResult, - void Function(Process process)? onProcess}) async { + ShellOnProcessCallback? onProcess}) async { if (verbose == true) { stdout ??= io.stdout; stderr ??= io.stderr; diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 1f60639..a1409fc 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -447,7 +447,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { @override Future runExecutableArguments( String executable, List arguments, - {void Function(Process process)? onProcess}) async { + {ShellOnProcessCallback? onProcess}) async { return _runLocked((runId) async { return _lockedRunExecutableArguments(runId, executable, arguments, onProcess: onProcess); @@ -579,7 +579,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// Returns a process result (or throw if specified in the shell). Future _lockedRunExecutableArguments( int runId, String executable, List arguments, - {void Function(Process process)? onProcess}) { + {ShellOnProcessCallback? onProcess}) { /// Global process handler. try { _clearPreviousContext(); diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index 8869811..2a88980 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -5,7 +5,7 @@ import 'package:process_run/shell.dart'; import 'package:process_run/src/platform/platform.dart'; import 'package:process_run/src/shell_context_common.dart'; -import 'io/io_import.dart' show ProcessResult, Process, ProcessSignal; +import 'io/io_import.dart' show ProcessResult, ProcessSignal; /// shell debug flag (dev only) var shellDebug = false; // devWarning(true); // false @@ -52,7 +52,7 @@ abstract class ShellCore { /// [onProcess] is called for each started process. /// Future> run(String script, - {void Function(Process process)? onProcess}); + {ShellOnProcessCallback? onProcess}); /// Run a single [executable] with [arguments], resolving the [executable] if needed. /// @@ -61,7 +61,7 @@ abstract class ShellCore { /// [onProcess] is called for each started process. Future runExecutableArguments( String executable, List arguments, - {void Function(Process process)? onProcess}); + {ShellOnProcessCallback? onProcess}); /// Create new shell at the given path Shell cd(String path); diff --git a/packages/process_run/test/shell_api_test.dart b/packages/process_run/test/shell_api_test.dart index f219ded..7c04ad9 100644 --- a/packages/process_run/test/shell_api_test.dart +++ b/packages/process_run/test/shell_api_test.dart @@ -1,3 +1,5 @@ +import 'dart:io' as io; + import 'package:process_run/shell.dart'; import 'package:process_run/src/env_utils.dart' show kDartIsWeb; import 'package:test/test.dart'; @@ -5,6 +7,9 @@ import 'package:test/test.dart'; void main() { group('shell_api_test', () { test('public', () { + io.Process; + var processResult = io.ProcessResult(0, 0, '', ''); + expect(processResult.exitCode, 0); // ignore_for_file: unnecessary_statements if (!kDartIsWeb) { sharedStdIn; @@ -44,6 +49,7 @@ void main() { ShellEnvironmentPaths; ShellEnvironmentVars; ShellEnvironmentAliases; + ShellOnProcessCallback; whichSync; which; ProcessRunProcessResultsExt(null)?.outText; diff --git a/packages/process_run/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart index 2396bf5..e560194 100644 --- a/packages/process_run/test/shell_common_test.dart +++ b/packages/process_run/test/shell_common_test.dart @@ -113,7 +113,7 @@ class ShellMock with ShellMixin implements Shell { @override Future> run(String script, - {void Function(Process process)? onProcess}) async { + {ShellOnProcessCallback? onProcess}) async { scripts.add(script); // Take "hola" from "echo hola" var outLines = [script.split(' ').last]; @@ -127,7 +127,7 @@ class ShellMock with ShellMixin implements Shell { @override Future runExecutableArguments( String executable, List arguments, - {void Function(Process process)? onProcess}) { + {ShellOnProcessCallback? onProcess}) { // TODO: implement runExecutableArguments throw UnimplementedError(); } From 9f43a7866b0ac6e3218913f065bbd803943347a6 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 2 Dec 2024 01:19:32 +0100 Subject: [PATCH 133/150] [process_run] v1.2.2+1 --- packages/process_run/CHANGELOG.md | 3 ++- packages/process_run/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 33c41d2..578ef40 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,6 +1,7 @@ -## 1.2.2 +## 1.2.2+1 * Special kill behavior on linux, mac and windows when using sigkill (kills all children too) +* Export `ShellOnProcessCallback` ## 1.2.1+1 diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 10043f2..e419698 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.2 +version: 1.2.2+1 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From f4d4051d3de3f24e25f89c000a20ecfc4c3b7aa0 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Sun, 15 Dec 2024 16:57:31 +0100 Subject: [PATCH 134/150] fix beta lints --- packages/process_run/analysis_options.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/process_run/analysis_options.yaml b/packages/process_run/analysis_options.yaml index 8a22fa0..053e286 100644 --- a/packages/process_run/analysis_options.yaml +++ b/packages/process_run/analysis_options.yaml @@ -49,6 +49,4 @@ linter: - test_types_in_equals - throw_in_finally - unawaited_futures - - unintended_html_in_doc_comment - - unnecessary_statements - - unsafe_html \ No newline at end of file + - unnecessary_statements \ No newline at end of file From 2ef8a924111335963623d8e779e1f9c09ccf7c40 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 4 Feb 2025 16:13:36 +0100 Subject: [PATCH 135/150] simple demo --- packages/process_run/example/demo.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/process_run/example/demo.dart b/packages/process_run/example/demo.dart index f0f2e22..b6ea57c 100755 --- a/packages/process_run/example/demo.dart +++ b/packages/process_run/example/demo.dart @@ -4,14 +4,14 @@ import 'dart:io'; import 'package:process_run/process_run.dart'; Future main() async { - // Run the command - await runExecutableArguments('echo', ['hello world']); + // Calling dart + await runExecutableArguments('dart', ['--version'], verbose: true); // Stream the out to stdout - await runExecutableArguments('echo', ['hello world']); + await runExecutableArguments('echo', ['hello world'], verbose: true); - // Calling dart - await runExecutableArguments('dart', ['--version'], verbose: true); + // Run the command + await runExecutableArguments('echo', ['hello world']); // stream the output to stderr await runExecutableArguments('dart', ['--version'], stderr: stderr); From 0b3b133fa603350e35c725a964e50440f2136400 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 13 Feb 2025 09:39:12 +0100 Subject: [PATCH 136/150] dart 3.7 --- packages/process_run/example/cmd_demo.dart | 5 +- packages/process_run/example/demo_sync.dart | 3 +- packages/process_run/example/echo.dart | 69 +++- .../process_run/example/shell/common.dart | 2 +- .../example/shell/get_var_now.dart | 10 +- .../example/shell/shared_stdin.dart | 7 +- .../example/shell/shared_stdin_not_used.dart | 7 +- .../example/shell_stdio_lines_grouper.dart | 6 +- packages/process_run/example/streamer.dart | 31 +- .../process_run/example/sudo_example.dart | 9 +- packages/process_run/lib/cmd_run.dart | 27 +- packages/process_run/lib/shell.dart | 1 - .../process_run/lib/src/bin/shell/dump.dart | 5 +- .../process_run/lib/src/bin/shell/env.dart | 42 +- .../lib/src/bin/shell/env_alias.dart | 2 +- .../lib/src/bin/shell/env_alias_delete.dart | 8 +- .../lib/src/bin/shell/env_alias_dump.dart | 2 +- .../lib/src/bin/shell/env_alias_get.dart | 5 +- .../lib/src/bin/shell/env_alias_set.dart | 5 +- .../lib/src/bin/shell/env_delete.dart | 10 +- .../lib/src/bin/shell/env_edit.dart | 2 +- .../lib/src/bin/shell/env_file_content.dart | 8 +- .../lib/src/bin/shell/env_info.dart | 2 +- .../lib/src/bin/shell/env_path_delete.dart | 8 +- .../lib/src/bin/shell/env_path_dump.dart | 2 +- .../lib/src/bin/shell/env_path_get.dart | 14 +- .../lib/src/bin/shell/env_path_prepend.dart | 5 +- .../lib/src/bin/shell/env_var.dart | 7 +- .../lib/src/bin/shell/env_var_delete.dart | 17 +- .../lib/src/bin/shell/env_var_dump.dart | 7 +- .../lib/src/bin/shell/env_var_get.dart | 5 +- .../lib/src/bin/shell/env_var_set.dart | 15 +- .../process_run/lib/src/bin/shell/run.dart | 10 +- .../lib/src/bin/shell/shell_bin_command.dart | 28 +- packages/process_run/lib/src/characters.dart | 27 +- .../process_run/lib/src/common/dev_utils.dart | 2 - packages/process_run/lib/src/dartbin_cmd.dart | 11 +- .../process_run/lib/src/dartbin_impl.dart | 8 +- packages/process_run/lib/src/dev_cmd_run.dart | 26 +- .../process_run/lib/src/flutterbin_cmd.dart | 3 +- packages/process_run/lib/src/io/env_io.dart | 24 +- .../lib/src/io/env_var_delete_io.dart | 10 +- .../lib/src/io/env_var_set_io.dart | 10 +- .../process_run/lib/src/io/shared_stdin.dart | 23 +- .../process_run/lib/src/io/shell_words.dart | 7 +- .../lib/src/lines_utils_common.dart | 85 +++-- packages/process_run/lib/src/process_cmd.dart | 34 +- packages/process_run/lib/src/process_run.dart | 279 ++++++++------ packages/process_run/lib/src/shell.dart | 358 ++++++++++-------- .../process_run/lib/src/shell_common.dart | 123 +++--- .../process_run/lib/src/shell_common_io.dart | 16 +- .../lib/src/shell_context_common.dart | 31 +- .../process_run/lib/src/shell_context_io.dart | 24 +- .../lib/src/shell_environment.dart | 12 +- .../lib/src/shell_environment_common.dart | 4 +- packages/process_run/lib/src/shell_utils.dart | 62 +-- .../lib/src/shell_utils_common.dart | 14 +- packages/process_run/lib/src/stdio/stdio.dart | 29 +- packages/process_run/lib/src/user_config.dart | 66 ++-- packages/process_run/lib/src/which.dart | 28 +- packages/process_run/pubspec.yaml | 2 +- .../process_run/test/bin/bin_shell_test.dart | 18 +- .../test/bin/compiled_bin_shell_test.dart | 5 +- packages/process_run/test/cmd_run_test.dart | 6 +- packages/process_run/test/compile_test.dart | 99 ++--- .../test/dart_compile_js_test.dart | 7 +- packages/process_run/test/dart_doc_test.dart | 18 +- packages/process_run/test/dartbin_test.dart | 76 ++-- packages/process_run/test/echo_test.dart | 136 ++++--- .../process_run/test/flutterbin_cmd_test.dart | 6 +- .../test/flutterbin_impl_test.dart | 12 +- packages/process_run/test/package_test.dart | 6 +- .../process_run/test/process_cmd_test.dart | 43 ++- .../test/process_run_in_test2_.dart | 6 +- .../test/process_run_in_test_.dart | 14 +- .../test/process_run_out_test_.dart | 16 +- .../process_run/test/process_run_test.dart | 145 ++++--- .../test/process_run_test_common.dart | 5 +- .../process_run/test/shell_common_test.dart | 43 ++- .../test/shell_environment_test.dart | 131 ++++--- .../test/shell_lines_controller_test.dart | 44 ++- packages/process_run/test/shell_run_test.dart | 54 ++- .../test/shell_stdio_lines_grouper_test.dart | 101 +++-- packages/process_run/test/shell_test.dart | 203 ++++++---- .../process_run/test/src/compile_echo.dart | 6 +- .../process_run/test/src/compile_shell.dart | 3 +- .../test/src/compile_streamer.dart | 8 +- .../process_run/test/src/shell_impl_test.dart | 191 +++++----- .../test/src_dartbin_cmd_test.dart | 26 +- .../test/src_shell_utils_test.dart | 60 +-- .../test/src_user_config_test.dart | 107 +++--- packages/process_run/test/which_test.dart | 11 +- packages/process_run_test/pubspec.yaml | 2 +- 93 files changed, 1953 insertions(+), 1359 deletions(-) diff --git a/packages/process_run/example/cmd_demo.dart b/packages/process_run/example/cmd_demo.dart index 0edc81f..99fe6e0 100755 --- a/packages/process_run/example/cmd_demo.dart +++ b/packages/process_run/example/cmd_demo.dart @@ -41,8 +41,9 @@ Future main() async { // Calling dart script // $ dart example/my_script.dart my_first_arg my_second_arg await runCmd( - DartCmd(['example/my_script.dart', 'my_first_arg', 'my_second_arg']), - commandVerbose: true); + DartCmd(['example/my_script.dart', 'my_first_arg', 'my_second_arg']), + commandVerbose: true, + ); // Calling pub // > $ pub --version diff --git a/packages/process_run/example/demo_sync.dart b/packages/process_run/example/demo_sync.dart index be91ee3..e74e8a4 100755 --- a/packages/process_run/example/demo_sync.dart +++ b/packages/process_run/example/demo_sync.dart @@ -8,7 +8,8 @@ void main() { var results = shell.runSync('echo "Hello world"'); var result = results.first; stdout.writeln( - 'output: "${result.outText.trim()}" exitCode: ${result.exitCode}'); + 'output: "${result.outText.trim()}" exitCode: ${result.exitCode}', + ); // should display: output: "Hello world" exitCode: 0 // Run the command diff --git a/packages/process_run/example/echo.dart b/packages/process_run/example/echo.dart index 2387748..327bfb7 100755 --- a/packages/process_run/example/echo.dart +++ b/packages/process_run/example/echo.dart @@ -44,26 +44,59 @@ Future main(List arguments) async { final parser = ArgParser(allowTrailingOptions: false); parser.addFlag('help', abbr: 'h', help: 'Usage help', negatable: false); parser.addFlag('verbose', abbr: 'v', help: 'Verbose', negatable: false); - parser.addOption('stdout', - abbr: 'o', help: 'stdout content as string', defaultsTo: null); - parser.addOption('stdout-hex', - abbr: 'p', help: 'stdout as hexa string', defaultsTo: null); - parser.addOption('stdout-env', - abbr: 'r', help: 'echo env variable to stdout', defaultsTo: null); - parser.addOption('stderr', - abbr: 'e', help: 'stderr content as string', defaultsTo: null); - parser.addOption('stderr-hex', - abbr: 'f', help: 'stderr as hexa string', defaultsTo: null); - parser.addFlag('write-line', - abbr: 'l', help: 'Write an additional new line', negatable: false); - parser.addFlag('stdin', - abbr: 'i', help: 'Handle first line of stdin', negatable: false); + parser.addOption( + 'stdout', + abbr: 'o', + help: 'stdout content as string', + defaultsTo: null, + ); + parser.addOption( + 'stdout-hex', + abbr: 'p', + help: 'stdout as hexa string', + defaultsTo: null, + ); + parser.addOption( + 'stdout-env', + abbr: 'r', + help: 'echo env variable to stdout', + defaultsTo: null, + ); + parser.addOption( + 'stderr', + abbr: 'e', + help: 'stderr content as string', + defaultsTo: null, + ); + parser.addOption( + 'stderr-hex', + abbr: 'f', + help: 'stderr as hexa string', + defaultsTo: null, + ); + parser.addFlag( + 'write-line', + abbr: 'l', + help: 'Write an additional new line', + negatable: false, + ); + parser.addFlag( + 'stdin', + abbr: 'i', + help: 'Handle first line of stdin', + negatable: false, + ); parser.addOption('wait', help: 'Wait milliseconds'); - parser.addFlag('all-env', - help: 'Display all environment (vars and paths) in json pretty print'); + parser.addFlag( + 'all-env', + help: 'Display all environment (vars and paths) in json pretty print', + ); parser.addOption('exit-code', abbr: 'x', help: 'Exit code to return'); - parser.addFlag('version', - help: 'Print the command version', negatable: false); + parser.addFlag( + 'version', + help: 'Print the command version', + negatable: false, + ); final argsResult = parser.parse(arguments); diff --git a/packages/process_run/example/shell/common.dart b/packages/process_run/example/shell/common.dart index 2ef94cb..a096fd6 100644 --- a/packages/process_run/example/shell/common.dart +++ b/packages/process_run/example/shell/common.dart @@ -7,5 +7,5 @@ var shell = Shell(environment: env); var commonAliases = { 'ds': 'dart run bin/shell.dart', 'write': 'dart run example/echo.dart --write-line', - 'prompt': 'dart run example/echo.dart --write-line --stdin' + 'prompt': 'dart run example/echo.dart --write-line --stdin', }; diff --git a/packages/process_run/example/shell/get_var_now.dart b/packages/process_run/example/shell/get_var_now.dart index 9307616..0205352 100644 --- a/packages/process_run/example/shell/get_var_now.dart +++ b/packages/process_run/example/shell/get_var_now.dart @@ -1,8 +1,10 @@ import 'common.dart'; Future main() async { - await shell.run('ds env var get ' - 'TEST_USER_VAR_NOW ' - 'TEST_LOCAL_VAR_NOW ' - 'TEST_VAR_NOW '); + await shell.run( + 'ds env var get ' + 'TEST_USER_VAR_NOW ' + 'TEST_LOCAL_VAR_NOW ' + 'TEST_VAR_NOW ', + ); } diff --git a/packages/process_run/example/shell/shared_stdin.dart b/packages/process_run/example/shell/shared_stdin.dart index 69c9557..0d5c690 100644 --- a/packages/process_run/example/shell/shared_stdin.dart +++ b/packages/process_run/example/shell/shared_stdin.dart @@ -18,8 +18,11 @@ prompt // Create a new shell var echoEnv = ShellEnvironment()..aliases.addAll(commonAliases); - echoAndPromptShell = - Shell(environment: echoEnv, stdin: sharedStdIn, commandVerbose: false); + echoAndPromptShell = Shell( + environment: echoEnv, + stdin: sharedStdIn, + commandVerbose: false, + ); await echoAndPromptShell.run(''' # Wait for input write "Third time" diff --git a/packages/process_run/example/shell/shared_stdin_not_used.dart b/packages/process_run/example/shell/shared_stdin_not_used.dart index 4f4e2db..2b252fc 100644 --- a/packages/process_run/example/shell/shared_stdin_not_used.dart +++ b/packages/process_run/example/shell/shared_stdin_not_used.dart @@ -3,8 +3,11 @@ import 'package:process_run/shell.dart'; import '../echo.dart'; // Shell with hello command and sharedStdIn -var sharedStdinSilentShell = - Shell(environment: echoEnv, stdin: sharedStdIn, commandVerbose: false); +var sharedStdinSilentShell = Shell( + environment: echoEnv, + stdin: sharedStdIn, + commandVerbose: false, +); Future main() async { await sharedStdinSilentShell.run(''' diff --git a/packages/process_run/example/shell_stdio_lines_grouper.dart b/packages/process_run/example/shell_stdio_lines_grouper.dart index f6d52b4..24404e0 100644 --- a/packages/process_run/example/shell_stdio_lines_grouper.dart +++ b/packages/process_run/example/shell_stdio_lines_grouper.dart @@ -6,7 +6,9 @@ void main() async { var echo = await compileEchoExample(); var options = ShellOptions( - verbose: true, environment: ShellEnvironment()..aliases['echo'] = echo); + verbose: true, + environment: ShellEnvironment()..aliases['echo'] = echo, + ); Future printHello12345Slow() async { var shell = Shell(options: options); @@ -23,6 +25,6 @@ echo --wait 100 --stderr hello3 --write-line var stdio = shellStdioLinesGrouper; await Future.wait([ stdio.runZoned(() => printHello12345Slow()), - stdio.runZoned(() => printHello12345Slow()) + stdio.runZoned(() => printHello12345Slow()), ]); } diff --git a/packages/process_run/example/streamer.dart b/packages/process_run/example/streamer.dart index 98a0aa7..f93e720 100755 --- a/packages/process_run/example/streamer.dart +++ b/packages/process_run/example/streamer.dart @@ -37,14 +37,29 @@ Future main(List arguments) async { final parser = ArgParser(allowTrailingOptions: false); parser.addFlag('help', abbr: 'h', help: 'Usage help', negatable: false); // parser.addFlag('verbose', abbr: 'v', help: 'Verbose', negatable: false); - parser.addOption(udelayOption, - abbr: 'd', help: 'delay in microseconds', defaultsTo: null); - parser.addOption('count', - abbr: 'c', help: 'count of print', defaultsTo: null); - parser.addOption('timeout', - abbr: 't', help: 'timeout in millis', defaultsTo: null); - parser.addFlag('version', - help: 'Print the command version', negatable: false); + parser.addOption( + udelayOption, + abbr: 'd', + help: 'delay in microseconds', + defaultsTo: null, + ); + parser.addOption( + 'count', + abbr: 'c', + help: 'count of print', + defaultsTo: null, + ); + parser.addOption( + 'timeout', + abbr: 't', + help: 'timeout in millis', + defaultsTo: null, + ); + parser.addFlag( + 'version', + help: 'Print the command version', + negatable: false, + ); final argsResult = parser.parse(arguments); diff --git a/packages/process_run/example/sudo_example.dart b/packages/process_run/example/sudo_example.dart index 813219d..979d116 100644 --- a/packages/process_run/example/sudo_example.dart +++ b/packages/process_run/example/sudo_example.dart @@ -9,10 +9,11 @@ void main(List arguments) async { /// Use an alias for simplicity (only need to refer to sudo instead of sudo --stdin var env = ShellEnvironment()..aliases['sudo'] = 'sudo --stdin'; var shell = Shell( - stdin: sharedStdIn, - // lsof return exitCode 1 if not found - environment: env, - throwOnError: false); + stdin: sharedStdIn, + // lsof return exitCode 1 if not found + environment: env, + throwOnError: false, + ); await shell.run('sudo lsof -i:22'); // second time should not ask for password diff --git a/packages/process_run/lib/cmd_run.dart b/packages/process_run/lib/cmd_run.dart index 47a9565..d0e965f 100644 --- a/packages/process_run/lib/cmd_run.dart +++ b/packages/process_run/lib/cmd_run.dart @@ -68,15 +68,18 @@ export 'src/webdev.dart' show WebDevCmd; /// stdout/error if [verbose] is true. /// [verbose] implies [commandVerbose] /// -Future runCmd(ProcessCmd cmd, - {bool? verbose, - bool? commandVerbose, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr}) => - processCmdRun(cmd, - verbose: verbose, - commandVerbose: commandVerbose, - stdin: stdin, - stdout: stdout, - stderr: stderr); +Future runCmd( + ProcessCmd cmd, { + bool? verbose, + bool? commandVerbose, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, +}) => processCmdRun( + cmd, + verbose: verbose, + commandVerbose: commandVerbose, + stdin: stdin, + stdout: stdout, + stderr: stderr, +); diff --git a/packages/process_run/lib/shell.dart b/packages/process_run/lib/shell.dart index 505fd67..4535214 100644 --- a/packages/process_run/lib/shell.dart +++ b/packages/process_run/lib/shell.dart @@ -51,7 +51,6 @@ export 'src/process_cmd.dart' show processCmdToDebugString, processResultToDebugString, - /// Deprecated ProcessCmd; export 'src/process_run.dart' diff --git a/packages/process_run/lib/src/bin/shell/dump.dart b/packages/process_run/lib/src/bin/shell/dump.dart index d0ce1f9..9dfd2ec 100644 --- a/packages/process_run/lib/src/bin/shell/dump.dart +++ b/packages/process_run/lib/src/bin/shell/dump.dart @@ -2,8 +2,9 @@ import 'package:process_run/src/io/io.dart'; /// Dump a string map void dumpStringMap(Map map) { - var keys = map.keys.toList() - ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); + var keys = + map.keys.toList() + ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); for (var key in keys) { var value = map[key]; stdout.writeln('$key: $value'); diff --git a/packages/process_run/lib/src/bin/shell/env.dart b/packages/process_run/lib/src/bin/shell/env.dart index 80b8e10..adabe0a 100644 --- a/packages/process_run/lib/src/bin/shell/env.dart +++ b/packages/process_run/lib/src/bin/shell/env.dart @@ -20,10 +20,19 @@ import 'import.dart'; class ShellEnvCommandBase extends ShellBinCommand { /// Shell env command base ShellEnvCommandBase({required super.name, super.description}) { - parser.addFlag(flagLocal, - abbr: 'l', help: 'Use local env', negatable: false, defaultsTo: true); - parser.addFlag(flagUser, - abbr: 'u', help: 'Use user env instead of local env', negatable: false); + parser.addFlag( + flagLocal, + abbr: 'l', + help: 'Use local env', + negatable: false, + defaultsTo: true, + ); + parser.addFlag( + flagUser, + abbr: 'u', + help: 'Use user env instead of local env', + negatable: false, + ); } /// Local env (default) @@ -60,16 +69,19 @@ class ShellEnvCommandBase extends ShellBinCommand { /// Env file path String? get envFilePath => _envFilePath; - String? get _envFilePath => local - ? getLocalEnvFilePath(userEnvironment) - : getUserEnvFilePath(userEnvironment); + String? get _envFilePath => + local + ? getLocalEnvFilePath(userEnvironment) + : getUserEnvFilePath(userEnvironment); List? _sampleFileContent; /// Sample file content - List get sampleFileContent => _sampleFileContent ??= () { - var content = local - ? ''' + List get sampleFileContent => + _sampleFileContent ??= () { + var content = + local + ? ''' # Local Environment path and variable for `Shell.run` calls. # # `path(s)` is a list of path, `var(s)` is a key/value map. @@ -85,7 +97,7 @@ class ShellEnvCommandBase extends ShellBinCommand { # alias: # qr: /path/to/my_qr_app ''' - : ''' + : ''' # Environment path and variable for `Shell.run` calls. # # `path` is a list of path, `var` is a key/value map. @@ -113,10 +125,10 @@ class ShellEnvCommandBase extends ShellBinCommand { class ShellEnvCommand extends ShellEnvCommandBase { /// Shell env command ShellEnvCommand() - : super( - name: commandEnv, - description: - 'Manipulate local and global env vars, paths and aliases') { + : super( + name: commandEnv, + description: 'Manipulate local and global env vars, paths and aliases', + ) { addCommand(ShellEnvVarCommand()); addCommand(ShellEnvEditCommand()); addCommand(ShellEnvDeleteCommand()); diff --git a/packages/process_run/lib/src/bin/shell/env_alias.dart b/packages/process_run/lib/src/bin/shell/env_alias.dart index 7805157..500bf05 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias.dart @@ -9,7 +9,7 @@ import 'import.dart'; class ShellEnvAliasCommand extends ShellBinCommand { /// Alias operations ShellEnvAliasCommand() - : super(name: commandEnvAliases, description: 'Alias operations') { + : super(name: commandEnvAliases, description: 'Alias operations') { addCommand(ShellEnvAliasDumpCommand()); addCommand(ShellEnvAliasSetCommand()); addCommand(ShellEnvAliasGetCommand()); diff --git a/packages/process_run/lib/src/bin/shell/env_alias_delete.dart b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart index f71c1bf..8afe3ad 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_delete.dart @@ -9,10 +9,10 @@ import 'package:process_run/src/io/io.dart'; class ShellEnvAliasDeleteCommand extends ShellEnvCommandBase { /// Shell env alias delete command. ShellEnvAliasDeleteCommand() - : super( - name: 'delete', - description: 'Delete an alias from a user/local config file', - ); + : super( + name: 'delete', + description: 'Delete an alias from a user/local config file', + ); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/env_alias_dump.dart b/packages/process_run/lib/src/bin/shell/env_alias_dump.dart index 2e203d8..2fd02ba 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_dump.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_dump.dart @@ -7,7 +7,7 @@ import 'import.dart'; class ShellEnvAliasDumpCommand extends ShellBinCommand { /// Shell env alias dump command. ShellEnvAliasDumpCommand() - : super(name: 'dump', description: 'Dump process_run aliases'); + : super(name: 'dump', description: 'Dump process_run aliases'); @override FutureOr onRun() async { diff --git a/packages/process_run/lib/src/bin/shell/env_alias_get.dart b/packages/process_run/lib/src/bin/shell/env_alias_get.dart index 9cc6d50..d0eca64 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_get.dart @@ -9,10 +9,7 @@ import 'dump.dart'; class ShellEnvAliasGetCommand extends ShellEnvCommandBase { /// Shell env alias get command. ShellEnvAliasGetCommand() - : super( - name: 'get', - description: 'Get an alias from the config file', - ); + : super(name: 'get', description: 'Get an alias from the config file'); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/env_alias_set.dart b/packages/process_run/lib/src/bin/shell/env_alias_set.dart index 9ace091..def87d7 100644 --- a/packages/process_run/lib/src/bin/shell/env_alias_set.dart +++ b/packages/process_run/lib/src/bin/shell/env_alias_set.dart @@ -9,10 +9,7 @@ import 'package:process_run/src/io/io.dart'; class ShellEnvAliasSetCommand extends ShellEnvCommandBase { /// Shell env alias set command. ShellEnvAliasSetCommand() - : super( - name: 'set', - description: 'Set process_run alias', - ); + : super(name: 'set', description: 'Set process_run alias'); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/env_delete.dart b/packages/process_run/lib/src/bin/shell/env_delete.dart index cf3a1f3..9e00928 100644 --- a/packages/process_run/lib/src/bin/shell/env_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_delete.dart @@ -9,9 +9,13 @@ import 'env.dart'; class ShellEnvDeleteCommand extends ShellEnvCommandBase { /// Shell env delete command. ShellEnvDeleteCommand() - : super(name: 'delete', description: 'Delete the environment file') { - parser.addFlag(flagForce, - abbr: 'f', help: 'Force deletion, no prompt', negatable: false); + : super(name: 'delete', description: 'Delete the environment file') { + parser.addFlag( + flagForce, + abbr: 'f', + help: 'Force deletion, no prompt', + negatable: false, + ); } @override diff --git a/packages/process_run/lib/src/bin/shell/env_edit.dart b/packages/process_run/lib/src/bin/shell/env_edit.dart index 32c04dd..8565a9a 100644 --- a/packages/process_run/lib/src/bin/shell/env_edit.dart +++ b/packages/process_run/lib/src/bin/shell/env_edit.dart @@ -8,7 +8,7 @@ import 'env.dart'; class ShellEnvEditCommand extends ShellEnvCommandBase { /// Shell env edit command. ShellEnvEditCommand() - : super(name: 'edit', description: 'Edit the environment file'); + : super(name: 'edit', description: 'Edit the environment file'); @override FutureOr onRun() async { diff --git a/packages/process_run/lib/src/bin/shell/env_file_content.dart b/packages/process_run/lib/src/bin/shell/env_file_content.dart index 31ab86f..de9c05b 100644 --- a/packages/process_run/lib/src/bin/shell/env_file_content.dart +++ b/packages/process_run/lib/src/bin/shell/env_file_content.dart @@ -59,8 +59,12 @@ class FileContent { } /// Supported top level [parentKeys] - bool writeKeyValue(List parentKeys, String key, - {bool delete = false, String? value}) { + bool writeKeyValue( + List parentKeys, + String key, { + bool delete = false, + String? value, + }) { // Remove alias header var modified = false; var insertTopLevelKey = false; diff --git a/packages/process_run/lib/src/bin/shell/env_info.dart b/packages/process_run/lib/src/bin/shell/env_info.dart index 2856e2d..32675ca 100644 --- a/packages/process_run/lib/src/bin/shell/env_info.dart +++ b/packages/process_run/lib/src/bin/shell/env_info.dart @@ -7,7 +7,7 @@ import 'import.dart'; class ShellEnvInfoCommand extends ShellBinCommand { /// pub run process_run:shell run ShellEnvInfoCommand() - : super(name: 'info', description: 'Display environment info'); + : super(name: 'info', description: 'Display environment info'); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/env_path_delete.dart b/packages/process_run/lib/src/bin/shell/env_path_delete.dart index 5b73d49..a82bdf4 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_delete.dart @@ -9,10 +9,10 @@ import 'package:process_run/src/io/io.dart'; class ShellEnvPathDeleteCommand extends ShellEnvCommandBase { /// Shell env path delete command. ShellEnvPathDeleteCommand() - : super( - name: 'delete', - description: 'Delete paths for executable lookup in config file', - ); + : super( + name: 'delete', + description: 'Delete paths for executable lookup in config file', + ); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/env_path_dump.dart b/packages/process_run/lib/src/bin/shell/env_path_dump.dart index 30e3af6..ec0e5da 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_dump.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_dump.dart @@ -7,7 +7,7 @@ import 'import.dart'; class ShellEnvPathDumpCommand extends ShellBinCommand { /// Shell env path dump command. ShellEnvPathDumpCommand() - : super(name: 'dump', description: 'Dump process_run paths'); + : super(name: 'dump', description: 'Dump process_run paths'); @override FutureOr onRun() async { diff --git a/packages/process_run/lib/src/bin/shell/env_path_get.dart b/packages/process_run/lib/src/bin/shell/env_path_get.dart index 07ce82b..bdc5e6e 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_get.dart @@ -8,10 +8,7 @@ import 'package:process_run/src/io/io.dart'; class ShellEnvPathGetCommand extends ShellEnvCommandBase { /// Shell env path get command. ShellEnvPathGetCommand() - : super( - name: 'get', - description: 'Get the paths from environment', - ); + : super(name: 'get', description: 'Get the paths from environment'); @override void printUsage() { @@ -34,10 +31,11 @@ class ShellEnvPathGetCommand extends ShellEnvCommandBase { if (verbose) { stdout.writeln('File $label: $envFilePath'); } - dumpStringList(ShellEnvironment() - .paths - .where((element) => paths.contains(element)) - .toList()); + dumpStringList( + ShellEnvironment().paths + .where((element) => paths.contains(element)) + .toList(), + ); return true; } diff --git a/packages/process_run/lib/src/bin/shell/env_path_prepend.dart b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart index d7b051f..f3eaac9 100644 --- a/packages/process_run/lib/src/bin/shell/env_path_prepend.dart +++ b/packages/process_run/lib/src/bin/shell/env_path_prepend.dart @@ -9,10 +9,7 @@ import 'package:process_run/src/io/io.dart'; class ShellEnvPathPrependCommand extends ShellEnvCommandBase { /// Shell env path prepend command. ShellEnvPathPrependCommand() - : super( - name: 'prepend', - description: 'Prepend path for executable lookup', - ); + : super(name: 'prepend', description: 'Prepend path for executable lookup'); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/env_var.dart b/packages/process_run/lib/src/bin/shell/env_var.dart index 4301eda..ceeb773 100644 --- a/packages/process_run/lib/src/bin/shell/env_var.dart +++ b/packages/process_run/lib/src/bin/shell/env_var.dart @@ -10,9 +10,10 @@ import 'import.dart'; class ShellEnvVarCommand extends ShellEnvCommandBase { /// Shell env var command. ShellEnvVarCommand() - : super( - name: commandEnvVar, - description: 'Manipulate local and global env variables') { + : super( + name: commandEnvVar, + description: 'Manipulate local and global env variables', + ) { addCommand(ShellEnvVarDumpCommand()); addCommand(ShellEnvVarSetCommand()); addCommand(ShellEnvVarGetCommand()); diff --git a/packages/process_run/lib/src/bin/shell/env_var_delete.dart b/packages/process_run/lib/src/bin/shell/env_var_delete.dart index 5bc4043..f9725a7 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_delete.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_delete.dart @@ -6,16 +6,19 @@ import 'package:process_run/src/io/io.dart'; /// Delete an environment variable from a user/local config file class ShellEnvVarDeleteCommand extends ShellEnvCommandBase { - late final _helper = - ShellEnvVarDeleteIoHelper(shell: Shell(), local: local, verbose: verbose); + late final _helper = ShellEnvVarDeleteIoHelper( + shell: Shell(), + local: local, + verbose: verbose, + ); /// Delete an environment variable from a user/local config file ShellEnvVarDeleteCommand() - : super( - name: 'delete', - description: - 'Delete an environment variable from a user/local config file', - ); + : super( + name: 'delete', + description: + 'Delete an environment variable from a user/local config file', + ); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/env_var_dump.dart b/packages/process_run/lib/src/bin/shell/env_var_dump.dart index 4424f04..da908e2 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_dump.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_dump.dart @@ -6,13 +6,14 @@ import 'import.dart'; class ShellEnvVarDumpCommand extends ShellBinCommand { /// Dump environment variable ShellEnvVarDumpCommand() - : super(name: 'dump', description: 'Dump environment variable'); + : super(name: 'dump', description: 'Dump environment variable'); @override FutureOr onRun() async { var vars = ShellEnvironment().vars; - var keys = vars.keys.toList() - ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); + var keys = + vars.keys.toList() + ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); for (var key in keys) { var value = vars[key]; stdout.writeln('$key: $value'); diff --git a/packages/process_run/lib/src/bin/shell/env_var_get.dart b/packages/process_run/lib/src/bin/shell/env_var_get.dart index 85692cf..d38ad19 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_get.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_get.dart @@ -11,10 +11,7 @@ class ShellEnvVarGetCommand extends ShellEnvCommandBase { /// Get an environment variable from a user/local config file ShellEnvVarGetCommand() - : super( - name: 'get', - description: 'Get environment variable', - ); + : super(name: 'get', description: 'Get environment variable'); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/env_var_set.dart b/packages/process_run/lib/src/bin/shell/env_var_set.dart index 19c78be..646dc0d 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_set.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_set.dart @@ -6,15 +6,18 @@ import 'package:process_run/src/io/io.dart'; /// Set an environment variable in a user/local config file class ShellEnvVarSetCommand extends ShellEnvCommandBase { - late final _helper = - ShellEnvVarSetIoHelper(shell: Shell(), local: local, verbose: verbose); + late final _helper = ShellEnvVarSetIoHelper( + shell: Shell(), + local: local, + verbose: verbose, + ); /// Set an environment variable in a user/local config file ShellEnvVarSetCommand() - : super( - name: 'set', - description: 'Set environment variable in a user/local config file', - ); + : super( + name: 'set', + description: 'Set environment variable in a user/local config file', + ); @override void printUsage() { diff --git a/packages/process_run/lib/src/bin/shell/run.dart b/packages/process_run/lib/src/bin/shell/run.dart index 4537cbe..2040149 100644 --- a/packages/process_run/lib/src/bin/shell/run.dart +++ b/packages/process_run/lib/src/bin/shell/run.dart @@ -8,9 +8,10 @@ import 'import.dart'; class ShellRunCommand extends ShellBinCommand { /// pub run process_run:shell run ShellRunCommand() - : super( - name: commandRun, - description: 'Run a command using user environment') { + : super( + name: commandRun, + description: 'Run a command using user environment', + ) { parser.addFlag(flagInfo, abbr: 'i', help: 'display info', negatable: false); } @@ -20,7 +21,8 @@ class ShellRunCommand extends ShellBinCommand { stdout.writeln(); stdout.writeln('Usage: $script run '); stdout.writeln( - ' command being a command line as a single argument, examples:'); + ' command being a command line as a single argument, examples:', + ); stdout.writeln(" - 'firebase deploy'"); stdout.writeln(' - script.bat'); stdout.writeln(' - script.sh'); diff --git a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart index 30621df..b358ff6 100644 --- a/packages/process_run/lib/src/bin/shell/shell_bin_command.dart +++ b/packages/process_run/lib/src/bin/shell/shell_bin_command.dart @@ -94,12 +94,13 @@ class ShellBinCommand { final _commands = {}; /// Shell bin command - ShellBinCommand( - {required this.name, - Version? version, - ArgParser? parser, - ShellBinCommand? parent, - String? description}) { + ShellBinCommand({ + required this.name, + Version? version, + ArgParser? parser, + ShellBinCommand? parent, + String? description, + }) { //_onRun = onRun; _parser = parser; _description = description; @@ -108,10 +109,17 @@ class ShellBinCommand { parser = this.parser; // Add missing common commands if (parent == null) { - parser.addFlag(flagVersion, - help: 'Print the command version', negatable: false); - parser.addFlag(flagVerbose, - abbr: 'v', help: 'Verbose mode', negatable: false); + parser.addFlag( + flagVersion, + help: 'Print the command version', + negatable: false, + ); + parser.addFlag( + flagVerbose, + abbr: 'v', + help: 'Verbose mode', + negatable: false, + ); } parser.addFlag(flagHelp, abbr: 'h', help: 'Usage help', negatable: false); } diff --git a/packages/process_run/lib/src/characters.dart b/packages/process_run/lib/src/characters.dart index 3a6b17c..e538fce 100644 --- a/packages/process_run/lib/src/characters.dart +++ b/packages/process_run/lib/src/characters.dart @@ -8,19 +8,20 @@ /// /// from quiver /// -bool isWhitespace(int rune) => ((rune >= 0x0009 && rune <= 0x000D) || - rune == 0x0020 || - rune == 0x0085 || - rune == 0x00A0 || - rune == 0x1680 || - rune == 0x180E || - (rune >= 0x2000 && rune <= 0x200A) || - rune == 0x2028 || - rune == 0x2029 || - rune == 0x202F || - rune == 0x205F || - rune == 0x3000 || - rune == 0xFEFF); +bool isWhitespace(int rune) => + ((rune >= 0x0009 && rune <= 0x000D) || + rune == 0x0020 || + rune == 0x0085 || + rune == 0x00A0 || + rune == 0x1680 || + rune == 0x180E || + (rune >= 0x2000 && rune <= 0x200A) || + rune == 0x2028 || + rune == 0x2029 || + rune == 0x202F || + rune == 0x205F || + rune == 0x3000 || + rune == 0xFEFF); /// True if empty or starts with white space bool startsWithWhitespace(String text) => diff --git a/packages/process_run/lib/src/common/dev_utils.dart b/packages/process_run/lib/src/common/dev_utils.dart index 9c977eb..7b090c6 100644 --- a/packages/process_run/lib/src/common/dev_utils.dart +++ b/packages/process_run/lib/src/common/dev_utils.dart @@ -25,7 +25,6 @@ void devPrint(Object? object) { } @Deprecated('Dev only') - /// Warning in dev mode T devWarning(T t) => t; @@ -45,7 +44,6 @@ void _devError([Object? msg]) { } @Deprecated('Dev only') - /// Error in dev mode void devError([String? msg]) => _devError(msg); diff --git a/packages/process_run/lib/src/dartbin_cmd.dart b/packages/process_run/lib/src/dartbin_cmd.dart index 8f9698a..1a5f0a9 100644 --- a/packages/process_run/lib/src/dartbin_cmd.dart +++ b/packages/process_run/lib/src/dartbin_cmd.dart @@ -30,7 +30,7 @@ class _DartBinCmd extends ProcessCmd { final String binName; _DartBinCmd(this.binName, List arguments) - : super(join(dartSdkBinDirPath, binName), arguments); + : super(join(dartSdkBinDirPath, binName), arguments); @override String toString() => executableArgumentsToString(binName, arguments); @@ -43,7 +43,7 @@ class PubRunCmd extends PubCmd { /// Call pub run PubRunCmd(this._command, this._arguments) - : super(['run', _command, ..._arguments]); + : super(['run', _command, ..._arguments]); @override String toString() => executableArgumentsToString(_command, _arguments); @@ -56,7 +56,7 @@ class PubGlobalRunCmd extends PubCmd { /// Call pub global run PubGlobalRunCmd(this._command, this._arguments) - : super(['global', 'run', _command, ..._arguments]); + : super(['global', 'run', _command, ..._arguments]); @override String toString() => executableArgumentsToString(_command, _arguments); @@ -87,8 +87,9 @@ Future getDartBinVersion() async { // $ dart --version // Linux: Dart VM version: 2.7.0 (Unknown timestamp) on "linux_x64" - var result = - await runExecutableArguments('dart', ['--version'], verbose: false); + var result = await runExecutableArguments('dart', [ + '--version', + ], verbose: false); // Take from stderr first var version = parseDartBinVersionOutput(result.stderr.toString().trim()); diff --git a/packages/process_run/lib/src/dartbin_impl.dart b/packages/process_run/lib/src/dartbin_impl.dart index e8fec33..07893c7 100644 --- a/packages/process_run/lib/src/dartbin_impl.dart +++ b/packages/process_run/lib/src/dartbin_impl.dart @@ -20,8 +20,9 @@ String? resolveDartExecutable({Map? environment}) { if (!_dartExecutableLock) { _dartExecutableLock = true; try { - var dartExecutable = - findDartExecutableSync(getUserPaths(environment ?? userEnvironment)); + var dartExecutable = findDartExecutableSync( + getUserPaths(environment ?? userEnvironment), + ); // Handle the flutter case if (dartExecutable != null) { return findFlutterDartExecutableSync(dirname(dartExecutable)) ?? @@ -48,7 +49,8 @@ String? _resolvedDartExecutable; /// /// Get dart vm either from executable or using the which command /// -String? get resolvedDartExecutable => _resolvedDartExecutable ??= () { +String? get resolvedDartExecutable => + _resolvedDartExecutable ??= () { var executable = platformResolvedExecutable; if (executable != null) { return executable; diff --git a/packages/process_run/lib/src/dev_cmd_run.dart b/packages/process_run/lib/src/dev_cmd_run.dart index 89f4430..891d56e 100644 --- a/packages/process_run/lib/src/dev_cmd_run.dart +++ b/packages/process_run/lib/src/dev_cmd_run.dart @@ -5,15 +5,19 @@ import 'package:process_run/src/io/io.dart'; /// dev only run command @Deprecated('Dev only, verbose') -Future devRunCmd(ProcessCmd cmd, - {bool? verbose, - bool? commandVerbose, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr}) async { - return runCmd(cmd, - verbose: true, - commandVerbose: commandVerbose, - stdin: stdin, - stderr: stderr); +Future devRunCmd( + ProcessCmd cmd, { + bool? verbose, + bool? commandVerbose, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, +}) async { + return runCmd( + cmd, + verbose: true, + commandVerbose: commandVerbose, + stdin: stdin, + stderr: stderr, + ); } diff --git a/packages/process_run/lib/src/flutterbin_cmd.dart b/packages/process_run/lib/src/flutterbin_cmd.dart index f707952..6c4fc9d 100644 --- a/packages/process_run/lib/src/flutterbin_cmd.dart +++ b/packages/process_run/lib/src/flutterbin_cmd.dart @@ -19,7 +19,6 @@ set flutterExecutablePath(String? path) { } @Deprecated('Dev only') - /// Flutter command ProcessCmd flutterCmd(List arguments) => FlutterCmd(arguments); @@ -33,7 +32,7 @@ bool get isFlutterSupportedSync => flutterExecutablePath != null; class FlutterCmd extends ProcessCmd { /// Somehow flutter requires runInShell on Linux, does not hurt on windows FlutterCmd(List arguments) - : super(flutterExecutablePath!, arguments, runInShell: true); + : super(flutterExecutablePath!, arguments, runInShell: true); @override String toString() => executableArgumentsToString('flutter', arguments); diff --git a/packages/process_run/lib/src/io/env_io.dart b/packages/process_run/lib/src/io/env_io.dart index 0464afe..241bbbf 100644 --- a/packages/process_run/lib/src/io/env_io.dart +++ b/packages/process_run/lib/src/io/env_io.dart @@ -16,8 +16,11 @@ class ShellEnvIoHelper { final bool verbose; /// Create a helper - ShellEnvIoHelper( - {required this.shell, required this.local, required this.verbose}); + ShellEnvIoHelper({ + required this.shell, + required this.local, + required this.verbose, + }); /// Label String get label => local ? 'local' : 'user'; @@ -37,16 +40,19 @@ class ShellEnvIoHelper { /// Get the environment file path String? get envFilePath => _envFilePath; - String? get _envFilePath => local - ? getLocalEnvFilePath(shell.options.environment) - : getUserEnvFilePath(shell.options.environment); + String? get _envFilePath => + local + ? getLocalEnvFilePath(shell.options.environment) + : getUserEnvFilePath(shell.options.environment); List? _sampleFileContent; /// Sample file content - List get sampleFileContent => _sampleFileContent ??= () { - var content = local - ? ''' + List get sampleFileContent => + _sampleFileContent ??= () { + var content = + local + ? ''' # Local Environment path and variable for `Shell.run` calls. # # `path(s)` is a list of path, `var(s)` is a key/value map. @@ -62,7 +68,7 @@ class ShellEnvIoHelper { # alias: # qr: /path/to/my_qr_app ''' - : ''' + : ''' # Environment path and variable for `Shell.run` calls. # # `path` is a list of path, `var` is a key/value map. diff --git a/packages/process_run/lib/src/io/env_var_delete_io.dart b/packages/process_run/lib/src/io/env_var_delete_io.dart index e0a33e2..4cfef77 100644 --- a/packages/process_run/lib/src/io/env_var_delete_io.dart +++ b/packages/process_run/lib/src/io/env_var_delete_io.dart @@ -8,8 +8,11 @@ import 'package:process_run/src/io/io.dart'; /// Helper to delete environment variables class ShellEnvVarDeleteIoHelper extends ShellEnvIoHelper { /// Helper to delete environment variables - ShellEnvVarDeleteIoHelper( - {required super.shell, required super.local, required super.verbose}); + ShellEnvVarDeleteIoHelper({ + required super.shell, + required super.local, + required super.verbose, + }); /// delete multiple environment variables Future deleteMulti(List keys) async { @@ -31,7 +34,8 @@ class ShellEnvVarDeleteIoHelper extends ShellEnvIoHelper { // Convenient fix, although it could be wrong... var newShellEnvironment = shell.context.newShellEnvironment( - environment: ShellEnvironment(environment: shell.options.environment)); + environment: ShellEnvironment(environment: shell.options.environment), + ); newShellEnvironment.vars.removeWhere((name, _) => keys.contains(name)); diff --git a/packages/process_run/lib/src/io/env_var_set_io.dart b/packages/process_run/lib/src/io/env_var_set_io.dart index d736234..e8b69cb 100644 --- a/packages/process_run/lib/src/io/env_var_set_io.dart +++ b/packages/process_run/lib/src/io/env_var_set_io.dart @@ -9,8 +9,11 @@ import 'package:process_run/src/io/io.dart'; /// Helper to set environment variables class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { /// Local should be true by default - ShellEnvVarSetIoHelper( - {required super.shell, required super.local, super.verbose = true}); + ShellEnvVarSetIoHelper({ + required super.shell, + required super.local, + super.verbose = true, + }); /// Set a single environment variable Future setValue(String name, String? value) async { @@ -37,7 +40,8 @@ class ShellEnvVarSetIoHelper extends ShellEnvIoHelper { } // reload var newShellEnvironment = shell.context.newShellEnvironment( - environment: ShellEnvironment(environment: shell.options.environment)); + environment: ShellEnvironment(environment: shell.options.environment), + ); if (value == null) { newShellEnvironment.vars.remove(name); } else { diff --git a/packages/process_run/lib/src/io/shared_stdin.dart b/packages/process_run/lib/src/io/shared_stdin.dart index 398bf2c..944bd01 100644 --- a/packages/process_run/lib/src/io/shared_stdin.dart +++ b/packages/process_run/lib/src/io/shared_stdin.dart @@ -62,13 +62,14 @@ class SharedStdIn extends Stream> { StreamController> _getCurrent() => _current ??= StreamController>( - onListen: () { - _sub ??= _originalStream.listen(_onInput); - }, - onCancel: () { - _current = null; - }, - sync: true); + onListen: () { + _sub ??= _originalStream.listen(_onInput); + }, + onCancel: () { + _current = null; + }, + sync: true, + ); @override StreamSubscription> listen( @@ -82,9 +83,11 @@ class SharedStdIn extends Stream> { } final controller = _getCurrent(); if (controller.hasListener) { - throw StateError('' - 'Subscriber already listening. The existing subscriber must cancel ' - 'before another may be added.'); + throw StateError( + '' + 'Subscriber already listening. The existing subscriber must cancel ' + 'before another may be added.', + ); } return controller.stream.listen( onData, diff --git a/packages/process_run/lib/src/io/shell_words.dart b/packages/process_run/lib/src/io/shell_words.dart index a2b653b..a6e98e7 100644 --- a/packages/process_run/lib/src/io/shell_words.dart +++ b/packages/process_run/lib/src/io/shell_words.dart @@ -241,8 +241,9 @@ List shellSplitWindowsImpl(String command) { /// quote matching the one at position [openingQuote] is missing. void _checkUnmatchedQuote(StringScanner scanner, int openingQuote) { if (!scanner.isDone) return; - final type = scanner.substring(openingQuote, openingQuote + 1) == '"' - ? 'double' - : 'single'; + final type = + scanner.substring(openingQuote, openingQuote + 1) == '"' + ? 'double' + : 'single'; scanner.error('Unmatched $type quote.', position: openingQuote, length: 1); } diff --git a/packages/process_run/lib/src/lines_utils_common.dart b/packages/process_run/lib/src/lines_utils_common.dart index 3c2527f..eb4d89d 100644 --- a/packages/process_run/lib/src/lines_utils_common.dart +++ b/packages/process_run/lib/src/lines_utils_common.dart @@ -73,8 +73,10 @@ class ShellLinesController { } /// Basic line streaming. Assuming system encoding -Stream shellStreamLines(Stream> stream, - {Encoding? encoding}) { +Stream shellStreamLines( + Stream> stream, { + Encoding? encoding, +}) { encoding ??= shellContext.encoding; StreamSubscription? subscription; List? currentLine; @@ -101,35 +103,36 @@ Stream shellStreamLines(Stream> stream, } ctlr = StreamController( - onPause: () { - if (shellDebug) { - // ignore: avoid_print - print('onPause (paused: ${subscription?.isPaused})'); - } - // Last one - addCurrentLine(); - subscription?.pause(); - }, - onResume: () { - // devPrint('onResume (paused: $paused)'); - if (subscription?.isPaused ?? false) { - subscription?.resume(); - } - }, - onListen: () { - void addToCurrentLine(List data) { - if (currentLine == null) { - currentLine = data; - } else { - var newCurrentLine = Uint8List(currentLine!.length + data.length); - newCurrentLine.setAll(0, currentLine!); - newCurrentLine.setAll(currentLine!.length, data); - currentLine = newCurrentLine; - } + onPause: () { + if (shellDebug) { + // ignore: avoid_print + print('onPause (paused: ${subscription?.isPaused})'); + } + // Last one + addCurrentLine(); + subscription?.pause(); + }, + onResume: () { + // devPrint('onResume (paused: $paused)'); + if (subscription?.isPaused ?? false) { + subscription?.resume(); + } + }, + onListen: () { + void addToCurrentLine(List data) { + if (currentLine == null) { + currentLine = data; + } else { + var newCurrentLine = Uint8List(currentLine!.length + data.length); + newCurrentLine.setAll(0, currentLine!); + newCurrentLine.setAll(currentLine!.length, data); + currentLine = newCurrentLine; } + } - var lastWasCR = false; - subscription = stream.listen((data) { + var lastWasCR = false; + subscription = stream.listen( + (data) { var paused = subscription?.isPaused ?? false; // devPrint('read $data (paused: $paused)'); if (paused) { @@ -154,7 +157,7 @@ Stream shellStreamLines(Stream> stream, addToCurrentLine(data.sublist(start, i)); addCurrentLine(); -// Skip it + // Skip it start = i + 1; } else { lastWasCR = false; @@ -164,20 +167,24 @@ Stream shellStreamLines(Stream> stream, if (data.length > start) { addToCurrentLine(data.sublist(start, data.length)); } - }, onDone: () { + }, + onDone: () { // devPrint('onDone'); // Last one addCurrentLine(); ctlr.close(); - }, onError: (Object e, StackTrace st) { + }, + onError: (Object e, StackTrace st) { ctlr.addError(e, st); - }); - }, - onCancel: () { - // devPrint('onCancel'); - subscription?.cancel(); - }, - sync: true); + }, + ); + }, + onCancel: () { + // devPrint('onCancel'); + subscription?.cancel(); + }, + sync: true, + ); return ctlr.stream; } diff --git a/packages/process_run/lib/src/process_cmd.dart b/packages/process_run/lib/src/process_cmd.dart index 0466e76..f8cc9aa 100644 --- a/packages/process_run/lib/src/process_cmd.dart +++ b/packages/process_run/lib/src/process_cmd.dart @@ -31,22 +31,28 @@ class ProcessCmd { Encoding stderrEncoding; /// Process command - ProcessCmd(this.executable, this.arguments, - {this.workingDirectory, - this.environment, - this.includeParentEnvironment = true, - this.runInShell, - this.stdoutEncoding = systemEncoding, - this.stderrEncoding = systemEncoding}); + ProcessCmd( + this.executable, + this.arguments, { + this.workingDirectory, + this.environment, + this.includeParentEnvironment = true, + this.runInShell, + this.stdoutEncoding = systemEncoding, + this.stderrEncoding = systemEncoding, + }); /// Clone - ProcessCmd clone() => ProcessCmd(executable, arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding); + ProcessCmd clone() => ProcessCmd( + executable, + arguments, + workingDirectory: workingDirectory, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + ); @override int get hashCode => executable.hashCode; diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index 68d29cc..72ee6b4 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -23,21 +23,23 @@ export 'shell_utils_io.dart' show executableArgumentsToString; /// /// Don't mess-up with the input and output for now here. only use it for kill. Future runExecutableArguments( - String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool? runInShell, - Encoding? stdoutEncoding = systemEncoding, - Encoding? stderrEncoding = systemEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose, - bool? noStdoutResult, - bool? noStderrResult, - ShellOnProcessCallback? onProcess}) async { + String executable, + List arguments, { + String? workingDirectory, + Map? environment, + bool includeParentEnvironment = true, + bool? runInShell, + Encoding? stdoutEncoding = systemEncoding, + Encoding? stderrEncoding = systemEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, + bool? noStdoutResult, + bool? noStderrResult, + ShellOnProcessCallback? onProcess, +}) async { if (verbose == true) { commandVerbose = true; stdout ??= io.stdout; @@ -45,15 +47,18 @@ Future runExecutableArguments( } if (commandVerbose == true) { - utils.streamSinkWriteln(stdout ?? io.stdout, - '\$ ${executableArgumentsToString(executable, arguments)}', - encoding: stdoutEncoding); + utils.streamSinkWriteln( + stdout ?? io.stdout, + '\$ ${executableArgumentsToString(executable, arguments)}', + encoding: stdoutEncoding, + ); } // Build our environment var shellEnvironment = ShellEnvironment.full( - environment: environment, - includeParentEnvironment: includeParentEnvironment); + environment: environment, + includeParentEnvironment: includeParentEnvironment, + ); // Default is the full command var executableShortName = executable; @@ -61,12 +66,14 @@ Future runExecutableArguments( // Find executable if needed, i.e. if it is only a name if (basename(executable) == executable) { // Try to find it in path or use it as is - executable = utils.findExecutableSync(executable, shellEnvironment.paths) ?? + executable = + utils.findExecutableSync(executable, shellEnvironment.paths) ?? executable; } else { // resolve locally - executable = utils.findExecutableSync(basename(executable), [ - join(workingDirectory ?? Directory.current.path, dirname(executable)) + executable = + utils.findExecutableSync(basename(executable), [ + join(workingDirectory ?? Directory.current.path, dirname(executable)), ]) ?? executable; } @@ -76,11 +83,14 @@ Future runExecutableArguments( Process process; try { - process = await Process.start(executable, arguments, - workingDirectory: workingDirectory, - environment: shellEnvironment, - includeParentEnvironment: false, - runInShell: runInShell); + process = await Process.start( + executable, + arguments, + workingDirectory: workingDirectory, + environment: shellEnvironment, + includeParentEnvironment: false, + runInShell: runInShell, + ); if (shellDebug) { // ignore: avoid_print print('process: ${process.pid}'); @@ -104,10 +114,11 @@ Future runExecutableArguments( } catch (e) { if (verbose == true) { dumpException( - executable: executableShortName, - arguments: arguments, - exception: e, - workingDirectory: workingDirectory); + executable: executableShortName, + arguments: arguments, + exception: e, + workingDirectory: workingDirectory, + ); } rethrow; } @@ -122,10 +133,9 @@ Future runExecutableArguments( //stdin.pipe(process.stdin); // this closes the stream... stdinSubscription = stdin.listen((List data) { process.stdin.add(data); - }) - ..onDone(() { - process.stdin.close(); - }); + })..onDone(() { + process.stdin.close(); + }); // OLD 2: process.stdin.addStream(stdin); } else { // Close the input sync, we want this not interractive @@ -133,7 +143,9 @@ Future runExecutableArguments( } Future streamToResult( - Stream> stream, Encoding? encoding) async { + Stream> stream, + Encoding? encoding, + ) async { final list = []; await for (final data in stream) { //devPrint('s: ${data}'); @@ -145,30 +157,38 @@ Future runExecutableArguments( return list; } - var out = (noStdoutResult ?? false) - ? Future.value(null) - : streamToResult(outCtlr.stream, stdoutEncoding); - var err = (noStderrResult ?? false) - ? Future.value(null) - : streamToResult(errCtlr.stream, stderrEncoding); - - process.stdout.listen((List d) { - if (stdout != null) { - stdout.add(d); - } - outCtlr.add(d); - }, onDone: () { - outCtlr.close(); - }); - - process.stderr.listen((List d) async { - if (stderr != null) { - stderr.add(d); - } - errCtlr.add(d); - }, onDone: () { - errCtlr.close(); - }); + var out = + (noStdoutResult ?? false) + ? Future.value(null) + : streamToResult(outCtlr.stream, stdoutEncoding); + var err = + (noStderrResult ?? false) + ? Future.value(null) + : streamToResult(errCtlr.stream, stderrEncoding); + + process.stdout.listen( + (List d) { + if (stdout != null) { + stdout.add(d); + } + outCtlr.add(d); + }, + onDone: () { + outCtlr.close(); + }, + ); + + process.stderr.listen( + (List d) async { + if (stderr != null) { + stderr.add(d); + } + errCtlr.add(d); + }, + onDone: () { + errCtlr.close(); + }, + ); final exitCode = await process.exitCode; @@ -208,17 +228,19 @@ Future runExecutableArguments( /// Compared to the async version, it is not possible to kill the spawn process nor to /// feed any input. ProcessResult runExecutableArgumentsSync( - String executable, List arguments, - {String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool? runInShell, - Encoding? stdoutEncoding = systemEncoding, - Encoding? stderrEncoding = systemEncoding, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose}) { + String executable, + List arguments, { + String? workingDirectory, + Map? environment, + bool includeParentEnvironment = true, + bool? runInShell, + Encoding? stdoutEncoding = systemEncoding, + Encoding? stderrEncoding = systemEncoding, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, +}) { if (verbose == true) { commandVerbose = true; stdout ??= io.stdout; @@ -226,15 +248,18 @@ ProcessResult runExecutableArgumentsSync( } if (commandVerbose == true) { - utils.streamSinkWriteln(stdout ?? io.stdout, - '\$ ${executableArgumentsToString(executable, arguments)}', - encoding: stdoutEncoding); + utils.streamSinkWriteln( + stdout ?? io.stdout, + '\$ ${executableArgumentsToString(executable, arguments)}', + encoding: stdoutEncoding, + ); } // Build our environment var shellEnvironment = ShellEnvironment.full( - environment: environment, - includeParentEnvironment: includeParentEnvironment); + environment: environment, + includeParentEnvironment: includeParentEnvironment, + ); // Default is the full command var executableShortName = executable; @@ -242,12 +267,14 @@ ProcessResult runExecutableArgumentsSync( // Find executable if needed, i.e. if it is only a name if (basename(executable) == executable) { // Try to find it in path or use it as is - executable = utils.findExecutableSync(executable, shellEnvironment.paths) ?? + executable = + utils.findExecutableSync(executable, shellEnvironment.paths) ?? executable; } else { // resolve locally - executable = utils.findExecutableSync(basename(executable), [ - join(workingDirectory ?? Directory.current.path, dirname(executable)) + executable = + utils.findExecutableSync(basename(executable), [ + join(workingDirectory ?? Directory.current.path, dirname(executable)), ]) ?? executable; } @@ -270,10 +297,11 @@ ProcessResult runExecutableArgumentsSync( } catch (e) { if (verbose == true) { dumpException( - executable: executableShortName, - arguments: arguments, - exception: e, - workingDirectory: workingDirectory); + executable: executableShortName, + arguments: arguments, + exception: e, + workingDirectory: workingDirectory, + ); } rethrow; } @@ -309,15 +337,17 @@ ProcessResult runExecutableArgumentsSync( /// stdout/error if [verbose] is true. /// [verbose] implies [commandVerbose] /// -Future processCmdRun(ProcessCmd cmd, - {bool? verbose, - bool? commandVerbose, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? noStdoutResult, - bool? noStderrResult, - ShellOnProcessCallback? onProcess}) async { +Future processCmdRun( + ProcessCmd cmd, { + bool? verbose, + bool? commandVerbose, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? noStdoutResult, + bool? noStderrResult, + ShellOnProcessCallback? onProcess, +}) async { if (verbose == true) { stdout ??= io.stdout; stderr ??= io.stderr; @@ -325,46 +355,55 @@ Future processCmdRun(ProcessCmd cmd, } if (commandVerbose == true) { - streamSinkWriteln(stdout ?? io.stdout, '\$ $cmd', - encoding: cmd.stdoutEncoding); + streamSinkWriteln( + stdout ?? io.stdout, + '\$ $cmd', + encoding: cmd.stdoutEncoding, + ); } try { - return await runExecutableArguments(cmd.executable, cmd.arguments, - workingDirectory: cmd.workingDirectory, - environment: cmd.environment, - includeParentEnvironment: cmd.includeParentEnvironment, - runInShell: cmd.runInShell, - stdoutEncoding: cmd.stdoutEncoding, - stderrEncoding: cmd.stderrEncoding, - //verbose: verbose, - //commandVerbose: commandVerbose, - stdin: stdin, - stdout: stdout, - stderr: stderr, - noStdoutResult: noStdoutResult, - noStderrResult: noStderrResult, - onProcess: onProcess); + return await runExecutableArguments( + cmd.executable, + cmd.arguments, + workingDirectory: cmd.workingDirectory, + environment: cmd.environment, + includeParentEnvironment: cmd.includeParentEnvironment, + runInShell: cmd.runInShell, + stdoutEncoding: cmd.stdoutEncoding, + stderrEncoding: cmd.stderrEncoding, + //verbose: verbose, + //commandVerbose: commandVerbose, + stdin: stdin, + stdout: stdout, + stderr: stderr, + noStdoutResult: noStdoutResult, + noStderrResult: noStderrResult, + onProcess: onProcess, + ); } catch (e) { if (verbose == true) { dumpException( - executable: cmd.executable, - arguments: cmd.arguments, - exception: e, - workingDirectory: cmd.workingDirectory); + executable: cmd.executable, + arguments: cmd.arguments, + exception: e, + workingDirectory: cmd.workingDirectory, + ); } rethrow; } } /// Dump the exception to stderr -void dumpException( - {required String executable, - required List arguments, - required Object exception, - String? workingDirectory}) { +void dumpException({ + required String executable, + required List arguments, + required Object exception, + String? workingDirectory, +}) { io.stderr.writeln(exception); io.stderr.writeln('\$ ${executableArgumentsToString(executable, arguments)}'); io.stderr.writeln( - 'workingDirectory: ${normalize(absolute(workingDirectory ?? Directory.current.path))}'); + 'workingDirectory: ${normalize(absolute(workingDirectory ?? Directory.current.path))}', + ); } diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index a1409fc..50b1dc7 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -58,21 +58,21 @@ Future> run( ShellOnProcessCallback? onProcess, }) { return Shell( - throwOnError: throwOnError, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding, - stdin: stdin, - stdout: stdout, - stderr: stderr, - verbose: verbose, - commandVerbose: commandVerbose, - commentVerbose: commentVerbose, - options: options) - .run(script, onProcess: onProcess); + throwOnError: throwOnError, + workingDirectory: workingDirectory, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdin: stdin, + stdout: stdout, + stderr: stderr, + verbose: verbose, + commandVerbose: commandVerbose, + commentVerbose: commentVerbose, + options: options, + ).run(script, onProcess: onProcess); } /// @@ -118,21 +118,21 @@ List runSync( ShellOptions? options, }) { return Shell( - throwOnError: throwOnError, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding, - stdin: stdin, - stdout: stdout, - stderr: stderr, - verbose: verbose, - commandVerbose: commandVerbose, - commentVerbose: commentVerbose, - options: options) - .runSync(script); + throwOnError: throwOnError, + workingDirectory: workingDirectory, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdin: stdin, + stdout: stdout, + stderr: stderr, + verbose: verbose, + commandVerbose: commandVerbose, + commentVerbose: commentVerbose, + options: options, + ).runSync(script); } /// Multiplatform Shell utility to run a script with multiple commands. @@ -193,41 +193,45 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// comments as well /// /// [options] overrides all other parameters - factory Shell( - {bool throwOnError = true, - String? workingDirectory, - Map? environment, - bool includeParentEnvironment = true, - bool? runInShell, - Encoding stdoutEncoding = systemEncoding, - Encoding stderrEncoding = systemEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool verbose = true, - // Default to true - bool? commandVerbose, - // Default to false - bool? commentVerbose, - - /// Overrides all parameters - ShellOptions? options}) { + factory Shell({ + bool throwOnError = true, + String? workingDirectory, + Map? environment, + bool includeParentEnvironment = true, + bool? runInShell, + Encoding stdoutEncoding = systemEncoding, + Encoding stderrEncoding = systemEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool verbose = true, + // Default to true + bool? commandVerbose, + // Default to false + bool? commentVerbose, + + /// Overrides all parameters + ShellOptions? options, + }) { var shell = shellContext.newShell( - options: options ?? - ShellOptions( - verbose: verbose, - stdin: stdin, - stdout: stdout, - stderr: stderr, - throwOnError: throwOnError, - workingDirectory: workingDirectory, - runInShell: runInShell, - commandVerbose: commandVerbose ?? verbose, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - commentVerbose: commentVerbose ?? false, - stderrEncoding: stderrEncoding, - stdoutEncoding: stdoutEncoding)); + options: + options ?? + ShellOptions( + verbose: verbose, + stdin: stdin, + stdout: stdout, + stderr: stderr, + throwOnError: throwOnError, + workingDirectory: workingDirectory, + runInShell: runInShell, + commandVerbose: commandVerbose ?? verbose, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + commentVerbose: commentVerbose ?? false, + stderrEncoding: stderrEncoding, + stdoutEncoding: stdoutEncoding, + ), + ); return shell; } @@ -250,8 +254,11 @@ abstract class Shell implements ShellCore, ShellCoreSync { path = context.path.join(_workingDirectoryPath, path); } if (_options.commandVerbose) { - streamSinkWriteln(_options.stdout ?? stdout, '\$ cd $path', - encoding: _options.stdoutEncoding); + streamSinkWriteln( + _options.stdout ?? stdout, + '\$ cd $path', + encoding: _options.stdoutEncoding, + ); } return cloneWithOptions(options.clone(workingDirectory: path)); } @@ -295,7 +302,8 @@ abstract class Shell implements ShellCore, ShellCoreSync { bool result; try { io.stderr.writeln( - 'killing $_killedRunId, ${_currentProcessToString()} signal $_killedProcessSignal'); + 'killing $_killedRunId, ${_currentProcessToString()} signal $_killedProcessSignal', + ); if (_killedProcessSignal == ProcessSignal.sigkill) { var pid = _currentProcess!.pid; @@ -313,8 +321,12 @@ abstract class Shell implements ShellCore, ShellCoreSync { // /pid Specifies the process ID of the process to be terminated. // /f Specifies that processes be forcefully ended. This parameter is ignored for remote processes; all remote processes are forcefully ended. // /t Ends the specified process and any child processes started by it. - runExecutableArgumentsSync( - 'taskkill', ['/t', '/f', '/pid', '$pid']); + runExecutableArgumentsSync('taskkill', [ + '/t', + '/f', + '/pid', + '$pid', + ]); } catch (_) {} } } @@ -351,8 +363,10 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// [onProcess] is called for each started process. /// @override - Future> run(String script, - {ShellOnProcessCallback? onProcess}) { + Future> run( + String script, { + ShellOnProcessCallback? onProcess, + }) { // devPrint('Running $script'); return _runLocked((runId) async { var commands = scriptToCommands(script); @@ -382,8 +396,11 @@ abstract class Shell implements ShellCore, ShellCoreSync { arguments = [...parts.sublist(1), ...arguments]; } var processResult = await _lockedRunExecutableArguments( - runId, executable, arguments, - onProcess: onProcess); + runId, + executable, + arguments, + onProcess: onProcess, + ); processResults.add(processResult); } @@ -404,9 +421,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// feed any input. /// @override - List runSync( - String script, - ) { + List runSync(String script) { var commands = scriptToCommands(script); var processResults = []; @@ -446,11 +461,17 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// [onProcess] is called for each started process. @override Future runExecutableArguments( - String executable, List arguments, - {ShellOnProcessCallback? onProcess}) async { + String executable, + List arguments, { + ShellOnProcessCallback? onProcess, + }) async { return _runLocked((runId) async { - return _lockedRunExecutableArguments(runId, executable, arguments, - onProcess: onProcess); + return _lockedRunExecutableArguments( + runId, + executable, + arguments, + onProcess: onProcess, + ); }); } @@ -465,11 +486,7 @@ abstract class Shell implements ShellCore, ShellCoreSync { List arguments, ) { var runId = ++_runId; - return _runExecutableArgumentsSync( - runId, - executable, - arguments, - ); + return _runExecutableArgumentsSync(runId, executable, arguments); } Future _runLocked(FutureOr Function(int runId) action) { @@ -491,11 +508,13 @@ abstract class Shell implements ShellCore, ShellCoreSync { if (shellDebug) { // ignore: avoid_print print( - 'Clear previous context ${_currentProcessResultCompleter?.isCompleted}'); + 'Clear previous context ${_currentProcessResultCompleter?.isCompleted}', + ); } if (!(_currentProcessResultCompleter?.isCompleted ?? true)) { - _currentProcessResultCompleter! - .completeError(ShellException('Killed by framework', null)); + _currentProcessResultCompleter!.completeError( + ShellException('Killed by framework', null), + ); } _currentProcessResultCompleter = null; } @@ -525,25 +544,29 @@ abstract class Shell implements ShellCore, ShellCoreSync { } processResult = impl.runExecutableArgumentsSync( - executableFullPath, arguments, - runInShell: _options.runInShell, - environment: _options.environment, - includeParentEnvironment: false, - stderrEncoding: _options.stderrEncoding ?? io.systemEncoding, - stdoutEncoding: _options.stdoutEncoding ?? io.systemEncoding, - workingDirectory: _options.workingDirectory); + executableFullPath, + arguments, + runInShell: _options.runInShell, + environment: _options.environment, + includeParentEnvironment: false, + stderrEncoding: _options.stderrEncoding ?? io.systemEncoding, + stdoutEncoding: _options.stdoutEncoding ?? io.systemEncoding, + workingDirectory: _options.workingDirectory, + ); } finally { if (shellDebug) { // ignore: avoid_print print( - '$_runId: After $executableFullPath exitCode ${processResult?.exitCode}'); + '$_runId: After $executableFullPath exitCode ${processResult?.exitCode}', + ); } } // devPrint('After $processCmd'); if (_options.throwOnError && processResult.exitCode != 0) { throw ShellException( - '$processCmd, exitCode ${processResult.exitCode}, workingDirectory: $_workingDirectoryPath', - processResult); + '$processCmd, exitCode ${processResult.exitCode}, workingDirectory: $_workingDirectoryPath', + processResult, + ); } return processResult; } on ProcessException catch (e) { @@ -567,8 +590,9 @@ abstract class Shell implements ShellCore, ShellCoreSync { writeln(); throw ShellException( - '$processCmd, error: $e, workingDirectory: $_workingDirectoryPath', - null); + '$processCmd, error: $e, workingDirectory: $_workingDirectoryPath', + null, + ); } } @@ -578,8 +602,11 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// /// Returns a process result (or throw if specified in the shell). Future _lockedRunExecutableArguments( - int runId, String executable, List arguments, - {ShellOnProcessCallback? onProcess}) { + int runId, + String executable, + List arguments, { + ShellOnProcessCallback? onProcess, + }) { /// Global process handler. try { _clearPreviousContext(); @@ -592,14 +619,18 @@ abstract class Shell implements ShellCore, ShellCoreSync { var executableFullPath = findExecutableSync(executable, _userPaths) ?? executable; - var processCmd = _ProcessCmd(executableFullPath, arguments, - executableShortName: executable) - ..runInShell = _options.runInShell - ..environment = _options.environment - ..includeParentEnvironment = false - ..stderrEncoding = _options.stderrEncoding ?? io.systemEncoding - ..stdoutEncoding = _options.stdoutEncoding ?? io.systemEncoding - ..workingDirectory = _options.workingDirectory; + var processCmd = + _ProcessCmd( + executableFullPath, + arguments, + executableShortName: executable, + ) + ..runInShell = _options.runInShell + ..environment = _options.environment + ..includeParentEnvironment = false + ..stderrEncoding = _options.stderrEncoding ?? io.systemEncoding + ..stdoutEncoding = _options.stdoutEncoding ?? io.systemEncoding + ..workingDirectory = _options.workingDirectory; try { // devPrint(_options.environment.keys.where((element) => element.contains('TEKARTIK'))); if (shellDebug) { @@ -608,45 +639,50 @@ abstract class Shell implements ShellCore, ShellCoreSync { } try { - processResult = await processCmdRun(processCmd, - verbose: _options.verbose, - commandVerbose: _options.commandVerbose, - stderr: _options.stderr, - stdin: _options.stdin, - stdout: _options.stdout, - noStdoutResult: _options.noStdoutResult, - noStderrResult: _options.noStderrResult, onProcess: (process) { - _currentProcess = process; - _currentProcessCmd = processCmd; - _currentProcessRunId = runId; - if (shellDebug) { - // ignore: avoid_print - print('onProcess ${_currentProcessToString()}'); - } - if (onProcess != null) { - onProcess(process); - } - if (_killedRunId >= _runId) { + processResult = await processCmdRun( + processCmd, + verbose: _options.verbose, + commandVerbose: _options.commandVerbose, + stderr: _options.stderr, + stdin: _options.stdin, + stdout: _options.stdout, + noStdoutResult: _options.noStdoutResult, + noStderrResult: _options.noStderrResult, + onProcess: (process) { + _currentProcess = process; + _currentProcessCmd = processCmd; + _currentProcessRunId = runId; if (shellDebug) { // ignore: avoid_print - print('shell was killed'); + print('onProcess ${_currentProcessToString()}'); } - _kill(); - return; - } - }); + if (onProcess != null) { + onProcess(process); + } + if (_killedRunId >= _runId) { + if (shellDebug) { + // ignore: avoid_print + print('shell was killed'); + } + _kill(); + return; + } + }, + ); } finally { if (shellDebug) { // ignore: avoid_print print( - '$_runId: After $processCmd exitCode ${processResult?.exitCode}'); + '$_runId: After $processCmd exitCode ${processResult?.exitCode}', + ); } } // devPrint('After $processCmd'); if (_options.throwOnError && processResult.exitCode != 0) { throw ShellException( - '$processCmd, exitCode ${processResult.exitCode}, workingDirectory: $_workingDirectoryPath', - processResult); + '$processCmd, exitCode ${processResult.exitCode}, workingDirectory: $_workingDirectoryPath', + processResult, + ); } } on ProcessException catch (e) { var stderr = _options.stderr ?? io.stderr; @@ -669,30 +705,33 @@ abstract class Shell implements ShellCore, ShellCoreSync { writeln(); throw ShellException( - '$processCmd, error: $e, workingDirectory: $_workingDirectoryPath', - null); + '$processCmd, error: $e, workingDirectory: $_workingDirectoryPath', + null, + ); } return processResult; } - run().then((value) { - if (shellDebug) { - // ignore: avoid_print - print('$runId: done'); - } - if (!completer.isCompleted) { - completer.complete(value); - } - }).catchError((Object e) { - if (shellDebug) { - // ignore: avoid_print - print('$runId: error $e'); - } - if (!completer.isCompleted) { - completer.completeError(e); - } - }); + run() + .then((value) { + if (shellDebug) { + // ignore: avoid_print + print('$runId: done'); + } + if (!completer.isCompleted) { + completer.complete(value); + } + }) + .catchError((Object e) { + if (shellDebug) { + // ignore: avoid_print + print('$runId: error $e'); + } + if (!completer.isCompleted) { + completer.completeError(e); + } + }); return completer.future; } finally { _currentProcess = null; @@ -704,8 +743,11 @@ abstract class Shell implements ShellCore, ShellCoreSync { class _ProcessCmd extends ProcessCmd { final String executableShortName; - _ProcessCmd(super.executable, super.arguments, - {required this.executableShortName}); + _ProcessCmd( + super.executable, + super.arguments, { + required this.executableShortName, + }); @override String toString() => diff --git a/packages/process_run/lib/src/shell_common.dart b/packages/process_run/lib/src/shell_common.dart index 2a88980..bdc0f5f 100644 --- a/packages/process_run/lib/src/shell_common.dart +++ b/packages/process_run/lib/src/shell_common.dart @@ -51,8 +51,10 @@ abstract class ShellCore { /// /// [onProcess] is called for each started process. /// - Future> run(String script, - {ShellOnProcessCallback? onProcess}); + Future> run( + String script, { + ShellOnProcessCallback? onProcess, + }); /// Run a single [executable] with [arguments], resolving the [executable] if needed. /// @@ -60,8 +62,10 @@ abstract class ShellCore { /// /// [onProcess] is called for each started process. Future runExecutableArguments( - String executable, List arguments, - {ShellOnProcessCallback? onProcess}); + String executable, + List arguments, { + ShellOnProcessCallback? onProcess, + }); /// Create new shell at the given path Shell cd(String path); @@ -114,7 +118,9 @@ abstract class ShellCoreSync { /// Compared to the async version, it is not possible to kill the spawn process nor to /// feed any input. ProcessResult runExecutableArgumentsSync( - String executable, List arguments); + String executable, + List arguments, + ); } /// Shell options. @@ -191,22 +197,23 @@ class ShellOptions { bool? noStdoutResult, // Default to false bool? noStderrResult, - }) : _throwOnError = throwOnError, - _workingDirectory = workingDirectory, - _runInShell = runInShell, - _stdoutEncoding = stdoutEncoding, - _stderrEncoding = stderrEncoding, - _stdin = stdin, - _stdout = stdout, - _stderr = stderr, - _verbose = verbose, - _commandVerbose = commandVerbose ?? verbose, - _commentVerbose = commentVerbose ?? false, - _noStderrResult = noStderrResult, - _noStdoutResult = noStdoutResult { + }) : _throwOnError = throwOnError, + _workingDirectory = workingDirectory, + _runInShell = runInShell, + _stdoutEncoding = stdoutEncoding, + _stderrEncoding = stderrEncoding, + _stdin = stdin, + _stdout = stdout, + _stderr = stderr, + _verbose = verbose, + _commandVerbose = commandVerbose ?? verbose, + _commentVerbose = commentVerbose ?? false, + _noStderrResult = noStderrResult, + _noStdoutResult = noStdoutResult { _environment = ShellEnvironment.full( - environment: environment, - includeParentEnvironment: includeParentEnvironment); + environment: environment, + includeParentEnvironment: includeParentEnvironment, + ); } /// True if commands are displayed. @@ -231,46 +238,52 @@ class ShellOptions { bool? get noStderrResult => _noStderrResult; /// Create a new shell - ShellOptions clone( - {bool? throwOnError, - String? workingDirectory, - bool? runInShell, - Encoding? stdoutEncoding, - Encoding? stderrEncoding, - Stream>? stdin, - StreamSink>? stdout, - StreamSink>? stderr, - bool? verbose, - bool? commandVerbose, - bool? commentVerbose, - bool? noStdoutResult, - bool? noStderrResult, - ShellEnvironment? shellEnvironment}) { + ShellOptions clone({ + bool? throwOnError, + String? workingDirectory, + bool? runInShell, + Encoding? stdoutEncoding, + Encoding? stderrEncoding, + Stream>? stdin, + StreamSink>? stdout, + StreamSink>? stderr, + bool? verbose, + bool? commandVerbose, + bool? commentVerbose, + bool? noStdoutResult, + bool? noStderrResult, + ShellEnvironment? shellEnvironment, + }) { return ShellOptions( - verbose: verbose ?? _verbose, - runInShell: runInShell ?? _runInShell, - commandVerbose: commandVerbose ?? _commandVerbose, - commentVerbose: commentVerbose ?? _commentVerbose, - stderr: stderr ?? _stderr, - stderrEncoding: stderrEncoding ?? _stderrEncoding, - stdin: stdin ?? _stdin, - stdout: stdout ?? _stdout, - stdoutEncoding: stdoutEncoding ?? _stdoutEncoding, - throwOnError: throwOnError ?? _throwOnError, - workingDirectory: workingDirectory ?? _workingDirectory, - environment: shellEnvironment ?? _environment, - noStdoutResult: noStdoutResult ?? _noStdoutResult, - noStderrResult: noStderrResult ?? _noStderrResult); + verbose: verbose ?? _verbose, + runInShell: runInShell ?? _runInShell, + commandVerbose: commandVerbose ?? _commandVerbose, + commentVerbose: commentVerbose ?? _commentVerbose, + stderr: stderr ?? _stderr, + stderrEncoding: stderrEncoding ?? _stderrEncoding, + stdin: stdin ?? _stdin, + stdout: stdout ?? _stdout, + stdoutEncoding: stdoutEncoding ?? _stdoutEncoding, + throwOnError: throwOnError ?? _throwOnError, + workingDirectory: workingDirectory ?? _workingDirectory, + environment: shellEnvironment ?? _environment, + noStdoutResult: noStdoutResult ?? _noStdoutResult, + noStderrResult: noStderrResult ?? _noStderrResult, + ); } } /// Which common implementation -Future which(String command, - {ShellEnvironment? environment, - bool includeParentEnvironment = true}) async { - return shellContext.which(command, - environment: environment, - includeParentEnvironment: includeParentEnvironment); +Future which( + String command, { + ShellEnvironment? environment, + bool includeParentEnvironment = true, +}) async { + return shellContext.which( + command, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + ); } /// Default missing implementation. diff --git a/packages/process_run/lib/src/shell_common_io.dart b/packages/process_run/lib/src/shell_common_io.dart index 934fd90..749a893 100644 --- a/packages/process_run/lib/src/shell_common_io.dart +++ b/packages/process_run/lib/src/shell_common_io.dart @@ -7,15 +7,19 @@ import 'shell_common.dart'; /// Shell implementation using io. class ShellIo extends Shell with ShellMixin { /// Shell implementation using io. - ShellIo({ - required ShellOptions options, - }) : super.implWithOptions(options); + ShellIo({required ShellOptions options}) : super.implWithOptions(options); @override - Future shellVarOverride(String name, String? value, - {bool? local}) async { + Future shellVarOverride( + String name, + String? value, { + bool? local, + }) async { var helper = ShellEnvVarSetIoHelper( - shell: this, local: local ?? true, verbose: options.verbose); + shell: this, + local: local ?? true, + verbose: options.verbose, + ); var env = await helper.setValue(name, value); return context.newShell(options: options.clone(shellEnvironment: env)); } diff --git a/packages/process_run/lib/src/shell_context_common.dart b/packages/process_run/lib/src/shell_context_common.dart index e04ad65..350af3e 100644 --- a/packages/process_run/lib/src/shell_context_common.dart +++ b/packages/process_run/lib/src/shell_context_common.dart @@ -11,8 +11,11 @@ abstract class ShellContext { ShellEnvironment get shellEnvironment; /// Which command. - Future which(String command, - {ShellEnvironment? environment, bool includeParentEnvironment = true}); + Future which( + String command, { + ShellEnvironment? environment, + bool includeParentEnvironment = true, + }); /// Path context. p.Context get path; @@ -22,14 +25,10 @@ abstract class ShellContext { /// New shell must set itself as a shell Context, shell environement is /// no longer relevent. - Shell newShell({ - ShellOptions? options, - }); + Shell newShell({ShellOptions? options}); /// New shell environment - ShellEnvironment newShellEnvironment({ - Map? environment, - }); + ShellEnvironment newShellEnvironment({Map? environment}); } /// Shell context mixin @@ -38,10 +37,11 @@ mixin ShellContextMixin implements ShellContext { Encoding get encoding => throw UnimplementedError('ShellContextMixin.encoding'); @override - Shell newShell( - {ShellOptions? options, - Map? environment, - bool includeParentEnvironment = true}) { + Shell newShell({ + ShellOptions? options, + Map? environment, + bool includeParentEnvironment = true, + }) { throw UnimplementedError('ShellContext.newShell'); } @@ -58,8 +58,11 @@ mixin ShellContextMixin implements ShellContext { throw UnimplementedError('ShellContext.shellEnvironment'); @override - Future which(String command, - {ShellEnvironment? environment, bool includeParentEnvironment = true}) { + Future which( + String command, { + ShellEnvironment? environment, + bool includeParentEnvironment = true, + }) { throw UnimplementedError('ShellContext.which'); } } diff --git a/packages/process_run/lib/src/shell_context_io.dart b/packages/process_run/lib/src/shell_context_io.dart index e0cd5a3..551f324 100644 --- a/packages/process_run/lib/src/shell_context_io.dart +++ b/packages/process_run/lib/src/shell_context_io.dart @@ -18,12 +18,15 @@ class ShellContextIo with ShellContextMixin implements ShellContext { p.Context get path => p.context; @override - Future which(String command, - {ShellEnvironment? environment, - bool includeParentEnvironment = true}) => - ds.which(command, - environment: environment, - includeParentEnvironment: includeParentEnvironment); + Future which( + String command, { + ShellEnvironment? environment, + bool includeParentEnvironment = true, + }) => ds.which( + command, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + ); @override Encoding get encoding => systemEncoding; @@ -34,10 +37,11 @@ class ShellContextIo with ShellContextMixin implements ShellContext { } @override - Shell newShell( - {ShellOptions? options, - Map? environment, - bool includeParentEnvironment = true}) { + Shell newShell({ + ShellOptions? options, + Map? environment, + bool includeParentEnvironment = true, + }) { var ioShell = ShellIo(options: options ?? ShellOptions()); ioShell.context = this; return ioShell; diff --git a/packages/process_run/lib/src/shell_environment.dart b/packages/process_run/lib/src/shell_environment.dart index 7813a39..49454f3 100644 --- a/packages/process_run/lib/src/shell_environment.dart +++ b/packages/process_run/lib/src/shell_environment.dart @@ -25,9 +25,10 @@ class ShellEnvironment extends common.ShellEnvironmentBase { /// From a run start content, includeParentEnvironment should later be set /// to false - factory ShellEnvironment.full( - {Map? environment, - bool includeParentEnvironment = true}) { + factory ShellEnvironment.full({ + Map? environment, + bool includeParentEnvironment = true, + }) { ShellEnvironment newEnvironment; // devPrint(environment?.keys.where((element) => element.contains('TEKA'))); if (includeParentEnvironment) { @@ -53,10 +54,7 @@ class ShellEnvironment extends common.ShellEnvironmentBase { /// Find a [command] path location in the environment String? whichSync(String command) { - return findExecutableSync( - command, - paths, - ); + return findExecutableSync(command, paths); } /// Find a [command] path location in the environment diff --git a/packages/process_run/lib/src/shell_environment_common.dart b/packages/process_run/lib/src/shell_environment_common.dart index ee43fc2..70574f1 100644 --- a/packages/process_run/lib/src/shell_environment_common.dart +++ b/packages/process_run/lib/src/shell_environment_common.dart @@ -108,7 +108,7 @@ class ShellEnvironmentAliases with MapMixin { final Map _map; ShellEnvironmentAliases._([Map? map]) - : _map = map ?? {}; + : _map = map ?? {}; /// the other object takes precedence, vars are added void merge(ShellEnvironmentAliases other) { @@ -367,7 +367,7 @@ abstract class ShellEnvironmentCore with MapMixin { /// `paths` and `vars` key Map toJson(); -/* + /* /// Create a new shell environment from the current shellEnvironment. /// /// Defaults create a full parent environment. diff --git a/packages/process_run/lib/src/shell_utils.dart b/packages/process_run/lib/src/shell_utils.dart index 6fb2ead..2624a8e 100644 --- a/packages/process_run/lib/src/shell_utils.dart +++ b/packages/process_run/lib/src/shell_utils.dart @@ -3,7 +3,8 @@ import 'dart:convert'; import 'package:path/path.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/common/constant.dart'; -import 'package:process_run/src/io/shell_words.dart' as io +import 'package:process_run/src/io/shell_words.dart' + as io show shellSplitImpl, shellSplitWindowsImpl; import 'package:process_run/src/shell_environment.dart'; @@ -88,17 +89,19 @@ String? _userAppDataPath; /// /// On windows, it is read from the `APPDATA` environment variable. Otherwise /// it is the `~/.config` folder -String get userAppDataPath => _userAppDataPath ??= () { - var override = platformEnvironment[userAppDataPathEnvKey]; - if (override != null) { - return override; - } - if (Platform.isWindows) { - return platformEnvironment['APPDATA']; - } - return null; - }() ?? - join(userHomePath, '.config'); +String get userAppDataPath => + _userAppDataPath ??= + () { + var override = platformEnvironment[userAppDataPathEnvKey]; + if (override != null) { + return override; + } + if (Platform.isWindows) { + return platformEnvironment['APPDATA']; + } + return null; + }() ?? + join(userHomePath, '.config'); String? _userHomePath; @@ -107,7 +110,8 @@ String? _userHomePath; /// Usually read from the `HOME` environment variable or `USERPROFILE` on /// Windows. String get userHomePath => - _userHomePath ??= platformEnvironment[userHomePathEnvKey] ?? + _userHomePath ??= + platformEnvironment[userHomePathEnvKey] ?? platformEnvironment['HOME'] ?? platformEnvironment['USERPROFILE'] ?? '~'; @@ -143,8 +147,10 @@ Map? _platformEnvironment; /// Environment without debug VM_OPTIONS and without any user overrides /// /// Instead replace with an optional TEKARTIK_DART_VM_OPTIONS -Map get platformEnvironment => _platformEnvironment ??= - environmentFilterOutVmOptions(Platform.environment); +Map get platformEnvironment => + _platformEnvironment ??= environmentFilterOutVmOptions( + Platform.environment, + ); /// Warning, change the platform environment and reset. set platformEnvironment(Map? environment) { @@ -165,7 +171,8 @@ set shellEnvironment(Map? environment) { /// Raw overriden environment Map environmentFilterOutVmOptions( - Map platformEnvironment) { + Map platformEnvironment, +) { Map? environment; var vmOptions = platformEnvironment['DART_VM_OPTIONS']; if (vmOptions != null) { @@ -183,16 +190,18 @@ Map environmentFilterOutVmOptions( List? _windowsPathExts; /// Default extension for PATHEXT on Windows -List get windowsPathExts => _windowsPathExts ??= - environmentGetWindowsPathExt(platformEnvironment) ?? windowsDefaultPathExt; +List get windowsPathExts => + _windowsPathExts ??= + environmentGetWindowsPathExt(platformEnvironment) ?? + windowsDefaultPathExt; /// Get the PATHEXT environment variable (windows) List? environmentGetWindowsPathExt( - Map platformEnvironment) => - platformEnvironment['PATHEXT'] - ?.split(windowsEnvPathSeparator) - .map((ext) => ext.toLowerCase()) - .toList(growable: false); + Map platformEnvironment, +) => platformEnvironment['PATHEXT'] + ?.split(windowsEnvPathSeparator) + .map((ext) => ext.toLowerCase()) + .toList(growable: false); /// fix runInShell for Windows bool fixRunInShell(bool? runInShell, String executable) { @@ -209,9 +218,10 @@ bool fixRunInShell(bool? runInShell, String executable) { } /// Use io package shellSplit implementation -List shellSplit(String command) => context.style == windows.style - ? io.shellSplitWindowsImpl(command) - : io.shellSplitImpl(command); +List shellSplit(String command) => + context.style == windows.style + ? io.shellSplitWindowsImpl(command) + : io.shellSplitImpl(command); /// Inverse of shell split String shellJoin(List parts) => diff --git a/packages/process_run/lib/src/shell_utils_common.dart b/packages/process_run/lib/src/shell_utils_common.dart index 32bbf60..09ad6b1 100644 --- a/packages/process_run/lib/src/shell_utils_common.dart +++ b/packages/process_run/lib/src/shell_utils_common.dart @@ -25,15 +25,21 @@ String get envPathSeparator => platformIoIsWindows ? windowsEnvPathSeparator : posixEnvPathSeparator; /// Write a string line to the ouput -void streamSinkWriteln(StreamSink> sink, String message, - {Encoding? encoding}) { +void streamSinkWriteln( + StreamSink> sink, + String message, { + Encoding? encoding, +}) { encoding ??= shellContext.encoding; streamSinkWrite(sink, '$message\n', encoding: encoding); } /// Write a string to a to sink -void streamSinkWrite(StreamSink> sink, String message, - {Encoding? encoding}) { +void streamSinkWrite( + StreamSink> sink, + String message, { + Encoding? encoding, +}) { encoding ??= shellContext.encoding; sink.add(encoding.encode(message)); } diff --git a/packages/process_run/lib/src/stdio/stdio.dart b/packages/process_run/lib/src/stdio/stdio.dart index 0c3d55a..674dd8c 100644 --- a/packages/process_run/lib/src/stdio/stdio.dart +++ b/packages/process_run/lib/src/stdio/stdio.dart @@ -121,8 +121,11 @@ class ShellStdioLinesGrouperIOSink with IOSinkMixin implements IOSink { @override void add(core.List data) { var zoneId = grouper.zoneId; - var streamer = grouper.streamers[zoneId] ??= ShellOutputLinesStreamer( - stdout: grouper.stdout, stderr: grouper.stderr); + var streamer = + grouper.streamers[zoneId] ??= ShellOutputLinesStreamer( + stdout: grouper.stdout, + stderr: grouper.stderr, + ); // devPrint('[$zoneId/$currentZoneId] Adding data ${encoding.decode(data).trim()}'); var sink = _isErr ? streamer.err : streamer.out; sink.add(data); @@ -155,12 +158,18 @@ class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { ShellStdioLinesGrouper({this.stdout, this.stderr}); @override - late final out = - ShellStdioLinesGrouperIOSink(this, StdioStreamType.out, ioSink: stdout); + late final out = ShellStdioLinesGrouperIOSink( + this, + StdioStreamType.out, + ioSink: stdout, + ); @override - late final err = - ShellStdioLinesGrouperIOSink(this, StdioStreamType.err, ioSink: stderr); + late final err = ShellStdioLinesGrouperIOSink( + this, + StdioStreamType.err, + ioSink: stderr, + ); void _setCurrent() { if (_debugLinesGrouper) { @@ -200,8 +209,10 @@ class ShellStdioLinesGrouper with ShellStdioMixin implements ShellStdio { /// Run in a zone, grouping lines Future _runZonedImpl(Future Function() action) async { var zoneId = _nextZoneId(); - streamers[zoneId] = - ShellOutputLinesStreamer(stdout: stdout, stderr: stderr); + streamers[zoneId] = ShellOutputLinesStreamer( + stdout: stdout, + stderr: stderr, + ); streamerZoneIds.add(zoneId); _setCurrent(); @@ -270,7 +281,7 @@ enum StdioStreamType { out, /// Err - err + err, } /// Stdio stream line. diff --git a/packages/process_run/lib/src/user_config.dart b/packages/process_run/lib/src/user_config.dart index ea39d3c..0c3c830 100644 --- a/packages/process_run/lib/src/user_config.dart +++ b/packages/process_run/lib/src/user_config.dart @@ -34,13 +34,13 @@ class UserConfig { final Map aliases; /// User config - UserConfig( - {Map? vars, - List? paths, - Map? aliases}) - : vars = vars ?? {}, - paths = paths ?? [], - aliases = aliases ?? {}; + UserConfig({ + Map? vars, + List? paths, + Map? aliases, + }) : vars = vars ?? {}, + paths = paths ?? [], + aliases = aliases ?? {}; @override String toString() => @@ -84,13 +84,13 @@ List get userPaths => userConfig.paths; /// [userEnvironment] must be explicitly used as it could contain sensitive /// information. /// -Map get userEnvironment => ShellEnvironment.empty() - ..vars.addAll(userConfig.vars) - ..aliases.addAll(userConfig.aliases) - ..paths.addAll(userConfig.paths); +Map get userEnvironment => + ShellEnvironment.empty() + ..vars.addAll(userConfig.vars) + ..aliases.addAll(userConfig.aliases) + ..paths.addAll(userConfig.paths); @protected - /// Reset user config @visibleForTesting void resetUserConfig() { @@ -110,11 +110,13 @@ class EnvFileConfig { final Map aliases; /// Env file config - EnvFileConfig(List? paths, Map? vars, - Map? aliases) - : paths = paths ?? [], - vars = vars ?? {}, - aliases = aliases ?? {}; + EnvFileConfig( + List? paths, + Map? vars, + Map? aliases, + ) : paths = paths ?? [], + vars = vars ?? {}, + aliases = aliases ?? {}; /// Has no vars, paths nor aliases. bool get isEmpty => paths.isEmpty && vars.isEmpty && aliases.isEmpty; @@ -123,8 +125,11 @@ class EnvFileConfig { bool get isNotEmpty => !isEmpty; /// Debug map - Map toDebugMap() => - {'paths': paths, 'vars': vars, 'aliases': aliases}; + Map toDebugMap() => { + 'paths': paths, + 'vars': vars, + 'aliases': aliases, + }; /// Load from path Future loadFromPath(String path) async { @@ -297,10 +302,11 @@ void userLoadConfigMap(Map map) { } /// Only specify the vars to override and the paths to add -void userLoadEnv( - {Map? vars, - List? paths, - Map? aliases}) { +void userLoadEnv({ + Map? vars, + List? paths, + Map? aliases, +}) { userLoadEnvFileConfig(EnvFileConfig(paths, vars, aliases)); } @@ -313,7 +319,9 @@ void userLoadEnvFileConfig(EnvFileConfig envFileConfig) { var added = envFileConfig; // devPrint('adding config: $config'); if (const ListEquality().equals( - paths.sublist(0, min(added.paths.length, paths.length)), added.paths)) { + paths.sublist(0, min(added.paths.length, paths.length)), + added.paths, + )) { // don't add if already in same order at the beginning } else { paths.insertAll(0, added.paths); @@ -348,8 +356,9 @@ String? getFlutterAncestorPath(String dartSdkBinDirPath) { // Second test, check if flutter is at path in this case // dart sdk comes from flutter dart path try { - if (File(join(dartSdkBinDirPath, getBashOrBatExecutableFilename('flutter'))) - .existsSync()) { + if (File( + join(dartSdkBinDirPath, getBashOrBatExecutableFilename('flutter')), + ).existsSync()) { return dartSdkBinDirPath; } } catch (_) {} @@ -402,7 +411,10 @@ UserConfig getUserConfig(Map? environment) { addConfig(getLocalEnvFilePath(shEnv)); return UserConfig( - paths: shEnv.paths, vars: shEnv.vars, aliases: shEnv.aliases); + paths: shEnv.paths, + vars: shEnv.vars, + aliases: shEnv.aliases, + ); } /// get users paths diff --git a/packages/process_run/lib/src/which.dart b/packages/process_run/lib/src/which.dart index dc74909..90ae840 100644 --- a/packages/process_run/lib/src/which.dart +++ b/packages/process_run/lib/src/which.dart @@ -4,24 +4,32 @@ import 'package:path/path.dart'; import 'package:process_run/src/shell_environment.dart'; /// Find the command according to the [paths] or env variables (`PATH`) -Future which(String command, - {Map? environment, - bool includeParentEnvironment = true}) async { - return whichSync(command, - environment: environment, - includeParentEnvironment: includeParentEnvironment); +Future which( + String command, { + Map? environment, + bool includeParentEnvironment = true, +}) async { + return whichSync( + command, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + ); } /// Find the command according to the [paths] or env variables (`PATH`) -String? whichSync(String command, - {Map? environment, bool includeParentEnvironment = true}) { +String? whichSync( + String command, { + Map? environment, + bool includeParentEnvironment = true, +}) { // only valid for single commands if (basename(command) != command) { return null; } // Merge system environment var shellEnvironment = ShellEnvironment.full( - environment: environment, - includeParentEnvironment: includeParentEnvironment); + environment: environment, + includeParentEnvironment: includeParentEnvironment, + ); return shellEnvironment.whichSync(command); } diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index e419698..2733bff 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -4,7 +4,7 @@ description: Process run helpers for Linux/Win/Mac and which like feature for fi homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run environment: - sdk: ^3.5.0 + sdk: ^3.7.0 dependencies: path: ">=1.8.0 <3.0.0" diff --git a/packages/process_run/test/bin/bin_shell_test.dart b/packages/process_run/test/bin/bin_shell_test.dart index c9a8688..e1e4b1f 100644 --- a/packages/process_run/test/bin/bin_shell_test.dart +++ b/packages/process_run/test/bin/bin_shell_test.dart @@ -10,14 +10,16 @@ import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; var shell = Shell( - environment: ShellEnvironment()..aliases['ds'] = 'dart run bin/shell.dart', - verbose: false); + environment: ShellEnvironment()..aliases['ds'] = 'dart run bin/shell.dart', + verbose: false, +); var safeLocalEnvFile = '.dart_tool/process_run/test/test_local_env3_safe.yaml'; -var safeShellEnvironment = ShellEnvironment() - ..aliases['ds'] = 'dart run bin/shell.dart' - ..vars[userEnvFilePathEnvKey] = 'test/data/test_user_env3_safe.yaml'; +var safeShellEnvironment = + ShellEnvironment() + ..aliases['ds'] = 'dart run bin/shell.dart' + ..vars[userEnvFilePathEnvKey] = 'test/data/test_user_env3_safe.yaml'; Shell get safeShell => Shell(environment: safeShellEnvironment, verbose: false); @@ -115,9 +117,9 @@ void main() { expect(fileContent.addAlias('a1', 'v1'), true); expect(fileContent.lines, ['alias:', ' a1: v1']); expect( - true, - fileContent.addAlias( - 'a1', 'v1')); // yes even if not changed, we don't know + true, + fileContent.addAlias('a1', 'v1'), + ); // yes even if not changed, we don't know expect(fileContent.lines, ['alias:', ' a1: v1']); fileContent.deleteAlias('a1'); expect(fileContent.lines, ['alias:']); diff --git a/packages/process_run/test/bin/compiled_bin_shell_test.dart b/packages/process_run/test/bin/compiled_bin_shell_test.dart index ff8e749..90fea6e 100644 --- a/packages/process_run/test/bin/compiled_bin_shell_test.dart +++ b/packages/process_run/test/bin/compiled_bin_shell_test.dart @@ -14,8 +14,9 @@ void main() { setUpAll(() async { var dsExePath = await compileShellBin(force: false); shell = Shell( - environment: ShellEnvironment()..aliases['ds'] = dsExePath, - verbose: false); + environment: ShellEnvironment()..aliases['ds'] = dsExePath, + verbose: false, + ); }); test('version', () async { var output = (await shell.run('ds --version')).outText.trim(); diff --git a/packages/process_run/test/cmd_run_test.dart b/packages/process_run/test/cmd_run_test.dart index dfdce65..db904ac 100644 --- a/packages/process_run/test/cmd_run_test.dart +++ b/packages/process_run/test/cmd_run_test.dart @@ -44,8 +44,10 @@ void main() { final out = TestSink>(); result = await runCmd(cmd, verbose: true, stdout: out); expect(out.results.length, 2, reason: '${out.results}'); - expect(systemEncoding.decode(out.results[0].asValue!.value), - '\$ dart $echoScriptPath --stdout out\n'); + expect( + systemEncoding.decode(out.results[0].asValue!.value), + '\$ dart $echoScriptPath --stdout out\n', + ); expect(systemEncoding.decode(out.results[1].asValue!.value), 'out'); }); diff --git a/packages/process_run/test/compile_test.dart b/packages/process_run/test/compile_test.dart index 92843a2..1414803 100644 --- a/packages/process_run/test/compile_test.dart +++ b/packages/process_run/test/compile_test.dart @@ -10,59 +10,66 @@ import 'package:test/test.dart'; import 'src/compile_echo.dart'; void main() { - test('compile and run exe', () async { - var echoExePath = await compileEchoExample(); - var echoExeDir = dirname(echoExePath); - var echoExeName = basename(echoExePath); + test( + 'compile and run exe', + () async { + var echoExePath = await compileEchoExample(); + var echoExeDir = dirname(echoExePath); + var echoExeName = basename(echoExePath); - // Try path access - var lines = (await Shell(verbose: false) - .run('${shellArgument(echoExePath)} --stdout test')) - .outLines; - expect(lines, ['test']); + // Try path access + var lines = + (await Shell( + verbose: false, + ).run('${shellArgument(echoExePath)} --stdout test')).outLines; + expect(lines, ['test']); - // Try using alias - lines = (await Shell( - verbose: false, - environment: ShellEnvironment()..aliases['echo'] = echoExePath) - .run('echo --stdout test')) - .outLines; - expect(lines, ['test']); + // Try using alias + lines = + (await Shell( + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echoExePath, + ).run('echo --stdout test')).outLines; + expect(lines, ['test']); - // Try using alias in options - var options = ShellOptions( + // Try using alias in options + var options = ShellOptions( verbose: false, - environment: ShellEnvironment()..aliases['echo'] = echoExePath); - lines = (await Shell(options: options).run('echo --stdout test')).outLines; - expect(lines, ['test']); - // Try using alias - lines = (await Shell( - verbose: false, - environment: ShellEnvironment()..aliases['echo'] = echoExePath) - .run(''' + environment: ShellEnvironment()..aliases['echo'] = echoExePath, + ); + lines = + (await Shell(options: options).run('echo --stdout test')).outLines; + expect(lines, ['test']); + // Try using alias + lines = + (await Shell( + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echoExePath, + ).run(''' echo --stdout test1 echo --stdout test2 - ''')) - .outLines; - expect(lines, ['test1', 'test2']); + ''')).outLines; + expect(lines, ['test1', 'test2']); - // Try relative access - var exePathShell = Shell(workingDirectory: echoExeDir, verbose: false); - lines = (await exePathShell - .run('${shellArgument(join('.', echoExeName))} --stdout test')) - .outLines; - expect(lines, ['test']); + // Try relative access + var exePathShell = Shell(workingDirectory: echoExeDir, verbose: false); + lines = + (await exePathShell.run( + '${shellArgument(join('.', echoExeName))} --stdout test', + )).outLines; + expect(lines, ['test']); - // Without using a relative path, this should fail - try { - await exePathShell.run('${shellArgument(echoExeName)} --stdout test'); - fail('should fail'); - } on ShellException catch (_) { - // print(e); - } + // Without using a relative path, this should fail + try { + await exePathShell.run('${shellArgument(echoExeName)} --stdout test'); + fail('should fail'); + } on ShellException catch (_) { + // print(e); + } - expect(lines, ['test']); - }, - skip: !(Platform.isWindows || Platform.isLinux || Platform.isMacOS), - timeout: const Timeout(Duration(minutes: 10))); + expect(lines, ['test']); + }, + skip: !(Platform.isWindows || Platform.isLinux || Platform.isMacOS), + timeout: const Timeout(Duration(minutes: 10)), + ); } diff --git a/packages/process_run/test/dart_compile_js_test.dart b/packages/process_run/test/dart_compile_js_test.dart index ee894df..94bc17e 100644 --- a/packages/process_run/test/dart_compile_js_test.dart +++ b/packages/process_run/test/dart_compile_js_test.dart @@ -38,9 +38,10 @@ void defineTests() { expect(File(destination).existsSync(), isFalse); var shell = Shell(verbose: false); - final result = (await shell.run( - 'dart compile js -o ${shellArgument(destination)} ${shellArgument(source)}')) - .first; + final result = + (await shell.run( + 'dart compile js -o ${shellArgument(destination)} ${shellArgument(source)}', + )).first; expect(result.exitCode, 0); expect(File(destination).existsSync(), isTrue); }); diff --git a/packages/process_run/test/dart_doc_test.dart b/packages/process_run/test/dart_doc_test.dart index b57a829..af92a22 100644 --- a/packages/process_run/test/dart_doc_test.dart +++ b/packages/process_run/test/dart_doc_test.dart @@ -18,18 +18,24 @@ void defineTests() { try { // Try output-dir first - final result = await runExecutableArguments('dart', - ['doc', '--output-dir', join(testOut, 'dartdoc_build'), '.'], - verbose: true); + final result = await runExecutableArguments('dart', [ + 'doc', + '--output-dir', + join(testOut, 'dartdoc_build'), + '.', + ], verbose: true); //expect(result.stdout, contains('dartdoc')); expect(result.exitCode, 0); } catch (e) { // New for dev? print('failed with --output-dir: $e'); // Try output-dir first - final result = await runExecutableArguments( - 'dart', ['doc', '--output', join(testOut, 'dartdoc_build'), '.'], - verbose: true); + final result = await runExecutableArguments('dart', [ + 'doc', + '--output', + join(testOut, 'dartdoc_build'), + '.', + ], verbose: true); //expect(result.stdout, contains('dartdoc')); expect(result.exitCode, 0); } diff --git a/packages/process_run/test/dartbin_test.dart b/packages/process_run/test/dartbin_test.dart index ff92261..a1dc6dc 100644 --- a/packages/process_run/test/dartbin_test.dart +++ b/packages/process_run/test/dartbin_test.dart @@ -69,17 +69,20 @@ void defineTests() { test('dartExecutable_path', () { expect(isAbsolute(dartExecutable!), isTrue); expect( - Directory(join(dirname(dartExecutable!), 'snapshots')).existsSync(), - isTrue); + Directory(join(dirname(dartExecutable!), 'snapshots')).existsSync(), + isTrue, + ); }); test('flutterDart', () async { if (isFlutterSupportedSync) { try { expect( - dirname(findFlutterDartExecutableSync( - dirname(flutterExecutablePath!))!), - endsWith(join('cache', 'dart-sdk', 'bin'))); + dirname( + findFlutterDartExecutableSync(dirname(flutterExecutablePath!))!, + ), + endsWith(join('cache', 'dart-sdk', 'bin')), + ); } finally { resolvedDartExecutable = null; debugDartExecutableForceWhich = false; @@ -87,19 +90,26 @@ void defineTests() { } }); - test('dart_empty_param', () async { - final result = await Process.run(dartExecutable!, []); - if (dartVersion > Version(2, 10, 0, pre: '1')) { - // Not yet in 2.9.0-21 - // Ok in 2.10.0-1.0.dev - expect(result.exitCode, 0, + test( + 'dart_empty_param', + () async { + final result = await Process.run(dartExecutable!, []); + if (dartVersion > Version(2, 10, 0, pre: '1')) { + // Not yet in 2.9.0-21 + // Ok in 2.10.0-1.0.dev + expect( + result.exitCode, + 0, reason: - 'dartVersion empty param not exitcode 0 yet in $dartVersion, exit code 255 in <=2.9.0 to check'); - } else { - // pre 2.9 behavior - expect(result.exitCode, 255); - } - }, skip: 'dart without params hangs on dev now 2020/10/31'); + 'dartVersion empty param not exitcode 0 yet in $dartVersion, exit code 255 in <=2.9.0 to check', + ); + } else { + // pre 2.9 behavior + expect(result.exitCode, 255); + } + }, + skip: 'dart without params hangs on dev now 2020/10/31', + ); }); test('which', () { @@ -107,8 +117,10 @@ void defineTests() { // might not be in path during the test if (whichDart != null) { if (Platform.isWindows) { - expect(['dart.exe', 'dart.bat'], - contains(basename(whichDart).toLowerCase())); + expect([ + 'dart.exe', + 'dart.bat', + ], contains(basename(whichDart).toLowerCase())); } else { expect(basename(whichDart), getBashOrExeExecutableFilename('dart')); } @@ -122,7 +134,9 @@ void defineTests() { try { resolvedDartExecutable = null; expect( - resolveDartExecutable(environment: {}), isNull); + resolveDartExecutable(environment: {}), + isNull, + ); } catch (e) { print(e); } @@ -145,18 +159,26 @@ void defineTests() { resolvedDartExecutable = null; expect( - dirname(resolveDartExecutable(environment: { - 'PATH': dirname(flutterExecutablePath!) - })!), - endsWith(join('cache', 'dart-sdk', 'bin'))); + dirname( + resolveDartExecutable( + environment: { + 'PATH': dirname(flutterExecutablePath!), + }, + )!, + ), + endsWith(join('cache', 'dart-sdk', 'bin')), + ); expect(resolveDartExecutable(), isNotNull); // Dart from flutter - if (dirname(dartExecutable!) - .contains(dirname(flutterExecutablePath!))) { + if (dirname( + dartExecutable!, + ).contains(dirname(flutterExecutablePath!))) { expect( - dartSdkBinDirPath, endsWith(join('cache', 'dart-sdk', 'bin'))); + dartSdkBinDirPath, + endsWith(join('cache', 'dart-sdk', 'bin')), + ); } } finally { resolvedDartExecutable = null; diff --git a/packages/process_run/test/echo_test.dart b/packages/process_run/test/echo_test.dart index 25a5948..3767151 100644 --- a/packages/process_run/test/echo_test.dart +++ b/packages/process_run/test/echo_test.dart @@ -43,23 +43,29 @@ void main() { stderrEncoding: stderrEncoding, ); check(result); - result = await runExecutableArguments(executable, arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding, - stdout: stdout); + result = await runExecutableArguments( + executable, + arguments, + workingDirectory: workingDirectory, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdout: stdout, + ); check(result); - result = runExecutableArgumentsSync(executable, arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding, - stdout: stdout); + result = runExecutableArgumentsSync( + executable, + arguments, + workingDirectory: workingDirectory, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdout: stdout, + ); check(result); } @@ -85,11 +91,18 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - checkOut, dartExecutable!, [echoScriptPath, '--stdout', 'out']); + await runCheck(checkOut, dartExecutable!, [ + echoScriptPath, + '--stdout', + 'out', + ]); await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); - await runCheck(checkOutWriteLine, dartExecutable!, - [echoScriptPath, '--stdout', 'out', '--write-line']); + await runCheck(checkOutWriteLine, dartExecutable!, [ + echoScriptPath, + '--stdout', + 'out', + '--write-line', + ]); }); test('stdout_bin', () async { @@ -107,31 +120,39 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - check123, dartExecutable!, [echoScriptPath, '--stdout-hex', '010203'], - stdoutEncoding: null); - await runCheck(checkEmpty, dartExecutable!, [echoScriptPath], - stdoutEncoding: null); + await runCheck(check123, dartExecutable!, [ + echoScriptPath, + '--stdout-hex', + '010203', + ], stdoutEncoding: null); + await runCheck(checkEmpty, dartExecutable!, [ + echoScriptPath, + ], stdoutEncoding: null); }); group('stdout_env', () { test('var', () async { - var result = await runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdout-env', 'PATH']); + var result = await runExecutableArguments(dartExecutable!, [ + echoScriptPath, + '--stdout-env', + 'PATH', + ]); //devPrint(result.stdout.toString()); expect(result.stdout.toString().trim(), isNotEmpty); result = await runExecutableArguments(dartExecutable!, [ echoScriptPath, '--stdout-env', - '__dummy_that_will_never_exists__' + '__dummy_that_will_never_exists__', ]); //devPrint(result.stdout.toString()); expect(result.stdout.toString().trim(), isEmpty); result = await runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdout-env', '__CUSTOM'], - environment: {'__CUSTOM': '12345'}); + dartExecutable!, + [echoScriptPath, '--stdout-env', '__CUSTOM'], + environment: {'__CUSTOM': '12345'}, + ); expect(result.stdout.toString().trim(), '12345'); }); }); @@ -158,24 +179,26 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - checkErr, - dartExecutable!, - [echoScriptPath, '--stderr', 'err'], - ); - await runCheck( - checkErrWriteLine, - dartExecutable!, - [echoScriptPath, '--stderr', 'err', '--write-line'], - ); + await runCheck(checkErr, dartExecutable!, [ + echoScriptPath, + '--stderr', + 'err', + ]); + await runCheck(checkErrWriteLine, dartExecutable!, [ + echoScriptPath, + '--stderr', + 'err', + '--write-line', + ]); await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); }); test('stdin', () async { final inCtrl = StreamController>(); - final processResultFuture = runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdin'], - stdin: inCtrl.stream); + final processResultFuture = runExecutableArguments(dartExecutable!, [ + echoScriptPath, + '--stdin', + ], stdin: inCtrl.stream); inCtrl.add('in'.codeUnits); await inCtrl.close(); final result = await processResultFuture; @@ -201,11 +224,14 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - check123, dartExecutable!, [echoScriptPath, '--stderr-hex', '010203'], - stderrEncoding: null); - await runCheck(checkEmpty, dartExecutable!, [echoScriptPath], - stderrEncoding: null); + await runCheck(check123, dartExecutable!, [ + echoScriptPath, + '--stderr-hex', + '010203', + ], stderrEncoding: null); + await runCheck(checkEmpty, dartExecutable!, [ + echoScriptPath, + ], stderrEncoding: null); }); test('exitCode', () async { @@ -223,8 +249,11 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - check123, dartExecutable!, [echoScriptPath, '--exit-code', '123']); + await runCheck(check123, dartExecutable!, [ + echoScriptPath, + '--exit-code', + '123', + ]); await runCheck(check0, dartExecutable!, [echoScriptPath]); }); @@ -236,8 +265,11 @@ void main() { expect(result.exitCode, 255); } - await runCheck( - check, dartExecutable!, [echoScriptPath, '--exit-code', 'crash']); + await runCheck(check, dartExecutable!, [ + echoScriptPath, + '--exit-code', + 'crash', + ]); }); }); } diff --git a/packages/process_run/test/flutterbin_cmd_test.dart b/packages/process_run/test/flutterbin_cmd_test.dart index 9f09ea4..11e0819 100644 --- a/packages/process_run/test/flutterbin_cmd_test.dart +++ b/packages/process_run/test/flutterbin_cmd_test.dart @@ -69,8 +69,10 @@ void main() { }, skip: !isFlutterSupportedSync); test('which', () { - expect(basename(whichSync('flutter')!), - getBashOrBatExecutableFilename('flutter')); + expect( + basename(whichSync('flutter')!), + getBashOrBatExecutableFilename('flutter'), + ); }, skip: !isFlutterSupportedSync); }); } diff --git a/packages/process_run/test/flutterbin_impl_test.dart b/packages/process_run/test/flutterbin_impl_test.dart index b780d99..e65d769 100644 --- a/packages/process_run/test/flutterbin_impl_test.dart +++ b/packages/process_run/test/flutterbin_impl_test.dart @@ -9,13 +9,17 @@ import 'package:test/test.dart'; void main() { group('flutterbin_impl', () { test('FlutterBinInfo', () { - var info = FlutterBinInfo.parseVersionOutput( - 'Flutter 1.7.8+hotfix.4 • channel stable • https://github.com/flutter/flutter.git')!; + var info = + FlutterBinInfo.parseVersionOutput( + 'Flutter 1.7.8+hotfix.4 • channel stable • https://github.com/flutter/flutter.git', + )!; expect(info.version, Version(1, 7, 8, build: 'hotfix.4')); expect(info.channel, 'stable'); - info = FlutterBinInfo.parseVersionOutput( - 'Flutter 1.14.3 • channel dev • https://github.com/flutter/flutter.git')!; + info = + FlutterBinInfo.parseVersionOutput( + 'Flutter 1.14.3 • channel dev • https://github.com/flutter/flutter.git', + )!; expect(info.version, Version(1, 14, 3)); expect(info.channel, 'dev'); }); diff --git a/packages/process_run/test/package_test.dart b/packages/process_run/test/package_test.dart index 5180480..9f348f8 100644 --- a/packages/process_run/test/package_test.dart +++ b/packages/process_run/test/package_test.dart @@ -13,8 +13,10 @@ void defineTests() { group('package', () { test('getPackageVersion', () async { expect(await getPackageVersion(), greaterThan(Version(0, 10, 0))); - expect(await getPackageVersion(dir: join('test', '..')), - greaterThan(Version(0, 10, 0))); + expect( + await getPackageVersion(dir: join('test', '..')), + greaterThan(Version(0, 10, 0)), + ); expect(await getPackageVersion(dir: 'test'), isNull); }); }); diff --git a/packages/process_run/test/process_cmd_test.dart b/packages/process_run/test/process_cmd_test.dart index 6598886..ee646dc 100644 --- a/packages/process_run/test/process_cmd_test.dart +++ b/packages/process_run/test/process_cmd_test.dart @@ -44,14 +44,19 @@ void main() { test('system_command', () async { // read pubspec.yaml final lines = LineSplitter.split( - await File(join(projectTop, 'pubspec.yaml')).readAsString()); + await File(join(projectTop, 'pubspec.yaml')).readAsString(), + ); // use 'cat' on mac and linux // use 'type' on windows ProcessCmd cmd; if (Platform.isWindows) { - cmd = ProcessCmd('type', ['pubspec.yaml'], - workingDirectory: projectTop, runInShell: true); + cmd = ProcessCmd( + 'type', + ['pubspec.yaml'], + workingDirectory: projectTop, + runInShell: true, + ); } else { cmd = ProcessCmd('cat', ['pubspec.yaml'], workingDirectory: projectTop); } @@ -65,25 +70,33 @@ void main() { test('processResultToDebugString', () { expect( - LineSplitter.split( - processResultToDebugString(ProcessResult(1, 0, 'out', 'err'))), - ['exitCode: 0', 'out: out', 'err: err']); + LineSplitter.split( + processResultToDebugString(ProcessResult(1, 0, 'out', 'err')), + ), + ['exitCode: 0', 'out: out', 'err: err'], + ); expect( - LineSplitter.split(processResultToDebugString( - ProcessResult(2, 1, 'testout', 'testerr'))), - ['exitCode: 1', 'out: testout', 'err: testerr']); + LineSplitter.split( + processResultToDebugString(ProcessResult(2, 1, 'testout', 'testerr')), + ), + ['exitCode: 1', 'out: testout', 'err: testerr'], + ); }); test('processCmdToDebugString', () { expect( - LineSplitter.split( - processCmdToDebugString(ProcessCmd('cmd', ['arg']))), - ['cmd: cmd arg']); + LineSplitter.split(processCmdToDebugString(ProcessCmd('cmd', ['arg']))), + ['cmd: cmd arg'], + ); expect( - LineSplitter.split(processCmdToDebugString( - ProcessCmd('cmd', ['arg'])..workingDirectory = 'dir')), - ['dir: dir', 'cmd: cmd arg']); + LineSplitter.split( + processCmdToDebugString( + ProcessCmd('cmd', ['arg'])..workingDirectory = 'dir', + ), + ), + ['dir: dir', 'cmd: cmd arg'], + ); }); }); } diff --git a/packages/process_run/test/process_run_in_test2_.dart b/packages/process_run/test/process_run_in_test2_.dart index baf92f2..e84114d 100644 --- a/packages/process_run/test/process_run_in_test2_.dart +++ b/packages/process_run/test/process_run_in_test2_.dart @@ -13,13 +13,15 @@ import 'process_run_test_common.dart'; Future main() async { print("Please enter 'hi'"); var result = await runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdin'], + dartExecutable!, + [echoScriptPath, '--stdin'], //stdin: testStdin); ); print('out: ${result.stdout}'); print("Please enter 'ho'"); result = await runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdin'], + dartExecutable!, + [echoScriptPath, '--stdin'], //stdin: testStdin); ); print('out: ${result.stdout}'); diff --git a/packages/process_run/test/process_run_in_test_.dart b/packages/process_run/test/process_run_in_test_.dart index f12f2d1..c368beb 100644 --- a/packages/process_run/test/process_run_in_test_.dart +++ b/packages/process_run/test/process_run_in_test_.dart @@ -11,14 +11,16 @@ import 'process_run_test_common.dart'; void main() { test('connect_stdin', () async { print("Please enter 'hi'"); - var result = await runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdin'], - stdin: testStdin); + var result = await runExecutableArguments(dartExecutable!, [ + echoScriptPath, + '--stdin', + ], stdin: testStdin); expect(result.stdout, 'hi'); print("Please enter 'ho'"); - result = await runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdin'], - stdin: testStdin); + result = await runExecutableArguments(dartExecutable!, [ + echoScriptPath, + '--stdin', + ], stdin: testStdin); expect(result.stdout, 'ho'); }); } diff --git a/packages/process_run/test/process_run_out_test_.dart b/packages/process_run/test/process_run_out_test_.dart index 2523bbe..214ea1a 100644 --- a/packages/process_run/test/process_run_out_test_.dart +++ b/packages/process_run/test/process_run_out_test_.dart @@ -11,9 +11,11 @@ import 'process_run_test_common.dart'; void main() { test('connect_stdout', () async { await stdout.flush(); - final result = await runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdout', 'out'], - stdout: stdout); + final result = await runExecutableArguments(dartExecutable!, [ + echoScriptPath, + '--stdout', + 'out', + ], stdout: stdout); expect(result.stderr, ''); expect(result.stdout, 'out'); expect(result.pid, isNotNull); @@ -23,9 +25,11 @@ void main() { test('connect_stderr', () async { await stderr.flush(); - final result = await runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stderr', 'err'], - stderr: stderr); + final result = await runExecutableArguments(dartExecutable!, [ + echoScriptPath, + '--stderr', + 'err', + ], stderr: stderr); expect(result.stdout, ''); expect(result.stderr, 'err'); expect(result.pid, isNotNull); diff --git a/packages/process_run/test/process_run_test.dart b/packages/process_run/test/process_run_test.dart index 2020875..ed30f61 100644 --- a/packages/process_run/test/process_run_test.dart +++ b/packages/process_run/test/process_run_test.dart @@ -73,14 +73,17 @@ void main() { stderrEncoding: stderrEncoding, ); check(result); - result = await runExecutableArguments(executable, arguments, - workingDirectory: workingDirectory, - environment: environment, - includeParentEnvironment: includeParentEnvironment, - runInShell: runInShell, - stdoutEncoding: stdoutEncoding, - stderrEncoding: stderrEncoding, - stdout: stdout); + result = await runExecutableArguments( + executable, + arguments, + workingDirectory: workingDirectory, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + runInShell: runInShell, + stdoutEncoding: stdoutEncoding, + stderrEncoding: stderrEncoding, + stdout: stdout, + ); check(result); } @@ -99,8 +102,11 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - checkOut, dartExecutable!, [echoScriptPath, '--stdout', 'out']); + await runCheck(checkOut, dartExecutable!, [ + echoScriptPath, + '--stdout', + 'out', + ]); await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); }); @@ -119,11 +125,14 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - check123, dartExecutable!, [echoScriptPath, '--stdout-hex', '010203'], - stdoutEncoding: null); - await runCheck(checkEmpty, dartExecutable!, [echoScriptPath], - stdoutEncoding: null); + await runCheck(check123, dartExecutable!, [ + echoScriptPath, + '--stdout-hex', + '010203', + ], stdoutEncoding: null); + await runCheck(checkEmpty, dartExecutable!, [ + echoScriptPath, + ], stdoutEncoding: null); }); test('stderr', () async { @@ -141,17 +150,20 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - checkErr, dartExecutable!, [echoScriptPath, '--stderr', 'err'], - stdout: stdout); + await runCheck(checkErr, dartExecutable!, [ + echoScriptPath, + '--stderr', + 'err', + ], stdout: stdout); await runCheck(checkEmpty, dartExecutable!, [echoScriptPath]); }); test('stdin', () async { final inCtrl = StreamController>(); - final processResultFuture = runExecutableArguments( - dartExecutable!, [echoScriptPath, '--stdin'], - stdin: inCtrl.stream); + final processResultFuture = runExecutableArguments(dartExecutable!, [ + echoScriptPath, + '--stdin', + ], stdin: inCtrl.stream); inCtrl.add('in'.codeUnits); await inCtrl.close(); final result = await processResultFuture; @@ -177,11 +189,14 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - check123, dartExecutable!, [echoScriptPath, '--stderr-hex', '010203'], - stderrEncoding: null); - await runCheck(checkEmpty, dartExecutable!, [echoScriptPath], - stderrEncoding: null); + await runCheck(check123, dartExecutable!, [ + echoScriptPath, + '--stderr-hex', + '010203', + ], stderrEncoding: null); + await runCheck(checkEmpty, dartExecutable!, [ + echoScriptPath, + ], stderrEncoding: null); }); test('exitCode', () async { @@ -199,8 +214,11 @@ void main() { expect(result.exitCode, 0); } - await runCheck( - check123, dartExecutable!, [echoScriptPath, '--exit-code', '123']); + await runCheck(check123, dartExecutable!, [ + echoScriptPath, + '--exit-code', + '123', + ]); await runCheck(check0, dartExecutable!, [echoScriptPath]); }); @@ -212,8 +230,11 @@ void main() { expect(result.exitCode, 255); } - await runCheck( - check, dartExecutable!, [echoScriptPath, '--exit-code', 'crash']); + await runCheck(check, dartExecutable!, [ + echoScriptPath, + '--exit-code', + 'crash', + ]); }); test('invalid_executable', () async { @@ -259,12 +280,16 @@ void main() { test('relative', () async { if (Platform.isWindows) { var result = await runExecutableArguments( - join('test', 'src', 'current_dir.bat'), []); + join('test', 'src', 'current_dir.bat'), + [], + ); expect(result.exitCode, 0); expect(result.stdout.toString().trim(), Directory.current.path); } else { var result = await runExecutableArguments( - join('test', 'src', 'current_dir'), []); + join('test', 'src', 'current_dir'), + [], + ); expect(result.exitCode, 0); expect(result.stdout.toString().trim(), Directory.current.path); } @@ -272,8 +297,9 @@ void main() { test('system_command', () async { // read pubspec.yaml - final lines = const LineSplitter() - .convert(await File(join(projectTop, 'pubspec.yaml')).readAsString()); + final lines = const LineSplitter().convert( + await File(join(projectTop, 'pubspec.yaml')).readAsString(), + ); void check(ProcessResult result) { expect(const LineSplitter().convert(result.stdout.toString()), lines); @@ -286,11 +312,17 @@ void main() { // use 'type' on windows if (Platform.isWindows) { - await runCheck(check, 'type', ['pubspec.yaml'], - workingDirectory: projectTop, runInShell: true); + await runCheck( + check, + 'type', + ['pubspec.yaml'], + workingDirectory: projectTop, + runInShell: true, + ); } else { - await runCheck(check, 'cat', ['pubspec.yaml'], - workingDirectory: projectTop); + await runCheck(check, 'cat', [ + 'pubspec.yaml', + ], workingDirectory: projectTop); } }); @@ -301,18 +333,19 @@ void main() { env[envPathKey] = '${dirname(path)}$envPathSeparator${env[envPathKey]}'; print(env[envPathKey]); var result = await runExecutableArguments( - 'space in binary$basicScriptExecutableExtension', [], - environment: env); + 'space in binary$basicScriptExecutableExtension', + [], + environment: env, + ); expect(result.stdout.toString().trim(), 'Hello'); expect( - (await Shell(environment: env, verbose: false) - .run(shellArgument('space in binary'))) - .first - .stdout - .toString() - .trim(), - 'Hello'); + (await Shell( + environment: env, + verbose: false, + ).run(shellArgument('space in binary'))).first.stdout.toString().trim(), + 'Hello', + ); }); test('space in path', () async { var path = '.dart_tool/process_run/test/space in path/binary'; @@ -321,17 +354,19 @@ void main() { env[envPathKey] = '${dirname(path)}$envPathSeparator${env[envPathKey]}'; print(env[envPathKey]); var result = await runExecutableArguments( - 'binary$basicScriptExecutableExtension', [], - environment: env); + 'binary$basicScriptExecutableExtension', + [], + environment: env, + ); expect(result.stdout.toString().trim(), 'Hello'); expect( - (await Shell(environment: env, verbose: false).run('binary')) - .first - .stdout - .toString() - .trim(), - 'Hello'); + (await Shell( + environment: env, + verbose: false, + ).run('binary')).first.stdout.toString().trim(), + 'Hello', + ); }); test('windows_system_command', () async { if (Platform.isWindows) { diff --git a/packages/process_run/test/process_run_test_common.dart b/packages/process_run/test/process_run_test_common.dart index cecac93..abb126d 100644 --- a/packages/process_run/test/process_run_test_common.dart +++ b/packages/process_run/test/process_run_test_common.dart @@ -76,8 +76,9 @@ Future createEchoExecutable(String path) async { await Directory(dirname(path)).create(recursive: true); } catch (_) {} var fullPath = '$path$basicScriptExecutableExtension'; - await File(fullPath) - .writeAsString(Platform.isWindows ? '@echo Hello' : 'echo Hello'); + await File( + fullPath, + ).writeAsString(Platform.isWindows ? '@echo Hello' : 'echo Hello'); if (Platform.isLinux || Platform.isMacOS) { await Shell().run('chmod +x ${shellArgument(fullPath)}'); } diff --git a/packages/process_run/test/shell_common_test.dart b/packages/process_run/test/shell_common_test.dart index e560194..c0cf982 100644 --- a/packages/process_run/test/shell_common_test.dart +++ b/packages/process_run/test/shell_common_test.dart @@ -15,10 +15,11 @@ import 'package:test/test.dart'; class ShellContextMock with ShellContextMixin implements ShellContext { @override - Shell newShell( - {ShellOptions? options, - Map? environment, - bool includeParentEnvironment = true}) { + Shell newShell({ + ShellOptions? options, + Map? environment, + bool includeParentEnvironment = true, + }) { return ShellMock(options: options, context: this); } @@ -76,8 +77,10 @@ class ProcessMock implements Process { Stream> get stdout => throw UnimplementedError(); } -var shellOptionsMock = - ShellOptions(environment: {}, includeParentEnvironment: false); +var shellOptionsMock = ShellOptions( + environment: {}, + includeParentEnvironment: false, +); class ShellMock with ShellMixin implements Shell { var scripts = []; @@ -112,8 +115,10 @@ class ShellMock with ShellMixin implements Shell { } @override - Future> run(String script, - {ShellOnProcessCallback? onProcess}) async { + Future> run( + String script, { + ShellOnProcessCallback? onProcess, + }) async { scripts.add(script); // Take "hola" from "echo hola" var outLines = [script.split(' ').last]; @@ -126,8 +131,10 @@ class ShellMock with ShellMixin implements Shell { @override Future runExecutableArguments( - String executable, List arguments, - {ShellOnProcessCallback? onProcess}) { + String executable, + List arguments, { + ShellOnProcessCallback? onProcess, + }) { // TODO: implement runExecutableArguments throw UnimplementedError(); } @@ -154,9 +161,12 @@ class ShellMock with ShellMixin implements Shell { void main() { group('shell_common_test', () { Future testLinuxEcho(Shell shell) async { - var results = await shell.run('echo hola', onProcess: (process) { - process.kill(); - }); + var results = await shell.run( + 'echo hola', + onProcess: (process) { + process.kill(); + }, + ); expect(results.first.exitCode, 0); var outLines = results.outLines; @@ -206,10 +216,13 @@ void main() { //expect(shell.scripts, ['hola']); }); test('cloneWithOptions', () async { - var shell = ShellMock().cloneWithOptions(ShellOptions( + var shell = ShellMock().cloneWithOptions( + ShellOptions( workingDirectory: 'a/b', environment: {}, - includeParentEnvironment: false)); + includeParentEnvironment: false, + ), + ); expect(shell.path, 'a/b'); expect(shell.options.workingDirectory, 'a/b'); }); diff --git a/packages/process_run/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart index f0b4277..d027522 100644 --- a/packages/process_run/test/shell_environment_test.dart +++ b/packages/process_run/test/shell_environment_test.dart @@ -42,7 +42,7 @@ void main() { expect(env, { 'VAR1': 'var1', - 'PATH': (Platform.isWindows ? 'path1;path2' : 'path1:path2') + 'PATH': (Platform.isWindows ? 'path1;path2' : 'path1:path2'), }); }); @@ -60,15 +60,10 @@ void main() { expect(env, {'PATH': 'path1', 'VAR2': 'var2', 'VAR3': 'var3'}); env.vars.remove('VAR2'); env.vars.remove('VAR4'); - expect(env, { - 'PATH': 'path1', - 'VAR3': 'var3', - }); + expect(env, {'PATH': 'path1', 'VAR3': 'var3'}); env.paths.remove('path1'); env.paths.remove('path2'); - expect(env, { - 'VAR3': 'var3', - }); + expect(env, {'VAR3': 'var3'}); }); test('prepend', () { var env = ShellEnvironment.empty(); @@ -77,7 +72,7 @@ void main() { env.paths.remove('path3'); expect(env, { - envPathKey: ['path1', 'path2'].join(envPathSeparator) + envPathKey: ['path1', 'path2'].join(envPathSeparator), }); }); @@ -90,7 +85,7 @@ void main() { env.paths.remove('path3'); expect(env, { - envPathKey: ['path1', 'test', 'path2'].join(envPathSeparator) + envPathKey: ['path1', 'test', 'path2'].join(envPathSeparator), }); }); @@ -98,8 +93,9 @@ void main() { var prevEnv = shellEnvironment; expect(shellEnvironment, isNotEmpty); var shell = Shell(verbose: false); - var env = ShellEnvironment() - ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; + var env = + ShellEnvironment() + ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; var result = await getEchoEnv(shell); @@ -124,8 +120,9 @@ void main() { }); // not working test('local vars', () async { - var env = ShellEnvironment() - ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; + var env = + ShellEnvironment() + ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; var localShell = Shell(environment: env, verbose: false); var shell = Shell(verbose: false); @@ -133,27 +130,33 @@ void main() { expect(result.vars['TEST_PROCESS_RUN_VAR1'], isNull); var resultWithParent = await getEchoEnv(localShell); - expect(resultWithParent.vars['TEST_PROCESS_RUN_VAR1'], - 'test_process_run_value1'); + expect( + resultWithParent.vars['TEST_PROCESS_RUN_VAR1'], + 'test_process_run_value1', + ); localShell = Shell(environment: env, includeParentEnvironment: false); var resultWithoutParent = await getEchoEnv(localShell); - expect(resultWithoutParent.vars['TEST_PROCESS_RUN_VAR1'], - 'test_process_run_value1'); + expect( + resultWithoutParent.vars['TEST_PROCESS_RUN_VAR1'], + 'test_process_run_value1', + ); }); test('local one var', () async { try { - var env = ShellEnvironment.empty() - ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; + var env = + ShellEnvironment.empty() + ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; var shell = Shell(environment: env, verbose: false); print(await getEchoEnv(shell)); shell = Shell( - environment: env, - includeParentEnvironment: false, - verbose: true); // This should be small + environment: env, + includeParentEnvironment: false, + verbose: true, + ); // This should be small var resultWithoutParent = await getEchoEnv(shell); print(resultWithoutParent); @@ -211,30 +214,32 @@ void main() { shellEnvironment = prevEnv; } }); - test('local empty include parent', () async { - var git = 'git'; - if (await which(git) != null) { - var env = ShellEnvironment.empty(); - expect(await env.which(git), isNull); - var shell = Shell( + test( + 'local empty include parent', + () async { + var git = 'git'; + if (await which(git) != null) { + var env = ShellEnvironment.empty(); + expect(await env.which(git), isNull); + var shell = Shell( environment: env, - includeParentEnvironment: - false); // Shell(environment: env, includeParentEnvironment: false); + includeParentEnvironment: false, + ); // Shell(environment: env, includeParentEnvironment: false); - try { - await shell.run('git --version'); - fail('Should fail'); - } catch (e) { - expect(e, isNot(const TypeMatcher())); - } + try { + await shell.run('git --version'); + fail('Should fail'); + } catch (e) { + expect(e, isNot(const TypeMatcher())); + } - shell = Shell(environment: env, includeParentEnvironment: true); + shell = Shell(environment: env, includeParentEnvironment: true); - await shell.run('git --version'); - } - }, - skip: - true); // It does not seem to prevent calling git although not in the path + await shell.run('git --version'); + } + }, + skip: true, + ); // It does not seem to prevent calling git although not in the path test('equals', () async { expect(ShellEnvironment.empty(), ShellEnvironment.empty()); }); @@ -242,12 +247,12 @@ void main() { expect(ShellEnvironment.empty().toJson(), { 'paths': [], 'vars': {}, - 'aliases': {} + 'aliases': {}, }); expect(basicEnv.toJson(), { 'paths': ['path1'], 'vars': {'VAR1': 'var1'}, - 'aliases': {'alias1': 'command1'} + 'aliases': {'alias1': 'command1'}, }); var jsonText = jsonEncode(basicEnv.toJson()); expect(jsonDecode(jsonText), basicEnv.toJson()); @@ -258,12 +263,13 @@ void main() { }); test('fromJson', () async { expect( - ShellEnvironment.fromJson({ - 'paths': ['path1'], - 'vars': {'VAR1': 'var1'}, - 'aliases': {'alias1': 'command1'} - }), - basicEnv); + ShellEnvironment.fromJson({ + 'paths': ['path1'], + 'vars': {'VAR1': 'var1'}, + 'aliases': {'alias1': 'command1'}, + }), + basicEnv, + ); expect(ShellEnvironment.fromJson({}), emptyEnv); }); test('merge', () { @@ -275,25 +281,27 @@ void main() { var envOther = ShellEnvironment.empty(); envOther.vars.addAll({'VAR2': 'new_value2', 'VAR3': 'var3'}); - envOther.paths.addAll([ - 'path_first', - 'path_second', - 'path_third', - ]); + envOther.paths.addAll(['path_first', 'path_second', 'path_third']); env.merge(envOther); expect(env, { 'VAR1': 'var1', 'VAR2': 'new_value2', - 'PATH': ['path_first', 'path_second', 'path_third', 'path_fourth'] - .join(envPathSeparator), - 'VAR3': 'var3' + 'PATH': [ + 'path_first', + 'path_second', + 'path_third', + 'path_fourth', + ].join(envPathSeparator), + 'VAR3': 'var3', }); }); test('path merge', () { var paths = ShellEnvironment().paths; paths.merge(paths); var env = ShellEnvironment.full( - environment: shellEnvironment, includeParentEnvironment: true); + environment: shellEnvironment, + includeParentEnvironment: true, + ); paths = env.paths; paths.merge(paths); @@ -340,5 +348,6 @@ void main() { /// Better with non verbose shell. Future getEchoEnv(Shell shell) async { return ShellEnvironment.fromJson( - jsonDecode((await shell.run('$echo --all-env')).outLines.join()) as Map?); + jsonDecode((await shell.run('$echo --all-env')).outLines.join()) as Map?, + ); } diff --git a/packages/process_run/test/shell_lines_controller_test.dart b/packages/process_run/test/shell_lines_controller_test.dart index f42ee47..b5f4423 100644 --- a/packages/process_run/test/shell_lines_controller_test.dart +++ b/packages/process_run/test/shell_lines_controller_test.dart @@ -12,9 +12,10 @@ void main() { group('ShellLinesController', () { late ShellEnvironment env; setUpAll(() async { - env = ShellEnvironment() - ..aliases['streamer'] = await compileStreamerExample() - ..aliases['echo'] = await compileEchoExample(); + env = + ShellEnvironment() + ..aliases['streamer'] = await compileStreamerExample() + ..aliases['echo'] = await compileEchoExample(); }); test('stream all', () async { var ctlr = ShellLinesController(); @@ -50,12 +51,15 @@ void main() { test('addError', () async { var ctlr = ShellLinesController(); var completer = Completer(); - ctlr.stream.listen((event) { - fail('should not be called'); - }, onError: (Object e) { - expect(e, 'test'); - completer.complete(true); - }); + ctlr.stream.listen( + (event) { + fail('should not be called'); + }, + onError: (Object e) { + expect(e, 'test'); + completer.complete(true); + }, + ); ctlr.sink.addError('test'); await completer.future; @@ -64,12 +68,15 @@ void main() { test('shell error', () async { var ctlr = ShellLinesController(); var completer = Completer(); - ctlr.stream.listen((event) {}, onError: (Object e) { - var shellException = e as ShellException; - expect(shellException.result!.exitCode, 1); - //expect(e, 'test'); - completer.complete(true); - }); + ctlr.stream.listen( + (event) {}, + onError: (Object e) { + var shellException = e as ShellException; + expect(shellException.result!.exitCode, 1); + //expect(e, 'test'); + completer.complete(true); + }, + ); var shell = Shell(stdout: ctlr.sink, environment: env); await shell .run('echo --exit-code 1') @@ -86,9 +93,10 @@ void main() { } }); var shell = Shell( - stdout: ctlr.sink, - stdin: inputController.binaryStream, - environment: env); + stdout: ctlr.sink, + stdin: inputController.binaryStream, + environment: env, + ); var done = shell.run('echo --stdin --write-line --verbose'); inputController.writeln('stdin_done'); inputController.close(); diff --git a/packages/process_run/test/shell_run_test.dart b/packages/process_run/test/shell_run_test.dart index 1875a1d..8bebb3b 100644 --- a/packages/process_run/test/shell_run_test.dart +++ b/packages/process_run/test/shell_run_test.dart @@ -33,24 +33,34 @@ void main() { }); test('userEnvironment', () async { await run( - 'dart example/echo.dart ${shellArgument(stringTruncate(userEnvironment.toString(), 1500))}', - verbose: false); + 'dart example/echo.dart ${shellArgument(stringTruncate(userEnvironment.toString(), 1500))}', + verbose: false, + ); - expect(userEnvironment.length, - greaterThanOrEqualTo(shellEnvironment.length)); - expect(userEnvironment.length, - greaterThanOrEqualTo(platformEnvironment.length)); + expect( + userEnvironment.length, + greaterThanOrEqualTo(shellEnvironment.length), + ); + expect( + userEnvironment.length, + greaterThanOrEqualTo(platformEnvironment.length), + ); }); test('shellEnvironment', () async { await run( - 'dart example/echo.dart ${shellArgument(stringTruncate(shellEnvironment.toString(), 1500))}', - verbose: false); + 'dart example/echo.dart ${shellArgument(stringTruncate(shellEnvironment.toString(), 1500))}', + verbose: false, + ); }); test('sync --version', () async { - var result = runSync('dart --version', - throwOnError: false, verbose: false, commandVerbose: true) - .first; + var result = + runSync( + 'dart --version', + throwOnError: false, + verbose: false, + commandVerbose: true, + ).first; stdout.writeln('stdout: ${result.stdout.toString().trim()}'); stdout.writeln('stderr: ${result.stderr.toString().trim()}'); stdout.writeln('exitCode: ${result.exitCode}'); @@ -66,9 +76,13 @@ void main() { // 'dartanalyzer', deprecated ]) { stdout.writeln(''); - var result = (await run('$bin --version', - throwOnError: false, verbose: false, commandVerbose: true)) - .first; + var result = + (await run( + '$bin --version', + throwOnError: false, + verbose: false, + commandVerbose: true, + )).first; stdout.writeln('stdout: ${result.stdout.toString().trim()}'); stdout.writeln('stderr: ${result.stderr.toString().trim()}'); stdout.writeln('exitCode: ${result.exitCode}'); @@ -85,12 +99,16 @@ void main() { }); test('throwOnError', () async { var verbose = false; // devWarning(true); - var env = ShellEnvironment() - ..aliases['echo'] = 'dart run ${shellArgument(echoScriptPath)}'; + var env = + ShellEnvironment() + ..aliases['echo'] = 'dart run ${shellArgument(echoScriptPath)}'; // Prevent error to be thrown if exitCode is not 0 - var shell = - Shell(throwOnError: false, verbose: verbose, environment: env); + var shell = Shell( + throwOnError: false, + verbose: verbose, + environment: env, + ); // This won't throw var exitCode = (await shell.run('echo --exit-code 1')).first.exitCode; expect(exitCode, 1); diff --git a/packages/process_run/test/shell_stdio_lines_grouper_test.dart b/packages/process_run/test/shell_stdio_lines_grouper_test.dart index 793726b..65ae5a8 100644 --- a/packages/process_run/test/shell_stdio_lines_grouper_test.dart +++ b/packages/process_run/test/shell_stdio_lines_grouper_test.dart @@ -14,8 +14,9 @@ void main() { var echo = await compileEchoExample(); var options = ShellOptions( - verbose: false, - environment: ShellEnvironment()..aliases['echo'] = echo); + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echo, + ); var lines = (await Shell(options: options).run('echo --stdout test')).outLines; expect(lines, ['test']); @@ -44,15 +45,21 @@ echo --wait 100 --stdout hello2 // await printHello123Slow(); var stdio = shellStdioLinesGrouper; - await Future.wait>( - [stdio.runZoned(() => printHello123Slow()), printHello123Slow()]); + await Future.wait>([ + stdio.runZoned(() => printHello123Slow()), + printHello123Slow(), + ]); var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); var isMemoryStdout = InMemoryIOSink(StdioStreamType.out); stdio = ShellStdioLinesGrouper( - stderr: inMemoryStderr, stdout: isMemoryStdout); - await Future.wait>( - [stdio.runZoned(() => printHello123Slow()), printHello123Slow()]); + stderr: inMemoryStderr, + stdout: isMemoryStdout, + ); + await Future.wait>([ + stdio.runZoned(() => printHello123Slow()), + printHello123Slow(), + ]); // Not working yet // expect(isMemoryStdout.lines, ['hello1', 'hello2', 'hello1', 'hello2', 'hello1', 'hello2']); }); @@ -60,7 +67,9 @@ echo --wait 100 --stdout hello2 var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); var stdio = ShellStdioLinesGrouper( - stderr: inMemoryStderr, stdout: inMemoryStdout); + stderr: inMemoryStderr, + stdout: inMemoryStdout, + ); await stdio.runZoned(() async { stdout.writeln('test1'); stderr.writeln('test2'); @@ -74,7 +83,9 @@ echo --wait 100 --stdout hello2 var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); var stdio = ShellStdioLinesGrouper( - stderr: inMemoryStderr, stdout: inMemoryStdout); + stderr: inMemoryStderr, + stdout: inMemoryStdout, + ); await stdio.runZoned(() async { stdout.writeln('test1'); stdout.writeln(''); @@ -87,7 +98,9 @@ echo --wait 100 --stdout hello2 var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); var stdio = ShellStdioLinesGrouper( - stderr: inMemoryStderr, stdout: inMemoryStdout); + stderr: inMemoryStderr, + stdout: inMemoryStdout, + ); await stdio.runZoned(() async { stdout.write('test1\r\n'); stdout.write('test2\r'); @@ -101,7 +114,9 @@ echo --wait 100 --stdout hello2 var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); var stdio = ShellStdioLinesGrouper( - stderr: inMemoryStderr, stdout: inMemoryStdout); + stderr: inMemoryStderr, + stdout: inMemoryStdout, + ); await stdio.runZoned(() async { stdout.writeln('test1'); stdout.writeln(''); @@ -115,19 +130,27 @@ echo --wait 100 --stdout hello2 var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); var stdio = ShellStdioLinesGrouper( - stderr: inMemoryStderr, stdout: inMemoryStdout); + stderr: inMemoryStderr, + stdout: inMemoryStdout, + ); var futures = []; - futures.add(stdio.runZoned(() async { - await Future.delayed(const Duration(milliseconds: 100)); - stdout.writeln('test1'); - })); - futures.add(stdio.runZoned(() async { - await Future.delayed(const Duration(milliseconds: 5)); - stdout.writeln('test2'); - })); - futures.add(stdio.runZoned(() async { - stdout.writeln('test3'); - })); + futures.add( + stdio.runZoned(() async { + await Future.delayed(const Duration(milliseconds: 100)); + stdout.writeln('test1'); + }), + ); + futures.add( + stdio.runZoned(() async { + await Future.delayed(const Duration(milliseconds: 5)); + stdout.writeln('test2'); + }), + ); + futures.add( + stdio.runZoned(() async { + stdout.writeln('test3'); + }), + ); await Future.wait(futures); expect(inMemoryStdout.lines, ['test1', 'test2', 'test3']); }); @@ -136,19 +159,27 @@ echo --wait 100 --stdout hello2 var inMemoryStderr = InMemoryIOSink(StdioStreamType.err); var inMemoryStdout = InMemoryIOSink(StdioStreamType.out); var stdio = ShellStdioLinesGrouper( - stderr: inMemoryStderr, stdout: inMemoryStdout); + stderr: inMemoryStderr, + stdout: inMemoryStdout, + ); var futures = []; - futures.add(stdio.runZoned(() async { - stdout.writeln('test1'); - })); - futures.add(stdio.runZoned(() async { - await Future.delayed(const Duration(milliseconds: 5)); - stdout.writeln('test2'); - })); - futures.add(stdio.runZoned(() async { - await Future.delayed(const Duration(milliseconds: 100)); - stdout.writeln('test3'); - })); + futures.add( + stdio.runZoned(() async { + stdout.writeln('test1'); + }), + ); + futures.add( + stdio.runZoned(() async { + await Future.delayed(const Duration(milliseconds: 5)); + stdout.writeln('test2'); + }), + ); + futures.add( + stdio.runZoned(() async { + await Future.delayed(const Duration(milliseconds: 100)); + stdout.writeln('test3'); + }), + ); await Future.wait(futures); expect(inMemoryStdout.lines, ['test1', 'test2', 'test3']); }); diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index 3e4deb2..68c00e5 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -23,7 +23,8 @@ Future ensureEchoExe() async { if (!File(echoExe).existsSync()) { await Directory(dirname(echoExePath)).create(recursive: true); await run( - 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o $echoExe'); + 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o $echoExe', + ); } } @@ -36,11 +37,12 @@ bool debug = false; // To set in both variable for a full empty environment var dummyEnvPath = join('test', 'data', 'test_env.yaml_dummy'); -ShellEnvironment newEnvNoOverride() => - ShellEnvironment(environment: { - userEnvFilePathEnvKey: dummyEnvPath, - localEnvFilePathEnvKey: dummyEnvPath - }); +ShellEnvironment newEnvNoOverride() => ShellEnvironment( + environment: { + userEnvFilePathEnvKey: dummyEnvPath, + localEnvFilePathEnvKey: dummyEnvPath, + }, +); void main() { group('Shell', () { @@ -126,8 +128,12 @@ $echoExe -o éà var result = (await shell.run(script)).first; expect(result.stdout, isNull); expect(result.stderr, 'Err'); - result = (await shell - .runExecutableArguments(echoExe, ['-o', 'Out', '-e', 'Err'])); + result = (await shell.runExecutableArguments(echoExe, [ + '-o', + 'Out', + '-e', + 'Err', + ])); expect(result.stdout, isNull); expect(result.stderr, 'Err'); // Not valid for runSync @@ -135,16 +141,23 @@ $echoExe -o éà expect(result.stdout, 'Out'); expect(result.stderr, 'Err'); // Not valid for runExecutableArgumentsSync - result = (shell - .runExecutableArgumentsSync(echoExe, ['-o', 'Out', '-e', 'Err'])); + result = (shell.runExecutableArgumentsSync(echoExe, [ + '-o', + 'Out', + '-e', + 'Err', + ])); expect(result.stdout, 'Out'); expect(result.stderr, 'Err'); result = (await run(script, options: options)).first; expect(result.stdout, isNull); expect(result.stderr, 'Err'); - result = (await runExecutableArguments( - echoExe, ['-o', 'Out', '-e', 'Err'], - noStdoutResult: true)); + result = (await runExecutableArguments(echoExe, [ + '-o', + 'Out', + '-e', + 'Err', + ], noStdoutResult: true)); expect(result.stdout, isNull); expect(result.stderr, 'Err'); // Not valid for runSync @@ -177,7 +190,8 @@ $echoExe -o 你好 var shell = Shell(verbose: debug, runInShell: true); var results = await shell.run( - '$echoExe --stdout-hex ${bytesToHex(utf8.encode('Hello\nWorld'))}'); + '$echoExe --stdout-hex ${bytesToHex(utf8.encode('Hello\nWorld'))}', + ); expect(results.outLines, ['Hello', 'World']); expect(results[0].outLines, ['Hello', 'World']); expect(results.errLines, isEmpty); @@ -267,8 +281,7 @@ $echoExe -o ${shellArgument(weirdText)} // 2: ShellException(dart echo.dart --wait 3000, exitCode -15, workingDirectory: // devPrint('2: $_'); } - }() - .timeout(const Duration(seconds: 30)); + }().timeout(const Duration(seconds: 30)); } on TimeoutException catch (e) { stderr.writeln('TimeOutException $e'); stderr.writeln('Allowed: could happen on CI'); @@ -292,8 +305,7 @@ $echoExe -o ${shellArgument(weirdText)} } on ShellException catch (_) { // 2: ShellException(dart echo.dart --wait 3000, exitCode -15, workingDirectory: } - }() - .timeout(const Duration(seconds: 30)); + }().timeout(const Duration(seconds: 30)); } on TimeoutException catch (e) { stderr.writeln('TimeOutException $e'); stderr.writeln('Allowed: could happen on CI'); @@ -343,8 +355,7 @@ $echoExe -o ${shellArgument(weirdText)} } on ShellException catch (_) { // devPrint('3: $e'); } - }() - .timeout(const Duration(seconds: 40)); + }().timeout(const Duration(seconds: 40)); } on TimeoutException catch (e) { stderr.writeln('TimeOutException $e'); stderr.writeln('Allowed: could happen on CI'); @@ -368,8 +379,11 @@ $echoExe -o ${shellArgument(weirdText)} $echoExe some_text3 '''); linesController.close(); - expect(await linesController.stream.toList(), - ['some_text1', 'some_text2', 'some_text3']); + expect(await linesController.stream.toList(), [ + 'some_text1', + 'some_text2', + 'some_text3', + ]); }); test('pause', () async { await ensureEchoExe(); @@ -407,16 +421,19 @@ $echoExe -o ${shellArgument(weirdText)} subscription!.pause(); var count = 0; - await shell.run(''' + await shell.run( + ''' $echoExe some_text2 $echoExe some_text3 - ''', onProcess: (process) { - count++; - // devPrint('onProcess ${process.pid} (paused: $paused)'); - process.exitCode.then((exitCode) { - expect(exitCode, 0); - }); - }); + ''', + onProcess: (process) { + count++; + // devPrint('onProcess ${process.pid} (paused: $paused)'); + process.exitCode.then((exitCode) { + expect(exitCode, 0); + }); + }, + ); expect(count, 2); expect(lines, isEmpty); lines.clear(); @@ -438,8 +455,10 @@ $echoExe -o ${shellArgument(weirdText)} results = await shell.cd('test/src').run(''' dart current_dir.dart '''); - expect(results[0].stdout.toString().trim(), - join(Directory.current.path, 'test', 'src')); + expect( + results[0].stdout.toString().trim(), + join(Directory.current.path, 'test', 'src'), + ); }); test('path', () { @@ -456,8 +475,10 @@ dart current_dir.dart shell = shell.pushd('test/src'); results = await shell.run('dart current_dir.dart'); - expect(results[0].stdout.toString().trim(), - join(Directory.current.path, 'test', 'src')); + expect( + results[0].stdout.toString().trim(), + join(Directory.current.path, 'test', 'src'), + ); // pop once shell = shell.popd(); @@ -534,7 +555,8 @@ _tekartik_dummy_app_that_does_not_exits await testCommand('flutter --version'); // flutter.bat on windows await testCommand('dart --version'); // dart.exe on windows await testCommand( - '${shellArgument(dartExecutable!)} --version'); // dart.exe on windows + '${shellArgument(dartExecutable!)} --version', + ); // dart.exe on windows if (dartVersion < Version(2, 17, 0, pre: '0')) { await testCommand('pub --version'); // dart.exe on windows } @@ -555,18 +577,22 @@ _tekartik_dummy_app_that_does_not_exits // Write to file await file.writeAsString( - (await shell.run('echo Hello world')).first.stdout.toString()); + (await shell.run('echo Hello world')).first.stdout.toString(), + ); // Append to file await file.writeAsString( - (await shell.run('echo Hello world')).first.stdout.toString(), - mode: FileMode.append); + (await shell.run('echo Hello world')).first.stdout.toString(), + mode: FileMode.append, + ); try { // Update 2024-11-17 Windows used to have different separator. var separator = '\n'; - expect(await file.readAsString(), - 'Hello world${separator}Hello world$separator'); + expect( + await file.readAsString(), + 'Hello world${separator}Hello world$separator', + ); if (Platform.isWindows) { stdout.writeln('report: echo output \\n'); } @@ -574,8 +600,10 @@ _tekartik_dummy_app_that_does_not_exits if (Platform.isWindows) { // Old test var separator = Platform.isWindows ? '\r\n' : '\n'; - expect(await file.readAsString(), - 'Hello world${separator}Hello world$separator'); + expect( + await file.readAsString(), + 'Hello world${separator}Hello world$separator', + ); if (Platform.isWindows) { stdout.writeln('report: echo output \\r\\n'); } @@ -636,31 +664,38 @@ _tekartik_dummy_app_that_does_not_exits // TODO test on other platform if (Platform.isLinux) { var environment = { - 'PATH': '${absolute('test/src')}:${platformEnvironment['PATH']}' + 'PATH': '${absolute('test/src')}:${platformEnvironment['PATH']}', }; print(environment); - var shell = - Shell(environment: environment, includeParentEnvironment: false); + var shell = Shell( + environment: environment, + includeParentEnvironment: false, + ); await shell.run('current_dir'); } }); - test('flutter_resolve', () async { - // Edge case finding flutter from dart - if (Platform.isLinux) { - var paths = platformEnvironment['PATH']!.split(':') - ..removeWhere((element) => element.endsWith('flutter/bin')); - - paths.insert(0, dartSdkBinDirPath); - print(paths); - var environment = {'PATH': paths.join(':')}; - print(environment); - var shell = - Shell(environment: environment, includeParentEnvironment: false); - await shell.run('flutter --version'); - } - }, - // skip: !isFlutterSupportedSync || - skip: true); + test( + 'flutter_resolve', + () async { + // Edge case finding flutter from dart + if (Platform.isLinux) { + var paths = platformEnvironment['PATH']!.split(':') + ..removeWhere((element) => element.endsWith('flutter/bin')); + + paths.insert(0, dartSdkBinDirPath); + print(paths); + var environment = {'PATH': paths.join(':')}; + print(environment); + var shell = Shell( + environment: environment, + includeParentEnvironment: false, + ); + await shell.run('flutter --version'); + } + }, + // skip: !isFlutterSupportedSync || + skip: true, + ); // This is plain wrong now...assumed dart below flutter which will no longer be the case test('flutter info', () async { @@ -674,21 +709,25 @@ _tekartik_dummy_app_that_does_not_exits var whichDart = await which('dart'); var resolvedVersion = parseDartBinVersionOutput( - (await sh.runExecutableArguments(dartExecutable!, ['--version'])) - .stderr - .toString()); + (await sh.runExecutableArguments(dartExecutable!, [ + '--version', + ])).stderr.toString(), + ); var resolvedVersionSync = parseDartBinVersionOutput( - (sh.runExecutableArgumentsSync(dartExecutable!, ['--version'])) - .stderr - .toString()); + (sh.runExecutableArgumentsSync(dartExecutable!, [ + '--version', + ])).stderr.toString(), + ); var whichVersion = parseDartBinVersionOutput( - (await sh.runExecutableArguments(whichDart!, ['--version'])) - .stderr - .toString()); + (await sh.runExecutableArguments(whichDart!, [ + '--version', + ])).stderr.toString(), + ); var version = parseDartBinVersionOutput( - (await sh.runExecutableArguments('dart', ['--version'])) - .stderr - .toString()); + (await sh.runExecutableArguments('dart', [ + '--version', + ])).stderr.toString(), + ); expect(version, resolvedVersion); expect(version, whichVersion); expect(version, resolvedVersionSync); @@ -698,9 +737,10 @@ _tekartik_dummy_app_that_does_not_exits await ensureEchoExe(); var controller = ShellLinesController(); var shell = Shell( - stdout: controller.sink, - verbose: true, - environment: ShellEnvironment()..aliases['echo'] = '$echoExe -o'); + stdout: controller.sink, + verbose: true, + environment: ShellEnvironment()..aliases['echo'] = '$echoExe -o', + ); await shell.run('echo 你好é'); controller.close(); if (!Platform.isWindows) { @@ -712,10 +752,11 @@ _tekartik_dummy_app_that_does_not_exits var localFile = '.dart_tool/process_run/test/local1.yaml'; var userFile = '.dart_tool/process_run/test/user1.yaml'; var dsCommand = 'dart run bin/shell.dart'; - var safeShellEnvironment = ShellEnvironment() - ..aliases['ds'] = dsCommand - ..vars[userEnvFilePathEnvKey] = userFile - ..vars[localEnvFilePathEnvKey] = localFile; + var safeShellEnvironment = + ShellEnvironment() + ..aliases['ds'] = dsCommand + ..vars[userEnvFilePathEnvKey] = userFile + ..vars[localEnvFilePathEnvKey] = localFile; var shell = Shell(environment: safeShellEnvironment, verbose: true); expect(shell.options.environment.aliases['ds'], dsCommand); diff --git a/packages/process_run/test/src/compile_echo.dart b/packages/process_run/test/src/compile_echo.dart index dd816df..843690f 100644 --- a/packages/process_run/test/src/compile_echo.dart +++ b/packages/process_run/test/src/compile_echo.dart @@ -24,7 +24,8 @@ Future compileEchoExample({bool force = false}) async { if (!needCompile && file.existsSync()) { try { var version = Version.parse( - (await shell.run('$echoExePath --version')).outText.trim()); + (await shell.run('$echoExePath --version')).outText.trim(), + ); if (version != packageVersion) { needCompile = true; } else { @@ -38,7 +39,8 @@ Future compileEchoExample({bool force = false}) async { if (needCompile) { Directory(echoExeDir).createSync(recursive: true); await shell.run( - 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o ${shellArgument(echoExePath)}'); + 'dart compile exe ${shellArgument(join('example', 'echo.dart'))} -o ${shellArgument(echoExePath)}', + ); } return echoExePath; } diff --git a/packages/process_run/test/src/compile_shell.dart b/packages/process_run/test/src/compile_shell.dart index 1e4ac16..6058209 100644 --- a/packages/process_run/test/src/compile_shell.dart +++ b/packages/process_run/test/src/compile_shell.dart @@ -28,7 +28,8 @@ Future compileShellBin({bool force = false}) async { if (!File(dsExePath).existsSync() || force) { Directory(dsExeDir).createSync(recursive: true); await shell.run( - 'dart compile exe ${shellArgument(join('bin', 'shell.dart'))} -o ${shellArgument(dsExePath)}'); + 'dart compile exe ${shellArgument(join('bin', 'shell.dart'))} -o ${shellArgument(dsExePath)}', + ); } return dsExePath; } diff --git a/packages/process_run/test/src/compile_streamer.dart b/packages/process_run/test/src/compile_streamer.dart index e07800e..f6a372f 100644 --- a/packages/process_run/test/src/compile_streamer.dart +++ b/packages/process_run/test/src/compile_streamer.dart @@ -24,8 +24,9 @@ Future compileStreamerExample({bool force = false}) async { } if (!needCompile && file.existsSync()) { try { - var version = - Version.parse((await shell.run('$exe --version')).outText.trim()); + var version = Version.parse( + (await shell.run('$exe --version')).outText.trim(), + ); if (version != packageVersion) { needCompile = true; } else { @@ -39,7 +40,8 @@ Future compileStreamerExample({bool force = false}) async { if (needCompile) { Directory(exeDir).createSync(recursive: true); await shell.run( - 'dart compile exe ${shellArgument(join('example', 'streamer.dart'))} -o ${shellArgument(exe)}'); + 'dart compile exe ${shellArgument(join('example', 'streamer.dart'))} -o ${shellArgument(exe)}', + ); } return exe; } diff --git a/packages/process_run/test/src/shell_impl_test.dart b/packages/process_run/test/src/shell_impl_test.dart index f7077e4..88c1d3a 100644 --- a/packages/process_run/test/src/shell_impl_test.dart +++ b/packages/process_run/test/src/shell_impl_test.dart @@ -18,14 +18,14 @@ import '../shell_test.dart'; var expectedDartPaths = [ if (getFlutterAncestorPath(dartSdkBinDirPath) != null) getFlutterAncestorPath(dartSdkBinDirPath), - dartSdkBinDirPath + dartSdkBinDirPath, ]; List getExpectedPartPaths(ShellEnvironment environment) { return [ if (getFlutterAncestorPath(dartSdkBinDirPath) != null) getFlutterAncestorPath(dartSdkBinDirPath), - dartSdkBinDirPath + dartSdkBinDirPath, ]; } @@ -65,10 +65,11 @@ void main() { test('null HOME', () async { try { - var env = Map.from(platformEnvironment) - ..remove('HOME') - ..remove('USERPROFILE') - ..remove('APPDATA'); + var env = + Map.from(platformEnvironment) + ..remove('HOME') + ..remove('USERPROFILE') + ..remove('APPDATA'); platformEnvironment = env; expect(userHomePath, '~'); expect(userAppDataPath, join('~', '.config')); @@ -94,38 +95,53 @@ void main() { test('userEnvironment in dart context', () async { try { platformEnvironment = newEnvNoOverride(); - expect(userPaths, - getExpectedPartPaths(shellEnvironment as ShellEnvironment)); + expect( + userPaths, + getExpectedPartPaths(shellEnvironment as ShellEnvironment), + ); } finally { platformEnvironment = null; } }); var localFlutterExecutablePath = flutterExecutablePath; - test('userEnvironment in flutter context', () async { - try { - var flutterBinDirPath = dirname(localFlutterExecutablePath!); - platformEnvironment = newEnvNoOverride() - ..paths.prepend(flutterBinDirPath); + test( + 'userEnvironment in flutter context', + () async { + try { + var flutterBinDirPath = dirname(localFlutterExecutablePath!); + platformEnvironment = + newEnvNoOverride()..paths.prepend(flutterBinDirPath); - // '/opt/app/flutter/dev/flutter/bin', - // '/opt/app/flutter/dev/flutter/bin/cache/dart-sdk/bin' - if (dartSdkBinDirPath.contains(flutterBinDirPath)) { - expect(userPaths, - [dirname(localFlutterExecutablePath), dartSdkBinDirPath]); - } else { - expect(userPaths, - [dartSdkBinDirPath, dirname(localFlutterExecutablePath)]); + // '/opt/app/flutter/dev/flutter/bin', + // '/opt/app/flutter/dev/flutter/bin/cache/dart-sdk/bin' + if (dartSdkBinDirPath.contains(flutterBinDirPath)) { + expect(userPaths, [ + dirname(localFlutterExecutablePath), + dartSdkBinDirPath, + ]); + } else { + expect(userPaths, [ + dartSdkBinDirPath, + dirname(localFlutterExecutablePath), + ]); + } + } finally { + platformEnvironment = null; } - } finally { - platformEnvironment = null; - } - }, skip: localFlutterExecutablePath == null); + }, + skip: localFlutterExecutablePath == null, + ); test('userEnvironment', () async { try { - var filePath = - join('.dart_tool', 'process_run', 'test', 'user_env', 'env.yaml'); + var filePath = join( + '.dart_tool', + 'process_run', + 'test', + 'user_env', + 'env.yaml', + ); resetUserConfig(); await Directory(dirname(filePath)).create(recursive: true); await File(filePath).writeAsString(''' @@ -157,7 +173,7 @@ void main() { platformEnvironment = { userEnvFilePathEnvKey: filePath, localEnvFilePathEnvKey: configFileEmptyPath, - userHomePathEnvKey: getTestAbsPath() + userHomePathEnvKey: getTestAbsPath(), }; // expect(getUserEnvFilePath(shellEnvironment), filePath); expect(userPaths, [ @@ -186,15 +202,12 @@ void main() { // empty environment platformEnvironment = { userEnvFilePathEnvKey: configFileEmptyPath, - localEnvFilePathEnvKey: configFileEmptyPath + localEnvFilePathEnvKey: configFileEmptyPath, }; var dartBinDir = dirname(dartExecutable!); var flutterDir = getFlutterAncestorPath(dartSdkBinDirPath); - expect(userPaths, [ - if (flutterDir != null) flutterDir, - dartBinDir, - ]); + expect(userPaths, [if (flutterDir != null) flutterDir, dartBinDir]); expect(dirname((await which('dart'))!), flutterDir ?? dartBinDir); } finally { platformEnvironment = null; @@ -203,8 +216,13 @@ void main() { test('user env in shell', () async { try { - var filePath = join('.dart_tool', 'process_run', 'test', - 'user_env_in_shell', 'env.yaml'); + var filePath = join( + '.dart_tool', + 'process_run', + 'test', + 'user_env_in_shell', + 'env.yaml', + ); resetUserConfig(); await Directory(dirname(filePath)).create(recursive: true); await File(filePath).writeAsString(''' @@ -217,72 +235,65 @@ void main() { expect(userEnvironment['_TEKARTIK_PROCESS_RUN_TEST'], '1'); var shell = Shell(verbose: false); - var result = (await shell.run('$echo --stdout-env PATH')) - .first - .stdout - .toString() - .trim(); + var result = + (await shell.run( + '$echo --stdout-env PATH', + )).first.stdout.toString().trim(); expect(result, isNotEmpty); result = - (await shell.run('$echo --stdout-env _dummy_that_will_never_exist')) - .first - .stdout - .toString() - .trim(); + (await shell.run( + '$echo --stdout-env _dummy_that_will_never_exist', + )).first.stdout.toString().trim(); expect(result, isEmpty); result = - (await shell.run('$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST')) - .first - .stdout - .toString() - .trim(); + (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).first.stdout.toString().trim(); // Default environment is user environment expect(result, '1'); shell = Shell( - verbose: false, - environment: platformEnvironment, - includeParentEnvironment: false); + verbose: false, + environment: platformEnvironment, + includeParentEnvironment: false, + ); result = - (await shell.run('$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST')) - .first - .stdout - .toString() - .trim(); + (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).first.stdout.toString().trim(); expect(result, isEmpty); shell = Shell( - verbose: false, - environment: userEnvironment, - includeParentEnvironment: false); + verbose: false, + environment: userEnvironment, + includeParentEnvironment: false, + ); result = - (await shell.run('$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST')) - .first - .stdout - .toString() - .trim(); + (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).first.stdout.toString().trim(); expect(result, '1'); shell = Shell( - verbose: false, - environment: shellEnvironment, - includeParentEnvironment: false); + verbose: false, + environment: shellEnvironment, + includeParentEnvironment: false, + ); result = - (await shell.run('$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST')) - .first - .stdout - .toString() - .trim(); + (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).first.stdout.toString().trim(); expect(result, '1'); - shell = Shell(verbose: true, environment: { - '_TEKARTIK_PROCESS_RUN_TEST': '78910' - }); + shell = Shell( + verbose: true, + environment: {'_TEKARTIK_PROCESS_RUN_TEST': '78910'}, + ); try { - var lines = (await shell.run( - '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', - )) - .outLines; + var lines = + (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).outLines; result = lines.last; expect(result, '78910', reason: lines.join('\n')); } catch (e) { @@ -312,20 +323,22 @@ void main() { // expect(platformEnvironment, isNot({'test': '1'})); //TODO test on other platform if (Platform.isLinux) { - var out = (await Shell(verbose: false).run('$linuxEnvCommand')) - .map((result) => result.stdout.toString()) - .join('\n'); + var out = (await Shell(verbose: false).run( + '$linuxEnvCommand', + )).map((result) => result.stdout.toString()).join('\n'); expect(out, contains('test=1')); } else if (Platform.isWindows) { try { //TODO test on other platform - var out = (await Shell(verbose: false).run('echo test=%test%')) - .map((result) => result.stdout.toString()) - .join('\n'); + var out = (await Shell(verbose: false).run( + 'echo test=%test%', + )).map((result) => result.stdout.toString()).join('\n'); expect(out, contains('test=1')); } on TestFailure catch (e) { - stderr.writeln('%var% seems to start failing $e\n' - '...to investigate or simple drop as it is a windows inconsistency'); + stderr.writeln( + '%var% seems to start failing $e\n' + '...to investigate or simple drop as it is a windows inconsistency', + ); } } userConfig = UserConfig(vars: {'test': '2'}); diff --git a/packages/process_run/test/src_dartbin_cmd_test.dart b/packages/process_run/test/src_dartbin_cmd_test.dart index 8ce15c4..dd362f3 100644 --- a/packages/process_run/test/src_dartbin_cmd_test.dart +++ b/packages/process_run/test/src_dartbin_cmd_test.dart @@ -14,21 +14,29 @@ void main() { test('parse', () { expect(parsePlatformVersion('1.0.0'), Version(1, 0, 0)); expect( - parsePlatformVersion('2.7.0 (Unknown timestamp)'), Version(2, 7, 0)); + parsePlatformVersion('2.7.0 (Unknown timestamp)'), + Version(2, 7, 0), + ); // 2.8.0-dev.18.0.flutter-eea9717938 (be) (Wed Apr 1 08:55:31 2020 +0000) on "linux_x64" - expect(parsePlatformVersion('2.8.0-dev.18.0.flutter-eea9717938 (be)'), - Version(2, 8, 0, pre: 'dev.18.0.flutter-eea9717938')); + expect( + parsePlatformVersion('2.8.0-dev.18.0.flutter-eea9717938 (be)'), + Version(2, 8, 0, pre: 'dev.18.0.flutter-eea9717938'), + ); // expect(parsePlatformChannel('2.8.0-dev.18.0.flutter-eea9717938 (be)'), dartChannelBeta); expect( - parsePlatformChannel( - '2.9.0-5.0.dev (dev) (Thu Apr 30 13:02:02 2020 +0200) on "linux_x64"'), - dartChannelDev); + parsePlatformChannel( + '2.9.0-5.0.dev (dev) (Thu Apr 30 13:02:02 2020 +0200) on "linux_x64"', + ), + dartChannelDev, + ); expect( - parsePlatformChannel( - '2.8.0-20.11.beta (beta) (Mon Apr 20 14:33:01 2020 +0200) on "linux_x64"'), - dartChannelBeta); + parsePlatformChannel( + '2.8.0-20.11.beta (beta) (Mon Apr 20 14:33:01 2020 +0200) on "linux_x64"', + ), + dartChannelBeta, + ); }); }); } diff --git a/packages/process_run/test/src_shell_utils_test.dart b/packages/process_run/test/src_shell_utils_test.dart index 1caa227..08b050d 100644 --- a/packages/process_run/test/src_shell_utils_test.dart +++ b/packages/process_run/test/src_shell_utils_test.dart @@ -14,8 +14,12 @@ void main() { test('scriptToCommands', () { expect(scriptToCommands(''), isEmpty); // expect(scriptToCommands('\\'), ['\\']); - expect(scriptToCommands(' e\n#\n # comment\nf \n '), - ['e', '#', '# comment', 'f']); + expect(scriptToCommands(' e\n#\n # comment\nf \n '), [ + 'e', + '#', + '# comment', + 'f', + ]); }); test('isLineToBeContinued', () { @@ -46,18 +50,19 @@ void main() { test('environmentFilterOutVmOptions', () { var env = { - 'DART_VM_OPTIONS': '--pause-isolates-on-start --enable-vm-service:51156' + 'DART_VM_OPTIONS': + '--pause-isolates-on-start --enable-vm-service:51156', }; env = environmentFilterOutVmOptions(env); expect(env, isEmpty); env = { 'DART_VM_OPTIONS': '--enable-vm-service:51156', - 'TEKARTIK_DART_VM_OPTIONS': '--profile' + 'TEKARTIK_DART_VM_OPTIONS': '--profile', }; env = environmentFilterOutVmOptions(env); expect(env, { 'TEKARTIK_DART_VM_OPTIONS': '--profile', - 'DART_VM_OPTIONS': '--profile' + 'DART_VM_OPTIONS': '--profile', }); }); @@ -72,17 +77,19 @@ void main() { expect(shellSplit('"Hello world"'), ['Hello world']); expect(shellSplit("'Hello world'"), ['Hello world']); expect( - shellSplit( - 'curl --location --request POST "https://postman-echo.com/post" --data "This is expected to be sent back as part of response body."'), - [ - 'curl', - '--location', - '--request', - 'POST', - 'https://postman-echo.com/post', - '--data', - 'This is expected to be sent back as part of response body.' - ]); + shellSplit( + 'curl --location --request POST "https://postman-echo.com/post" --data "This is expected to be sent back as part of response body."', + ), + [ + 'curl', + '--location', + '--request', + 'POST', + 'https://postman-echo.com/post', + '--data', + 'This is expected to be sent back as part of response body.', + ], + ); }); test('shellJoin', () { @@ -114,23 +121,32 @@ void main() { }); test('various', () { - expect(scriptToCommands(''' + expect( + scriptToCommands(''' a ^ b - '''), ['a', 'b']); - expect(scriptToCommands(''' + '''), + ['a', 'b'], + ); + expect( + scriptToCommands(''' a ^ b c - '''), ['a b', 'c']); - expect(scriptToCommands(''' + '''), + ['a b', 'c'], + ); + expect( + scriptToCommands(''' a ^ "b" ^ "c" d e - '''), ['a "b" "c" d', 'e']); + '''), + ['a "b" "c" d', 'e'], + ); }); test('streamSinkWrite', () async { diff --git a/packages/process_run/test/src_user_config_test.dart b/packages/process_run/test/src_user_config_test.dart index 498f614..bd534f4 100644 --- a/packages/process_run/test/src_user_config_test.dart +++ b/packages/process_run/test/src_user_config_test.dart @@ -24,7 +24,7 @@ void main() { var path2 = dummyEnvPath2; var userConfig = getUserConfig({ userEnvFilePathEnvKey: path1, - localEnvFilePathEnvKey: path2 + localEnvFilePathEnvKey: path2, }); expect(userConfig.vars, { 'TEKARTIK_PROCESS_RUN_USER_ENV_FILE_PATH': path1, @@ -33,7 +33,7 @@ void main() { expect(userConfig.paths, [ if (getFlutterAncestorPath(dartSdkBinDirPath) != null) getFlutterAncestorPath(dartSdkBinDirPath), - dartSdkBinDirPath + dartSdkBinDirPath, ]); // user only @@ -46,17 +46,23 @@ void main() { // user only userConfig = getUserConfig({ localEnvFilePathEnvKey: path1, - userEnvFilePathEnvKey: path1 + userEnvFilePathEnvKey: path1, }); expect( - userConfig.vars['TEKARTIK_PROCESS_RUN_LOCAL_ENV_FILE_PATH'], path1); + userConfig.vars['TEKARTIK_PROCESS_RUN_LOCAL_ENV_FILE_PATH'], + path1, + ); }); test('overriding local env file name', () { //print(a); - var path = - join('test', 'data', 'test_user_env1_local_env_file_override.yaml'); - var userConfig = - getUserConfig({userEnvFilePathEnvKey: path}); + var path = join( + 'test', + 'data', + 'test_user_env1_local_env_file_override.yaml', + ); + var userConfig = getUserConfig({ + userEnvFilePathEnvKey: path, + }); expect(userConfig.aliases['test'], 'test alias'); }); @@ -65,36 +71,44 @@ void main() { var path = join('test', 'data', 'test_env1.yaml'); var userConfig = getUserConfig({ userEnvFilePathEnvKey: path, - localEnvFilePathEnvKey: dummyEnvPath1 + localEnvFilePathEnvKey: dummyEnvPath1, }); expect(userConfig.vars, { 'TEKARTIK_PROCESS_RUN_USER_ENV_FILE_PATH': path, 'TEKARTIK_PROCESS_RUN_LOCAL_ENV_FILE_PATH': dummyEnvPath1, 'test': '1', }); - expect(userConfig.paths, - [...getExpectedPartPaths(newEnvNoOverride()), 'my_path']); - var shEnv = ShellEnvironment.empty() - ..paths.addAll(userConfig.paths) - ..vars.addAll(userConfig.vars); + expect(userConfig.paths, [ + ...getExpectedPartPaths(newEnvNoOverride()), + 'my_path', + ]); + var shEnv = + ShellEnvironment.empty() + ..paths.addAll(userConfig.paths) + ..vars.addAll(userConfig.vars); expect(shEnv['TEKARTIK_PROCESS_RUN_USER_ENV_FILE_PATH'], path); expect(shEnv['test'], '1'); expect( - shEnv['PATH'], - [...expectedDartPaths, 'my_path'] - .join(Platform.isWindows ? ';' : ':')); + shEnv['PATH'], + [...expectedDartPaths, 'my_path'].join(Platform.isWindows ? ';' : ':'), + ); }); test('config no overload', () async { - var env = Map.from(platformEnvironment) - ..[userEnvFilePathEnvKey] = dummyEnvPath1 - ..[localEnvFilePathEnvKey] = dummyEnvPath1; + var env = + Map.from(platformEnvironment) + ..[userEnvFilePathEnvKey] = dummyEnvPath1 + ..[localEnvFilePathEnvKey] = dummyEnvPath1; var userConfig = getUserConfig(env); - expect(userConfig.vars['TEKARTIK_PROCESS_RUN_USER_ENV_FILE_PATH'], - dummyEnvPath1); - expect(userConfig.vars['TEKARTIK_PROCESS_RUN_LOCAL_ENV_FILE_PATH'], - dummyEnvPath1); + expect( + userConfig.vars['TEKARTIK_PROCESS_RUN_USER_ENV_FILE_PATH'], + dummyEnvPath1, + ); + expect( + userConfig.vars['TEKARTIK_PROCESS_RUN_LOCAL_ENV_FILE_PATH'], + dummyEnvPath1, + ); }); test('config order', () async { @@ -103,17 +117,14 @@ void main() { var path = join('test', 'data', 'test_env1.yaml'); var userConfig = getUserConfig({ userEnvFilePathEnvKey: path, - localEnvFilePathEnvKey: dummyEnvPath1 + localEnvFilePathEnvKey: dummyEnvPath1, }); expect(userConfig.paths, [...expectedDartPaths, 'my_path']); userConfig = getUserConfig({ userEnvFilePathEnvKey: dummyEnvPath1, - localEnvFilePathEnvKey: path + localEnvFilePathEnvKey: path, }); - expect(userConfig.paths, [ - 'my_path', - ...expectedDartPaths, - ]); + expect(userConfig.paths, ['my_path', ...expectedDartPaths]); }); test('userLoadConfigFile', () async { @@ -136,12 +147,12 @@ void main() { //print(a); userLoadConfigMap({ - 'vars': {'test': '1'} + 'vars': {'test': '1'}, }); expect(userConfig.vars, {'test': '1', 'PATH': ''}); expect(userConfig.paths, isEmpty); userLoadConfigMap({ - 'path': ['my_path'] + 'path': ['my_path'], }); expect(userConfig.vars, {'test': '1', 'PATH': 'my_path'}); expect(userConfig.paths, ['my_path']); @@ -151,55 +162,59 @@ void main() { userConfig = UserConfig(); userLoadConfigMap({ - 'path': ['my_path'] + 'path': ['my_path'], }); expect(userConfig.vars, {'PATH': 'my_path'}); expect(userConfig.paths, ['my_path']); userLoadConfigMap({ - 'path': ['my_path'] + 'path': ['my_path'], }); expect(userConfig.vars, {'PATH': 'my_path'}); expect(userConfig.paths, ['my_path']); userLoadConfigMap({ - 'path': ['other_path'] + 'path': ['other_path'], }); expect(userConfig.vars, { - 'PATH': ['other_path', 'my_path'].join(envPathSeparator) + 'PATH': ['other_path', 'my_path'].join(envPathSeparator), }); expect(userConfig.paths, ['other_path', 'my_path']); userLoadConfigMap({ - 'path': ['other_path'] + 'path': ['other_path'], }); expect(userConfig.vars, { - 'PATH': ['other_path', 'my_path'].join(envPathSeparator) + 'PATH': ['other_path', 'my_path'].join(envPathSeparator), }); expect(userConfig.paths, ['other_path', 'my_path']); userLoadConfigMap({'path': []}); expect(userConfig.vars, { - 'PATH': ['other_path', 'my_path'].join(envPathSeparator) + 'PATH': ['other_path', 'my_path'].join(envPathSeparator), }); expect(userConfig.paths, ['other_path', 'my_path']); userLoadConfigMap({ - 'path': ['my_path'] + 'path': ['my_path'], }); expect(userConfig.paths, ['my_path', 'other_path', 'my_path']); }); test('loadFromMap', () async { var config = loadFromMap({ - 'var': {'test': 1} + 'var': {'test': 1}, }); expect(config.paths, []); expect(config.vars, {'test': '1'}); }); test('flutter ancestor', () async { - expect(getFlutterAncestorPath(join('bin', 'cache', 'dart-sdk', 'bin')), - 'bin'); expect( - getFlutterAncestorPath( - join('flutter', 'bin', 'cache', 'dart-sdk', 'bin')), - join('flutter', 'bin')); + getFlutterAncestorPath(join('bin', 'cache', 'dart-sdk', 'bin')), + 'bin', + ); + expect( + getFlutterAncestorPath( + join('flutter', 'bin', 'cache', 'dart-sdk', 'bin'), + ), + join('flutter', 'bin'), + ); }); test('loadFromMap missing file', () async { diff --git a/packages/process_run/test/which_test.dart b/packages/process_run/test/which_test.dart index f51893f..91fa519 100644 --- a/packages/process_run/test/which_test.dart +++ b/packages/process_run/test/which_test.dart @@ -48,9 +48,14 @@ void main() { expect(whichSync('current_dir', environment: empty), isNull); expect( - basename(whichSync('current_dir', - environment: {'PATH': join('test', 'src')})!), - Platform.isWindows ? 'current_dir.bat' : 'current_dir'); + basename( + whichSync( + 'current_dir', + environment: {'PATH': join('test', 'src')}, + )!, + ), + Platform.isWindows ? 'current_dir.bat' : 'current_dir', + ); }); test('dart_env', () async { diff --git a/packages/process_run_test/pubspec.yaml b/packages/process_run_test/pubspec.yaml index b730021..853a34f 100644 --- a/packages/process_run_test/pubspec.yaml +++ b/packages/process_run_test/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.0.0 publish_to: none environment: - sdk: ^3.5.0 + sdk: ^3.7.0 # Add regular dependencies here. dependencies: From 28249ea188c8ca7a8680e94d3791aef39dabcef7 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 13 Feb 2025 09:40:04 +0100 Subject: [PATCH 137/150] [process_run] v1.2.3 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 578ef40..d78e511 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.2 + +* Requires dart 3.7 + ## 1.2.2+1 * Special kill behavior on linux, mac and windows when using sigkill (kills all children too) diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 2733bff..bcab943 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.2+1 +version: 1.2.3 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run From e66077f2a7a3ced2fe63d838c8bf5413516085b0 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Thu, 13 Feb 2025 09:40:24 +0100 Subject: [PATCH 138/150] [process_run] v1.2.3 --- packages/process_run/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index d78e511..8990708 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.2.2 +## 1.2.3 * Requires dart 3.7 From 0daa33bc642ec76d23e0f04c589035f288238d5c Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 4 Mar 2025 19:53:16 +0100 Subject: [PATCH 139/150] feat: allow running in zoned shell context environment --- packages/process_run/example/echo.dart | 1 + packages/process_run/example/info.dart | 1 - packages/process_run/lib/dartbin.dart | 2 + packages/process_run/lib/shell.dart | 6 +- .../process_run/lib/src/dartbin_impl.dart | 3 +- .../process_run/lib/src/flutterbin_cmd.dart | 11 +++ .../lib/src/platform/platform_common.dart | 4 + .../lib/src/platform/platform_io.dart | 3 +- .../lib/src/platform/platform_stub.dart | 2 +- .../lib/src/shell_context_common.dart | 75 +++++++++++++++++++ .../process_run/lib/src/shell_context_io.dart | 5 ++ .../lib/src/shell_environment_common.dart | 9 +++ packages/process_run/test/dartbin_test.dart | 1 - .../process_run/test/flutterbin_cmd_test.dart | 10 ++- .../process_run/test/shell_context_test.dart | 38 ++++++++++ .../test/shell_environment_test.dart | 25 ++++++- .../process_run/test/shell_zoned_test.dart | 44 +++++++++++ .../process_run/test/src/shell_impl_test.dart | 1 - 18 files changed, 230 insertions(+), 11 deletions(-) create mode 100644 packages/process_run/test/shell_context_test.dart create mode 100644 packages/process_run/test/shell_zoned_test.dart diff --git a/packages/process_run/example/echo.dart b/packages/process_run/example/echo.dart index 327bfb7..bcfde87 100755 --- a/packages/process_run/example/echo.dart +++ b/packages/process_run/example/echo.dart @@ -90,6 +90,7 @@ Future main(List arguments) async { parser.addFlag( 'all-env', help: 'Display all environment (vars and paths) in json pretty print', + negatable: false, ); parser.addOption('exit-code', abbr: 'x', help: 'Exit code to return'); parser.addFlag( diff --git a/packages/process_run/example/info.dart b/packages/process_run/example/info.dart index a19da8c..5a9a2d7 100644 --- a/packages/process_run/example/info.dart +++ b/packages/process_run/example/info.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:process_run/cmd_run.dart' show flutterExecutablePath; import 'package:process_run/shell.dart'; import 'package:process_run/stdio.dart'; diff --git a/packages/process_run/lib/dartbin.dart b/packages/process_run/lib/dartbin.dart index cfa9126..e429f60 100644 --- a/packages/process_run/lib/dartbin.dart +++ b/packages/process_run/lib/dartbin.dart @@ -14,6 +14,8 @@ export 'package:process_run/src/flutterbin_cmd.dart' getFlutterBinVersion, getFlutterBinChannel, isFlutterSupported, + flutterDartExecutablePath, + flutterExecutablePath, isFlutterSupportedSync; export 'src/common/dartbin.dart'; diff --git a/packages/process_run/lib/shell.dart b/packages/process_run/lib/shell.dart index 4535214..c9df79a 100644 --- a/packages/process_run/lib/shell.dart +++ b/packages/process_run/lib/shell.dart @@ -23,7 +23,6 @@ export 'package:process_run/dartbin.dart' dartChannelDev, dartChannelMaster; export 'package:process_run/src/api/shell_common.dart' show ShellOptions; - // We reuse io sharedStdIn definition. export 'package:process_run/src/io/shared_stdin.dart' show sharedStdIn; export 'package:process_run/src/shell_utils.dart' @@ -45,7 +44,9 @@ export 'dartbin.dart' getFlutterBinVersion, getFlutterBinChannel, isFlutterSupported, - isFlutterSupportedSync; + isFlutterSupportedSync, + flutterDartExecutablePath, + flutterExecutablePath; export 'src/lines_utils.dart' show ShellLinesController, shellStreamLines; export 'src/process_cmd.dart' show @@ -67,6 +68,7 @@ export 'src/shell_environment.dart' ShellEnvironmentPaths, ShellEnvironmentVars, ShellEnvironmentAliases; +export 'src/shell_environment_common.dart' show ShellEnvironmentCommonExt; export 'src/which.dart' show whichSync, which; export 'utils/process_result_extension.dart' show diff --git a/packages/process_run/lib/src/dartbin_impl.dart b/packages/process_run/lib/src/dartbin_impl.dart index 07893c7..6ad6548 100644 --- a/packages/process_run/lib/src/dartbin_impl.dart +++ b/packages/process_run/lib/src/dartbin_impl.dart @@ -23,7 +23,8 @@ String? resolveDartExecutable({Map? environment}) { var dartExecutable = findDartExecutableSync( getUserPaths(environment ?? userEnvironment), ); - // Handle the flutter case + // Handle the flutter case when dart was in the same folder than flutter + // TODO: check in 2025 if (dartExecutable != null) { return findFlutterDartExecutableSync(dirname(dartExecutable)) ?? dartExecutable; diff --git a/packages/process_run/lib/src/flutterbin_cmd.dart b/packages/process_run/lib/src/flutterbin_cmd.dart index 6c4fc9d..ddf56c9 100644 --- a/packages/process_run/lib/src/flutterbin_cmd.dart +++ b/packages/process_run/lib/src/flutterbin_cmd.dart @@ -1,6 +1,8 @@ import 'dart:convert'; +import 'package:path/path.dart'; import 'package:process_run/shell_run.dart'; +import 'package:process_run/src/dartbin_impl.dart'; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; @@ -10,6 +12,15 @@ String? _flutterExecutablePath; String? get flutterExecutablePath => _flutterExecutablePath ??= whichSync('flutter'); +/// Resolved flutter dart path if found +String? get flutterDartExecutablePath { + var flutterPath = flutterExecutablePath; + if (flutterPath != null) { + return findFlutterDartExecutableSync(dirname(flutterPath)); + } + return null; +} + /// Test only @Deprecated('Dev only') set flutterExecutablePath(String? path) { diff --git a/packages/process_run/lib/src/platform/platform_common.dart b/packages/process_run/lib/src/platform/platform_common.dart index 6841dcd..8712dc3 100644 --- a/packages/process_run/lib/src/platform/platform_common.dart +++ b/packages/process_run/lib/src/platform/platform_common.dart @@ -1,4 +1,5 @@ import 'package:meta/meta.dart'; +import 'package:process_run/src/platform/platform.dart'; import 'package:process_run/src/shell_context_common.dart'; /// Global platform shell context, if any. @@ -14,3 +15,6 @@ set shellContext(ShellContext shellContext) => void clearShellContext() { shellContextPlatformOrNull = null; } + +/// Shell context for the current zone or platform +ShellContext get shellContext => zonedShellContextOrNull ?? shellContextDefault; diff --git a/packages/process_run/lib/src/platform/platform_io.dart b/packages/process_run/lib/src/platform/platform_io.dart index e917259..b0b140c 100644 --- a/packages/process_run/lib/src/platform/platform_io.dart +++ b/packages/process_run/lib/src/platform/platform_io.dart @@ -11,4 +11,5 @@ bool get platformIoIsWindows => Platform.isWindows; final shellContextIo = ShellContextIo(); /// Get the global shell context -ShellContext get shellContext => shellContextPlatformOrNull ??= shellContextIo; +ShellContext get shellContextDefault => + shellContextPlatformOrNull ??= shellContextIo; diff --git a/packages/process_run/lib/src/platform/platform_stub.dart b/packages/process_run/lib/src/platform/platform_stub.dart index d1da5ca..bc6aa8c 100644 --- a/packages/process_run/lib/src/platform/platform_stub.dart +++ b/packages/process_run/lib/src/platform/platform_stub.dart @@ -5,5 +5,5 @@ import 'package:process_run/src/shell_context_common.dart'; bool get platformIoIsWindows => false; /// Never null -ShellContext get shellContext => +ShellContext get shellContextDefault => shellContextPlatformOrNull ??= shellContextMemory; diff --git a/packages/process_run/lib/src/shell_context_common.dart b/packages/process_run/lib/src/shell_context_common.dart index 350af3e..b24ba6b 100644 --- a/packages/process_run/lib/src/shell_context_common.dart +++ b/packages/process_run/lib/src/shell_context_common.dart @@ -1,3 +1,4 @@ +import 'dart:async' as async; import 'dart:convert'; import 'package:path/path.dart' as p; @@ -31,6 +32,42 @@ abstract class ShellContext { ShellEnvironment newShellEnvironment({Map? environment}); } +class _ShellContextWithDelegate implements ShellContext { + final ShellContext delegate; + + _ShellContextWithDelegate(this.delegate, {required this.shellEnvironment}); + + @override + Encoding get encoding => delegate.encoding; + + @override + Shell newShell({ShellOptions? options}) => + delegate.newShell(options: options); + + @override + ShellEnvironment newShellEnvironment({Map? environment}) => + delegate.newShellEnvironment(environment: environment); + + @override + p.Context get path => delegate.path; + + @override + final ShellEnvironment shellEnvironment; + + @override + async.Future which( + String command, { + ShellEnvironment? environment, + bool includeParentEnvironment = true, + }) { + return delegate.which( + command, + environment: environment, + includeParentEnvironment: includeParentEnvironment, + ); + } +} + /// Shell context mixin mixin ShellContextMixin implements ShellContext { @override @@ -67,6 +104,44 @@ mixin ShellContextMixin implements ShellContext { } } +/// Global zone count for fast access +int _inZoneCount = 0; + +/// Shell context extension +extension ShellContextExt on ShellContext { + /// Run in a zone, + Future runZoned(Future Function() action) => _runZonedImpl(action); + + /// Run in a zone, grouping lines + Future _runZonedImpl(Future Function() action) async { + try { + _inZoneCount++; + return await async.runZoned(() async { + try { + return await action(); + } finally {} + }, zoneValues: {_shellContextZoneVar: this}); + } finally { + _inZoneCount--; + } + } + + /// Copy with a new shell environment + ShellContext copyWith({ShellEnvironment? shellEnvironment}) { + return _ShellContextWithDelegate( + this, + shellEnvironment: shellEnvironment ?? this.shellEnvironment, + ); + } +} + +/// Overriden shell stdio if any. +ShellContext? get zonedShellContextOrNull => + _inZoneCount > 0 + ? async.Zone.current[_shellContextZoneVar] as ShellContext? + : null; +const _shellContextZoneVar = #tekartik_shell_context; + /// In memory shell context. class ShellContextMemory with ShellContextMixin implements ShellContext { @override diff --git a/packages/process_run/lib/src/shell_context_io.dart b/packages/process_run/lib/src/shell_context_io.dart index 551f324..e9aa609 100644 --- a/packages/process_run/lib/src/shell_context_io.dart +++ b/packages/process_run/lib/src/shell_context_io.dart @@ -46,4 +46,9 @@ class ShellContextIo with ShellContextMixin implements ShellContext { ioShell.context = this; return ioShell; } + + @override + String toString() { + return 'ShellContextIo()'; + } } diff --git a/packages/process_run/lib/src/shell_environment_common.dart b/packages/process_run/lib/src/shell_environment_common.dart index 70574f1..27e3354 100644 --- a/packages/process_run/lib/src/shell_environment_common.dart +++ b/packages/process_run/lib/src/shell_environment_common.dart @@ -1,8 +1,10 @@ +import 'dart:async'; import 'dart:collection'; import 'package:collection/collection.dart'; //import 'package:process_run/shell.dart'; import 'package:process_run/src/platform/platform.dart'; +import 'package:process_run/src/shell_context_common.dart'; import 'package:process_run/src/shell_environment.dart'; //import 'package:process_run/shell.dart'; //import 'package:process_run/src/common/import.dart'; @@ -380,3 +382,10 @@ abstract class ShellEnvironmentCore with MapMixin { } */ } + +/// Shell environment extension +extension ShellEnvironmentCommonExt on ShellEnvironment { + /// Run in a zone, + Future runZoned(Future Function() action) => + shellContext.copyWith(shellEnvironment: this).runZoned(action); +} diff --git a/packages/process_run/test/dartbin_test.dart b/packages/process_run/test/dartbin_test.dart index a1dc6dc..1fd112b 100644 --- a/packages/process_run/test/dartbin_test.dart +++ b/packages/process_run/test/dartbin_test.dart @@ -6,7 +6,6 @@ library; import 'dart:io'; import 'package:path/path.dart'; -import 'package:process_run/cmd_run.dart' show flutterExecutablePath; import 'package:process_run/dartbin.dart'; import 'package:process_run/shell.dart'; import 'package:process_run/src/dartbin_impl.dart' diff --git a/packages/process_run/test/flutterbin_cmd_test.dart b/packages/process_run/test/flutterbin_cmd_test.dart index 11e0819..d472f05 100644 --- a/packages/process_run/test/flutterbin_cmd_test.dart +++ b/packages/process_run/test/flutterbin_cmd_test.dart @@ -6,8 +6,10 @@ import 'dart:io'; import 'package:path/path.dart'; import 'package:process_run/cmd_run.dart'; import 'package:process_run/shell.dart'; -import 'package:process_run/src/script_filename.dart'; -import 'package:process_run/src/user_config.dart'; + +import 'package:process_run/src/script_filename.dart' + show getBashOrBatExecutableFilename; +import 'package:process_run/src/user_config.dart' show getFlutterAncestorPath; // ignore: import_of_legacy_library_into_null_safe import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; @@ -18,6 +20,10 @@ void main() { // ignore: unnecessary_statements getFlutterBinVersion; }); + test('flutterDart', () { + expect(flutterExecutablePath, isNotNull); + expect(flutterDartExecutablePath, isNotNull); + }); test('run_version', () async { //print(flutterExecutablePath); ProcessCmd cmd = FlutterCmd(['--version']); diff --git a/packages/process_run/test/shell_context_test.dart b/packages/process_run/test/shell_context_test.dart new file mode 100644 index 0000000..e635e13 --- /dev/null +++ b/packages/process_run/test/shell_context_test.dart @@ -0,0 +1,38 @@ +// ignore_for_file: avoid_print + +@TestOn('vm') +library; + +import 'package:process_run/shell.dart'; +import 'package:process_run/src/platform/platform.dart'; +import 'package:process_run/src/shell_context_common.dart'; +import 'package:process_run/src/shell_environment_common.dart'; +import 'package:test/test.dart'; + +void main() { + group('ShellContext (prv)', () { + test('runZoned', () async { + var env1 = ShellEnvironment()..vars['test'] = 'value1'; + var env2 = ShellEnvironment()..vars['test'] = 'value2'; + var ctx1 = shellContext.copyWith(shellEnvironment: env1); + var ctx2 = shellContext.copyWith(shellEnvironment: env2); + Future testEnv(String expected) async { + for (var i = 0; i < 10; i++) { + await Future.delayed(const Duration(milliseconds: 1)); + var readVar = ShellEnvironment().vars['test']; + expect(readVar, expected); + } + } + + var future1 = ctx1.runZoned(() async { + await testEnv('value1'); + }); + var future2 = ctx2.runZoned(() async { + await testEnv('value2'); + }); + await Future.wait([future1, future2]); + + //var env1 = ShellEnvironment().runZoned() + }); + }); +} diff --git a/packages/process_run/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart index d027522..79634b5 100644 --- a/packages/process_run/test/shell_environment_test.dart +++ b/packages/process_run/test/shell_environment_test.dart @@ -7,7 +7,8 @@ import 'dart:convert'; import 'dart:io'; import 'package:process_run/shell.dart'; -import 'package:process_run/src/shell_utils.dart'; +import 'package:process_run/src/shell_utils.dart' + show envPathKey, envPathSeparator; import 'package:test/test.dart'; import 'echo_test.dart'; @@ -343,6 +344,28 @@ void main() { shell = shell.cd('test'); expect(shell.options.environment.aliases['cd_alias'], 'cd'); }); + test('runZoned', () async { + var env1 = ShellEnvironment()..vars['test'] = 'value1'; + var env2 = ShellEnvironment()..vars['test'] = 'value2'; + Future testEnv(String expected) async { + for (var i = 0; i < 10; i++) { + await Future.delayed(const Duration(milliseconds: 1)); + var readVar = ShellEnvironment().vars['test']; + print('$readVar vs $expected'); + expect(readVar, expected); + } + } + + var future1 = env1.runZoned(() async { + await testEnv('value1'); + }); + var future2 = env2.runZoned(() async { + await testEnv('value2'); + }); + await Future.wait([future1, future2]); + + //var env1 = ShellEnvironment().runZoned() + }); } /// Better with non verbose shell. diff --git a/packages/process_run/test/shell_zoned_test.dart b/packages/process_run/test/shell_zoned_test.dart new file mode 100644 index 0000000..a686b8f --- /dev/null +++ b/packages/process_run/test/shell_zoned_test.dart @@ -0,0 +1,44 @@ +// ignore_for_file: avoid_print + +@TestOn('vm') +library; + +import 'package:process_run/shell.dart'; +import 'package:test/test.dart'; + +import 'src/compile_echo.dart'; + +Future main() async { + var echo = await compileEchoExample(); + + var env = ShellEnvironment()..aliases['echo'] = echo; + + group('ShellZoned', () { + test('runZoned', () async { + var varName = 'PROCESS_RUN_VAR_ZONED_TEST'; + var env1 = ShellEnvironment(environment: env)..vars[varName] = 'value1'; + var env2 = ShellEnvironment(environment: env)..vars[varName] = 'value2'; + Future testEnv(String expected) async { + for (var i = 0; i < 10; i++) { + await Future.delayed(const Duration(milliseconds: 1)); + + var readVar = ShellEnvironment().vars[varName]; + print('$readVar vs $expected'); + expect(readVar, expected); + } + var output = (await run('echo --stdout-env $varName')).outText.trim(); + expect(output, expected); + } + + var future1 = env1.runZoned(() async { + await testEnv('value1'); + }); + var future2 = env2.runZoned(() async { + await testEnv('value2'); + }); + await Future.wait([future1, future2]); + + //var env1 = ShellEnvironment().runZoned() + }); + }); +} diff --git a/packages/process_run/test/src/shell_impl_test.dart b/packages/process_run/test/src/shell_impl_test.dart index 88c1d3a..00fb43a 100644 --- a/packages/process_run/test/src/shell_impl_test.dart +++ b/packages/process_run/test/src/shell_impl_test.dart @@ -8,7 +8,6 @@ import 'package:process_run/shell.dart'; import 'package:process_run/shell_run.dart'; import 'package:process_run/src/common/constant.dart'; import 'package:process_run/src/common/import.dart'; -import 'package:process_run/src/flutterbin_cmd.dart'; import 'package:process_run/src/user_config.dart'; import 'package:test/test.dart'; From 4b28d6b1665cfd9f7339aa65a44539633508351b Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 4 Mar 2025 19:54:59 +0100 Subject: [PATCH 140/150] [process_run] v1.2.4 --- packages/process_run/CHANGELOG.md | 4 ++++ packages/process_run/pubspec.yaml | 2 +- packages/process_run/test/shell_environment_test.dart | 1 - packages/process_run/test/shell_zoned_test.dart | 7 +++++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/process_run/CHANGELOG.md b/packages/process_run/CHANGELOG.md index 8990708..2b5360d 100644 --- a/packages/process_run/CHANGELOG.md +++ b/packages/process_run/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.4 + +* Allow running in a zoned environment context. + ## 1.2.3 * Requires dart 3.7 diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index bcab943..ebaa802 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -1,5 +1,5 @@ name: process_run -version: 1.2.3 +version: 1.2.4 description: Process run helpers for Linux/Win/Mac and which like feature for finding executables. homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run diff --git a/packages/process_run/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart index 79634b5..d999b60 100644 --- a/packages/process_run/test/shell_environment_test.dart +++ b/packages/process_run/test/shell_environment_test.dart @@ -351,7 +351,6 @@ void main() { for (var i = 0; i < 10; i++) { await Future.delayed(const Duration(milliseconds: 1)); var readVar = ShellEnvironment().vars['test']; - print('$readVar vs $expected'); expect(readVar, expected); } } diff --git a/packages/process_run/test/shell_zoned_test.dart b/packages/process_run/test/shell_zoned_test.dart index a686b8f..de8eacc 100644 --- a/packages/process_run/test/shell_zoned_test.dart +++ b/packages/process_run/test/shell_zoned_test.dart @@ -23,10 +23,13 @@ Future main() async { await Future.delayed(const Duration(milliseconds: 1)); var readVar = ShellEnvironment().vars[varName]; - print('$readVar vs $expected'); expect(readVar, expected); } - var output = (await run('echo --stdout-env $varName')).outText.trim(); + var output = + (await run( + 'echo --stdout-env $varName', + verbose: false, + )).outText.trim(); expect(output, expected); } From 3b2505a67ee404a8b656fcbda3084eb71706156e Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Wed, 5 Mar 2025 00:44:39 +0100 Subject: [PATCH 141/150] fix ci on non-flutter platform --- .github/dependabot.yml | 4 + .github/workflows/run_ci_flutter.yml | 39 ++++++++++ .../process_run/test/flutterbin_cmd_test.dart | 73 ++++++++++--------- 3 files changed, 80 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/run_ci_flutter.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 313bbaf..1756cbb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,10 @@ version: 2 enable-beta-ecosystems: true updates: + - package-ecosystem: "pub" + directory: "." + schedule: + interval: "monthly" - package-ecosystem: "pub" directory: "packages/process_run" schedule: diff --git a/.github/workflows/run_ci_flutter.yml b/.github/workflows/run_ci_flutter.yml new file mode 100644 index 0000000..e3e7aea --- /dev/null +++ b/.github/workflows/run_ci_flutter.yml @@ -0,0 +1,39 @@ +name: Run CI Flutter +on: + push: + workflow_dispatch: + schedule: + - cron: '0 0 * * 0' # every sunday at midnight + +jobs: + test: + name: Test on ${{ matrix.os }} / flutter ${{ matrix.flutter }} + runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: . + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + flutter: stable + - os: ubuntu-latest + flutter: beta + - os: windows-latest + flutter: stable + - os: macos-latest + flutter: stable + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17.x' + - uses: subosito/flutter-action@v2 + with: + channel: ${{ matrix.flutter }} + - run: dart --version + - run: flutter --version + - run: dart pub global activate dev_build + - run: dart pub global run dev_build:run_ci --recursive diff --git a/packages/process_run/test/flutterbin_cmd_test.dart b/packages/process_run/test/flutterbin_cmd_test.dart index d472f05..d9d5633 100644 --- a/packages/process_run/test/flutterbin_cmd_test.dart +++ b/packages/process_run/test/flutterbin_cmd_test.dart @@ -20,29 +20,45 @@ void main() { // ignore: unnecessary_statements getFlutterBinVersion; }); - test('flutterDart', () { - expect(flutterExecutablePath, isNotNull); - expect(flutterDartExecutablePath, isNotNull); - }); - test('run_version', () async { - //print(flutterExecutablePath); - ProcessCmd cmd = FlutterCmd(['--version']); - // expect(cmd.executable, flutterExecutablePath); - expect(cmd.arguments, ['--version']); - final result = await runCmd(cmd); - expect(result.outText.toLowerCase(), contains('dart')); - expect(result.outText.toLowerCase(), contains('revision')); - expect(result.outText.toLowerCase(), contains('flutter')); + group('flutter', () { + test('flutterDart', () { + expect(flutterExecutablePath, isNotNull); + expect(flutterDartExecutablePath, isNotNull); + }); + test('dart', () async { + var flutterDir = dirname((await which('flutter'))!); + // New in 2.9 + expect(File(join(flutterDir, 'dart')).existsSync(), isTrue); + getFlutterAncestorPath(flutterDir); + expect(getFlutterAncestorPath(flutterDir), flutterDir); + }); - // Whatever ship stable - expect(await getFlutterBinVersion(), greaterThan(Version(1, 10, 0))); - expect(await getFlutterBinChannel(), isNotNull); - }, skip: !isFlutterSupportedSync); + test('which', () { + expect( + basename(whichSync('flutter')!), + getBashOrBatExecutableFilename('flutter'), + ); + }); + test('run_version', () async { + //print(flutterExecutablePath); + ProcessCmd cmd = FlutterCmd(['--version']); + // expect(cmd.executable, flutterExecutablePath); + expect(cmd.arguments, ['--version']); + final result = await runCmd(cmd); + expect(result.outText.toLowerCase(), contains('dart')); + expect(result.outText.toLowerCase(), contains('revision')); + expect(result.outText.toLowerCase(), contains('flutter')); - test('version & channel', () async { - // Whatever ship stable - expect(await getFlutterBinVersion(), greaterThan(Version(1, 10, 0))); - expect(await getFlutterBinChannel(), isNotNull); + // Whatever ship stable + expect(await getFlutterBinVersion(), greaterThan(Version(1, 10, 0))); + expect(await getFlutterBinChannel(), isNotNull); + }); + + test('version & channel', () async { + // Whatever ship stable + expect(await getFlutterBinVersion(), greaterThan(Version(1, 10, 0))); + expect(await getFlutterBinChannel(), isNotNull); + }); }, skip: !isFlutterSupportedSync); test('get version', () async { @@ -65,20 +81,5 @@ void main() { shellEnvironment = null; } }); - - test('dart', () async { - var flutterDir = dirname((await which('flutter'))!); - // New in 2.9 - expect(File(join(flutterDir, 'dart')).existsSync(), isTrue); - getFlutterAncestorPath(flutterDir); - expect(getFlutterAncestorPath(flutterDir), flutterDir); - }, skip: !isFlutterSupportedSync); - - test('which', () { - expect( - basename(whichSync('flutter')!), - getBashOrBatExecutableFilename('flutter'), - ); - }, skip: !isFlutterSupportedSync); }); } From 894ef7a059dcb275ea27862e9b4126c350d6c198 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 10 Mar 2025 10:42:39 +0100 Subject: [PATCH 142/150] fix ci --- packages/process_run/test/dartbin_cmd_test.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/process_run/test/dartbin_cmd_test.dart b/packages/process_run/test/dartbin_cmd_test.dart index ef8e79e..e39e95c 100644 --- a/packages/process_run/test/dartbin_cmd_test.dart +++ b/packages/process_run/test/dartbin_cmd_test.dart @@ -46,7 +46,9 @@ void main() { try { var version = await getDartBinVersion(); // Always present - expect(version, greaterThan(Version(2, 0, 0))); + if (version != null) { + expect(version, greaterThan(Version(2, 0, 0))); + } } finally { // ignore: deprecated_member_use_from_same_package flutterExecutablePath = null; From 02bf6daf97bee29d86e671e8d8989c0994e4fae4 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 6 May 2025 21:46:32 +0200 Subject: [PATCH 143/150] fix beta lints --- packages/process_run/test/shell_api_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/process_run/test/shell_api_test.dart b/packages/process_run/test/shell_api_test.dart index 7c04ad9..151bcd5 100644 --- a/packages/process_run/test/shell_api_test.dart +++ b/packages/process_run/test/shell_api_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: dead_code + import 'dart:io' as io; import 'package:process_run/shell.dart'; From 88feaf142c4bfd8cfeca5821c53c7ce9a2c6e30b Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 27 Jun 2025 14:58:30 +0200 Subject: [PATCH 144/150] dart 3.8 support --- packages/process_run/pubspec.yaml | 2 +- packages/process_run_test/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index ebaa802..8de1355 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -4,7 +4,7 @@ description: Process run helpers for Linux/Win/Mac and which like feature for fi homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run environment: - sdk: ^3.7.0 + sdk: ^3.8.0 dependencies: path: ">=1.8.0 <3.0.0" diff --git a/packages/process_run_test/pubspec.yaml b/packages/process_run_test/pubspec.yaml index 853a34f..94c662b 100644 --- a/packages/process_run_test/pubspec.yaml +++ b/packages/process_run_test/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.0.0 publish_to: none environment: - sdk: ^3.7.0 + sdk: ^3.8.0 # Add regular dependencies here. dependencies: From b6e8cc4f5c76fe72d604162c924e46f07ab4d05e Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 27 Jun 2025 15:57:06 +0200 Subject: [PATCH 145/150] dart 3.8 support --- .../process_run/lib/src/bin/shell/dump.dart | 5 +- .../process_run/lib/src/bin/shell/env.dart | 21 +++--- .../lib/src/bin/shell/env_var_dump.dart | 5 +- packages/process_run/lib/src/characters.dart | 24 +++---- .../process_run/lib/src/dartbin_impl.dart | 15 ++--- packages/process_run/lib/src/io/env_io.dart | 21 +++--- .../process_run/lib/src/io/shell_words.dart | 7 +- packages/process_run/lib/src/process_run.dart | 25 ++++--- packages/process_run/lib/src/prompt.dart | 6 +- packages/process_run/lib/src/shell.dart | 4 +- .../lib/src/shell_context_common.dart | 7 +- .../lib/src/shell_environment.dart | 4 +- packages/process_run/lib/src/shell_utils.dart | 55 +++++++-------- packages/process_run/lib/src/stdio/stdio.dart | 9 ++- packages/process_run/lib/src/user_config.dart | 9 ++- .../process_run/test/bin/bin_shell_test.dart | 7 +- packages/process_run/test/compile_test.dart | 37 +++++----- .../test/dart_compile_js_test.dart | 7 +- .../test/flutterbin_impl_test.dart | 14 ++-- .../test/shell_environment_test.dart | 15 ++--- .../test/shell_lines_controller_test.dart | 7 +- packages/process_run/test/shell_run_test.dart | 31 ++++----- .../test/shell_stdio_lines_grouper_test.dart | 5 +- packages/process_run/test/shell_test.dart | 9 ++- .../process_run/test/shell_zoned_test.dart | 9 ++- .../process_run/test/src/compile_echo.dart | 5 +- .../process_run/test/src/compile_shell.dart | 5 +- .../test/src/compile_streamer.dart | 5 +- .../process_run/test/src/shell_impl_test.dart | 67 +++++++++---------- .../test/src_user_config_test.dart | 14 ++-- 30 files changed, 208 insertions(+), 246 deletions(-) diff --git a/packages/process_run/lib/src/bin/shell/dump.dart b/packages/process_run/lib/src/bin/shell/dump.dart index 9dfd2ec..d0ce1f9 100644 --- a/packages/process_run/lib/src/bin/shell/dump.dart +++ b/packages/process_run/lib/src/bin/shell/dump.dart @@ -2,9 +2,8 @@ import 'package:process_run/src/io/io.dart'; /// Dump a string map void dumpStringMap(Map map) { - var keys = - map.keys.toList() - ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); + var keys = map.keys.toList() + ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); for (var key in keys) { var value = map[key]; stdout.writeln('$key: $value'); diff --git a/packages/process_run/lib/src/bin/shell/env.dart b/packages/process_run/lib/src/bin/shell/env.dart index adabe0a..3c5ea8d 100644 --- a/packages/process_run/lib/src/bin/shell/env.dart +++ b/packages/process_run/lib/src/bin/shell/env.dart @@ -69,19 +69,16 @@ class ShellEnvCommandBase extends ShellBinCommand { /// Env file path String? get envFilePath => _envFilePath; - String? get _envFilePath => - local - ? getLocalEnvFilePath(userEnvironment) - : getUserEnvFilePath(userEnvironment); + String? get _envFilePath => local + ? getLocalEnvFilePath(userEnvironment) + : getUserEnvFilePath(userEnvironment); List? _sampleFileContent; /// Sample file content - List get sampleFileContent => - _sampleFileContent ??= () { - var content = - local - ? ''' + List get sampleFileContent => _sampleFileContent ??= () { + var content = local + ? ''' # Local Environment path and variable for `Shell.run` calls. # # `path(s)` is a list of path, `var(s)` is a key/value map. @@ -97,7 +94,7 @@ class ShellEnvCommandBase extends ShellBinCommand { # alias: # qr: /path/to/my_qr_app ''' - : ''' + : ''' # Environment path and variable for `Shell.run` calls. # # `path` is a list of path, `var` is a key/value map. @@ -117,8 +114,8 @@ class ShellEnvCommandBase extends ShellBinCommand { '''; - return LineSplitter.split(content).toList(); - }(); + return LineSplitter.split(content).toList(); + }(); } /// Shell env command diff --git a/packages/process_run/lib/src/bin/shell/env_var_dump.dart b/packages/process_run/lib/src/bin/shell/env_var_dump.dart index da908e2..9e14789 100644 --- a/packages/process_run/lib/src/bin/shell/env_var_dump.dart +++ b/packages/process_run/lib/src/bin/shell/env_var_dump.dart @@ -11,9 +11,8 @@ class ShellEnvVarDumpCommand extends ShellBinCommand { @override FutureOr onRun() async { var vars = ShellEnvironment().vars; - var keys = - vars.keys.toList() - ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); + var keys = vars.keys.toList() + ..sort((t1, t2) => t1.toLowerCase().compareTo(t2.toLowerCase())); for (var key in keys) { var value = vars[key]; stdout.writeln('$key: $value'); diff --git a/packages/process_run/lib/src/characters.dart b/packages/process_run/lib/src/characters.dart index e538fce..da9563e 100644 --- a/packages/process_run/lib/src/characters.dart +++ b/packages/process_run/lib/src/characters.dart @@ -10,18 +10,18 @@ /// bool isWhitespace(int rune) => ((rune >= 0x0009 && rune <= 0x000D) || - rune == 0x0020 || - rune == 0x0085 || - rune == 0x00A0 || - rune == 0x1680 || - rune == 0x180E || - (rune >= 0x2000 && rune <= 0x200A) || - rune == 0x2028 || - rune == 0x2029 || - rune == 0x202F || - rune == 0x205F || - rune == 0x3000 || - rune == 0xFEFF); + rune == 0x0020 || + rune == 0x0085 || + rune == 0x00A0 || + rune == 0x1680 || + rune == 0x180E || + (rune >= 0x2000 && rune <= 0x200A) || + rune == 0x2028 || + rune == 0x2029 || + rune == 0x202F || + rune == 0x205F || + rune == 0x3000 || + rune == 0xFEFF); /// True if empty or starts with white space bool startsWithWhitespace(String text) => diff --git a/packages/process_run/lib/src/dartbin_impl.dart b/packages/process_run/lib/src/dartbin_impl.dart index 6ad6548..94cd36c 100644 --- a/packages/process_run/lib/src/dartbin_impl.dart +++ b/packages/process_run/lib/src/dartbin_impl.dart @@ -50,15 +50,14 @@ String? _resolvedDartExecutable; /// /// Get dart vm either from executable or using the which command /// -String? get resolvedDartExecutable => - _resolvedDartExecutable ??= () { - var executable = platformResolvedExecutable; - if (executable != null) { - return executable; - } +String? get resolvedDartExecutable => _resolvedDartExecutable ??= () { + var executable = platformResolvedExecutable; + if (executable != null) { + return executable; + } - return resolveDartExecutable(); - }(); + return resolveDartExecutable(); +}(); String? _platformResolvedExecutable; diff --git a/packages/process_run/lib/src/io/env_io.dart b/packages/process_run/lib/src/io/env_io.dart index 241bbbf..fc7e7e8 100644 --- a/packages/process_run/lib/src/io/env_io.dart +++ b/packages/process_run/lib/src/io/env_io.dart @@ -40,19 +40,16 @@ class ShellEnvIoHelper { /// Get the environment file path String? get envFilePath => _envFilePath; - String? get _envFilePath => - local - ? getLocalEnvFilePath(shell.options.environment) - : getUserEnvFilePath(shell.options.environment); + String? get _envFilePath => local + ? getLocalEnvFilePath(shell.options.environment) + : getUserEnvFilePath(shell.options.environment); List? _sampleFileContent; /// Sample file content - List get sampleFileContent => - _sampleFileContent ??= () { - var content = - local - ? ''' + List get sampleFileContent => _sampleFileContent ??= () { + var content = local + ? ''' # Local Environment path and variable for `Shell.run` calls. # # `path(s)` is a list of path, `var(s)` is a key/value map. @@ -68,7 +65,7 @@ class ShellEnvIoHelper { # alias: # qr: /path/to/my_qr_app ''' - : ''' + : ''' # Environment path and variable for `Shell.run` calls. # # `path` is a list of path, `var` is a key/value map. @@ -88,6 +85,6 @@ class ShellEnvIoHelper { '''; - return LineSplitter.split(content).toList(); - }(); + return LineSplitter.split(content).toList(); + }(); } diff --git a/packages/process_run/lib/src/io/shell_words.dart b/packages/process_run/lib/src/io/shell_words.dart index a6e98e7..a2b653b 100644 --- a/packages/process_run/lib/src/io/shell_words.dart +++ b/packages/process_run/lib/src/io/shell_words.dart @@ -241,9 +241,8 @@ List shellSplitWindowsImpl(String command) { /// quote matching the one at position [openingQuote] is missing. void _checkUnmatchedQuote(StringScanner scanner, int openingQuote) { if (!scanner.isDone) return; - final type = - scanner.substring(openingQuote, openingQuote + 1) == '"' - ? 'double' - : 'single'; + final type = scanner.substring(openingQuote, openingQuote + 1) == '"' + ? 'double' + : 'single'; scanner.error('Unmatched $type quote.', position: openingQuote, length: 1); } diff --git a/packages/process_run/lib/src/process_run.dart b/packages/process_run/lib/src/process_run.dart index 72ee6b4..ab38834 100644 --- a/packages/process_run/lib/src/process_run.dart +++ b/packages/process_run/lib/src/process_run.dart @@ -131,11 +131,12 @@ Future runExecutableArguments( StreamSubscription? stdinSubscription; if (stdin != null) { //stdin.pipe(process.stdin); // this closes the stream... - stdinSubscription = stdin.listen((List data) { - process.stdin.add(data); - })..onDone(() { - process.stdin.close(); - }); + stdinSubscription = + stdin.listen((List data) { + process.stdin.add(data); + })..onDone(() { + process.stdin.close(); + }); // OLD 2: process.stdin.addStream(stdin); } else { // Close the input sync, we want this not interractive @@ -157,14 +158,12 @@ Future runExecutableArguments( return list; } - var out = - (noStdoutResult ?? false) - ? Future.value(null) - : streamToResult(outCtlr.stream, stdoutEncoding); - var err = - (noStderrResult ?? false) - ? Future.value(null) - : streamToResult(errCtlr.stream, stderrEncoding); + var out = (noStdoutResult ?? false) + ? Future.value(null) + : streamToResult(outCtlr.stream, stdoutEncoding); + var err = (noStderrResult ?? false) + ? Future.value(null) + : streamToResult(errCtlr.stream, stderrEncoding); process.stdout.listen( (List d) { diff --git a/packages/process_run/lib/src/prompt.dart b/packages/process_run/lib/src/prompt.dart index d504688..68254e9 100644 --- a/packages/process_run/lib/src/prompt.dart +++ b/packages/process_run/lib/src/prompt.dart @@ -15,8 +15,10 @@ Future prompt(String? text, {Stream>? stdin}) async { /// Get text Future _promptGetText({Stream>? stdin}) async { stdin ??= sharedStdIn; - final input = - await stdin.transform(utf8.decoder).transform(const LineSplitter()).first; + final input = await stdin + .transform(utf8.decoder) + .transform(const LineSplitter()) + .first; // devPrint('input: $input'); return input; } diff --git a/packages/process_run/lib/src/shell.dart b/packages/process_run/lib/src/shell.dart index 50b1dc7..66257bf 100644 --- a/packages/process_run/lib/src/shell.dart +++ b/packages/process_run/lib/src/shell.dart @@ -610,8 +610,8 @@ abstract class Shell implements ShellCore, ShellCoreSync { /// Global process handler. try { _clearPreviousContext(); - var completer = - _currentProcessResultCompleter = Completer(); + var completer = _currentProcessResultCompleter = + Completer(); Future run() async { ProcessResult? processResult; diff --git a/packages/process_run/lib/src/shell_context_common.dart b/packages/process_run/lib/src/shell_context_common.dart index b24ba6b..894a814 100644 --- a/packages/process_run/lib/src/shell_context_common.dart +++ b/packages/process_run/lib/src/shell_context_common.dart @@ -136,10 +136,9 @@ extension ShellContextExt on ShellContext { } /// Overriden shell stdio if any. -ShellContext? get zonedShellContextOrNull => - _inZoneCount > 0 - ? async.Zone.current[_shellContextZoneVar] as ShellContext? - : null; +ShellContext? get zonedShellContextOrNull => _inZoneCount > 0 + ? async.Zone.current[_shellContextZoneVar] as ShellContext? + : null; const _shellContextZoneVar = #tekartik_shell_context; /// In memory shell context. diff --git a/packages/process_run/lib/src/shell_environment.dart b/packages/process_run/lib/src/shell_environment.dart index 49454f3..6c70a46 100644 --- a/packages/process_run/lib/src/shell_environment.dart +++ b/packages/process_run/lib/src/shell_environment.dart @@ -9,8 +9,8 @@ export 'shell_environment_common.dart' /// Use current if already and environment object. ShellEnvironment asShellEnvironment(Map? environment) => (environment is ShellEnvironment) - ? environment - : ShellEnvironment(environment: environment); + ? environment + : ShellEnvironment(environment: environment); /// Shell modifiable helpers. should not be modified after being set. class ShellEnvironment extends common.ShellEnvironmentBase { diff --git a/packages/process_run/lib/src/shell_utils.dart b/packages/process_run/lib/src/shell_utils.dart index 2624a8e..5f04efe 100644 --- a/packages/process_run/lib/src/shell_utils.dart +++ b/packages/process_run/lib/src/shell_utils.dart @@ -89,19 +89,18 @@ String? _userAppDataPath; /// /// On windows, it is read from the `APPDATA` environment variable. Otherwise /// it is the `~/.config` folder -String get userAppDataPath => - _userAppDataPath ??= - () { - var override = platformEnvironment[userAppDataPathEnvKey]; - if (override != null) { - return override; - } - if (Platform.isWindows) { - return platformEnvironment['APPDATA']; - } - return null; - }() ?? - join(userHomePath, '.config'); +String get userAppDataPath => _userAppDataPath ??= + () { + var override = platformEnvironment[userAppDataPathEnvKey]; + if (override != null) { + return override; + } + if (Platform.isWindows) { + return platformEnvironment['APPDATA']; + } + return null; + }() ?? + join(userHomePath, '.config'); String? _userHomePath; @@ -109,12 +108,11 @@ String? _userHomePath; /// /// Usually read from the `HOME` environment variable or `USERPROFILE` on /// Windows. -String get userHomePath => - _userHomePath ??= - platformEnvironment[userHomePathEnvKey] ?? - platformEnvironment['HOME'] ?? - platformEnvironment['USERPROFILE'] ?? - '~'; +String get userHomePath => _userHomePath ??= + platformEnvironment[userHomePathEnvKey] ?? + platformEnvironment['HOME'] ?? + platformEnvironment['USERPROFILE'] ?? + '~'; /// Expand home if needed String expandPath(String path) { @@ -147,10 +145,8 @@ Map? _platformEnvironment; /// Environment without debug VM_OPTIONS and without any user overrides /// /// Instead replace with an optional TEKARTIK_DART_VM_OPTIONS -Map get platformEnvironment => - _platformEnvironment ??= environmentFilterOutVmOptions( - Platform.environment, - ); +Map get platformEnvironment => _platformEnvironment ??= + environmentFilterOutVmOptions(Platform.environment); /// Warning, change the platform environment and reset. set platformEnvironment(Map? environment) { @@ -190,10 +186,8 @@ Map environmentFilterOutVmOptions( List? _windowsPathExts; /// Default extension for PATHEXT on Windows -List get windowsPathExts => - _windowsPathExts ??= - environmentGetWindowsPathExt(platformEnvironment) ?? - windowsDefaultPathExt; +List get windowsPathExts => _windowsPathExts ??= + environmentGetWindowsPathExt(platformEnvironment) ?? windowsDefaultPathExt; /// Get the PATHEXT environment variable (windows) List? environmentGetWindowsPathExt( @@ -218,10 +212,9 @@ bool fixRunInShell(bool? runInShell, String executable) { } /// Use io package shellSplit implementation -List shellSplit(String command) => - context.style == windows.style - ? io.shellSplitWindowsImpl(command) - : io.shellSplitImpl(command); +List shellSplit(String command) => context.style == windows.style + ? io.shellSplitWindowsImpl(command) + : io.shellSplitImpl(command); /// Inverse of shell split String shellJoin(List parts) => diff --git a/packages/process_run/lib/src/stdio/stdio.dart b/packages/process_run/lib/src/stdio/stdio.dart index 674dd8c..fcaf4e2 100644 --- a/packages/process_run/lib/src/stdio/stdio.dart +++ b/packages/process_run/lib/src/stdio/stdio.dart @@ -121,11 +121,10 @@ class ShellStdioLinesGrouperIOSink with IOSinkMixin implements IOSink { @override void add(core.List data) { var zoneId = grouper.zoneId; - var streamer = - grouper.streamers[zoneId] ??= ShellOutputLinesStreamer( - stdout: grouper.stdout, - stderr: grouper.stderr, - ); + var streamer = grouper.streamers[zoneId] ??= ShellOutputLinesStreamer( + stdout: grouper.stdout, + stderr: grouper.stderr, + ); // devPrint('[$zoneId/$currentZoneId] Adding data ${encoding.decode(data).trim()}'); var sink = _isErr ? streamer.err : streamer.out; sink.add(data); diff --git a/packages/process_run/lib/src/user_config.dart b/packages/process_run/lib/src/user_config.dart index 0c3c830..0d824db 100644 --- a/packages/process_run/lib/src/user_config.dart +++ b/packages/process_run/lib/src/user_config.dart @@ -84,11 +84,10 @@ List get userPaths => userConfig.paths; /// [userEnvironment] must be explicitly used as it could contain sensitive /// information. /// -Map get userEnvironment => - ShellEnvironment.empty() - ..vars.addAll(userConfig.vars) - ..aliases.addAll(userConfig.aliases) - ..paths.addAll(userConfig.paths); +Map get userEnvironment => ShellEnvironment.empty() + ..vars.addAll(userConfig.vars) + ..aliases.addAll(userConfig.aliases) + ..paths.addAll(userConfig.paths); @protected /// Reset user config diff --git a/packages/process_run/test/bin/bin_shell_test.dart b/packages/process_run/test/bin/bin_shell_test.dart index e1e4b1f..bdf44df 100644 --- a/packages/process_run/test/bin/bin_shell_test.dart +++ b/packages/process_run/test/bin/bin_shell_test.dart @@ -16,10 +16,9 @@ var shell = Shell( var safeLocalEnvFile = '.dart_tool/process_run/test/test_local_env3_safe.yaml'; -var safeShellEnvironment = - ShellEnvironment() - ..aliases['ds'] = 'dart run bin/shell.dart' - ..vars[userEnvFilePathEnvKey] = 'test/data/test_user_env3_safe.yaml'; +var safeShellEnvironment = ShellEnvironment() + ..aliases['ds'] = 'dart run bin/shell.dart' + ..vars[userEnvFilePathEnvKey] = 'test/data/test_user_env3_safe.yaml'; Shell get safeShell => Shell(environment: safeShellEnvironment, verbose: false); diff --git a/packages/process_run/test/compile_test.dart b/packages/process_run/test/compile_test.dart index 1414803..5e39dfc 100644 --- a/packages/process_run/test/compile_test.dart +++ b/packages/process_run/test/compile_test.dart @@ -18,18 +18,16 @@ void main() { var echoExeName = basename(echoExePath); // Try path access - var lines = - (await Shell( - verbose: false, - ).run('${shellArgument(echoExePath)} --stdout test')).outLines; + var lines = (await Shell( + verbose: false, + ).run('${shellArgument(echoExePath)} --stdout test')).outLines; expect(lines, ['test']); // Try using alias - lines = - (await Shell( - verbose: false, - environment: ShellEnvironment()..aliases['echo'] = echoExePath, - ).run('echo --stdout test')).outLines; + lines = (await Shell( + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echoExePath, + ).run('echo --stdout test')).outLines; expect(lines, ['test']); // Try using alias in options @@ -37,26 +35,27 @@ void main() { verbose: false, environment: ShellEnvironment()..aliases['echo'] = echoExePath, ); - lines = - (await Shell(options: options).run('echo --stdout test')).outLines; + lines = (await Shell( + options: options, + ).run('echo --stdout test')).outLines; expect(lines, ['test']); // Try using alias lines = (await Shell( - verbose: false, - environment: ShellEnvironment()..aliases['echo'] = echoExePath, - ).run(''' + verbose: false, + environment: ShellEnvironment()..aliases['echo'] = echoExePath, + ).run(''' echo --stdout test1 echo --stdout test2 - ''')).outLines; + ''')) + .outLines; expect(lines, ['test1', 'test2']); // Try relative access var exePathShell = Shell(workingDirectory: echoExeDir, verbose: false); - lines = - (await exePathShell.run( - '${shellArgument(join('.', echoExeName))} --stdout test', - )).outLines; + lines = (await exePathShell.run( + '${shellArgument(join('.', echoExeName))} --stdout test', + )).outLines; expect(lines, ['test']); // Without using a relative path, this should fail diff --git a/packages/process_run/test/dart_compile_js_test.dart b/packages/process_run/test/dart_compile_js_test.dart index 94bc17e..a1947bb 100644 --- a/packages/process_run/test/dart_compile_js_test.dart +++ b/packages/process_run/test/dart_compile_js_test.dart @@ -38,10 +38,9 @@ void defineTests() { expect(File(destination).existsSync(), isFalse); var shell = Shell(verbose: false); - final result = - (await shell.run( - 'dart compile js -o ${shellArgument(destination)} ${shellArgument(source)}', - )).first; + final result = (await shell.run( + 'dart compile js -o ${shellArgument(destination)} ${shellArgument(source)}', + )).first; expect(result.exitCode, 0); expect(File(destination).existsSync(), isTrue); }); diff --git a/packages/process_run/test/flutterbin_impl_test.dart b/packages/process_run/test/flutterbin_impl_test.dart index e65d769..97a80f0 100644 --- a/packages/process_run/test/flutterbin_impl_test.dart +++ b/packages/process_run/test/flutterbin_impl_test.dart @@ -9,17 +9,15 @@ import 'package:test/test.dart'; void main() { group('flutterbin_impl', () { test('FlutterBinInfo', () { - var info = - FlutterBinInfo.parseVersionOutput( - 'Flutter 1.7.8+hotfix.4 • channel stable • https://github.com/flutter/flutter.git', - )!; + var info = FlutterBinInfo.parseVersionOutput( + 'Flutter 1.7.8+hotfix.4 • channel stable • https://github.com/flutter/flutter.git', + )!; expect(info.version, Version(1, 7, 8, build: 'hotfix.4')); expect(info.channel, 'stable'); - info = - FlutterBinInfo.parseVersionOutput( - 'Flutter 1.14.3 • channel dev • https://github.com/flutter/flutter.git', - )!; + info = FlutterBinInfo.parseVersionOutput( + 'Flutter 1.14.3 • channel dev • https://github.com/flutter/flutter.git', + )!; expect(info.version, Version(1, 14, 3)); expect(info.channel, 'dev'); }); diff --git a/packages/process_run/test/shell_environment_test.dart b/packages/process_run/test/shell_environment_test.dart index d999b60..8244243 100644 --- a/packages/process_run/test/shell_environment_test.dart +++ b/packages/process_run/test/shell_environment_test.dart @@ -94,9 +94,8 @@ void main() { var prevEnv = shellEnvironment; expect(shellEnvironment, isNotEmpty); var shell = Shell(verbose: false); - var env = - ShellEnvironment() - ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; + var env = ShellEnvironment() + ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; var result = await getEchoEnv(shell); @@ -121,9 +120,8 @@ void main() { }); // not working test('local vars', () async { - var env = - ShellEnvironment() - ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; + var env = ShellEnvironment() + ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; var localShell = Shell(environment: env, verbose: false); var shell = Shell(verbose: false); @@ -146,9 +144,8 @@ void main() { test('local one var', () async { try { - var env = - ShellEnvironment.empty() - ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; + var env = ShellEnvironment.empty() + ..vars['TEST_PROCESS_RUN_VAR1'] = 'test_process_run_value1'; var shell = Shell(environment: env, verbose: false); print(await getEchoEnv(shell)); diff --git a/packages/process_run/test/shell_lines_controller_test.dart b/packages/process_run/test/shell_lines_controller_test.dart index b5f4423..309e6c1 100644 --- a/packages/process_run/test/shell_lines_controller_test.dart +++ b/packages/process_run/test/shell_lines_controller_test.dart @@ -12,10 +12,9 @@ void main() { group('ShellLinesController', () { late ShellEnvironment env; setUpAll(() async { - env = - ShellEnvironment() - ..aliases['streamer'] = await compileStreamerExample() - ..aliases['echo'] = await compileEchoExample(); + env = ShellEnvironment() + ..aliases['streamer'] = await compileStreamerExample() + ..aliases['echo'] = await compileEchoExample(); }); test('stream all', () async { var ctlr = ShellLinesController(); diff --git a/packages/process_run/test/shell_run_test.dart b/packages/process_run/test/shell_run_test.dart index 8bebb3b..94ca8c1 100644 --- a/packages/process_run/test/shell_run_test.dart +++ b/packages/process_run/test/shell_run_test.dart @@ -54,13 +54,12 @@ void main() { }); test('sync --version', () async { - var result = - runSync( - 'dart --version', - throwOnError: false, - verbose: false, - commandVerbose: true, - ).first; + var result = runSync( + 'dart --version', + throwOnError: false, + verbose: false, + commandVerbose: true, + ).first; stdout.writeln('stdout: ${result.stdout.toString().trim()}'); stdout.writeln('stderr: ${result.stderr.toString().trim()}'); stdout.writeln('exitCode: ${result.exitCode}'); @@ -76,13 +75,12 @@ void main() { // 'dartanalyzer', deprecated ]) { stdout.writeln(''); - var result = - (await run( - '$bin --version', - throwOnError: false, - verbose: false, - commandVerbose: true, - )).first; + var result = (await run( + '$bin --version', + throwOnError: false, + verbose: false, + commandVerbose: true, + )).first; stdout.writeln('stdout: ${result.stdout.toString().trim()}'); stdout.writeln('stderr: ${result.stderr.toString().trim()}'); stdout.writeln('exitCode: ${result.exitCode}'); @@ -99,9 +97,8 @@ void main() { }); test('throwOnError', () async { var verbose = false; // devWarning(true); - var env = - ShellEnvironment() - ..aliases['echo'] = 'dart run ${shellArgument(echoScriptPath)}'; + var env = ShellEnvironment() + ..aliases['echo'] = 'dart run ${shellArgument(echoScriptPath)}'; // Prevent error to be thrown if exitCode is not 0 var shell = Shell( diff --git a/packages/process_run/test/shell_stdio_lines_grouper_test.dart b/packages/process_run/test/shell_stdio_lines_grouper_test.dart index 65ae5a8..b39a200 100644 --- a/packages/process_run/test/shell_stdio_lines_grouper_test.dart +++ b/packages/process_run/test/shell_stdio_lines_grouper_test.dart @@ -17,8 +17,9 @@ void main() { verbose: false, environment: ShellEnvironment()..aliases['echo'] = echo, ); - var lines = - (await Shell(options: options).run('echo --stdout test')).outLines; + var lines = (await Shell( + options: options, + ).run('echo --stdout test')).outLines; expect(lines, ['test']); /* var env = ShellEnvironment() diff --git a/packages/process_run/test/shell_test.dart b/packages/process_run/test/shell_test.dart index 68c00e5..72c8322 100644 --- a/packages/process_run/test/shell_test.dart +++ b/packages/process_run/test/shell_test.dart @@ -752,11 +752,10 @@ _tekartik_dummy_app_that_does_not_exits var localFile = '.dart_tool/process_run/test/local1.yaml'; var userFile = '.dart_tool/process_run/test/user1.yaml'; var dsCommand = 'dart run bin/shell.dart'; - var safeShellEnvironment = - ShellEnvironment() - ..aliases['ds'] = dsCommand - ..vars[userEnvFilePathEnvKey] = userFile - ..vars[localEnvFilePathEnvKey] = localFile; + var safeShellEnvironment = ShellEnvironment() + ..aliases['ds'] = dsCommand + ..vars[userEnvFilePathEnvKey] = userFile + ..vars[localEnvFilePathEnvKey] = localFile; var shell = Shell(environment: safeShellEnvironment, verbose: true); expect(shell.options.environment.aliases['ds'], dsCommand); diff --git a/packages/process_run/test/shell_zoned_test.dart b/packages/process_run/test/shell_zoned_test.dart index de8eacc..f8129d3 100644 --- a/packages/process_run/test/shell_zoned_test.dart +++ b/packages/process_run/test/shell_zoned_test.dart @@ -25,11 +25,10 @@ Future main() async { var readVar = ShellEnvironment().vars[varName]; expect(readVar, expected); } - var output = - (await run( - 'echo --stdout-env $varName', - verbose: false, - )).outText.trim(); + var output = (await run( + 'echo --stdout-env $varName', + verbose: false, + )).outText.trim(); expect(output, expected); } diff --git a/packages/process_run/test/src/compile_echo.dart b/packages/process_run/test/src/compile_echo.dart index 843690f..3126368 100644 --- a/packages/process_run/test/src/compile_echo.dart +++ b/packages/process_run/test/src/compile_echo.dart @@ -9,8 +9,9 @@ var _echoVersionOk = false; /// Return the executable path. Future compileEchoExample({bool force = false}) async { - var folder = - Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); + var folder = Platform.isWindows + ? 'windows' + : (Platform.isMacOS ? 'macos' : 'linux'); var exeExtension = Platform.isWindows ? '.exe' : ''; var echoExePath = join('build', folder, 'process_run_echo$exeExtension'); var echoExeDir = dirname(echoExePath); diff --git a/packages/process_run/test/src/compile_shell.dart b/packages/process_run/test/src/compile_shell.dart index 6058209..e34b361 100644 --- a/packages/process_run/test/src/compile_shell.dart +++ b/packages/process_run/test/src/compile_shell.dart @@ -7,8 +7,9 @@ import 'package:pub_semver/pub_semver.dart'; /// Return the executable path. Future compileShellBin({bool force = false}) async { - var folder = - Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); + var folder = Platform.isWindows + ? 'windows' + : (Platform.isMacOS ? 'macos' : 'linux'); var exeExtension = Platform.isWindows ? '.exe' : ''; var dsExePath = join('build', folder, 'ds$exeExtension'); var dsExeDir = dirname(dsExePath); diff --git a/packages/process_run/test/src/compile_streamer.dart b/packages/process_run/test/src/compile_streamer.dart index f6a372f..26272a3 100644 --- a/packages/process_run/test/src/compile_streamer.dart +++ b/packages/process_run/test/src/compile_streamer.dart @@ -9,8 +9,9 @@ var _streamerVersionOk = false; /// Return the executable path. Future compileStreamerExample({bool force = false}) async { - var folder = - Platform.isWindows ? 'windows' : (Platform.isMacOS ? 'macos' : 'linux'); + var folder = Platform.isWindows + ? 'windows' + : (Platform.isMacOS ? 'macos' : 'linux'); var exeExtension = Platform.isWindows ? '.exe' : ''; var exe = join('build', folder, 'process_run_streamer$exeExtension'); var exeDir = dirname(exe); diff --git a/packages/process_run/test/src/shell_impl_test.dart b/packages/process_run/test/src/shell_impl_test.dart index 00fb43a..0456b14 100644 --- a/packages/process_run/test/src/shell_impl_test.dart +++ b/packages/process_run/test/src/shell_impl_test.dart @@ -64,17 +64,17 @@ void main() { test('null HOME', () async { try { - var env = - Map.from(platformEnvironment) - ..remove('HOME') - ..remove('USERPROFILE') - ..remove('APPDATA'); + var env = Map.from(platformEnvironment) + ..remove('HOME') + ..remove('USERPROFILE') + ..remove('APPDATA'); platformEnvironment = env; expect(userHomePath, '~'); expect(userAppDataPath, join('~', '.config')); // echo differs on windows - var firstLine = - (await run("echo 'Hello world'")).first.stdout.toString().trim(); + var firstLine = (await run( + "echo 'Hello world'", + )).first.stdout.toString().trim(); if (Platform.isWindows) { // We have both on windows depending on the shell used expect(['"Hello world"', 'Hello world'], contains(firstLine)); @@ -109,8 +109,8 @@ void main() { () async { try { var flutterBinDirPath = dirname(localFlutterExecutablePath!); - platformEnvironment = - newEnvNoOverride()..paths.prepend(flutterBinDirPath); + platformEnvironment = newEnvNoOverride() + ..paths.prepend(flutterBinDirPath); // '/opt/app/flutter/dev/flutter/bin', // '/opt/app/flutter/dev/flutter/bin/cache/dart-sdk/bin' @@ -234,22 +234,19 @@ void main() { expect(userEnvironment['_TEKARTIK_PROCESS_RUN_TEST'], '1'); var shell = Shell(verbose: false); - var result = - (await shell.run( - '$echo --stdout-env PATH', - )).first.stdout.toString().trim(); + var result = (await shell.run( + '$echo --stdout-env PATH', + )).first.stdout.toString().trim(); expect(result, isNotEmpty); - result = - (await shell.run( - '$echo --stdout-env _dummy_that_will_never_exist', - )).first.stdout.toString().trim(); + result = (await shell.run( + '$echo --stdout-env _dummy_that_will_never_exist', + )).first.stdout.toString().trim(); expect(result, isEmpty); - result = - (await shell.run( - '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', - )).first.stdout.toString().trim(); + result = (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).first.stdout.toString().trim(); // Default environment is user environment expect(result, '1'); @@ -258,30 +255,27 @@ void main() { environment: platformEnvironment, includeParentEnvironment: false, ); - result = - (await shell.run( - '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', - )).first.stdout.toString().trim(); + result = (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).first.stdout.toString().trim(); expect(result, isEmpty); shell = Shell( verbose: false, environment: userEnvironment, includeParentEnvironment: false, ); - result = - (await shell.run( - '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', - )).first.stdout.toString().trim(); + result = (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).first.stdout.toString().trim(); expect(result, '1'); shell = Shell( verbose: false, environment: shellEnvironment, includeParentEnvironment: false, ); - result = - (await shell.run( - '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', - )).first.stdout.toString().trim(); + result = (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).first.stdout.toString().trim(); expect(result, '1'); shell = Shell( verbose: true, @@ -289,10 +283,9 @@ void main() { ); try { - var lines = - (await shell.run( - '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', - )).outLines; + var lines = (await shell.run( + '$echo --stdout-env _TEKARTIK_PROCESS_RUN_TEST', + )).outLines; result = lines.last; expect(result, '78910', reason: lines.join('\n')); } catch (e) { diff --git a/packages/process_run/test/src_user_config_test.dart b/packages/process_run/test/src_user_config_test.dart index bd534f4..477c331 100644 --- a/packages/process_run/test/src_user_config_test.dart +++ b/packages/process_run/test/src_user_config_test.dart @@ -82,10 +82,9 @@ void main() { ...getExpectedPartPaths(newEnvNoOverride()), 'my_path', ]); - var shEnv = - ShellEnvironment.empty() - ..paths.addAll(userConfig.paths) - ..vars.addAll(userConfig.vars); + var shEnv = ShellEnvironment.empty() + ..paths.addAll(userConfig.paths) + ..vars.addAll(userConfig.vars); expect(shEnv['TEKARTIK_PROCESS_RUN_USER_ENV_FILE_PATH'], path); expect(shEnv['test'], '1'); expect( @@ -95,10 +94,9 @@ void main() { }); test('config no overload', () async { - var env = - Map.from(platformEnvironment) - ..[userEnvFilePathEnvKey] = dummyEnvPath1 - ..[localEnvFilePathEnvKey] = dummyEnvPath1; + var env = Map.from(platformEnvironment) + ..[userEnvFilePathEnvKey] = dummyEnvPath1 + ..[localEnvFilePathEnvKey] = dummyEnvPath1; var userConfig = getUserConfig(env); expect( From 87c5a11d75d93e283f2595b12bca2d5b4c5d30de Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Mon, 18 Aug 2025 11:14:40 +0200 Subject: [PATCH 146/150] dart 3.9 support --- packages/process_run/pubspec.yaml | 2 +- packages/process_run_test/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/process_run/pubspec.yaml b/packages/process_run/pubspec.yaml index 8de1355..b8d0721 100644 --- a/packages/process_run/pubspec.yaml +++ b/packages/process_run/pubspec.yaml @@ -4,7 +4,7 @@ description: Process run helpers for Linux/Win/Mac and which like feature for fi homepage: https://github.com/tekartik/process_run.dart/blob/master/packages/process_run environment: - sdk: ^3.8.0 + sdk: ^3.9.0 dependencies: path: ">=1.8.0 <3.0.0" diff --git a/packages/process_run_test/pubspec.yaml b/packages/process_run_test/pubspec.yaml index 94c662b..9744754 100644 --- a/packages/process_run_test/pubspec.yaml +++ b/packages/process_run_test/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.0.0 publish_to: none environment: - sdk: ^3.8.0 + sdk: ^3.9.0 # Add regular dependencies here. dependencies: From 3dcb3d806ec571f47bb0ef5ecc3856ce2925926f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Sep 2025 11:53:40 +0000 Subject: [PATCH 147/150] build(deps): bump actions/checkout from 4 to 5 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/run_ci.yml | 2 +- .github/workflows/run_ci_downgrade_analyze.yml | 2 +- .github/workflows/run_ci_flutter.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index c52b788..5d8c040 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -30,7 +30,7 @@ jobs: - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: dart --version - run: dart pub global activate dev_build - run: dart pub global run dev_build:run_ci \ No newline at end of file diff --git a/.github/workflows/run_ci_downgrade_analyze.yml b/.github/workflows/run_ci_downgrade_analyze.yml index 141f478..1e72714 100644 --- a/.github/workflows/run_ci_downgrade_analyze.yml +++ b/.github/workflows/run_ci_downgrade_analyze.yml @@ -20,7 +20,7 @@ jobs: - os: ubuntu-latest dart: stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} diff --git a/.github/workflows/run_ci_flutter.yml b/.github/workflows/run_ci_flutter.yml index e3e7aea..009c0e3 100644 --- a/.github/workflows/run_ci_flutter.yml +++ b/.github/workflows/run_ci_flutter.yml @@ -25,7 +25,7 @@ jobs: - os: macos-latest flutter: stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: actions/setup-java@v4 with: distribution: 'zulu' From 44b6246ee82c93b53a22173554e2f7a2b1523974 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Tue, 2 Sep 2025 14:46:57 +0200 Subject: [PATCH 148/150] fix git actions --- .github/workflows/run_ci.yml | 2 +- .github/workflows/run_ci_downgrade_analyze.yml | 2 +- .github/workflows/run_ci_flutter.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run_ci.yml b/.github/workflows/run_ci.yml index c52b788..5d8c040 100644 --- a/.github/workflows/run_ci.yml +++ b/.github/workflows/run_ci.yml @@ -30,7 +30,7 @@ jobs: - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - run: dart --version - run: dart pub global activate dev_build - run: dart pub global run dev_build:run_ci \ No newline at end of file diff --git a/.github/workflows/run_ci_downgrade_analyze.yml b/.github/workflows/run_ci_downgrade_analyze.yml index 141f478..1e72714 100644 --- a/.github/workflows/run_ci_downgrade_analyze.yml +++ b/.github/workflows/run_ci_downgrade_analyze.yml @@ -20,7 +20,7 @@ jobs: - os: ubuntu-latest dart: stable steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: dart-lang/setup-dart@v1.4 with: sdk: ${{ matrix.dart }} diff --git a/.github/workflows/run_ci_flutter.yml b/.github/workflows/run_ci_flutter.yml index e3e7aea..9685573 100644 --- a/.github/workflows/run_ci_flutter.yml +++ b/.github/workflows/run_ci_flutter.yml @@ -25,8 +25,8 @@ jobs: - os: macos-latest flutter: stable steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@v5 + - uses: actions/setup-java@v5 with: distribution: 'zulu' java-version: '17.x' From 763baa95895c3778dc147c14e03fa505b9ea7f76 Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 7 Nov 2025 15:59:59 +0100 Subject: [PATCH 149/150] fix: update kDartIsWeb environment variable to use 'dart.library.js_interop' --- packages/process_run/lib/src/env_utils.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/process_run/lib/src/env_utils.dart b/packages/process_run/lib/src/env_utils.dart index e88a3d6..7f14f18 100644 --- a/packages/process_run/lib/src/env_utils.dart +++ b/packages/process_run/lib/src/env_utils.dart @@ -23,4 +23,4 @@ bool get isDebug => !isRelease; const isRunningAsJavascript = identical(1, 1.0); /// Borrowed from flutter (isRunningAsJavascript is false in wasm) -const bool kDartIsWeb = bool.fromEnvironment('dart.library.js_util'); +const bool kDartIsWeb = bool.fromEnvironment('dart.library.js_interop'); From 76547e6f29248303fbd8e88923d9797b16fc87ce Mon Sep 17 00:00:00 2001 From: Alexandre Roux Date: Fri, 7 Nov 2025 16:23:58 +0100 Subject: [PATCH 150/150] chore: update analysis options and linter rules --- packages/process_run/analysis_options.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/process_run/analysis_options.yaml b/packages/process_run/analysis_options.yaml index 053e286..9a32b80 100644 --- a/packages/process_run/analysis_options.yaml +++ b/packages/process_run/analysis_options.yaml @@ -33,8 +33,6 @@ linter: - directives_ordering - implicit_reopen - invalid_case_patterns - - iterable_contains_unrelated_type - - list_remove_unrelated_type - no_adjacent_strings_in_list - no_literal_bool_comparisons - no_self_assignments