2019-07-29 22:01:24 +00:00
|
|
|
import 'dart:async';
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:args/args.dart';
|
|
|
|
import 'package:jael/jael.dart';
|
|
|
|
|
|
|
|
var argParser = ArgParser()
|
|
|
|
..addOption('line-length',
|
|
|
|
abbr: 'l',
|
|
|
|
help: 'The maximum length of a single line. Longer lines will wrap.',
|
|
|
|
defaultsTo: '80')
|
|
|
|
..addOption('stdin-name',
|
|
|
|
help: 'The filename to print when an error occurs in standard input.',
|
|
|
|
defaultsTo: '<stdin>')
|
|
|
|
..addOption('tab-size',
|
|
|
|
help: 'The number of spaces to output where a TAB would be inserted.',
|
|
|
|
defaultsTo: '2')
|
2019-07-29 22:05:46 +00:00
|
|
|
..addFlag('dry-run',
|
|
|
|
abbr: 'n',
|
|
|
|
help:
|
|
|
|
'Print the names of files that would be changed, without actually overwriting them.',
|
|
|
|
negatable: false)
|
2019-07-29 22:01:24 +00:00
|
|
|
..addFlag('help',
|
|
|
|
abbr: 'h', help: 'Print this usage information.', negatable: false)
|
|
|
|
..addFlag('insert-spaces',
|
|
|
|
help: 'Insert spaces instead of TAB character.', defaultsTo: true)
|
|
|
|
..addFlag('overwrite',
|
|
|
|
abbr: 'w',
|
|
|
|
help: 'Overwrite input files with formatted output.',
|
|
|
|
negatable: false);
|
|
|
|
|
|
|
|
main(List<String> args) async {
|
|
|
|
try {
|
|
|
|
var argResults = argParser.parse(args);
|
|
|
|
if (argResults['help'] as bool) {
|
|
|
|
stdout..writeln('Formatter for Jael templates.')..writeln();
|
|
|
|
printUsage(stdout);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argResults.rest.isEmpty) {
|
|
|
|
var text = await stdin.transform(utf8.decoder).join();
|
|
|
|
var result =
|
2021-04-28 00:37:33 +00:00
|
|
|
await format(argResults['stdin-name'] as String?, text, argResults);
|
2019-07-29 22:01:24 +00:00
|
|
|
if (result != null) print(result);
|
|
|
|
} else {
|
|
|
|
for (var arg in argResults.rest) {
|
|
|
|
await formatPath(arg, argResults);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} on ArgParserException catch (e) {
|
|
|
|
stderr..writeln(e.message)..writeln();
|
|
|
|
printUsage(stderr);
|
|
|
|
exitCode = 65;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void printUsage(IOSink sink) {
|
|
|
|
sink
|
|
|
|
..writeln('Usage: jaelfmt [options...] [files or directories...]')
|
|
|
|
..writeln()
|
|
|
|
..writeln('Options:')
|
|
|
|
..writeln(argParser.usage);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> formatPath(String path, ArgResults argResults) async {
|
|
|
|
var stat = await FileStat.stat(path);
|
|
|
|
await formatStat(stat, path, argResults);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> formatStat(
|
|
|
|
FileStat stat, String path, ArgResults argResults) async {
|
|
|
|
switch (stat.type) {
|
|
|
|
case FileSystemEntityType.directory:
|
|
|
|
await for (var entity in Directory(path).list()) {
|
|
|
|
await formatStat(await entity.stat(), entity.path, argResults);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case FileSystemEntityType.file:
|
|
|
|
if (path.endsWith('.jael')) await formatFile(File(path), argResults);
|
|
|
|
break;
|
|
|
|
case FileSystemEntityType.link:
|
|
|
|
var link = await Link(path).resolveSymbolicLinks();
|
|
|
|
await formatPath(link, argResults);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw 'No file or directory found at "$path".';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> formatFile(File file, ArgResults argResults) async {
|
|
|
|
var content = await file.readAsString();
|
2021-04-28 00:37:33 +00:00
|
|
|
var formatted = format(file.path, content, argResults);
|
2019-07-29 22:01:24 +00:00
|
|
|
if (formatted == null) return;
|
|
|
|
if (argResults['overwrite'] as bool) {
|
2019-07-29 22:05:46 +00:00
|
|
|
if (formatted != content) {
|
|
|
|
if (argResults['dry-run'] as bool) {
|
|
|
|
print('Would have formatted ${file.path}');
|
|
|
|
} else {
|
2021-04-28 00:37:33 +00:00
|
|
|
file.writeAsStringSync(formatted);
|
2019-07-29 22:05:46 +00:00
|
|
|
print('Formatted ${file.path}');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
print('Unchanged ${file.path}');
|
|
|
|
}
|
2019-07-29 22:01:24 +00:00
|
|
|
} else {
|
|
|
|
print(formatted);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-28 00:37:33 +00:00
|
|
|
String? format(String? filename, String content, ArgResults argResults) {
|
2019-07-29 22:01:24 +00:00
|
|
|
var errored = false;
|
|
|
|
var doc = parseDocument(content, sourceUrl: filename, onError: (e) {
|
|
|
|
stderr.writeln(e);
|
|
|
|
errored = true;
|
|
|
|
});
|
|
|
|
if (errored) return null;
|
|
|
|
var fmt = JaelFormatter(
|
|
|
|
int.parse(argResults['tab-size'] as String),
|
2021-04-28 00:37:33 +00:00
|
|
|
argResults['insert-spaces'] as bool?,
|
2019-07-29 22:01:24 +00:00
|
|
|
int.parse(argResults['line-length'] as String));
|
2021-04-29 07:21:31 +00:00
|
|
|
|
|
|
|
if (doc == null) {
|
|
|
|
return null;
|
|
|
|
}
|
2019-07-29 22:01:24 +00:00
|
|
|
return fmt.apply(doc);
|
|
|
|
}
|