#!/usr/bin/env dart /// Augment 代码生成规范验证脚本 /// 用于验证生成的代码是否符合规范要求 import 'dart:convert'; import 'dart:io'; void main(List args) async { print('🔍 Augment 代码生成规范验证'); print('=' * 50); final validator = StandardsValidator(); try { await validator.validateAll(); print('\n✅ 所有检查通过!代码符合 Augment 规范。'); } catch (e) { print('\n❌ 验证失败:$e'); exit(1); } } class StandardsValidator { final List errors = []; final List warnings = []; /// 验证所有规范 Future validateAll() async { print('📋 开始验证...\n'); await _validateSwaggerJson(); await _validateGeneratedFiles(); await _validateCodeQuality(); await _validateNamingConventions(); await _validateTypeConsistency(); _printResults(); if (errors.isNotEmpty) { throw Exception('发现 ${errors.length} 个错误'); } } /// 验证 swagger.json Future _validateSwaggerJson() async { print('🔍 验证 swagger.json...'); final swaggerFile = File('swagger.json'); if (!swaggerFile.existsSync()) { errors.add('swagger.json 文件不存在'); return; } try { final content = await swaggerFile.readAsString(); final swagger = jsonDecode(content) as Map; // 检查 OpenAPI 版本 final openapi = swagger['openapi'] as String?; if (openapi == null || !openapi.startsWith('3.0')) { errors.add('OpenAPI 版本必须是 3.0.x,当前:$openapi'); } // 检查基本结构 if (!swagger.containsKey('paths')) { errors.add('swagger.json 缺少 paths 定义'); } if (!swagger.containsKey('components')) { warnings.add('swagger.json 缺少 components 定义'); } // 检查 schemas final components = swagger['components'] as Map?; if (components != null) { final schemas = components['schemas'] as Map?; if (schemas == null || schemas.isEmpty) { warnings.add('components/schemas 为空,可能影响类型生成'); } } print(' ✅ swagger.json 格式正确'); } catch (e) { errors.add('swagger.json 格式错误:$e'); } } /// 验证生成的文件 Future _validateGeneratedFiles() async { print('🔍 验证生成的文件...'); final generatorDir = Directory('generator'); if (!generatorDir.existsSync()) { errors.add('generator 目录不存在'); return; } // 检查目录结构 final apiDir = Directory('generator/api'); final modelsDir = Directory('generator/api_models'); if (!apiDir.existsSync()) { errors.add('generator/api 目录不存在'); } if (!modelsDir.existsSync()) { errors.add('generator/api_models 目录不存在'); } // 检查 index.dart 文件 final indexFile = File('generator/api_models/index.dart'); if (!indexFile.existsSync()) { warnings.add('generator/api_models/index.dart 文件不存在'); } print(' ✅ 文件结构正确'); } /// 验证代码质量 Future _validateCodeQuality() async { print('🔍 验证代码质量...'); // 运行 dart analyze final analyzeResult = await Process.run('dart', ['analyze', 'generator/']); if (analyzeResult.exitCode != 0) { final output = analyzeResult.stdout.toString(); final errorOutput = analyzeResult.stderr.toString(); if (output.contains('error') || errorOutput.contains('error')) { errors.add('dart analyze 发现错误:\n$output\n$errorOutput'); } else if (output.contains('warning') || errorOutput.contains('warning')) { warnings.add('dart analyze 发现警告:\n$output\n$errorOutput'); } } else { print(' ✅ 静态分析通过'); } } /// 验证命名规范 Future _validateNamingConventions() async { print('🔍 验证命名规范...'); final apiDir = Directory('generator/api'); if (apiDir.existsSync()) { await for (final file in apiDir.list()) { if (file is File && file.path.endsWith('.dart')) { final fileName = file.path.split('/').last; // API 文件应该以 _api.dart 结尾 if (!fileName.endsWith('_api.dart')) { errors.add('API 文件命名不规范:$fileName(应该以 _api.dart 结尾)'); } // 检查文件名是否为 snake_case final baseName = fileName.replaceAll('_api.dart', ''); if (!_isSnakeCase(baseName)) { errors.add('API 文件名不是 snake_case:$fileName'); } } } } final modelsDir = Directory('generator/api_models'); if (modelsDir.existsSync()) { await for (final file in modelsDir.list()) { if (file is File && file.path.endsWith('.dart') && !file.path.endsWith('index.dart')) { final fileName = file.path.split('/').last; final baseName = fileName.replaceAll('.dart', ''); // 检查模型文件名是否为 snake_case if (!_isSnakeCase(baseName)) { errors.add('模型文件名不是 snake_case:$fileName'); } } } } print(' ✅ 命名规范检查完成'); } /// 验证类型一致性 Future _validateTypeConsistency() async { print('🔍 验证类型一致性...'); // 检查是否有硬编码的类型推断 final generatorFile = File('lib/generators/retrofit_api_generator.dart'); if (generatorFile.existsSync()) { final content = await generatorFile.readAsString(); // 检查是否还有硬编码的类型映射 final hardcodedPatterns = [ 'TaskInfoResult', 'if.*contains.*login.*return', 'if.*contains.*task.*return', 'if.*tag.*contains.*return', ]; for (final pattern in hardcodedPatterns) { final regex = RegExp(pattern, caseSensitive: false); if (regex.hasMatch(content)) { errors.add('发现硬编码类型推断:$pattern'); } } } print(' ✅ 类型一致性检查完成'); } /// 检查是否为 snake_case bool _isSnakeCase(String name) { return RegExp(r'^[a-z][a-z0-9_]*$').hasMatch(name); } /// 打印验证结果 void _printResults() { print('\n📊 验证结果:'); print(' 错误:${errors.length}'); print(' 警告:${warnings.length}'); if (errors.isNotEmpty) { print('\n❌ 错误列表:'); for (int i = 0; i < errors.length; i++) { print(' ${i + 1}. ${errors[i]}'); } } if (warnings.isNotEmpty) { print('\n⚠️ 警告列表:'); for (int i = 0; i < warnings.length; i++) { print(' ${i + 1}. ${warnings[i]}'); } } } }