157 lines
4 KiB
Dart
157 lines
4 KiB
Dart
|
import 'dart:io';
|
||
|
import 'package:args/args.dart';
|
||
|
import 'package:path/path.dart' as path;
|
||
|
import 'package:converter/src/extractors/base_extractor.dart';
|
||
|
import 'package:converter/src/extractors/php_extractor.dart';
|
||
|
|
||
|
/// Factory for creating language-specific extractors
|
||
|
class ExtractorFactory {
|
||
|
/// Create an appropriate extractor based on file extension
|
||
|
static LanguageExtractor? createExtractor(String extension) {
|
||
|
switch (extension.toLowerCase()) {
|
||
|
case '.php':
|
||
|
return PhpExtractor();
|
||
|
// TODO: Add more extractors as they're implemented
|
||
|
// case '.py':
|
||
|
// return PythonExtractor();
|
||
|
// case '.ts':
|
||
|
// case '.js':
|
||
|
// return TypeScriptExtractor();
|
||
|
// case '.java':
|
||
|
// return JavaExtractor();
|
||
|
default:
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Main contract extractor CLI
|
||
|
class ContractExtractorCLI {
|
||
|
final String sourcePath;
|
||
|
final String outputPath;
|
||
|
final bool verbose;
|
||
|
|
||
|
ContractExtractorCLI({
|
||
|
required this.sourcePath,
|
||
|
required this.outputPath,
|
||
|
this.verbose = false,
|
||
|
});
|
||
|
|
||
|
/// Run the extraction process
|
||
|
Future<void> run() async {
|
||
|
try {
|
||
|
if (await FileSystemEntity.isDirectory(sourcePath)) {
|
||
|
await _processDirectory(sourcePath);
|
||
|
} else if (await FileSystemEntity.isFile(sourcePath)) {
|
||
|
await _processFile(sourcePath);
|
||
|
} else {
|
||
|
throw Exception('Source path does not exist: $sourcePath');
|
||
|
}
|
||
|
} catch (e) {
|
||
|
print('Error: $e');
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Process a directory recursively
|
||
|
Future<void> _processDirectory(String dirPath) async {
|
||
|
final dir = Directory(dirPath);
|
||
|
await for (final entity in dir.list(recursive: true)) {
|
||
|
if (entity is File) {
|
||
|
await _processFile(entity.path);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Process a single file
|
||
|
Future<void> _processFile(String filePath) async {
|
||
|
final extension = path.extension(filePath);
|
||
|
final extractor = ExtractorFactory.createExtractor(extension);
|
||
|
|
||
|
if (extractor == null) {
|
||
|
if (verbose) {
|
||
|
print('Skipping unsupported file type: $filePath');
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
// Calculate relative path to maintain directory structure
|
||
|
final relativePath = path.relative(filePath, from: sourcePath);
|
||
|
final destDir = path.join(outputPath, path.dirname(relativePath));
|
||
|
|
||
|
// Create destination directory
|
||
|
await Directory(destDir).create(recursive: true);
|
||
|
|
||
|
// Extract contract
|
||
|
final contract = await extractor.parseFile(filePath);
|
||
|
final yamlContent = extractor.convertToYaml(contract);
|
||
|
|
||
|
// Write YAML contract
|
||
|
final yamlFile = File(path.join(
|
||
|
destDir,
|
||
|
'${path.basenameWithoutExtension(filePath)}.yaml',
|
||
|
));
|
||
|
await yamlFile.writeAsString(yamlContent);
|
||
|
|
||
|
if (verbose) {
|
||
|
print('Processed: $filePath');
|
||
|
}
|
||
|
} catch (e) {
|
||
|
print('Error processing $filePath: $e');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void main(List<String> arguments) async {
|
||
|
final parser = ArgParser()
|
||
|
..addOption(
|
||
|
'source',
|
||
|
abbr: 's',
|
||
|
help: 'Source file or directory path',
|
||
|
mandatory: true,
|
||
|
)
|
||
|
..addOption(
|
||
|
'output',
|
||
|
abbr: 'o',
|
||
|
help: 'Output directory for YAML contracts',
|
||
|
mandatory: true,
|
||
|
)
|
||
|
..addFlag(
|
||
|
'verbose',
|
||
|
abbr: 'v',
|
||
|
help: 'Enable verbose output',
|
||
|
defaultsTo: false,
|
||
|
)
|
||
|
..addFlag(
|
||
|
'help',
|
||
|
abbr: 'h',
|
||
|
help: 'Show this help message',
|
||
|
negatable: false,
|
||
|
);
|
||
|
|
||
|
try {
|
||
|
final results = parser.parse(arguments);
|
||
|
|
||
|
if (results['help'] as bool) {
|
||
|
print('Usage: dart extract_contracts.dart [options]');
|
||
|
print(parser.usage);
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
final cli = ContractExtractorCLI(
|
||
|
sourcePath: results['source'] as String,
|
||
|
outputPath: results['output'] as String,
|
||
|
verbose: results['verbose'] as bool,
|
||
|
);
|
||
|
|
||
|
await cli.run();
|
||
|
print('Contract extraction completed successfully.');
|
||
|
} catch (e) {
|
||
|
print('Error: $e');
|
||
|
print('\nUsage: dart extract_contracts.dart [options]');
|
||
|
print(parser.usage);
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|