blob: 84ed9a7e3646773c9b29b04c0f155ce0d52aceea [file] [log] [blame] [edit]
// 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:dart_style/dart_style.dart';
import 'package:path/path.dart';
import 'package:pub_semver/pub_semver.dart';
final _cleanRegEx = RegExp(r'[^\w$]');
String _cleanName(String name) => name.replaceAll(_cleanRegEx, '_');
final _formatter = DartFormatter(languageVersion: targetDartVersion);
final targetDartVersion = Version(3, 9, 0);
final targetDartVersionConstraint = '^$targetDartVersion';
String formatSource(String source) => _formatter.format(source);
void orderedForEach<K extends Comparable<K>, V>(
Map<K, V> map,
void Function(K, V?) fun,
) {
final keys = List<K>.from(map.keys)..sort();
for (var key in keys) {
fun(key, map[key]);
}
}
void writeDartSource(String path, String content) {
writeString(path, formatSource(content));
}
void writeString(String path, String content) {
final file = File(path);
if (!file.existsSync()) {
file.createSync(recursive: true);
}
file.writeAsStringSync(content);
}
String? findPackageRoot(String path) {
if (path.startsWith('file:')) {
path = fromUri(path);
}
path = absolute(path);
while (path != dirname(path)) {
// We use the pubspec.yaml file as an indicator of being in the package
// root directory.
final pubspec = File(join(path, 'pubspec.yaml'));
if (pubspec.existsSync()) return path;
path = dirname(path);
}
return null;
}
class GenerateResult {
final String? apiName;
final String? apiVersion;
final String? message;
final String? packagePath;
bool success = false;
bool info = false;
GenerateResult(
String this.apiName,
String this.apiVersion,
String this.packagePath,
) : success = true,
message = null;
GenerateResult.fromMessage(this.message)
: info = true,
apiName = null,
apiVersion = null,
packagePath = null;
GenerateResult.error(
String this.apiName,
String this.apiVersion,
String this.packagePath,
String this.message,
) : success = false;
String get shortName =>
_cleanName('${apiName}_${apiVersion}_api').toLowerCase();
@override
String toString() {
if (info) {
assert(message != null);
return message!;
} else {
assert(apiName != null && apiVersion != null && packagePath != null);
final flag = success ? '[SUCCESS]' : '[FAIL]';
final msg = message != null && message!.isNotEmpty ? ':\n$message' : '';
return '$flag $apiName $apiVersion @ $packagePath $msg';
}
}
}
class GeneratorError implements Exception {
final String? api;
final String? version;
final String message;
GeneratorError(this.api, this.version, this.message);
@override
String toString() => 'Error while generating API for $api/$version: $message';
}