blob: 6d2df550089041992384d76ef0c15d3f02a78b9d [file] [log] [blame]
// 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:io/ansi.dart' as ansi;
import 'package:io/io.dart';
import 'package:path/path.dart' as p;
import 'package:web_generator/src/cli.dart';
void main(List<String> arguments) async {
final ArgResults argResult;
try {
argResult = _parser.parse(arguments);
} on FormatException catch (e) {
print('''
${ansi.lightRed.wrap(e.message)}
$_usage''');
exitCode = ExitCode.usage.code;
return;
}
if (argResult['help'] as bool) {
print(_usage);
return;
}
if (argResult.rest.isEmpty && !argResult.wasParsed('config')) {
print('''
${ansi.lightRed.wrap('At least one argument is needed')}
$_usage''');
exitCode = ExitCode.usage.code;
return;
}
assert(p.fromUri(Platform.script).endsWith(_thisScript.toFilePath()));
// Run `npm install` or `npm update` as needed.
final update = argResult['update'] as bool;
await runProc(
'npm',
[update ? 'update' : 'install'],
workingDirectory: bindingsGeneratorPath,
);
final contextFile = await createJsTypeSupertypeContext();
// Compute JS type supertypes for union calculation in translator.
await generateJsTypeSupertypes(contextFile.path);
if (argResult['compile'] as bool) {
// Compile Dart to Javascript.
await compileDartMain();
}
final inputFile = argResult.rest.firstOrNull;
final outputFile = argResult['output'] as String? ??
p.join(p.current, inputFile?.replaceAll('.d.ts', '.dart'));
final defaultWebGenConfigPath = p.join(p.current, 'webgen.yaml');
final configFile = argResult['config'] as String? ??
(File(defaultWebGenConfigPath).existsSync()
? defaultWebGenConfigPath
: null);
final relativeConfigFile = configFile != null
? p.relative(configFile, from: bindingsGeneratorPath)
: null;
final relativeOutputPath =
p.relative(outputFile, from: bindingsGeneratorPath);
final tsConfigPath = argResult['ts-config'] as String?;
final tsConfigRelativePath = tsConfigPath != null
? p.relative(tsConfigPath, from: bindingsGeneratorPath)
: null;
// Run app with `node`.
await runProc(
'node',
[
'main.mjs',
'--declaration',
if (argResult.rest.isNotEmpty) ...[
'--input=${p.relative(inputFile!, from: bindingsGeneratorPath)}',
'--output=$relativeOutputPath',
],
if (tsConfigRelativePath case final tsConfig?) '--ts-config=$tsConfig',
if (relativeConfigFile case final config?) '--config=$config',
if (argResult.wasParsed('ignore-errors')) '--ignore-errors',
if (argResult.wasParsed('generate-all')) '--generate-all',
],
workingDirectory: bindingsGeneratorPath,
);
await contextFile.delete();
return;
}
final _thisScript = Uri.parse('bin/gen_interop_bindings.dart');
final _usage = '''
${ansi.styleBold.wrap('Dart Interop Gen')}:
$_thisScript dts <.d.ts file> [options]
Usage:
${_parser.usage}''';
final _parser = ArgParser()
..addFlag('help', negatable: false, help: 'Show help information')
..addFlag('update', abbr: 'u', help: 'Update npm dependencies')
..addFlag('compile', defaultsTo: true)
..addOption('output',
abbr: 'o', help: 'The output path to generate the Dart interface code')
..addOption('ts-config',
help: 'Path to TS Configuration Options File (tsconfig.json) to pass'
' to the parser/transformer')
..addFlag('ignore-errors', help: 'Ignore Generator Errors', negatable: false)
..addFlag('generate-all',
help: 'Generate all declarations '
'(including private declarations)',
negatable: false)
..addOption('config',
hide: true,
abbr: 'c',
help:
'The configuration file to use for this tool (NOTE: Unimplemented)');