resolveConfig function
Implementation
ConfigResult resolveConfig({
required String packageName,
required String packageRoot,
required String? packageConfig,
required PubspecReader readPubspec,
required void Function(String message) log,
void Function(Uri uri) addDependency = _ignoreDependency,
}) {
final normalizedPackageRoot = p.normalize(packageRoot);
var workspaceRootDetected = false;
if (packageConfig != null) {
// packageConfig is a file:/// URI pointing to .dart_tool/package_config.json
final packageConfigUri = Uri.parse(packageConfig);
final packageConfigPath = p.normalize(File.fromUri(packageConfigUri).path);
final configRoot = p.dirname(p.dirname(packageConfigPath));
final rootPubspec = File(p.join(configRoot, 'pubspec.yaml'));
addDependency(packageConfigUri);
final rootPubspecData = rootPubspec.existsSync()
? _readTrackedPubspec(rootPubspec, readPubspec, addDependency)
: null;
workspaceRootDetected = rootPubspecData?.isWorkspace ?? false;
final packageGraph = _readPackageGraph(
packageConfigUri.resolve('package_graph.json'),
log,
addDependency,
);
// 1. Prefer configuration from the package-config/workspace root.
if (rootPubspecData?.config != null) {
log('Using configuration from ${rootPubspec.path}');
return ConfigResult(
rootPubspecData!.config,
configRoot,
source: 'legacy ffmpeg_kit_extended_config',
);
}
// 2. If the root has no configuration, inspect package roots contained
// in it. Only a workspace root depending on this package may supply the
// configuration.
final candidates = <_ConfigCandidate>[];
for (final package in _readPackageEntries(packageConfigUri, log)) {
if (package.name == packageName ||
p.equals(package.root, normalizedPackageRoot)) {
continue;
}
if (!_isWithin(configRoot, package.root)) continue;
final packagePubspec = File(p.join(package.root, 'pubspec.yaml'));
if (!packagePubspec.existsSync()) continue;
final pubspec = _readTrackedPubspec(
packagePubspec,
readPubspec,
addDependency,
);
if (pubspec?.config != null) {
candidates.add(
_ConfigCandidate(
packageName: package.name,
pubspec: packagePubspec,
config: pubspec!.config,
),
);
}
}
final dependentRootNames = packageGraph?.dependentRootNames(packageName);
final dependentCandidates = packageGraph == null
? candidates
: candidates
.where(
(candidate) =>
dependentRootNames!.contains(candidate.packageName),
)
.toList();
if (workspaceRootDetected &&
dependentRootNames != null &&
dependentRootNames.length > 1 &&
dependentCandidates.isNotEmpty) {
final paths = dependentCandidates
.map(
(candidate) =>
'${candidate.packageName}: ${candidate.pubspec.path}',
)
.join('; ');
final message =
'Ambiguous FFmpegKit configuration: multiple workspace roots depend '
'on $packageName, so the hook cannot identify which '
'package-specific configuration applies. Place a shared '
'configuration in ${rootPubspec.path} or configure only one '
'workspace root (${dependentRootNames.join(', ')}): $paths';
log('Error: $message');
throw ConfigResolutionException(message);
}
if (dependentCandidates.length > 1) {
final paths = dependentCandidates
.map(
(candidate) =>
'${candidate.packageName}: ${candidate.pubspec.path}',
)
.join('; ');
final message =
'Ambiguous FFmpegKit configuration: multiple in-workspace packages '
'define ffmpeg_kit_extended_config. Remove all but one configuration '
'or place a shared configuration in ${rootPubspec.path}: $paths';
log('Error: $message');
throw ConfigResolutionException(message);
}
if (packageGraph == null && candidates.isNotEmpty) {
final message =
'Unable to determine which package may provide '
'ffmpeg_kit_extended_config because .dart_tool/package_graph.json '
'is unavailable. Run `flutter pub get` to rebuild package metadata, '
'or define a shared configuration in ${rootPubspec.path}.';
log('Error: $message');
throw ConfigResolutionException(message);
}
if (dependentCandidates.length == 1) {
final candidate = dependentCandidates.single;
log(
'Using dependent in-workspace package configuration from '
'${candidate.pubspec.path}',
);
return ConfigResult(
candidate.config,
p.dirname(candidate.pubspec.path),
source: 'legacy ffmpeg_kit_extended_config',
);
}
if (candidates.isNotEmpty && packageGraph != null) {
log(
'Ignoring configured workspace packages that are not package-graph '
'roots depending on $packageName. Using the default configuration.',
);
}
if (rootPubspecData != null) {
if (workspaceRootDetected) {
if (candidates.isNotEmpty && packageGraph != null) {
log(
'Warning: Dart Pub Workspace detected at $configRoot, but no '
'dependent in-workspace package defines '
'ffmpeg_kit_extended_config for $packageName. Falling back to '
'the default "base" '
'LGPL small build.',
);
} else {
log(
'Warning: Dart Pub Workspace detected at $configRoot, but no '
'unique in-workspace package defines ffmpeg_kit_extended_config. '
'Place one configuration in an in-workspace package or in '
'${rootPubspec.path}. Falling back to the default "base" LGPL '
'small build.',
);
}
} else {
log(
'Found configuration-root pubspec at ${rootPubspec.path} but no '
'ffmpeg_kit_extended_config',
);
}
}
}
// Preserve the package-local fallback for callers without package metadata.
// With package_config.json available, the package itself is deliberately
// excluded from workspace candidates and must not be selected implicitly.
if (packageConfig == null) {
final packagePubspec = File(p.join(normalizedPackageRoot, 'pubspec.yaml'));
if (packagePubspec.existsSync()) {
final pubspec = _readTrackedPubspec(
packagePubspec,
readPubspec,
addDependency,
);
if (pubspec?.config != null) {
log('Using package-local configuration from ${packagePubspec.path}');
return ConfigResult(
pubspec!.config,
normalizedPackageRoot,
source: 'legacy ffmpeg_kit_extended_config',
);
}
}
}
// Last resort: default configuration.
if (!workspaceRootDetected) {
log('No configuration found. Using default "base" LGPL small build.');
}
return ConfigResult(
{'type': 'base', 'gpl': false, 'small': true},
normalizedPackageRoot,
source: 'defaults',
);
}