11import 'dart:io' ;
2-
2+ import 'package:args/args.dart' ;
33import '../console/console.dart' ;
44import '../utils/process_runner.dart' ;
55
66/// Handles the "nylo clean" command
77/// Runs flutter clean followed by flutter pub get
8+ /// Supports --ios, --android, and --all flags for platform-specific deep cleaning
89class CleanCommand {
910 /// Execute the clean command
10- Future <void > run () async {
11+ Future <void > run ([List <String > arguments = const []]) async {
12+ final parser = ArgParser ()
13+ ..addFlag ('ios' , negatable: false , help: 'Deep clean iOS' )
14+ ..addFlag ('android' , negatable: false , help: 'Deep clean Android' )
15+ ..addFlag ('all' , negatable: false , help: 'Deep clean iOS and Android' );
16+
17+ final ArgResults results;
18+ try {
19+ results = parser.parse (arguments);
20+ } on FormatException catch (e) {
21+ NyloConsole .writeError (e.message);
22+ exit (1 );
23+ }
24+
25+ bool cleanIos = results['ios' ] as bool || results['all' ] as bool ;
26+ bool cleanAndroid = results['android' ] as bool || results['all' ] as bool ;
27+
28+ // Validate platform directories exist
29+ if (cleanIos && ! await Directory ('ios' ).exists ()) {
30+ NyloConsole .writeWarning ('ios/ directory not found. Skipping iOS clean.' );
31+ cleanIos = false ;
32+ }
33+ if (cleanAndroid && ! await Directory ('android' ).exists ()) {
34+ NyloConsole .writeWarning (
35+ 'android/ directory not found. Skipping Android clean.' );
36+ cleanAndroid = false ;
37+ }
38+
39+ // Calculate steps dynamically
40+ int totalSteps = 2 ; // flutter clean + flutter pub get
41+ if (cleanIos) totalSteps += 2 ; // rm artifacts + pod install
42+ if (cleanAndroid) totalSteps += 1 ; // gradlew clean
43+ int currentStep = 0 ;
44+ String stepLabel () {
45+ currentStep++ ;
46+ return '[$currentStep /$totalSteps ]' ;
47+ }
48+
1149 NyloConsole .writeBanner ();
1250 NyloConsole .write ('' );
1351 NyloConsole .writeInfo ('Cleaning project...' );
1452 NyloConsole .write ('' );
1553
16- // Step 1 : Run flutter clean
54+ // Step: Run flutter clean
1755 final cleanSpinner = Spinner ('' );
18- cleanSpinner.start ('[1/2] Running flutter clean...' );
56+ cleanSpinner.start ('${ stepLabel ()} Running flutter clean...' );
1957 final cleanResult = await ProcessRunner .run ('flutter' , ['clean' ]);
2058 cleanSpinner.stop ('flutter clean complete' );
2159
@@ -25,9 +63,57 @@ class CleanCommand {
2563 exit (1 );
2664 }
2765
28- // Step 2: Run flutter pub get
66+ // iOS deep clean
67+ if (cleanIos) {
68+ // Step: Remove iOS artifacts
69+ final rmSpinner = Spinner ('' );
70+ rmSpinner.start ('${stepLabel ()} Removing iOS build artifacts...' );
71+ await _removeIosArtifacts ();
72+ rmSpinner.stop ('iOS artifacts removed (Pods, .symlinks, Podfile.lock)' );
73+
74+ // Step: pod install --repo-update
75+ final podSpinner = Spinner ('' );
76+ podSpinner.start ('${stepLabel ()} Running pod install --repo-update...' );
77+ if (! Platform .isMacOS) {
78+ podSpinner.stop ('pod install skipped (not macOS)' );
79+ NyloConsole .writeWarning (
80+ 'pod install is only available on macOS. Skipping.' );
81+ } else {
82+ final podResult = await ProcessRunner .run (
83+ 'pod' ,
84+ ['install' , '--repo-update' ],
85+ workingDirectory: 'ios' ,
86+ );
87+ podSpinner.stop ('pod install complete' );
88+
89+ if (podResult.exitCode != 0 ) {
90+ NyloConsole .writeWarning ('pod install completed with warnings' );
91+ NyloConsole .writeWarning (podResult.stderr);
92+ }
93+ }
94+ }
95+
96+ // Android deep clean
97+ if (cleanAndroid) {
98+ final gradleSpinner = Spinner ('' );
99+ gradleSpinner.start ('${stepLabel ()} Running gradlew clean...' );
100+ final gradlew = Platform .isWindows ? 'gradlew.bat' : './gradlew' ;
101+ final gradleResult = await ProcessRunner .run (
102+ gradlew,
103+ ['clean' ],
104+ workingDirectory: 'android' ,
105+ );
106+ gradleSpinner.stop ('gradlew clean complete' );
107+
108+ if (gradleResult.exitCode != 0 ) {
109+ NyloConsole .writeWarning ('gradlew clean completed with warnings' );
110+ NyloConsole .writeWarning (gradleResult.stderr);
111+ }
112+ }
113+
114+ // Step: Run flutter pub get
29115 final pubGetSpinner = Spinner ('' );
30- pubGetSpinner.start ('[2/2] Running flutter pub get...' );
116+ pubGetSpinner.start ('${ stepLabel ()} Running flutter pub get...' );
31117 final pubGetResult = await ProcessRunner .run ('flutter' , ['pub' , 'get' ]);
32118 pubGetSpinner.stop ('flutter pub get complete' );
33119
@@ -38,4 +124,26 @@ class CleanCommand {
38124 NyloConsole .write ('' );
39125 NyloConsole .writeSuccess ('Project cleaned successfully!' );
40126 }
127+
128+ /// Remove iOS build artifacts (Pods, .symlinks, Podfile.lock)
129+ Future <void > _removeIosArtifacts () async {
130+ final directories = [
131+ Directory ('ios/Pods' ),
132+ Directory ('ios/.symlinks' ),
133+ ];
134+ final files = [
135+ File ('ios/Podfile.lock' ),
136+ ];
137+
138+ for (final dir in directories) {
139+ if (await dir.exists ()) {
140+ await dir.delete (recursive: true );
141+ }
142+ }
143+ for (final file in files) {
144+ if (await file.exists ()) {
145+ await file.delete ();
146+ }
147+ }
148+ }
41149}
0 commit comments