| // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:io'; |
| |
| import 'package:analyzer/dart/analysis/analysis_context_collection.dart'; |
| import 'package:analyzer/file_system/physical_file_system.dart'; |
| import 'package:path/path.dart' as p; |
| import 'package:yaml/yaml.dart'; |
| |
| import 'src/api_builder.dart'; |
| import 'src/api_declaration.dart'; |
| import 'src/api_summary_customizer.dart'; |
| export 'src/api_declaration.dart'; |
| export 'src/api_summary_customizer.dart' |
| show ApiSummaryContext, ApiSummaryCustomizer; |
| export 'src/api_type.dart'; |
| |
| /// Creates a canonical [ApiSummary] model of the public API of a package. |
| /// |
| /// [packagePath] is the path to the directory containing the package's |
| /// `pubspec.yaml` file. |
| /// |
| /// [packageName] is the name of the package, or extracted from `pubspec.yaml` |
| /// if omitted. |
| /// |
| /// If [customizer] is provided, it will be used to customize the behavior of |
| /// the tool. |
| Future<ApiSummary> apiSummary( |
| String packagePath, { |
| String? packageName, |
| ApiSummaryCustomizer? customizer, |
| }) async { |
| final resolvedPackageName = packageName ?? _extractPackageName(packagePath); |
| final provider = PhysicalResourceProvider.INSTANCE; |
| final libPath = provider.pathContext.join(packagePath, 'lib'); |
| if (!provider.getFolder(libPath).exists) { |
| throw ArgumentError('No "lib" directory found for "$packagePath".'); |
| } |
| final collection = AnalysisContextCollection( |
| resourceProvider: provider, |
| includedPaths: [libPath], |
| ); |
| final context = collection.contextFor(libPath); |
| return buildApiPackage( |
| resolvedPackageName, |
| context, |
| customizer ?? const ApiSummaryCustomizer(), |
| ); |
| } |
| |
| String _extractPackageName(String packagePath) { |
| final pubspecFile = File(p.join(packagePath, 'pubspec.yaml')); |
| if (!pubspecFile.existsSync()) { |
| throw ArgumentError('No pubspec.yaml found at "$packagePath".'); |
| } |
| final content = pubspecFile.readAsStringSync(); |
| final yaml = loadYaml(content); |
| if (yaml case {'name': final String name}) { |
| return name; |
| } |
| if (yaml is! Map) { |
| throw ArgumentError( |
| 'Expected pubspec.yaml at ${pubspecFile.path} to be a YAML map.', |
| ); |
| } |
| if (yaml['name'] == null) { |
| throw ArgumentError( |
| 'Could not find a "name" field in pubspec.yaml at ${pubspecFile.path}.', |
| ); |
| } |
| throw ArgumentError( |
| 'The "name" field in pubspec.yaml at ${pubspecFile.path} must be a ' |
| 'string.', |
| ); |
| } |