Skip to content

Commit b0de9cf

Browse files
committed
feat: add subfolder support to delete commands
Applied the same subdirectory parsing logic from create commands to all delete commands, ensuring consistent handling of subfolder paths. Changes: - Modified 4 delete command files to parse and handle subfolder paths - Files updated: * delete_view_command.dart * delete_service_command.dart * delete_dialog_command.dart * delete_bottomsheet_command.dart Implementation: - Parse input path (e.g., 'test/dashboard') to extract subfolder and name - Pass subfolder parameter to getTemplateOutputPath() calls - Updated method signatures to accept optional subfolder parameter - Added documentation for subfolder parameters Before: stacked delete view test/dashboard → Error: PathNotFoundException: 'lib/ui/views/test_dashboard/' ❌ After: stacked delete view test/dashboard → Deletes 'lib/ui/views/test/dashboard/' ✅ This completes the subdirectory support feature, making create and delete commands symmetric.
1 parent 1917a42 commit b0de9cf

4 files changed

Lines changed: 140 additions & 31 deletions

File tree

lib/src/commands/delete/delete_bottomsheet_command.dart

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,15 @@ class DeleteBottomsheetCommand extends Command with ProjectStructureValidator {
5757
try {
5858
final workingDirectory =
5959
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
60-
final bottomsheetName = argResults!.rest.first;
60+
61+
// Parse bottomsheet path to support subdirectories
62+
final bottomsheetPath = argResults!.rest.first;
63+
final pathParts = bottomsheetPath.split('/');
64+
final bottomsheetName = pathParts.last;
65+
final subfolder = pathParts.length > 1
66+
? pathParts.sublist(0, pathParts.length - 1).join('/')
67+
: null;
68+
6169
await _configService.composeAndLoadConfigFile(
6270
configFilePath: argResults![ksConfigPath],
6371
projectPath: workingDirectory,
@@ -67,9 +75,13 @@ class DeleteBottomsheetCommand extends Command with ProjectStructureValidator {
6775

6876
await validateStructure(outputPath: workingDirectory);
6977
await _deletebottomsheet(
70-
outputPath: workingDirectory, bottomsheetName: bottomsheetName);
78+
outputPath: workingDirectory,
79+
bottomsheetName: bottomsheetName,
80+
subfolder: subfolder);
7181
await _removebottomsheetFromDependency(
72-
outputPath: workingDirectory, bottomsheetName: bottomsheetName);
82+
outputPath: workingDirectory,
83+
bottomsheetName: bottomsheetName,
84+
subfolder: subfolder);
7385
await _processService.runBuildRunner(workingDirectory: workingDirectory);
7486
await _analyticsService.deleteBottomsheetEvent(
7587
name: argResults!.rest.first,
@@ -98,12 +110,18 @@ class DeleteBottomsheetCommand extends Command with ProjectStructureValidator {
98110
/// `outputPath` (String): The path to the output folder.
99111
///
100112
/// `bottomsheetName` (String): The name of the bottomsheet.
101-
Future<void> _deletebottomsheet(
102-
{String? outputPath, required String bottomsheetName}) async {
113+
///
114+
/// `subfolder` (String): Optional subfolder path for organized bottomsheets.
115+
Future<void> _deletebottomsheet({
116+
String? outputPath,
117+
required String bottomsheetName,
118+
String? subfolder,
119+
}) async {
103120
/// Deleting the bottomsheet folder.
104121
String directoryPath = _templateService.getTemplateOutputPath(
105122
inputTemplatePath: 'lib/ui/bottom_sheets/generic',
106123
name: bottomsheetName,
124+
subfolder: subfolder,
107125
outputFolder: outputPath,
108126
);
109127
await _fileService.deleteFolder(directoryPath: directoryPath);
@@ -112,6 +130,7 @@ class DeleteBottomsheetCommand extends Command with ProjectStructureValidator {
112130
final filePath = _templateService.getTemplateOutputPath(
113131
inputTemplatePath: kBottomSheetEmptyTemplateGenericSheetModelTestPath,
114132
name: bottomsheetName,
133+
subfolder: subfolder,
115134
outputFolder: outputPath,
116135
);
117136

@@ -128,11 +147,17 @@ class DeleteBottomsheetCommand extends Command with ProjectStructureValidator {
128147
/// `outputPath` (String): The path to the output folder.
129148
///
130149
/// `bottomsheetName` (String): The name of the bottomsheet.
131-
Future<void> _removebottomsheetFromDependency(
132-
{String? outputPath, required String bottomsheetName}) async {
150+
///
151+
/// `subfolder` (String): Optional subfolder path for organized bottomsheets.
152+
Future<void> _removebottomsheetFromDependency({
153+
String? outputPath,
154+
required String bottomsheetName,
155+
String? subfolder,
156+
}) async {
133157
String filePath = _templateService.getTemplateOutputPath(
134158
inputTemplatePath: kAppMobileTemplateAppPath,
135159
name: bottomsheetName,
160+
subfolder: subfolder,
136161
outputFolder: outputPath,
137162
);
138163
await _fileService.removeSpecificFileLines(

lib/src/commands/delete/delete_dialog_command.dart

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,30 @@ class DeleteDialogCommand extends Command with ProjectStructureValidator {
5757
try {
5858
final workingDirectory =
5959
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
60-
final dialogName = argResults!.rest.first;
60+
61+
// Parse dialog path to support subdirectories
62+
final dialogPath = argResults!.rest.first;
63+
final pathParts = dialogPath.split('/');
64+
final dialogName = pathParts.last;
65+
final subfolder = pathParts.length > 1
66+
? pathParts.sublist(0, pathParts.length - 1).join('/')
67+
: null;
68+
6169
await _configService.composeAndLoadConfigFile(
6270
configFilePath: argResults![ksConfigPath],
6371
projectPath: workingDirectory,
6472
);
6573
_processService.formattingLineLength = argResults?[ksLineLength];
6674
await _pubspecService.initialise(workingDirectory: workingDirectory);
6775
await validateStructure(outputPath: workingDirectory);
68-
await _deleteDialog(outputPath: workingDirectory, dialogName: dialogName);
76+
await _deleteDialog(
77+
outputPath: workingDirectory,
78+
dialogName: dialogName,
79+
subfolder: subfolder);
6980
await _removeDialogFromDependency(
70-
outputPath: workingDirectory, dialogName: dialogName);
81+
outputPath: workingDirectory,
82+
dialogName: dialogName,
83+
subfolder: subfolder);
7184
await _processService.runBuildRunner(workingDirectory: workingDirectory);
7285
await _analyticsService.deleteDialogEvent(
7386
name: argResults!.rest.first,
@@ -96,12 +109,18 @@ class DeleteDialogCommand extends Command with ProjectStructureValidator {
96109
/// `outputPath` (String): The path to the output folder.
97110
///
98111
/// `dialogName` (String): The name of the dialog.
99-
Future<void> _deleteDialog(
100-
{String? outputPath, required String dialogName}) async {
112+
///
113+
/// `subfolder` (String): Optional subfolder path for organized dialogs.
114+
Future<void> _deleteDialog({
115+
String? outputPath,
116+
required String dialogName,
117+
String? subfolder,
118+
}) async {
101119
/// Deleting the dialog folder.
102120
String directoryPath = _templateService.getTemplateOutputPath(
103121
inputTemplatePath: 'lib/ui/dialogs/generic',
104122
name: dialogName,
123+
subfolder: subfolder,
105124
outputFolder: outputPath,
106125
);
107126
await _fileService.deleteFolder(directoryPath: directoryPath);
@@ -110,6 +129,7 @@ class DeleteDialogCommand extends Command with ProjectStructureValidator {
110129
final filePath = _templateService.getTemplateOutputPath(
111130
inputTemplatePath: kDialogEmptyTemplateGenericDialogModelTestPath,
112131
name: dialogName,
132+
subfolder: subfolder,
113133
outputFolder: outputPath,
114134
);
115135

@@ -126,11 +146,17 @@ class DeleteDialogCommand extends Command with ProjectStructureValidator {
126146
/// `outputPath` (String): The path to the output folder.
127147
///
128148
/// `dialogName` (String): The name of the dialog.
129-
Future<void> _removeDialogFromDependency(
130-
{String? outputPath, required String dialogName}) async {
149+
///
150+
/// `subfolder` (String): Optional subfolder path for organized dialogs.
151+
Future<void> _removeDialogFromDependency({
152+
String? outputPath,
153+
required String dialogName,
154+
String? subfolder,
155+
}) async {
131156
String filePath = _templateService.getTemplateOutputPath(
132157
inputTemplatePath: kAppMobileTemplateAppPath,
133158
name: dialogName,
159+
subfolder: subfolder,
134160
outputFolder: outputPath,
135161
);
136162
await _fileService.removeSpecificFileLines(

lib/src/commands/delete/delete_service_command.dart

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,15 @@ class DeleteServiceCommand extends Command with ProjectStructureValidator {
5656
try {
5757
final workingDirectory =
5858
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
59-
final serviceName = argResults!.rest.first;
59+
60+
// Parse service path to support subdirectories
61+
final servicePath = argResults!.rest.first;
62+
final pathParts = servicePath.split('/');
63+
final serviceName = pathParts.last;
64+
final subfolder = pathParts.length > 1
65+
? pathParts.sublist(0, pathParts.length - 1).join('/')
66+
: null;
67+
6068
await _configService.composeAndLoadConfigFile(
6169
configFilePath: argResults![ksConfigPath],
6270
projectPath: workingDirectory,
@@ -65,11 +73,17 @@ class DeleteServiceCommand extends Command with ProjectStructureValidator {
6573
await _pubspecService.initialise(workingDirectory: workingDirectory);
6674
await validateStructure(outputPath: workingDirectory);
6775
await _deleteServiceAndTestFiles(
68-
outputPath: workingDirectory, serviceName: serviceName);
76+
outputPath: workingDirectory,
77+
serviceName: serviceName,
78+
subfolder: subfolder);
6979
await _removeServiceFromTestHelper(
70-
outputPath: workingDirectory, serviceName: serviceName);
80+
outputPath: workingDirectory,
81+
serviceName: serviceName,
82+
subfolder: subfolder);
7183
await _removeServiceFromDependency(
72-
outputPath: workingDirectory, serviceName: serviceName);
84+
outputPath: workingDirectory,
85+
serviceName: serviceName,
86+
subfolder: subfolder);
7387
await _processService.runBuildRunner(workingDirectory: workingDirectory);
7488
await _analyticsService.deleteServiceEvent(
7589
name: argResults!.rest.first,
@@ -92,12 +106,18 @@ class DeleteServiceCommand extends Command with ProjectStructureValidator {
92106
/// `outputPath` (String): The path to the output folder.
93107
///
94108
/// `serviceName` (String): The name of the service to be deleted.
95-
Future<void> _deleteServiceAndTestFiles(
96-
{String? outputPath, required String serviceName}) async {
109+
///
110+
/// `subfolder` (String): Optional subfolder path for organized services.
111+
Future<void> _deleteServiceAndTestFiles({
112+
String? outputPath,
113+
required String serviceName,
114+
String? subfolder,
115+
}) async {
97116
/// Deleting the service file.
98117
String filePath = _templateService.getTemplateOutputPath(
99118
inputTemplatePath: kServiceEmptyTemplateGenericServicePath,
100119
name: serviceName,
120+
subfolder: subfolder,
101121
outputFolder: outputPath,
102122
);
103123
await _fileService.deleteFile(filePath: filePath);
@@ -106,6 +126,7 @@ class DeleteServiceCommand extends Command with ProjectStructureValidator {
106126
filePath = _templateService.getTemplateOutputPath(
107127
inputTemplatePath: kServiceEmptyTemplateGenericServiceTestPath,
108128
name: serviceName,
129+
subfolder: subfolder,
109130
outputFolder: outputPath,
110131
);
111132
await _fileService.deleteFile(filePath: filePath);
@@ -118,11 +139,17 @@ class DeleteServiceCommand extends Command with ProjectStructureValidator {
118139
/// `outputPath` (String): The path to the output folder.
119140
///
120141
/// `serviceName` (String): The name of the service to be deleted.
121-
Future<void> _removeServiceFromTestHelper(
122-
{String? outputPath, required String serviceName}) async {
142+
///
143+
/// `subfolder` (String): Optional subfolder path for organized services.
144+
Future<void> _removeServiceFromTestHelper({
145+
String? outputPath,
146+
required String serviceName,
147+
String? subfolder,
148+
}) async {
123149
String filePath = _templateService.getTemplateOutputPath(
124150
inputTemplatePath: kAppMobileTemplateTestHelpersPath,
125151
name: serviceName,
152+
subfolder: subfolder,
126153
outputFolder: outputPath,
127154
);
128155
await _fileService.removeSpecificFileLines(
@@ -139,11 +166,17 @@ class DeleteServiceCommand extends Command with ProjectStructureValidator {
139166
/// `outputPath` (String): The path to the output folder.
140167
///
141168
/// `serviceName` (String): The name of the service to be deleted.
142-
Future<void> _removeServiceFromDependency(
143-
{String? outputPath, required String serviceName}) async {
169+
///
170+
/// `subfolder` (String): Optional subfolder path for organized services.
171+
Future<void> _removeServiceFromDependency({
172+
String? outputPath,
173+
required String serviceName,
174+
String? subfolder,
175+
}) async {
144176
String filePath = _templateService.getTemplateOutputPath(
145177
inputTemplatePath: kAppMobileTemplateAppPath,
146178
name: serviceName,
179+
subfolder: subfolder,
147180
outputFolder: outputPath,
148181
);
149182
await _fileService.removeSpecificFileLines(

lib/src/commands/delete/delete_view_command.dart

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,15 @@ class DeleteViewCommand extends Command with ProjectStructureValidator {
5656
try {
5757
final workingDirectory =
5858
argResults!.rest.length > 1 ? argResults!.rest[1] : null;
59-
final viewName = argResults!.rest.first;
59+
60+
// Parse view path to support subdirectories
61+
final viewPath = argResults!.rest.first;
62+
final pathParts = viewPath.split('/');
63+
final viewName = pathParts.last;
64+
final subfolder = pathParts.length > 1
65+
? pathParts.sublist(0, pathParts.length - 1).join('/')
66+
: null;
67+
6068
await _configService.composeAndLoadConfigFile(
6169
configFilePath: argResults![ksConfigPath],
6270
projectPath: workingDirectory,
@@ -65,9 +73,13 @@ class DeleteViewCommand extends Command with ProjectStructureValidator {
6573
await _pubspecService.initialise(workingDirectory: workingDirectory);
6674
await validateStructure(outputPath: workingDirectory);
6775
await _deleteViewAndTestFiles(
68-
outputPath: workingDirectory, viewName: viewName);
76+
outputPath: workingDirectory,
77+
viewName: viewName,
78+
subfolder: subfolder);
6979
await _removeViewFromRoute(
70-
outputPath: workingDirectory, viewName: viewName);
80+
outputPath: workingDirectory,
81+
viewName: viewName,
82+
subfolder: subfolder);
7183
await _processService.runBuildRunner(workingDirectory: workingDirectory);
7284
await _analyticsService.deleteViewEvent(
7385
name: argResults!.rest.first,
@@ -90,12 +102,18 @@ class DeleteViewCommand extends Command with ProjectStructureValidator {
90102
/// `outputPath` (String): The path to the output folder.
91103
///
92104
/// `viewName` (String): The name of the view.
93-
Future<void> _deleteViewAndTestFiles(
94-
{String? outputPath, required String viewName}) async {
105+
///
106+
/// `subfolder` (String): Optional subfolder path for organized views.
107+
Future<void> _deleteViewAndTestFiles({
108+
String? outputPath,
109+
required String viewName,
110+
String? subfolder,
111+
}) async {
95112
/// Deleting the view folder.
96113
String directoryPath = _templateService.getTemplateOutputPath(
97114
inputTemplatePath: 'lib/ui/views/generic/',
98115
name: viewName,
116+
subfolder: subfolder,
99117
outputFolder: outputPath,
100118
);
101119
await _fileService.deleteFolder(directoryPath: directoryPath);
@@ -104,6 +122,7 @@ class DeleteViewCommand extends Command with ProjectStructureValidator {
104122
String filePath = _templateService.getTemplateOutputPath(
105123
inputTemplatePath: kViewEmptyTemplateGenericViewmodelTestPath,
106124
name: viewName,
125+
subfolder: subfolder,
107126
outputFolder: outputPath,
108127
);
109128
await _fileService.deleteFile(filePath: filePath);
@@ -116,11 +135,17 @@ class DeleteViewCommand extends Command with ProjectStructureValidator {
116135
/// `outputPath` (String): The path to the output folder.
117136
///
118137
/// `viewName` (String): The name of the view.
119-
Future<void> _removeViewFromRoute(
120-
{String? outputPath, required String viewName}) async {
138+
///
139+
/// `subfolder` (String): Optional subfolder path for organized views.
140+
Future<void> _removeViewFromRoute({
141+
String? outputPath,
142+
required String viewName,
143+
String? subfolder,
144+
}) async {
121145
String filePath = _templateService.getTemplateOutputPath(
122146
inputTemplatePath: kAppMobileTemplateAppPath,
123147
name: viewName,
148+
subfolder: subfolder,
124149
outputFolder: outputPath,
125150
);
126151
await _fileService.removeSpecificFileLines(

0 commit comments

Comments
 (0)