diff --git a/pkgs/puppy/README.md b/pkgs/puppy/README.md index b4305165..bd6c1c0c 100644 --- a/pkgs/puppy/README.md +++ b/pkgs/puppy/README.md @@ -1,3 +1,9 @@ +## What's this? + +A package for miscellaneous Dart CLI tools. + +### Running + Activate locally using: ```console @@ -7,5 +13,4 @@ dart pub global activate --source=path . ### Commands -- `run`: runs a command in every directory containing - `pubspec.yaml`. +- `run`: runs a command in every directory containing `pubspec.yaml`. diff --git a/pkgs/puppy/bin/puppy.dart b/pkgs/puppy/bin/puppy.dart index 50c87809..d8625e73 100755 --- a/pkgs/puppy/bin/puppy.dart +++ b/pkgs/puppy/bin/puppy.dart @@ -4,11 +4,11 @@ import 'package:args/command_runner.dart'; import 'package:puppy/src/constants.dart'; -import 'package:puppy/src/map_command.dart'; +import 'package:puppy/src/run_command.dart'; Future main(List args) async { var runner = CommandRunner(cmdName, 'Dart repository management tools.') - ..addCommand(MapCommand()); + ..addCommand(RunCommand()); await runner.run(args); } diff --git a/pkgs/puppy/lib/src/map_command.g.dart b/pkgs/puppy/lib/src/map_command.g.dart deleted file mode 100644 index a7d44e21..00000000 --- a/pkgs/puppy/lib/src/map_command.g.dart +++ /dev/null @@ -1,34 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'map_command.dart'; - -// ************************************************************************** -// CliGenerator -// ************************************************************************** - -MapArgs _$parseMapArgsResult(ArgResults result) => MapArgs( - deep: result['deep'] as bool, - rest: result.rest, - ); - -ArgParser _$populateMapArgsParser(ArgParser parser) => parser - ..addFlag( - 'deep', - abbr: 'd', - help: 'Keep looking for "nested" pubspec files.', - ); - -final _$parserForMapArgs = _$populateMapArgsParser(ArgParser()); - -MapArgs parseMapArgs(List args) { - final result = _$parserForMapArgs.parse(args); - return _$parseMapArgsResult(result); -} - -abstract class _$MapArgsCommand extends Command { - _$MapArgsCommand() { - _$populateMapArgsParser(argParser); - } - - late final _options = _$parseMapArgsResult(argResults!); -} diff --git a/pkgs/puppy/lib/src/map_command.dart b/pkgs/puppy/lib/src/run_command.dart similarity index 53% rename from pkgs/puppy/lib/src/map_command.dart rename to pkgs/puppy/lib/src/run_command.dart index 5713a78e..09352779 100644 --- a/pkgs/puppy/lib/src/map_command.dart +++ b/pkgs/puppy/lib/src/run_command.dart @@ -10,10 +10,11 @@ import 'package:build_cli_annotations/build_cli_annotations.dart'; import 'package:io/ansi.dart'; import 'constants.dart'; +import 'utils.dart'; -part 'map_command.g.dart'; +part 'run_command.g.dart'; -class MapCommand extends _$MapArgsCommand { +class RunCommand extends _$RunArgsCommand { @override String get description => 'Run the provided command in each subdirectory containing ' @@ -24,18 +25,39 @@ class MapCommand extends _$MapArgsCommand { @override Future? run() async { - await _doMap(_options); + final args = _options; + + final exe = args.rest.first; + final extraArgs = args.rest.skip(1).toList(); + + final packages = findPackages(Directory.current, deep: args.deep); + final exits = {}; + + for (final packageDir in packages) { + print(green.wrap(packageDir.path)); + final proc = await Process.start( + exe, + extraArgs, + mode: ProcessStartMode.inheritStdio, + workingDirectory: packageDir.path, + ); + + // TODO(kevmoo): display a summary of results on completion + exits[packageDir.path] = await proc.exitCode; + + print(''); + } } } @CliOptions(createCommand: true) -class MapArgs { +class RunArgs { @CliOption(abbr: 'd', help: 'Keep looking for "nested" pubspec files.') final bool deep; final List rest; - MapArgs({ + RunArgs({ this.deep = false, required this.rest, }) { @@ -47,42 +69,3 @@ class MapArgs { } } } - -Future _doMap(MapArgs args) async { - final exe = args.rest.first; - final extraArgs = args.rest.skip(1).toList(); - - final exits = {}; - - Future inspectDirectory(Directory dir, {required bool deep}) async { - final pubspecs = dir - .listSync() - .whereType() - .where((element) => element.uri.pathSegments.last == 'pubspec.yaml') - .toList(); - - final pubspecHere = pubspecs.isNotEmpty; - if (pubspecHere) { - print(green.wrap(dir.path)); - final proc = await Process.start( - exe, - extraArgs, - mode: ProcessStartMode.inheritStdio, - workingDirectory: dir.path, - ); - - // TODO(kevmoo): display a summary of results on completion - exits[dir.path] = await proc.exitCode; - } - - if (!pubspecHere || deep) { - for (var subDir in dir.listSync().whereType().where( - (element) => !element.uri.pathSegments - .any((element) => element.startsWith('.')))) { - await inspectDirectory(subDir, deep: deep); - } - } - } - - await inspectDirectory(Directory.current, deep: args.deep); -} diff --git a/pkgs/puppy/lib/src/run_command.g.dart b/pkgs/puppy/lib/src/run_command.g.dart new file mode 100644 index 00000000..469eec3f --- /dev/null +++ b/pkgs/puppy/lib/src/run_command.g.dart @@ -0,0 +1,34 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'run_command.dart'; + +// ************************************************************************** +// CliGenerator +// ************************************************************************** + +RunArgs _$parseRunArgsResult(ArgResults result) => RunArgs( + deep: result['deep'] as bool, + rest: result.rest, + ); + +ArgParser _$populateRunArgsParser(ArgParser parser) => parser + ..addFlag( + 'deep', + abbr: 'd', + help: 'Keep looking for "nested" pubspec files.', + ); + +final _$parserForRunArgs = _$populateRunArgsParser(ArgParser()); + +RunArgs parseRunArgs(List args) { + final result = _$parserForRunArgs.parse(args); + return _$parseRunArgsResult(result); +} + +abstract class _$RunArgsCommand extends Command { + _$RunArgsCommand() { + _$populateRunArgsParser(argParser); + } + + late final _options = _$parseRunArgsResult(argResults!); +} diff --git a/pkgs/puppy/lib/src/utils.dart b/pkgs/puppy/lib/src/utils.dart new file mode 100644 index 00000000..d9601352 --- /dev/null +++ b/pkgs/puppy/lib/src/utils.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +List findPackages(Directory root, {bool deep = false}) { + final results = []; + + void traverse(Directory dir, {required bool deep}) { + final pubspecs = dir + .listSync() + .whereType() + .where((element) => element.uri.pathSegments.last == 'pubspec.yaml') + .toList(); + + if (pubspecs.isNotEmpty) { + results.add(dir); + } + + if (!pubspecs.isNotEmpty || deep) { + for (var subDir in dir.listSync().whereType().where( + (element) => !element.uri.pathSegments + .any((element) => element.startsWith('.')))) { + traverse(subDir, deep: deep); + } + } + } + + traverse(Directory.current, deep: deep); + + return results; +} diff --git a/pkgs/puppy/pubspec.yaml b/pkgs/puppy/pubspec.yaml index 26a6d9db..9f649ad4 100644 --- a/pkgs/puppy/pubspec.yaml +++ b/pkgs/puppy/pubspec.yaml @@ -1,4 +1,5 @@ name: puppy +description: A package for miscellaneous Dart CLI tools. publish_to: none environment: