| // 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:io'; | |
| import 'package:args/args.dart'; | |
| import 'package:json_syntax_generator/json_syntax_generator.dart'; | |
| import 'package:native_test_helpers/native_test_helpers.dart'; | |
| import '../test/json_schema/helpers.dart'; | |
| const generateFor = [ | |
| 'hooks', | |
| 'code_assets', | |
| 'data_assets', | |
| 'hooks_runner', | |
| 'web_assets', | |
| ]; | |
| final rootSchemas = loadSchemas([ | |
| packageUri.resolve('doc/schema/'), | |
| packageUri.resolve('../code_assets/doc/schema/'), | |
| packageUri.resolve('../data_assets/doc/schema/'), | |
| packageUri.resolve('../hooks_runner/doc/schema/'), | |
| packageUri.resolve('../web_assets/doc/schema/'), | |
| ]); | |
| void main(List<String> args) { | |
| 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( | |
| '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['d'] as bool; | |
| var generatedCount = 0; | |
| var changedCount = 0; | |
| for (final packageName in generateFor) { | |
| const schemaName = 'shared'; | |
| final schemaUri = packageUri.resolve( | |
| '../$packageName/doc/schema/$schemaName/shared_definitions.schema.json', | |
| ); | |
| final schema = rootSchemas[schemaUri]!; | |
| final analyzedSchema = SchemaAnalyzer( | |
| schema, | |
| nameOverrides: { | |
| 'ios': 'iOS', | |
| 'Ios': 'IOS', | |
| 'macos': 'macOS', | |
| 'Macos': 'MacOS', | |
| 'CodeAssetsCodeAsset': 'NativeCodeAssetNew', | |
| 'DataAssetsDataAsset': 'DataAssetNew', | |
| }, | |
| publicSetters: [ | |
| 'BuildOutput', | |
| 'Config', | |
| 'ConfigExtensions', | |
| 'HookInput', | |
| 'HookOutput', | |
| 'LinkOutput', | |
| ], | |
| publicUnionTagValues: ['Asset'], | |
| ).analyze(); | |
| final textDumpFile = File.fromUri( | |
| packageUri.resolve('../$packageName/lib/src/$packageName/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, | |
| requireNullableParameters: true, | |
| header: | |
| ''' | |
| // This file is generated, do not edit. | |
| // File generated by pkgs/hooks/tool/generate_syntax.dart. | |
| // Must be rerun when pkgs/$packageName/doc/schema/ is modified. | |
| ''', | |
| ).generate(); | |
| final outputUri = packageUri.resolve( | |
| '../$packageName/lib/src/$packageName/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); | |
| } | |
| } | |
| Uri packageUri = findPackageRoot('hooks'); |