@@ -266,24 +266,60 @@ struct Manager::Impl {
266266 initialized = false ;
267267 }
268268
269- inline static const std::array<std::string_view, 2 > MANIFEST_EXTENSIONS = { " *.pplugin" , " *.pmodule" };
270-
271269 Result<std::vector<Extension>> DiscoverExtensions () const {
272- auto paths = fileSystem->FindFiles (config.paths .extensionsDir , MANIFEST_EXTENSIONS, true );
273- if (!paths) {
274- return MakeError (std::move (paths.error ()));
270+ std::vector<std::filesystem::path> manifestPaths;
271+ std::vector<std::filesystem::path> directoriesToProcess;
272+
273+ // Start with the root extensions directory
274+ directoriesToProcess.push_back (config.paths .extensionsDir );
275+
276+ while (!directoriesToProcess.empty ()) {
277+ auto currentDir = std::move (directoriesToProcess.back ());
278+ directoriesToProcess.pop_back ();
279+
280+ // List contents of current directory
281+ auto entries = fileSystem->ListDirectory (currentDir);
282+ if (!entries) {
283+ // Log error but continue processing other directories
284+ continue ;
285+ }
286+
287+ bool foundManifest = false ;
288+ std::vector<std::filesystem::path> subdirs;
289+
290+ // First pass: look for manifest files and collect subdirectories
291+ for (auto && entry : *entries) {
292+ if (entry.is_regular_file ()) {
293+ if (Extension::GetExtensionType (entry.path ) != ExtensionType::Unknown) {
294+ manifestPaths.push_back (std::move (entry.path ));
295+ foundManifest = true ;
296+ }
297+ } else if (entry.is_directory ()) {
298+ subdirs.push_back (std::move (entry.path ));
299+ }
300+ }
301+
302+ // Only recurse into subdirectories if no manifest was found
303+ if (!foundManifest) {
304+ directoriesToProcess.insert (
305+ directoriesToProcess.end (),
306+ std::make_move_iterator (subdirs.begin ()),
307+ std::make_move_iterator (subdirs.end ())
308+ );
309+ }
275310 }
276311
277312 UniqueId id{ 0 };
278313
279314 std::vector<Extension> exts;
280- exts.reserve (paths-> size ());
281- for (auto && path : *paths ) {
315+ exts.reserve (manifestPaths. size ());
316+ for (auto && path : manifestPaths ) {
282317 exts.emplace_back (id++, std::move (path));
283318 }
284319 return exts;
285320 }
286321
322+ #pragma region Debug
287323 const size_t INITIAL_BUFFER_SIZE = 4096 ;
288324
289325 std::string GenerateLoadOrder () const {
@@ -369,6 +405,7 @@ struct Manager::Impl {
369405 std::format_to (it, " }}\n " );
370406 return buffer;
371407 }
408+ #pragma endregion Debug
372409};
373410
374411Manager::Manager (const ServiceLocator& services, const Config& config)
0 commit comments