analyze method

Future<AnalysisResult> analyze()

Analyze dependencies in the current project

Implementation

Future<AnalysisResult> analyze() async {
  final File pubspecFile = File(FileConfig.pubspecFile);

  if (!pubspecFile.existsSync()) {
    throw Exception('${FileConfig.pubspecFile} not found');
  }

  // Parse pubspec.yaml
  final String pubspecContent = await pubspecFile.readAsString();
  final Map pubspec = Map<dynamic, dynamic>.from(
      loadYaml(pubspecContent) ?? <dynamic, dynamic>{});

  // Extract dependencies
  final Map<String, dynamic> dependencies = _extractDependencies(pubspec);
  final Map<String, dynamic> devDependencies =
      _extractDevDependencies(pubspec);

  // Scan Dart files for imports
  final Map<String, PackageUsage> usageMap = await _scanDartFiles();

  // Analyze each dependency
  final List<DependencyInfo> results = <DependencyInfo>[];

  // Analyze regular dependencies
  for (final String dep in dependencies.keys) {
    final PackageUsage? usage = usageMap[dep];

    if (dep == AnalysisConfig.flutterSdk) {
      final DependencyInfo info = DependencyInfo(
        name: dep,
        version: 'sdk: flutter',
        section: DependencySection.dependencies,
        status: DependencyStatus.used,
        usedInLib: true,
        usedInTest: false,
        usedInBin: false,
        usedInTool: false,
      );
      results.add(info);
      continue;
    }

    final DependencyInfo info = DependencyInfo(
      name: dep,
      version: dependencies[dep].toString(),
      section: DependencySection.dependencies,
      status: _determineDependencyStatus(dep, usage),
      usedInLib: usage?.usedInLib ?? false,
      usedInTest: usage?.usedInTest ?? false,
      usedInBin: usage?.usedInBin ?? false,
      usedInTool: usage?.usedInTool ?? false,
    );
    results.add(info);
  }

  // Analyze dev dependencies
  for (final String dep in devDependencies.keys) {
    final PackageUsage? usage = usageMap[dep];

    if (dep == AnalysisConfig.flutterSdk) {
      final DependencyInfo info = DependencyInfo(
        name: dep,
        version: 'sdk: flutter',
        section: DependencySection.devDependencies,
        status: DependencyStatus.used,
        usedInLib: true,
        usedInTest: false,
        usedInBin: false,
        usedInTool: false,
      );
      results.add(info);
      continue;
    }

    final DependencyInfo info = DependencyInfo(
      name: dep,
      version: devDependencies[dep].toString(),
      section: DependencySection.devDependencies,
      status: _determineDevDependencyStatus(dep, usage),
      usedInLib: usage?.usedInLib ?? false,
      usedInTest: usage?.usedInTest ?? false,
      usedInBin: usage?.usedInBin ?? false,
      usedInTool: usage?.usedInTool ?? false,
    );
    results.add(info);
  }

  // Check for duplicates
  final List<DuplicateDependency> duplicates =
      _findDuplicates(dependencies, devDependencies, usageMap);

  // Detect missing dependencies
  final List<MissingDependency> missing = <MissingDependency>[];
  if (config.checks.missing) {
    final Set<String> declared = <String>{
      ...dependencies.keys,
      ...devDependencies.keys,
    };
    final String packageName = pubspec['name'] as String? ?? '';
    final Set<String> sdkPackages = const <String>{'dart', 'flutter'};

    for (final String importedPkg in usageMap.keys) {
      if (!declared.contains(importedPkg) &&
          importedPkg != packageName &&
          !sdkPackages.contains(importedPkg) &&
          !config.ignore.contains(importedPkg)) {
        final PackageUsage usage = usageMap[importedPkg]!;
        missing.add(MissingDependency(
          name: importedPkg,
          usedInLib: usage.usedInLib,
          usedInTest: usage.usedInTest,
          usedInBin: usage.usedInBin,
          usedInTool: usage.usedInTool,
        ));
      }
    }
    missing.sort((a, b) => a.name.compareTo(b.name));
  }

  return AnalysisResult(
    dependencies: results,
    duplicates: duplicates,
    missing: missing,
    totalScanned: results.length,
  );
}