From 62bc8f58ca632772ecbb7f74afb080150cdb2064 Mon Sep 17 00:00:00 2001 From: Chen Asraf Date: Sat, 17 Feb 2024 02:01:08 +0200 Subject: [PATCH] fix: path searching in inner-project dirs --- CHANGELOG.md | 4 ++++ README.md | 38 +++++++++++++++++++++----------------- lib/config_parser.dart | 3 +++ lib/unaconfig_core.dart | 17 ++++++++++++++--- pubspec.yaml | 2 +- 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd43fe9..b73f017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +- Fix: path searching in inner-project dirs + ## 0.2.0 - Refactor: simplify and unify fetch logic diff --git a/README.md b/README.md index b117f75..13e2b53 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ final explorer = Unaconfig( // Name to look for in filenames 'my_package', // Paths to search in, see "Paths" section - paths: [projectRoot, homeDirectory], + paths: [currentDirectory, projectRoot, homeDirectory], // Filenames to try in each search path, see "Filename Patterns" section filenamePatterns: Unaconfig.defaultFilenamePatterns, // Parsers that resolve config files, see "ConfigParsers" section @@ -52,6 +52,21 @@ final explorer = Unaconfig( ); ``` +## Paths + +Unaconfig searches in several directories, matching on the first matched file & config. + +By default, the following directories are tried, in order: + +- The current directory +- The project root (closest dir to current that contains `pubspec.yaml`) +- The user's home dir + +Patterns with paths containing directories in the `filenamePatterns` field can be triggered for the +provided directories inside any of the above or provided paths. For example, `.config/{name}.yaml` +will also try to use both `/.config/{name}.yaml` and `$HOME/.config/{name}.yaml`, +returning the first successful match. + ## Filename Patterns Filename patterns patterns define what files to look for in each searched directory. @@ -67,23 +82,11 @@ By default, Unaconfig checks the for the following config files in every matched - A property in `pubspec.yaml` - `{name}.yaml` - `{name}.json` +- `.{name}.yaml` +- `.{name}.json` - `.config/{name}.yaml` - `.config/{name}.json` -## Paths - -Unaconfig searches in several directories, matching on the first matched file & config. - -By default, the following directories are tried: - -- The project root (closest dir to current that contains `pubspec.yaml`) -- The user's home dir - -Patterns with paths containing directories in the `filenamePatterns` field can be triggered for the -provided directories inside any of the above or provided paths. For example, `.config/{name}.yaml` -will also try to use both `/.config/{name}.yaml` and `$HOME/.config/{name}.yaml`, -returning the first successful match. - ## ConfigParsers A config parser takes the file and its contents, along with the name to lookup, and produces a final @@ -95,7 +98,8 @@ be used on it. It also takes a function, which given the config name, path and string contents should return a `Map` which represents the config that you want to load. -For example, this is the `json` `ConfigParser`, you can use this example to implement your own: +For example, this is the `ConfigParser` for `json` files, you can use this example to implement your +own: ```dart ConfigParser( @@ -131,7 +135,7 @@ very helpful to sustaining its life. If you are feeling incredibly generous and just a small amount to help sustain this project, I would be very very thankful! - Buy Me a Coffee at ko-fi.com diff --git a/lib/config_parser.dart b/lib/config_parser.dart index 82d5976..74019d6 100644 --- a/lib/config_parser.dart +++ b/lib/config_parser.dart @@ -86,4 +86,7 @@ class ConfigParser { } return {}; } + + @override + String toString() => 'ConfigParser($pattern)'; } diff --git a/lib/unaconfig_core.dart b/lib/unaconfig_core.dart index b88d852..61f978c 100644 --- a/lib/unaconfig_core.dart +++ b/lib/unaconfig_core.dart @@ -45,13 +45,15 @@ class Unaconfig { List? filenamePatterns, List? parsers, this.fs = const LocalFileSystem(), - }) : paths = paths ?? [getProjectRoot(fs), getHomeDirectory(fs)], + }) : paths = paths ?? [getCurrentDirectory(fs), getProjectRoot(fs), getHomeDirectory(fs)], filenamePatterns = filenamePatterns ?? defaultFilenamePatterns, parsers = parsers ?? defaultParsers; /// The default search patterns. static final defaultFilenamePatterns = [ r'pubspec\.yaml$', + r'{name}\.json$', + r'{name}\.ya?ml$', r'.{name}\.json$', r'.{name}\.ya?ml$', r'\.config\/{name}.json$', @@ -89,6 +91,9 @@ class Unaconfig { /// The default home directory of the current user. String get homeDirectory => getHomeDirectory(fs); + /// The default current directory. + String get currentDirectory => getCurrentDirectory(fs); + /// Get the project root directory. The [fs] is the file system to use to search for the project root. /// /// The project root is the directory that contains a `pubspec.yaml` file. @@ -113,6 +118,9 @@ class Unaconfig { return home ?? fs.currentDirectory.path; } + /// Get the current directory. + static String getCurrentDirectory(FileSystem fs) => fs.currentDirectory.path; + /// Search for the configuration. /// /// Returns the configuration as a map, or null if no configuration was found. @@ -138,6 +146,7 @@ class Unaconfig { .map((p) => RegExp(p.replaceAll('{name}', name))) .toList(); final searchPaths = paths; + final tried = {}; for (final pathname in searchPaths) { final dirPath = p.isRelative(pathname) ? p.absolute(pathname) : pathname; @@ -147,7 +156,7 @@ class Unaconfig { continue; } await for (final entity in dir.list()) { - if (entity is! File) { + if (entity is! File || tried.contains(entity.path)) { continue; } final path = entity.path; @@ -160,11 +169,12 @@ class Unaconfig { } for (final parser in parsers) { - if (!parser.matches(filename)) { + if (!parser.matches(filename) || tried.contains(path)) { continue; } final config = await parser.search(name, path); if (config == null) { + tried.add(path); continue; } return ConfigMatchDetails(path, config); @@ -181,3 +191,4 @@ class ConfigMatchDetails { ConfigMatchDetails(this.path, this.config); } + diff --git a/pubspec.yaml b/pubspec.yaml index b6ec12a..5c8d129 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: unaconfig description: | Load your user's config files for your package easily, from multiple sources & formats -version: 0.2.0 +version: 0.3.0 homepage: https://github.com/chenasraf/unaconfig_dart environment: