detect function
Attempts to auto-discover a NativeProject from the nearest
native_prebuilt.yaml.
Returns null if the file is absent, has an unsupported
schema version, or cannot be parsed.
Implementation
NativeProject? detect([Directory? workingDirectory]) {
final configFile = resolveConfigFile(null, workingDirectory);
if (configFile == null) return null;
final raw = configFile.readAsStringSync();
final doc = loadYaml(raw);
if (doc is! Map) return null;
final schema = doc['schema'];
if (schema is! int || schema < 1) return null;
final packageName = doc['package'] as String? ?? 'native_prebuilt';
final assetName = doc['asset_name'] as String? ?? '';
final libraryStem = doc['library_stem'] as String? ?? '';
final linkMode = _parseLinkMode(doc['link_mode']);
final releaseSection = doc['release'] as Map?;
if (releaseSection == null) return null;
final release = _parseReleaseSource(releaseSection);
final artifactsSection = doc['artifacts'] as Map?;
final artifacts = <String, PrebuiltArtifact>{};
if (artifactsSection != null) {
for (final entry in artifactsSection.entries) {
final platform = entry.key as String;
final aDoc = entry.value as Map?;
if (aDoc == null) continue;
final archive = aDoc['archive'] as String? ?? '';
final payload = aDoc['payload'] as Map?;
final payloadType = payload?['type'] as String? ?? 'dynamic_library';
final isStatic = payloadType == 'static_library';
artifacts[platform] = PrebuiltArtifact(
archiveName: archive,
archiveSha256: aDoc['archive_sha256'] as String? ?? '',
payloadSha256: aDoc['payload_sha256'] as String? ?? '',
payload: isStatic
? StaticLibraryPayload(libraryStem: libraryStem)
: DynamicLibraryPayload(libraryStem: libraryStem),
);
}
}
// Parse source specification from YAML (supports nested 'source.git' format).
final sources = <SourceSpecification>[];
final sourceSection = doc['source'] as Map?;
if (sourceSection != null) {
final sourceSpec = _parseSourceSpec(sourceSection);
if (sourceSpec != null) {
sources.add(sourceSpec);
}
} else if (release is GitHubReleaseSource && release.repository.isNotEmpty) {
sources.add(
GitSource(
repository: Uri.parse(
'https://github.com/${release.owner}/${release.repository}',
),
revision: release.tag,
),
);
}
// Build recipes: use YAML-defined declarative recipes only.
final build = _parseBuildDefinition(doc, variables: _parseVariables(doc));
final project = NativeProject(
name: packageName,
asset: NativeAssetSpec(
assetName: assetName,
libraryStem: libraryStem,
linkMode: linkMode,
),
prebuilts: PrebuiltManifest(
schemaVersion: 1,
release: release,
artifacts: artifacts,
),
sources: sources,
build: build,
);
final lockFile = resolveLockFile(null, configFile.parent);
if (lockFile != null && lockFile.existsSync()) {
return _applyNativePrebuiltLock(project, lockFile);
}
return project;
}