Skip to content

Commit

Permalink
extension_discovery: add findPackageConfig() (#590)
Browse files Browse the repository at this point in the history
  • Loading branch information
sigurdm authored Sep 27, 2024
1 parent e1d8dbe commit 6cda88c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 3 deletions.
2 changes: 2 additions & 0 deletions pkgs/extension_discovery/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

- Require Dart 3.4.
- Update to the latest version of `package:dart_flutter_team_lints`.
- Add `findPackageConfig()` allowing for automatic discovery of the
packageConfig based on a package directory.

## 2.0.0

Expand Down
4 changes: 2 additions & 2 deletions pkgs/extension_discovery/lib/extension_discovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import 'src/package_config.dart';
import 'src/registry.dart';
import 'src/yaml_config_format.dart';

export 'src/package_config.dart' show PackageConfigException;
export 'src/package_config.dart' show PackageConfigException, findPackageConfig;

/// Information about an extension for target package.
final class Extension {
Expand Down Expand Up @@ -101,7 +101,7 @@ final class Extension {
/// ### Caching results
///
/// When [useCache] is `true` then the detected extensions will be cached
/// in `.dart_tool/extension_discovery/<targetPackage>.yaml`.
/// in `.dart_tool/extension_discovery/<targetPackage>.json`.
/// This function will compare modification timestamps of
/// `.dart_tool/package_config.json` with the cache file, before reusing cached
/// results.
Expand Down
30 changes: 30 additions & 0 deletions pkgs/extension_discovery/lib/src/package_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,36 @@ import 'expect_json.dart';
typedef PackageConfigEntry = ({String name, Uri rootUri, Uri packageUri});
typedef PackageConfig = List<PackageConfigEntry>;

/// Searches in [packageDir] and all directories above for a
/// `.dart_tool/package_config.json` file. Returns the Uri of that file if
/// found.
///
/// Returns `null` if no file was found.
Uri? findPackageConfig(Uri packageDir) {
if (!packageDir.isScheme('file')) {
throw ArgumentError(
'Expected [packageDir] to be a file URI, got $packageDir',
);
}
if (!packageDir.path.endsWith('/')) {
packageDir = packageDir.replace(path: '${packageDir.path}/');
}
while (true) {
final packageConfigCandidate =
packageDir.resolve('.dart_tool/package_config.json');
try {
if (File.fromUri(packageConfigCandidate).existsSync()) {
return packageConfigCandidate;
}
} on IOException {
return null; // if we get a permission error, etc, we return null
}
final next = packageDir.resolve('..');
if (next == packageDir) return null;
packageDir = next;
}
}

/// Load list of packages and associated URIs from the
/// `.dart_tool/package_config.json` file in [packageConfigFile].
Future<PackageConfig> loadPackageConfig(
Expand Down
30 changes: 30 additions & 0 deletions pkgs/extension_discovery/test/package_config_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,34 @@ void main() {
throwsA(isA<PackageConfigException>()),
);
});

test('`findPackageConfig()`', () async {
await d.dir('workspace', [
d.dir('.dart_tool', [
d.file('package_config.json'),
]),
d.dir('myapp', [])
]).create();

expect(
findPackageConfig(d.fileUri('workspace')),
d.fileUri('workspace/.dart_tool/package_config.json'),
);
expect(
findPackageConfig(d.fileUri('workspace/')),
d.fileUri('workspace/.dart_tool/package_config.json'),
);
expect(
findPackageConfig(d.fileUri('workspace/myapp')),
d.fileUri('workspace/.dart_tool/package_config.json'),
);
expect(
findPackageConfig(d.fileUri('.')),
isNull,
);
expect(
findPackageConfig(d.fileUri('foo')),
isNull,
);
});
}
2 changes: 1 addition & 1 deletion pkgs/extension_discovery/test/test_descriptor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ Future<String> dart([
}

Future<String> dartPubGet(String folder) async =>
await dart('pub', 'get', '-C', d.path('myapp'));
await dart('pub', 'get', '-C', folder);

0 comments on commit 6cda88c

Please sign in to comment.