| // 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. |
| |
| // ignore_for_file: prefer_expression_function_bodies |
| |
| 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']; |
| |
| final rootSchemas = loadSchemas([ |
| packageUri.resolve('doc/schema/'), |
| packageUri.resolve('../code_assets/doc/schema/'), |
| packageUri.resolve('../data_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'); |