|
| 1 | +import 'dart:io'; |
| 2 | +import 'package:path/path.dart' as path; |
| 3 | +import 'package:yaml/yaml.dart'; |
| 4 | + |
| 5 | +/// Runs `flutter clean` in every package listed in the root pubspec.yaml |
| 6 | +/// workspace. Useful for clearing stale build artifacts after switching Flutter |
| 7 | +/// channels. |
| 8 | +Future<void> main() async { |
| 9 | + final rootDir = Directory.current; |
| 10 | + final pubspecFile = File(path.join(rootDir.path, 'pubspec.yaml')); |
| 11 | + final pubspecContent = await pubspecFile.readAsString(); |
| 12 | + final pubspecYaml = loadYaml(pubspecContent); |
| 13 | + |
| 14 | + final workspace = pubspecYaml['workspace'] as YamlList?; |
| 15 | + if (workspace == null) { |
| 16 | + print('No workspace found in pubspec.yaml'); |
| 17 | + exit(1); |
| 18 | + } |
| 19 | + |
| 20 | + final flutterBin = _resolveFlutterBin(); |
| 21 | + print('Using flutter: $flutterBin'); |
| 22 | + |
| 23 | + var cleaned = 0; |
| 24 | + var skipped = 0; |
| 25 | + |
| 26 | + for (final entry in workspace) { |
| 27 | + final package = entry.toString(); |
| 28 | + final packagePath = path.join(rootDir.path, package); |
| 29 | + |
| 30 | + // Only clean packages that have a pubspec.yaml (i.e. are Flutter/Dart pkgs) |
| 31 | + final pubspec = File(path.join(packagePath, 'pubspec.yaml')); |
| 32 | + if (!await pubspec.exists()) { |
| 33 | + print('-- Skipping \'$package\' (no pubspec.yaml found)'); |
| 34 | + skipped++; |
| 35 | + continue; |
| 36 | + } |
| 37 | + |
| 38 | + print('== Cleaning \'$package\' =='); |
| 39 | + final process = await Process.start( |
| 40 | + flutterBin, |
| 41 | + ['clean'], |
| 42 | + workingDirectory: packagePath, |
| 43 | + runInShell: true, |
| 44 | + mode: ProcessStartMode.inheritStdio, |
| 45 | + ); |
| 46 | + final exitCode = await process.exitCode; |
| 47 | + if (exitCode != 0) { |
| 48 | + print( |
| 49 | + 'Warning: flutter clean failed with exit code $exitCode in $packagePath', |
| 50 | + ); |
| 51 | + } else { |
| 52 | + cleaned++; |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + print(''); |
| 57 | + print('Done. Cleaned $cleaned package(s), skipped $skipped.'); |
| 58 | +} |
| 59 | + |
| 60 | +/// Resolves the path to the `flutter` binary by finding it relative to the |
| 61 | +/// running Dart SDK. Falls back to 'flutter' (uses PATH) if not found. |
| 62 | +String _resolveFlutterBin() { |
| 63 | + // Platform.resolvedExecutable points to the dart binary, e.g.: |
| 64 | + // /path/to/flutter/bin/cache/dart-sdk/bin/dart |
| 65 | + // Flutter binary is at /path/to/flutter/bin/flutter |
| 66 | + final dartBin = File(Platform.resolvedExecutable); |
| 67 | + final flutterBin = path.join( |
| 68 | + dartBin.parent.parent.parent.parent.path, |
| 69 | + 'bin', |
| 70 | + 'flutter', |
| 71 | + ); |
| 72 | + if (File(flutterBin).existsSync()) { |
| 73 | + return flutterBin; |
| 74 | + } |
| 75 | + return 'flutter'; // fallback to PATH |
| 76 | +} |
0 commit comments