detect function

NativeProject? detect([
  1. Directory? workingDirectory
])

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;
}