Skip to content

Commit 40e74a6

Browse files
committed
refactor(tweaks): migrate to generated CLI commands
replaces hand-written Command boilerplate with the new CliCommandGenerator. The generator reads annotations on the abstract service layers and their methods, and produces Command subclasses automatically at build time. Services are injected: `addSubcommand(SecurityServiceCliCommand(const SecurityServiceImpl()));` currently used for 'lib/features/tweaks' features - PlaybookPatchesCommand renamed to TweaksPatchesCommand - refactor enum based methods (notifications, service grouping)
1 parent 4cffa1e commit 40e74a6

25 files changed

Lines changed: 2070 additions & 414 deletions

src/build.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,17 @@ targets:
55
enabled: true
66
generate_for:
77
- lib/i18n/*.i18n.json
8+
revitool|cli_command_builder:
9+
enabled: true
10+
generate_for:
11+
- lib/**.dart
12+
- test/core/cli_generator/**.dart
13+
14+
builders:
15+
cli_command_builder:
16+
import: "package:revitool/core/cli_generator/builder.dart"
17+
builder_factories: ["cliCommandBuilder"]
18+
build_extensions: {".dart": [".cli_command.g.part"]}
19+
auto_apply: dependents
20+
build_to: cache
21+
applies_builders: ["source_gen|combining_builder"]
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
export 'package:args/command_runner.dart';
2+
export '../../utils.dart';
3+
4+
/// Marks an abstract service as a generated CLI command group.
5+
///
6+
/// The generator creates `XxxCliCommand` with this [name] and [description].
7+
class CliCommand {
8+
const CliCommand({required this.name, required this.description});
9+
10+
final String name;
11+
final String description;
12+
}
13+
14+
/// Marks a boolean status getter that has enable/disable companion methods.
15+
///
16+
/// Requires explicit [enable], [disable], and [status] method names (as strings).
17+
/// Optional [enableForce] and [disableForce] for --force flag support.
18+
///
19+
/// Example:
20+
/// ```dart
21+
/// @CliToggle(
22+
/// name: 'example',
23+
/// status: 'statusExample',
24+
/// enable: 'enableExample',
25+
/// disable: 'disableExample',
26+
/// )
27+
/// bool get statusExample;
28+
/// ```
29+
class CliToggle {
30+
const CliToggle({
31+
required this.name,
32+
required this.status,
33+
required this.enable,
34+
required this.disable,
35+
this.enableForce,
36+
this.disableForce,
37+
});
38+
39+
final String name;
40+
final String status;
41+
final String enable;
42+
final String disable;
43+
final String? enableForce;
44+
final String? disableForce;
45+
}
46+
47+
/// Marks a getter that returns a value and has a setter method.
48+
///
49+
/// Generates a status command to get the value and a set command to modify it.
50+
/// Requires explicit [status] and [set] method names (as strings).
51+
///
52+
/// Example:
53+
/// ```dart
54+
/// @CliValue(
55+
/// name: 'rate-limit',
56+
/// status: 'statusRateLimit',
57+
/// set: 'setRateLimit',
58+
/// )
59+
/// int get statusRateLimit;
60+
/// ```
61+
class CliValue {
62+
const CliValue({required this.name, required this.status, this.set});
63+
64+
final String name;
65+
final String status;
66+
final String? set;
67+
}
68+
69+
/// Marks an action-only method that runs once and does not expose status.
70+
///
71+
/// Requires explicit [run] method name (as string).
72+
///
73+
/// Example:
74+
/// ```dart
75+
/// @CliAction(name: 'update-kgl', run: 'updateKGL')
76+
/// Future<void> updateKGL();
77+
/// ```
78+
class CliAction {
79+
const CliAction({required this.name, required this.run});
80+
81+
final String name;
82+
final String run;
83+
}
84+
85+
/// Marks an enum-based command group.
86+
///
87+
/// Use [values] from your enum and optional [help] for `allowedHelp` labels.
88+
/// [argName] controls the option name used by generated enum commands and
89+
/// defaults to `mode`.
90+
class CliEnumSubCommand<T extends Enum> {
91+
const CliEnumSubCommand({
92+
required this.name,
93+
required this.values,
94+
this.argName = 'mode',
95+
required this.status,
96+
this.enableMethod,
97+
this.disableMethod,
98+
this.setMethod,
99+
this.help = const {},
100+
});
101+
102+
final String name;
103+
final List<T> values;
104+
final String argName;
105+
final String status;
106+
final String? enableMethod;
107+
final String? disableMethod;
108+
final String? setMethod;
109+
final Map<String, String> help;
110+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import 'package:build/build.dart';
2+
import 'package:source_gen/source_gen.dart';
3+
4+
import 'src/cli_command_generator.dart';
5+
6+
Builder cliCommandBuilder(BuilderOptions options) {
7+
return SharedPartBuilder([CliCommandGenerator()], 'cli_command_builder');
8+
}

0 commit comments

Comments
 (0)