@@ -121,31 +121,56 @@ class TestAndFix {
121121 bool all = false ,
122122 }) async {
123123 final projects = < Directory > [];
124- await for (final FileSystemEntity entity in root.list (recursive: true )) {
125- if (entity is ! File || path.basename (entity.path) != 'pubspec.yaml' ) {
126- continue ;
127- }
128- final File pubspec = entity;
129- final Directory projectDir = pubspec.parent;
130- if (isProjectAllowed (projectDir, all: all)) {
131- projects.add (projectDir);
124+ await _findProjectsRecursive (root, projects, all: all);
125+ return projects;
126+ }
127+
128+ Future <void > _findProjectsRecursive (
129+ Directory dir,
130+ List <Directory > projects, {
131+ required bool all,
132+ }) async {
133+ final Set <String > excludedDirs = _getExcludedDirectories (all: all);
134+ try {
135+ await for (final FileSystemEntity entity in dir.list (
136+ followLinks: false ,
137+ )) {
138+ if (entity is File && fs.path.basename (entity.path) == 'pubspec.yaml' ) {
139+ final Directory projectDir = entity.parent;
140+ if (isProjectAllowed (projectDir, all: all)) {
141+ projects.add (projectDir);
142+ }
143+ } else if (entity is Directory ) {
144+ if (! excludedDirs.contains (fs.path.basename (entity.path))) {
145+ await _findProjectsRecursive (entity, projects, all: all);
146+ }
147+ }
132148 }
149+ } on FileSystemException catch (exception) {
150+ print (
151+ 'Warning: Failed to list directory contents while searching for '
152+ 'projects: $exception ' ,
153+ );
133154 }
134- return projects;
135155 }
136156
137- bool isProjectAllowed (Directory projectPath, {bool all = false }) {
138- // Skip the things that we really don't ever want to traverse, but skip the
139- // non-essential packages unless --all is specified.
140- final excluded = [
157+ Set <String > _getExcludedDirectories ({required bool all}) {
158+ return {
141159 '.dart_tool' ,
142160 'ephemeral' ,
143161 'firebase_core' ,
144162 'build' ,
145163 if (! all) 'spikes' ,
146164 if (! all) 'fix_copyright' ,
165+ if (! all) 'release' ,
147166 if (! all) 'test_and_fix' ,
148- ];
167+ };
168+ }
169+
170+ bool isProjectAllowed (Directory projectPath, {bool all = false }) {
171+ // Skip the things that we really don't ever want to traverse, but skip the
172+ // non-essential packages unless --all is specified.
173+ final Set <String > excluded = _getExcludedDirectories (all: all);
149174 final List <String > components = fs.path.split (projectPath.path);
150175 for (final exclude in excluded) {
151176 if (components.contains (exclude)) {
0 commit comments