refactored command to dart build

This commit is contained in:
Craig Labenz 2023-09-27 15:13:55 -04:00
parent 40503acdec
commit 7d0ac570b2
13 changed files with 222 additions and 178 deletions

View File

@ -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());

View File

@ -0,0 +1,3 @@
import 'args.dart';
void main(List<String> arguments) => runner.run(arguments);

View File

@ -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;
}

View File

@ -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<void> 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<void> 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;
}

View File

@ -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"

View File

@ -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:

View File

@ -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<String> 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,
);
}

View File

@ -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<void> 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;
}

View File

@ -1,4 +0,0 @@
import 'package:moveheaders/moveheaders.dart';
import 'package:test/test.dart';
void main() {}