Skip to content

Commit 5c21c57

Browse files
Feature create many (#55)
* feat: allow multiple views in create view command * test: change executable name to allow comparison * fix: rollback last commit * chore(commands): added todo comment * feat(commands): allow creation of multiple items in create widget-, bottomsheet-, dialog-, and service command * feat(commands)!: change workingDir to a flag * Fixes version check change when running locally * Makes cli tool beta * Updates changelof * Bumps pubspec * Fixes pubspec warning --------- Co-authored-by: Dane Mackier <[email protected]>
1 parent e736a8e commit 5c21c57

10 files changed

+164
-104
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## 2.0.0-beta.0 (2024-10-17)
2+
3+
### Features
4+
5+
* Adds multi create functionality for views, services, dialogs and bottom sheets.
6+
7+
Example: stacked create view -t web login signup dashboard home profile settings
8+
9+
### Breaking Changes
10+
11+
The names of the objects being created has to be last, meaning we now have an enforced order due to the implementation of this feature.
12+
13+
Docs and error messages has to be updated to reflect this change.
14+
115
## [1.13.4](https://github.com/Stacked-Org/cli/compare/v1.13.3...v1.13.4) (2025-01-26)
216

317

@@ -19,6 +33,7 @@
1933

2034
* **actions:** allow tests to pass with warning ([#53](https://github.com/Stacked-Org/cli/issues/53)) ([bc00354](https://github.com/Stacked-Org/cli/commit/bc00354f878d84f37bd3d14803ccac7d798e78ed))
2135

36+
2237
## [1.13.1](https://github.com/Stacked-Org/cli/compare/v1.13.0...v1.13.1) (2024-07-02)
2338

2439

lib/src/commands/create/create_bottom_sheet_command.dart

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,39 +58,46 @@ class CreateBottomSheetCommand extends Command with ProjectStructureValidator {
5858
abbr: 'l',
5959
help: kCommandHelpLineLength,
6060
valueHelp: '80',
61+
)
62+
..addOption(
63+
ksProjectPath,
64+
help: kCommandHelpProjectPath,
6165
);
6266
}
6367

6468
@override
6569
Future<void> run() async {
6670
try {
67-
final bottomSheetName = argResults!.rest.first;
71+
final List<String> bottomSheetNames = argResults!.rest;
6872
final templateType = argResults![ksTemplateType];
69-
final workingDirectory =
70-
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
7173
await _configService.composeAndLoadConfigFile(
7274
configFilePath: argResults![ksConfigPath],
73-
projectPath: workingDirectory,
75+
projectPath: argResults![ksProjectPath],
7476
);
7577
_processService.formattingLineLength = argResults![ksLineLength];
76-
await _pubspecService.initialise(workingDirectory: workingDirectory);
77-
await validateStructure(outputPath: workingDirectory);
78+
await _pubspecService.initialise(
79+
workingDirectory: argResults![ksProjectPath]);
80+
await validateStructure(outputPath: argResults![ksProjectPath]);
7881

79-
await _templateService.renderTemplate(
80-
templateName: name,
81-
name: bottomSheetName,
82-
outputPath: workingDirectory,
83-
verbose: true,
84-
excludeRoute: argResults![ksExcludeRoute],
85-
hasModel: argResults![ksModel],
86-
templateType: templateType,
87-
);
82+
for (var i = 0; i < bottomSheetNames.length; i++) {
83+
await _templateService.renderTemplate(
84+
templateName: name,
85+
name: bottomSheetNames[i],
86+
outputPath: argResults![ksProjectPath],
87+
verbose: true,
88+
excludeRoute: argResults![ksExcludeRoute],
89+
hasModel: argResults![ksModel],
90+
templateType: templateType,
91+
);
8892

89-
await _processService.runBuildRunner(workingDirectory: workingDirectory);
90-
await _analyticsService.createBottomSheetEvent(
91-
name: bottomSheetName,
92-
arguments: argResults!.arguments,
93-
);
93+
await _analyticsService.createBottomSheetEvent(
94+
name: bottomSheetNames[i],
95+
arguments: argResults!.arguments,
96+
);
97+
}
98+
99+
await _processService.runBuildRunner(
100+
workingDirectory: argResults![ksProjectPath]);
94101
} catch (e, s) {
95102
_log.error(message: e.toString());
96103
unawaited(_analyticsService.logExceptionEvent(

lib/src/commands/create/create_dialog_command.dart

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,39 +58,46 @@ class CreateDialogCommand extends Command with ProjectStructureValidator {
5858
abbr: 'l',
5959
help: kCommandHelpLineLength,
6060
valueHelp: '80',
61+
)
62+
..addOption(
63+
ksProjectPath,
64+
help: kCommandHelpProjectPath,
6165
);
6266
}
6367

6468
@override
6569
Future<void> run() async {
6670
try {
67-
final dialogName = argResults!.rest.first;
71+
final List<String> dialogNames = argResults!.rest;
6872
final templateType = argResults![ksTemplateType];
69-
final workingDirectory =
70-
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
7173
await _configService.composeAndLoadConfigFile(
7274
configFilePath: argResults![ksConfigPath],
73-
projectPath: workingDirectory,
75+
projectPath: argResults![ksProjectPath],
7476
);
7577
_processService.formattingLineLength = argResults![ksLineLength];
76-
await _pubspecService.initialise(workingDirectory: workingDirectory);
77-
await validateStructure(outputPath: workingDirectory);
78+
await _pubspecService.initialise(
79+
workingDirectory: argResults![ksProjectPath]);
80+
await validateStructure(outputPath: argResults![ksProjectPath]);
7881

79-
await _templateService.renderTemplate(
80-
templateName: name,
81-
name: dialogName,
82-
outputPath: workingDirectory,
83-
verbose: true,
84-
excludeRoute: argResults![ksExcludeRoute],
85-
hasModel: argResults![ksModel],
86-
templateType: templateType,
87-
);
82+
for (var i = 0; i < dialogNames.length; i++) {
83+
await _templateService.renderTemplate(
84+
templateName: name,
85+
name: dialogNames[i],
86+
outputPath: argResults![ksProjectPath],
87+
verbose: true,
88+
excludeRoute: argResults![ksExcludeRoute],
89+
hasModel: argResults![ksModel],
90+
templateType: templateType,
91+
);
8892

89-
await _processService.runBuildRunner(workingDirectory: workingDirectory);
90-
await _analyticsService.createDialogEvent(
91-
name: dialogName,
92-
arguments: argResults!.arguments,
93-
);
93+
await _analyticsService.createDialogEvent(
94+
name: dialogNames[i],
95+
arguments: argResults!.arguments,
96+
);
97+
}
98+
99+
await _processService.runBuildRunner(
100+
workingDirectory: argResults![ksProjectPath]);
94101
} catch (e, s) {
95102
_log.error(message: e.toString());
96103
unawaited(_analyticsService.logExceptionEvent(

lib/src/commands/create/create_service_command.dart

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,37 +53,45 @@ class CreateServiceCommand extends Command with ProjectStructureValidator {
5353
abbr: 'l',
5454
help: kCommandHelpLineLength,
5555
valueHelp: '80',
56+
)
57+
..addOption(
58+
ksProjectPath,
59+
help: kCommandHelpProjectPath,
5660
);
5761
}
5862

5963
@override
6064
Future<void> run() async {
6165
try {
62-
final serviceName = argResults!.rest.first;
66+
final List<String> serviceNames = argResults!.rest;
6367
final templateType = argResults![ksTemplateType];
64-
final workingDirectory =
65-
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
6668
await _configService.composeAndLoadConfigFile(
6769
configFilePath: argResults![ksConfigPath],
68-
projectPath: workingDirectory,
70+
projectPath: argResults![ksProjectPath],
6971
);
7072
_processService.formattingLineLength = argResults?[ksLineLength];
71-
await _pubspecService.initialise(workingDirectory: workingDirectory);
72-
await validateStructure(outputPath: workingDirectory);
73+
await _pubspecService.initialise(
74+
workingDirectory: argResults![ksProjectPath]);
75+
await validateStructure(outputPath: argResults![ksProjectPath]);
7376

74-
await _templateService.renderTemplate(
75-
templateName: name,
76-
name: serviceName,
77-
outputPath: workingDirectory,
78-
verbose: true,
79-
excludeRoute: argResults![ksExcludeDependency],
80-
templateType: templateType,
81-
);
82-
await _processService.runBuildRunner(workingDirectory: workingDirectory);
83-
await _analyticsService.createServiceEvent(
84-
name: serviceName,
85-
arguments: argResults!.arguments,
86-
);
77+
for (var i = 0; i < serviceNames.length; i++) {
78+
await _templateService.renderTemplate(
79+
templateName: name,
80+
name: serviceNames[i],
81+
outputPath: argResults![ksProjectPath],
82+
verbose: true,
83+
excludeRoute: argResults![ksExcludeDependency],
84+
templateType: templateType,
85+
);
86+
87+
await _analyticsService.createServiceEvent(
88+
name: serviceNames[i],
89+
arguments: argResults!.arguments,
90+
);
91+
}
92+
93+
await _processService.runBuildRunner(
94+
workingDirectory: argResults![ksProjectPath]);
8795
} catch (e, s) {
8896
_log.error(message: e.toString());
8997
unawaited(_analyticsService.logExceptionEvent(

lib/src/commands/create/create_view_command.dart

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,26 @@ class CreateViewCommand extends Command with ProjectStructureValidator {
5858
abbr: 'l',
5959
help: kCommandHelpLineLength,
6060
valueHelp: '80',
61+
)
62+
..addOption(
63+
ksProjectPath,
64+
help: kCommandHelpProjectPath,
6165
);
6266
}
6367

6468
@override
6569
Future<void> run() async {
6670
try {
67-
final viewName = argResults!.rest.first;
71+
final List<String> viewNames = argResults!.rest;
6872
var templateType = argResults![ksTemplateType] as String?;
69-
final workingDirectory =
70-
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
7173
await _configService.composeAndLoadConfigFile(
7274
configFilePath: argResults![ksConfigPath],
73-
projectPath: workingDirectory,
75+
projectPath: argResults![ksProjectPath],
7476
);
7577
_processService.formattingLineLength = argResults![ksLineLength];
76-
await _pubspecService.initialise(workingDirectory: workingDirectory);
77-
await validateStructure(outputPath: workingDirectory);
78+
await _pubspecService.initialise(
79+
workingDirectory: argResults![ksProjectPath]);
80+
await validateStructure(outputPath: argResults![ksProjectPath]);
7881

7982
// Determine which template to use with the following rules:
8083
// 1. If the template is supplied we use that template
@@ -84,20 +87,25 @@ class CreateViewCommand extends Command with ProjectStructureValidator {
8487
// We assign this when it's not null so there should be no default value for this
8588
templateType ??= _configService.preferWeb ? 'web' : 'empty';
8689

87-
await _templateService.renderTemplate(
88-
templateName: name,
89-
name: viewName,
90-
outputPath: workingDirectory,
91-
verbose: true,
92-
excludeRoute: argResults![ksExcludeRoute],
93-
useBuilder: argResults![ksV1] ?? _configService.v1,
94-
templateType: templateType,
95-
);
96-
await _processService.runBuildRunner(workingDirectory: workingDirectory);
97-
await _analyticsService.createViewEvent(
98-
name: viewName,
99-
arguments: argResults!.arguments,
100-
);
90+
for (var i = 0; i < viewNames.length; i++) {
91+
await _templateService.renderTemplate(
92+
templateName: name,
93+
name: viewNames[i],
94+
outputPath: argResults![ksProjectPath],
95+
verbose: true,
96+
excludeRoute: argResults![ksExcludeRoute],
97+
useBuilder: argResults![ksV1] ?? _configService.v1,
98+
templateType: templateType,
99+
);
100+
101+
await _analyticsService.createViewEvent(
102+
name: viewNames[i],
103+
arguments: argResults!.arguments,
104+
);
105+
}
106+
107+
await _processService.runBuildRunner(
108+
workingDirectory: argResults![ksProjectPath]);
101109
} catch (e, s) {
102110
_log.error(message: e.toString());
103111
unawaited(_analyticsService.logExceptionEvent(

lib/src/commands/create/create_widget_command.dart

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,42 +57,46 @@ class CreateWidgetCommand extends Command with ProjectStructureValidator {
5757
abbr: 'l',
5858
help: kCommandHelpLineLength,
5959
valueHelp: '80',
60+
)
61+
..addOption(
62+
ksProjectPath,
63+
help: kCommandHelpProjectPath,
6064
);
6165
}
6266

6367
@override
6468
Future<void> run() async {
6569
try {
66-
final widgetName = argResults!.rest.first;
70+
final List<String> widgetNames = argResults!.rest;
6771
final templateType = argResults![ksTemplateType];
68-
final workingDirectory =
69-
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
70-
7172
// load configuration
7273
await _configService.composeAndLoadConfigFile(
7374
configFilePath: argResults![ksConfigPath],
74-
projectPath: workingDirectory,
75+
projectPath: argResults![ksProjectPath],
7576
);
7677
// override [widgets_path] value on configuration
7778
_configService.setWidgetsPath(argResults![ksPath]);
7879

7980
_processService.formattingLineLength = argResults![ksLineLength];
80-
await _pubspecService.initialise(workingDirectory: workingDirectory);
81-
await validateStructure(outputPath: workingDirectory);
81+
await _pubspecService.initialise(
82+
workingDirectory: argResults![ksProjectPath]);
83+
await validateStructure(outputPath: argResults![ksProjectPath]);
8284

83-
await _templateService.renderTemplate(
84-
templateName: name,
85-
name: widgetName,
86-
outputPath: workingDirectory,
87-
verbose: true,
88-
hasModel: argResults![ksModel],
89-
templateType: templateType,
90-
);
85+
for (var i = 0; i < widgetNames.length; i) {
86+
await _templateService.renderTemplate(
87+
templateName: name,
88+
name: widgetNames[i],
89+
outputPath: argResults![ksProjectPath],
90+
verbose: true,
91+
hasModel: argResults![ksModel],
92+
templateType: templateType,
93+
);
9194

92-
await _analyticsService.createWidgetEvent(
93-
name: widgetName,
94-
arguments: argResults!.arguments,
95-
);
95+
await _analyticsService.createWidgetEvent(
96+
name: widgetNames[i],
97+
arguments: argResults!.arguments,
98+
);
99+
}
96100
} catch (e, s) {
97101
_log.error(message: e.toString());
98102
unawaited(_analyticsService.logExceptionEvent(

lib/src/constants/command_constants.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/// Stores all the commands used throughout the app that
2+
library;
23

34
const String ksDart = 'dart';
45
const String ksFlutter = 'flutter';
@@ -34,6 +35,7 @@ const String ksAppMinimalTemplate = 'empty';
3435
const String ksAppDescription = 'description';
3536
const String ksAppOrganization = 'org';
3637
const String ksAppPlatforms = 'platforms';
38+
const String ksProjectPath = 'project-path';
3739

3840
/// A list of strings that are used to run the run build_runner
3941
/// [build or watch] --delete-conflicting-outputs command.

lib/src/constants/message_constants.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/// Stores all the messages used throughout the app that communicates
22
/// with the user of the package.
3+
library;
34

45
/// Message shown when we encounter a failure during generation that's caused by an invalid
56
/// app structure.
@@ -101,3 +102,7 @@ Stacked config file should be renamed from "stacked.config.json" to "stacked.jso
101102
const String kDeprecatedPaths = '''
102103
Paths on Stacked config do not need to start with directory "lib" or "test" because are mandatory directories, defined by the Flutter framework. Stacked cli will not accept paths starting with "lib" or "test" after the next minor release.
103104
''';
105+
106+
const String kCommandHelpProjectPath = '''
107+
When path is provided, it will be considered the project directory instead of the current directory.
108+
''';

0 commit comments

Comments
 (0)