diff --git a/bin/parse_arguments.dart b/bin/parse_arguments.dart index 6c19ef2..f1f4b97 100644 --- a/bin/parse_arguments.dart +++ b/bin/parse_arguments.dart @@ -1,17 +1,18 @@ class Args { - Args(this.mode, this.flavor); + Args(this.mode, this.flavor, this.isReplaceMode); String mode; String flavor; + bool isReplaceMode; @override String toString() { - return 'Current mode is $mode, and flavor is ${flavor == '' ? 'default' : flavor}'; + return 'Current mode is $mode, and flavor is ${flavor == '' ? 'default' : flavor}${isReplaceMode ? ' , for replace' : ''}'; } } Args parse(arguments) { - var args = Args('debug', 'default'); + var args = Args('debug', 'default', false); for (var value in arguments) { if (value == '--release') { args.mode = 'release'; @@ -21,6 +22,9 @@ Args parse(arguments) { if (value == '--flavor') { args.flavor = arguments[arguments.indexOf('--flavor') + 1]; } + if (value == '--replace') { + args.isReplaceMode = true; + } } print(args); return args; diff --git a/bin/pre_script.dart b/bin/pre_script.dart index 385133d..27ad591 100644 --- a/bin/pre_script.dart +++ b/bin/pre_script.dart @@ -8,6 +8,10 @@ const FLAVORS = [ 'cn', ]; +const BLACK_FILE_EXT = [ + 'md', +]; + final _ctx = { 'debug': 'debug', 'release': 'release', @@ -18,12 +22,14 @@ final _ctx = { String? exp; late String mode; late String flavor; +late bool isReplace; enum STATE { none, notMatch, caching, replace, + inDefault, } void main(List arguments) { @@ -31,6 +37,7 @@ void main(List arguments) { var args = parse(arguments); mode = args.mode; flavor = args.flavor; + isReplace = args.isReplaceMode; _ctx.addEntries(FLAVORS.map((e) => MapEntry(e, e))); @@ -54,39 +61,83 @@ bool modified = false; const evaluator = const ExpressionEvaluator(); +// vars for replace mode +int currentLineIndex = 0; +List operations = []; +List tempOperations = []; +List currentTempOperations = []; + +final _commentReg = RegExp(' +\/\/'); + +var lastIndent = -1; + void walkPath(FileSystemEntity path) { var stat = path.statSync(); if (stat.type == FileSystemEntityType.directory) { Directory(path.path).listSync().forEach(walkPath); - } else if (stat.type == FileSystemEntityType.file) { + } else if (stat.type == FileSystemEntityType.file && + BLACK_FILE_EXT.indexWhere((ele) => path.path.endsWith(ele)) < 0) { file = File(path.path); sb.clear(); modified = false; + if (isReplace) { + currentLineIndex = 0; + operations.clear(); + tempOperations.clear(); + currentTempOperations.clear(); + } try { file!.readAsLinesSync().forEach((line) { + currentLineIndex++; ma = re.firstMatch(line); if (ma != null) { + lastIndent = line.indexOf('// #{{'); modified = true; exp = ma!.group(1); if (exp == "default") { + if (isReplace) { + tempOperations.addAll(currentTempOperations); + currentTempOperations.clear(); + } + // 默认代码块开始 if (tmp.isNotEmpty) { sb.write(tmp); print([ - "${file!.path} modified", - "-" * 80, + "${file!.path} modified" + '\n', + "-" * 80 + '\n', tmp.toString(), - "-" * 80, - ].join("\n")); + "-" * 80 + '\n', + ].join()); state = STATE.replace; } else { - state = STATE.none; + state = STATE.inDefault; } } else if (exp == "end") { // 默认代码块结束 state = STATE.none; + if (isReplace) { + if (tmp.isEmpty) { + // 说明匹配到了默认代码块,应该将之前的代码全注释掉 + tempOperations.forEach((ele) => ele.commented = true); + } else { + // 之前有匹配到的代码块,应该将默认代码块注释掉 + currentTempOperations.forEach((ele) => ele.commented = true); + } + tempOperations.addAll(currentTempOperations); + operations.addAll(tempOperations); + tempOperations.clear(); + currentTempOperations.clear(); + } tmp.clear(); } else { + if (isReplace) { + if (currentTempOperations.isNotEmpty && + !currentTempOperations.first.commented) + tempOperations.forEach((ele) => ele.commented = true); + tempOperations.addAll(currentTempOperations); + currentTempOperations.clear(); + } if (evaluator.eval(Expression.parse(exp!), _ctx)) { // 匹配到 tmp.clear(); @@ -97,18 +148,46 @@ void walkPath(FileSystemEntity path) { } } else { // none状态时直接将line写入sb - if (state == STATE.none) { + if ([STATE.none, STATE.inDefault].contains(state)) { sb.writeln(line); } // 缓存中状态,将用于替换的内容移除注释后写入缓存 else if (state == STATE.caching) tmp.writeln(line.replaceFirst('// ', '')); // 这样就跳过了没有匹配上的替换代码块和默认内容 + + if (isReplace && + [STATE.notMatch, STATE.caching, STATE.replace, STATE.inDefault] + .contains(state)) { + currentTempOperations.add(ReplaceOperation( + currentLineIndex, lastIndent, state == STATE.notMatch)); + } } }); if (modified) { - file!.renameSync(path.path + '.bak'); - File(path.path).writeAsStringSync(sb.toString(), flush: true); + if (isReplace) { + operations.forEach((ele) { + print('${ele.lineNumber} : ${ele.commented}'); + }); + file!.readAsLines().then((lines) { + operations.forEach((operation) { + if (operation.commented && + !lines[operation.lineNumber - 1].startsWith(_commentReg)) + lines[operation.lineNumber - 1] = + '${' ' * operation.indent}// ${lines[operation.lineNumber - 1].substring(operation.indent)}'; + else if (!operation.commented && + lines[operation.lineNumber - 1].startsWith(_commentReg)) + lines[operation.lineNumber - 1] = + lines[operation.lineNumber - 1].replaceFirst('// ', ''); + }); + print(lines.join('\n')); + file!.deleteSync(); + File(path.path).writeAsStringSync(lines.join('\n'), flush: true); + }); + } else { + file!.renameSync(path.path + '.bak'); + File(path.path).writeAsStringSync(sb.toString(), flush: true); + } } } catch (e) { if (!(e is FileSystemException)) { @@ -117,3 +196,11 @@ void walkPath(FileSystemEntity path) { } } } + +class ReplaceOperation { + int lineNumber; + int indent; + bool commented; + + ReplaceOperation(this.lineNumber, this.indent, this.commented); +}