From 7d0ac570b2577b46ff4ac13f9168c8fef7554427 Mon Sep 17 00:00:00 2001 From: Craig Labenz Date: Wed, 27 Sep 2023 15:13:55 -0400 Subject: [PATCH] refactored command to `dart build` --- .../dart/{moveheaders => build}/.gitignore | 0 .../dart/{moveheaders => build}/CHANGELOG.md | 0 .../dart/{moveheaders => build}/README.md | 0 .../analysis_options.yaml | 0 mediapipe/dart/build/bin/args.dart | 8 ++ mediapipe/dart/build/bin/main.dart | 3 + mediapipe/dart/build/lib/repo_finder.dart | 89 +++++++++++++ mediapipe/dart/build/lib/sync_headers.dart | 117 ++++++++++++++++++ .../dart/{moveheaders => build}/pubspec.lock | 6 +- .../dart/{moveheaders => build}/pubspec.yaml | 4 +- .../dart/moveheaders/bin/moveheaders.dart | 53 -------- .../dart/moveheaders/lib/moveheaders.dart | 116 ----------------- .../moveheaders/test/moveheaders_test.dart | 4 - 13 files changed, 222 insertions(+), 178 deletions(-) rename mediapipe/dart/{moveheaders => build}/.gitignore (100%) rename mediapipe/dart/{moveheaders => build}/CHANGELOG.md (100%) rename mediapipe/dart/{moveheaders => build}/README.md (100%) rename mediapipe/dart/{moveheaders => build}/analysis_options.yaml (100%) create mode 100644 mediapipe/dart/build/bin/args.dart create mode 100644 mediapipe/dart/build/bin/main.dart create mode 100644 mediapipe/dart/build/lib/repo_finder.dart create mode 100644 mediapipe/dart/build/lib/sync_headers.dart rename mediapipe/dart/{moveheaders => build}/pubspec.lock (99%) rename mediapipe/dart/{moveheaders => build}/pubspec.yaml (69%) delete mode 100644 mediapipe/dart/moveheaders/bin/moveheaders.dart delete mode 100644 mediapipe/dart/moveheaders/lib/moveheaders.dart delete mode 100644 mediapipe/dart/moveheaders/test/moveheaders_test.dart diff --git a/mediapipe/dart/moveheaders/.gitignore b/mediapipe/dart/build/.gitignore similarity index 100% rename from mediapipe/dart/moveheaders/.gitignore rename to mediapipe/dart/build/.gitignore diff --git a/mediapipe/dart/moveheaders/CHANGELOG.md b/mediapipe/dart/build/CHANGELOG.md similarity index 100% rename from mediapipe/dart/moveheaders/CHANGELOG.md rename to mediapipe/dart/build/CHANGELOG.md diff --git a/mediapipe/dart/moveheaders/README.md b/mediapipe/dart/build/README.md similarity index 100% rename from mediapipe/dart/moveheaders/README.md rename to mediapipe/dart/build/README.md diff --git a/mediapipe/dart/moveheaders/analysis_options.yaml b/mediapipe/dart/build/analysis_options.yaml similarity index 100% rename from mediapipe/dart/moveheaders/analysis_options.yaml rename to mediapipe/dart/build/analysis_options.yaml diff --git a/mediapipe/dart/build/bin/args.dart b/mediapipe/dart/build/bin/args.dart new file mode 100644 index 000000000..eb3710033 --- /dev/null +++ b/mediapipe/dart/build/bin/args.dart @@ -0,0 +1,8 @@ +import 'package:args/command_runner.dart'; +import 'package:build/sync_headers.dart'; + +final runner = CommandRunner( + 'build', + 'Performs build operations for google/flutter-mediapipe that ' + 'depend on contents in this repository', +)..addCommand(SyncHeadersCommand()); diff --git a/mediapipe/dart/build/bin/main.dart b/mediapipe/dart/build/bin/main.dart new file mode 100644 index 000000000..30733f6e3 --- /dev/null +++ b/mediapipe/dart/build/bin/main.dart @@ -0,0 +1,3 @@ +import 'args.dart'; + +void main(List arguments) => runner.run(arguments); diff --git a/mediapipe/dart/build/lib/repo_finder.dart b/mediapipe/dart/build/lib/repo_finder.dart new file mode 100644 index 000000000..7d9a8fb35 --- /dev/null +++ b/mediapipe/dart/build/lib/repo_finder.dart @@ -0,0 +1,89 @@ +import 'dart:io' as io; +import 'package:args/args.dart'; +import 'package:args/command_runner.dart'; +import 'package:path/path.dart' as path; +import 'package:io/ansi.dart'; + +mixin RepoFinderMixin on Command { + void addDestinationOption(ArgParser argParser) { + argParser.addOption( + 'destination', + abbr: 'd', + help: 'The location of google/flutter-mediapipe. Defaults to being ' + 'adjacent to google/mediapipe.', + ); + } + + /// Looks upward for the root of the `google/mediapipe` repository. This assumes + /// the `dart build` command is executed from within said repository. If it is + /// not executed from within, then this searching algorithm will reach the root + /// of the file system, log the error, and exit. + io.Directory findMediaPipeRoot() { + io.Directory dir = io.Directory(path.current); + while (true) { + if (_isMediaPipeRoot(dir)) { + return dir; + } + dir = dir.parent; + if (dir.parent.path == dir.path) { + io.stderr.writeln( + wrapWith( + 'Failed to find google/mediapipe root directory. ' + 'Did you execute this command from within the repository?', + [red], + ), + ); + io.exit(1); + } + } + } + + /// Finds the `google/flutter-mediapipe` checkout where artifacts built in this + /// repository should be copied. By default, this command assumes the two + /// repositories are siblings on the file system, but the `--destination` flag + /// allows for this assumption to be overridden. + io.Directory findFlutterMediaPipeRoot( + io.Directory mediaPipeDir, + String? destination, + ) { + final flutterMediaPipeDirectory = io.Directory( + destination ?? + path.joinAll([ + mediaPipeDir.parent.absolute.path, + 'flutter-mediapipe', + ]), + ); + + if (!flutterMediaPipeDirectory.existsSync()) { + io.stderr.writeln( + 'Could not find ${flutterMediaPipeDirectory.absolute.path}. ' + 'Folder does not exist.', + ); + io.exit(1); + } + return flutterMediaPipeDirectory; + } +} + +/// Looks for 3 files/directories known to be at the root of the google/mediapipe +/// repository. This allows the `dart build` command to be run from various +/// locations within the `google/mediapipe` repository and still correctly set +/// paths for all of its operations. +bool _isMediaPipeRoot(io.Directory dir) { + final bazelrcExists = io.File( + path.joinAll( + [dir.absolute.path, '.bazelrc'], + ), + ).existsSync(); + final mediapipeExists = io.Directory( + path.joinAll( + [dir.absolute.path, 'mediapipe'], + ), + ).existsSync(); + final dotGitExists = io.Directory( + path.joinAll( + [dir.absolute.path, '.git'], + ), + ).existsSync(); + return bazelrcExists && mediapipeExists && dotGitExists; +} diff --git a/mediapipe/dart/build/lib/sync_headers.dart b/mediapipe/dart/build/lib/sync_headers.dart new file mode 100644 index 000000000..bfc656abd --- /dev/null +++ b/mediapipe/dart/build/lib/sync_headers.dart @@ -0,0 +1,117 @@ +import 'dart:convert'; +import 'dart:io' as io; +import 'package:args/command_runner.dart'; +import 'package:build/repo_finder.dart'; +import 'package:io/ansi.dart'; +import 'package:path/path.dart' as path; +import 'package:process/process.dart'; + +/// google/mediapipe paths +final containers = 'mediapipe/tasks/c/components/containers'; +final processors = 'mediapipe/tasks/c/components/processors'; +final originCore = 'mediapipe/tasks/c/core'; +final tc = 'mediapipe/tasks/c/text/text_classifier'; + +/// google/flutter-mediapipe paths +final core = 'packages/mediapipe-core/third_party/mediapipe/'; +final text = 'packages/mediapipe-task-text/third_party/mediapipe/'; + +/// First string is its location in this repository; +/// Second string is its location in `google/flutter-mediapipe`, +/// Third string is the file name +List<(String, String, String)> headerPaths = [ + (containers, core, 'category.h'), + (containers, core, 'classification_result.h'), + (originCore, core, 'base_options.h'), + (processors, core, 'classifier_options.h'), + (tc, text, 'text_classifier.h'), +]; + +class SyncHeadersCommand extends Command with RepoFinderMixin { + @override + String description = 'Syncs header files to google/flutter-mediapipe'; + @override + String name = 'sync'; + + SyncHeadersCommand() { + argParser.addFlag( + 'overwrite', + abbr: 'o', + defaultsTo: true, + help: 'If true, will overwrite existing header files ' + 'at destination locations.', + ); + addDestinationOption(argParser); + } + + @override + Future run() async { + final io.Directory mediaPipeDirectory = findMediaPipeRoot(); + final io.Directory flutterMediaPipeDirectory = findFlutterMediaPipeRoot( + mediaPipeDirectory, + argResults!['destination'], + ); + + final config = Options( + allowOverwrite: argResults!['overwrite'], + ); + + return moveHeaders( + mediaPipeDirectory, + flutterMediaPipeDirectory, + config, + ); + } + + Future moveHeaders( + io.Directory mediaPipe, + io.Directory flutterMediaPipe, + Options config, + ) async { + final mgr = LocalProcessManager(); + for (final tup in headerPaths) { + final headerFile = io.File(path.joinAll( + [mediaPipe.absolute.path, tup.$1, tup.$3], + )); + if (!headerFile.existsSync()) { + io.stderr.writeln( + 'Expected to find ${headerFile.path}, but ' + 'file does not exist.', + ); + io.exit(1); + } + final destinationPath = path.joinAll( + [flutterMediaPipe.absolute.path, tup.$2, tup.$3], + ); + if (io.File(destinationPath).existsSync() && !config.allowOverwrite) { + io.stdout.writeln( + 'Warning: Not overwriting existing file at $destinationPath. ' + 'Skipping ${tup.$3}.', + ); + continue; + } + + io.stderr.writeln(wrapWith('Moving ${tup.$3}', [green])); + final process = await mgr.start([ + 'cp', + headerFile.path, + destinationPath, + ]); + int processExitCode = await process.exitCode; + if (processExitCode != 0) { + final processStdErr = + utf8.decoder.convert(await process.stderr.drain()); + io.stderr.write(wrapWith(processStdErr, [red])); + io.exit(processExitCode); + } + } + } +} + +class Options { + const Options({ + required this.allowOverwrite, + }); + + final bool allowOverwrite; +} diff --git a/mediapipe/dart/moveheaders/pubspec.lock b/mediapipe/dart/build/pubspec.lock similarity index 99% rename from mediapipe/dart/moveheaders/pubspec.lock rename to mediapipe/dart/build/pubspec.lock index 82ce35b2f..3027d1003 100644 --- a/mediapipe/dart/moveheaders/pubspec.lock +++ b/mediapipe/dart/build/pubspec.lock @@ -18,7 +18,7 @@ packages: source: hosted version: "6.2.0" args: - dependency: transitive + dependency: "direct main" description: name: args sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 @@ -114,7 +114,7 @@ packages: source: hosted version: "4.0.2" io: - dependency: transitive + dependency: "direct main" description: name: io sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" @@ -138,7 +138,7 @@ packages: source: hosted version: "2.1.1" logging: - dependency: transitive + dependency: "direct main" description: name: logging sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" diff --git a/mediapipe/dart/moveheaders/pubspec.yaml b/mediapipe/dart/build/pubspec.yaml similarity index 69% rename from mediapipe/dart/moveheaders/pubspec.yaml rename to mediapipe/dart/build/pubspec.yaml index 0833a3d4b..87135d309 100644 --- a/mediapipe/dart/moveheaders/pubspec.yaml +++ b/mediapipe/dart/build/pubspec.yaml @@ -1,5 +1,5 @@ -name: moveheaders -description: A sample command-line application. +name: build +description: Performs build operations for google/flutter-mediapipe that depend on contents in this repository. version: 1.0.0 # repository: https://github.com/my_org/my_repo environment: diff --git a/mediapipe/dart/moveheaders/bin/moveheaders.dart b/mediapipe/dart/moveheaders/bin/moveheaders.dart deleted file mode 100644 index aa6f1d978..000000000 --- a/mediapipe/dart/moveheaders/bin/moveheaders.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'dart:io' as io; -import 'package:moveheaders/moveheaders.dart' as moveheaders; -import 'package:args/args.dart'; -import 'package:path/path.dart' as path; - -final parser = ArgParser() - ..addFlag( - 'overwrite', - abbr: 'o', - defaultsTo: true, - help: 'If true, will overwrite existing header files ' - 'at destination locations.', - ) - ..addOption( - 'destination', - abbr: 'd', - help: 'The location of google/flutter-mediapipe. Defaults to being ' - 'adjacent to google/mediapipe.', - ); - -void main(List arguments) { - final results = parser.parse(arguments); - final config = moveheaders.Options( - allowOverwrite: results['overwrite'], - ); - - final io.Directory mediaPipeDirectory = moveheaders.findMediaPipeRoot(); - - final passedDestination = - results['destination'] != null && results['destination'] != ''; - final flutterMediaPipeDirectory = io.Directory( - passedDestination - ? results['destination'] - : path.joinAll([ - mediaPipeDirectory.parent.absolute.path, - 'flutter-mediapipe', - ]), - ); - - if (!flutterMediaPipeDirectory.existsSync()) { - io.stderr.writeln( - 'Could not find ${flutterMediaPipeDirectory.absolute.path}. ' - 'Folder does not exist.', - ); - io.exit(1); - } - - moveheaders.moveHeaders( - mediaPipeDirectory, - flutterMediaPipeDirectory, - config, - ); -} diff --git a/mediapipe/dart/moveheaders/lib/moveheaders.dart b/mediapipe/dart/moveheaders/lib/moveheaders.dart deleted file mode 100644 index 78dfb48ad..000000000 --- a/mediapipe/dart/moveheaders/lib/moveheaders.dart +++ /dev/null @@ -1,116 +0,0 @@ -import 'dart:convert'; -import 'dart:io' as io; -import 'package:io/ansi.dart'; -import 'package:path/path.dart' as path; -import 'package:process/process.dart'; - -/// google/mediapipe paths -final containers = 'mediapipe/tasks/c/components/containers'; -final processors = 'mediapipe/tasks/c/components/processors'; -final originCore = 'mediapipe/tasks/c/core'; -final tc = 'mediapipe/tasks/c/text/text_classifier'; - -/// google/flutter-mediapipe paths -final core = 'packages/mediapipe-core/third_party/mediapipe/'; -final text = 'packages/mediapipe-task-text/third_party/mediapipe/'; - -/// First string is its location in this repository; -/// Second string is its location in `google/flutter-mediapipe`, -/// Third string is the file name -List<(String, String, String)> headerPaths = [ - (containers, core, 'category.h'), - (containers, core, 'classification_result.h'), - (originCore, core, 'base_options.h'), - (processors, core, 'classifier_options.h'), - (tc, text, 'text_classifier.h'), -]; - -class Options { - const Options({ - required this.allowOverwrite, - }); - - final bool allowOverwrite; -} - -Future moveHeaders( - io.Directory mediaPipe, - io.Directory flutterMediaPipe, - Options config, -) async { - final mgr = LocalProcessManager(); - for (final tup in headerPaths) { - final headerFile = io.File(path.joinAll( - [mediaPipe.absolute.path, tup.$1, tup.$3], - )); - if (!headerFile.existsSync()) { - io.stderr.writeln( - 'Expected to find ${headerFile.path}, but ' - 'file does not exist.', - ); - io.exit(1); - } - final destinationPath = path.joinAll( - [flutterMediaPipe.absolute.path, tup.$2, tup.$3], - ); - if (io.File(destinationPath).existsSync() && !config.allowOverwrite) { - io.stdout.writeln( - 'Warning: Not overwriting existing file at $destinationPath. ' - 'Skipping ${tup.$3}.', - ); - continue; - } - - io.stderr.writeln(wrapWith('Moving ${tup.$3}', [green])); - final process = await mgr.start([ - 'cp', - headerFile.path, - destinationPath, - ]); - int processExitCode = await process.exitCode; - if (processExitCode != 0) { - final processStdErr = utf8.decoder.convert(await process.stderr.drain()); - io.stderr.write(wrapWith(processStdErr, [red])); - io.exit(processExitCode); - } - } -} - -io.Directory findMediaPipeRoot() { - io.Directory dir = io.Directory(path.current); - while (true) { - if (isMediaPipeRoot(dir)) { - return dir; - } - dir = dir.parent; - if (dir.parent.path == dir.path) { - io.stderr.writeln( - wrapWith( - 'Failed to find google/mediapipe root directory. ' - 'Did you execute this command from within the repository?', - [red], - ), - ); - io.exit(1); - } - } -} - -bool isMediaPipeRoot(io.Directory dir) { - final bazelrcExists = io.File( - path.joinAll( - [dir.absolute.path, '.bazelrc'], - ), - ).existsSync(); - final mediapipeExists = io.Directory( - path.joinAll( - [dir.absolute.path, 'mediapipe'], - ), - ).existsSync(); - final dotGitExists = io.Directory( - path.joinAll( - [dir.absolute.path, '.git'], - ), - ).existsSync(); - return bazelrcExists && mediapipeExists && dotGitExists; -} diff --git a/mediapipe/dart/moveheaders/test/moveheaders_test.dart b/mediapipe/dart/moveheaders/test/moveheaders_test.dart deleted file mode 100644 index 7d319a0d1..000000000 --- a/mediapipe/dart/moveheaders/test/moveheaders_test.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:moveheaders/moveheaders.dart'; -import 'package:test/test.dart'; - -void main() {}