blob: 52152a551080a60a18a41a2a0e3ac74b6906e9c7 [file] [log] [blame] [edit]
// Copyright (c) 2025, 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:convert';
import 'dart:io';
import 'package:args/args.dart';
import 'package:json_schema/json_schema.dart';
import 'package:json_syntax_generator/json_syntax_generator.dart';
import 'package:native_test_helpers/native_test_helpers.dart';
void main(List<String> args) {
final packageRoot = findPackageRoot('pub_formats');
final stopwatch = Stopwatch()..start();
final parser = ArgParser()
..addFlag(
'set-exit-if-changed',
negatable: false,
help: 'Return a non-zero exit code if any files were changed.',
)
..addFlag(
'dump',
abbr: 'd',
negatable: false,
help: 'Dump analyzed schema to .g.txt file.',
);
final argResults = parser.parse(args);
final setExitIfChanged = argResults['set-exit-if-changed'] as bool;
final dumpAnalyzedSchema = argResults['dump'] as bool;
var generatedCount = 0;
var changedCount = 0;
for (final name in [
'package_config',
'package_graph',
'pubspec_lock',
'pubspec',
]) {
final schemaFile = File.fromUri(
packageRoot.resolve('doc/schema/${name}.schema.json'),
);
final schemaJson = jsonDecode(schemaFile.readAsStringSync());
final schema = JsonSchema.create(schemaJson);
final analyzedSchema = SchemaAnalyzer(
schema,
nameOverrides: {'path': 'path\$'},
publicSetters: ['PubspecYamlFile'],
publicValidators: ['PubspecYamlFile'],
).analyze();
final textDumpFile = File.fromUri(
packageRoot.resolve('lib/src/${name}_syntax.g.txt'),
);
final newTextDumpContent = analyzedSchema.toString();
if (dumpAnalyzedSchema) {
var oldTextDumpContent = '';
if (textDumpFile.existsSync()) {
oldTextDumpContent = textDumpFile.readAsStringSync();
}
if (oldTextDumpContent != newTextDumpContent) {
textDumpFile.writeAsStringSync(newTextDumpContent);
print('Generated ${textDumpFile.uri}');
changedCount += 1;
}
generatedCount += 1;
} else if (textDumpFile.existsSync()) {
textDumpFile.deleteSync();
print('Deleted ${textDumpFile.uri}');
changedCount += 1;
}
final output = SyntaxGenerator(
analyzedSchema,
header: '''
// This file is generated, do not edit.
// File generated by pkgs/pub_formats/tool/generate.dart.
// Must be rerun when pkgs/pub_formats/doc/schema/ is modified.
''',
).generate();
final outputUri = packageRoot.resolve('lib/src/${name}_syntax.g.dart');
final outputFile = File.fromUri(outputUri);
var oldOutputContent = '';
if (outputFile.existsSync()) {
oldOutputContent = outputFile.readAsStringSync();
}
if (oldOutputContent != output) {
outputFile.writeAsStringSync(output);
}
Process.runSync(Platform.executable, ['format', outputUri.toFilePath()]);
final newOutputContent = outputFile.readAsStringSync();
final newContentNormalized = newOutputContent.replaceAll('\r\n', '\n');
final oldContentNormalized = oldOutputContent.replaceAll('\r\n', '\n');
if (newContentNormalized != oldContentNormalized) {
print('Generated $outputUri');
changedCount += 1;
}
generatedCount += 1;
}
stopwatch.stop();
final duration = stopwatch.elapsedMilliseconds / 1000.0;
print(
'Generated $generatedCount files ($changedCount changed) in '
'${duration.toStringAsFixed(2)} seconds.',
);
if (setExitIfChanged && changedCount > 0) {
exit(1);
}
}