// ignore_for_file: depend_on_referenced_packages import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:math'; import 'package:dart_framework/utils/system_util.dart'; import 'package:path/path.dart' as path; import 'cli_style.dart'; import '../oto/core/system_runtime.dart'; final _colorCodeMap = { Color.black: "30", Color.red: "31", Color.green: "32", Color.yellow: "33", Color.blue: "34", Color.magenta: "35", Color.cyan: "36", Color.lightGray: "37", Color.darkGray: "90", Color.redStrong: "91", Color.greenStrong: "92", Color.yellowStrong: "93", Color.blueStrong: "94", Color.magentaStrong: "95", Color.cyanStrong: "96", Color.white: "97" }; final _backgroundCodeMap = { Color.black: "40", Color.red: "41", Color.green: "42", Color.yellow: "43", Color.blue: "44", Color.magenta: "45", Color.cyan: "46", Color.lightGray: "47", Color.darkGray: "100", Color.redStrong: "101", Color.greenStrong: "102", Color.yellowStrong: "103", Color.blueStrong: "104", Color.magentaStrong: "105", Color.cyanStrong: "106", Color.white: "107" }; final _styleCodeMap = { Style.bold: "1", Style.dim: "2", Style.underline: "4", Style.reverse: "7" }; abstract class Printer { Printer(); factory Printer.windows( {SystemRuntime runtime = const DefaultSystemRuntime()}) => _PrinterWindows(runtime); factory Printer.unix( {SystemRuntime runtime = const DefaultSystemRuntime()}) => _PrinterUnix(runtime); String getStyle(String message, {Color? color, Color? background, Style? style}) { var combine = ''; if (color != null) { combine = _colorCodeMap[color]!; } if (background != null) { combine = combineText(combine, _backgroundCodeMap[background]!); } if (style != null) { combine = combineText(combine, _styleCodeMap[style]!); } return combine; } String combineText(String combine, String item) { if (combine == '') { combine = item; } else { combine += ';$item'; } return combine; } Future getTempFile(String content, String extension) async { var now = DateTime.now(); var time = '${now.hour}${now.minute}${now.second}${now.millisecond}${now.microsecond}'; var tempFile = File(path.join(Directory.systemTemp.path, 'temp_${time}_${Random().nextInt(1000)}.$extension')); await tempFile.writeAsString(content); return dataFutrue(tempFile); } Future printCLI(List printList) async {} } class _PrinterWindows extends Printer { final SystemRuntime runtime; _PrinterWindows(this.runtime); @override String getStyle(String message, {Color? color, Color? background, Style? style}) { var combine = super .getStyle(message, color: color, background: background, style: style); return '%ESC%[${combine}m$message%ESC%[0m'; } String removeTags(String value) { return value .replaceAll('^', '^^') .replaceAll('<', '^<') .replaceAll('>', '^>') .replaceAll('[', '^[') .replaceAll('╷', '^╷') .replaceAll('│', '^│') .replaceAll('╵', '^╵') .replaceAll(']', '^]') .replaceAll('|', '^|') .replaceAll('\r', '') .replaceAll('\n', ''); } @override Future printCLI(List printList) async { StringBuffer message = StringBuffer(); message.writeln('@echo off\r'); message.writeln('chcp 65001 > nul'); message.writeln('setlocal\r'); message.writeln('call :setESC\r'); if (printList.length == 1) { message.writeln('echo | set /p=${removeTags(printList.first)}'); } else { for (var item in printList) { item = removeTags(item); if (item.trim().isEmpty) { message.writeln('echo.\r'); } else { message.writeln('echo $item\r'); } } } message.writeln(':setESC\r'); message.writeln( '''for /F "tokens=1,2 delims=#" %%a in ('"prompt #\$H#\$E# & echo on & for %%b in (1) do rem"') do (\r'''); message.writeln(' set ESC=%%b\r'); message.writeln(' exit /B 0\r'); message.writeln(')\r'); message.writeln('exit /B 0\r'); var temp = await getTempFile(message.toString(), 'bat'); await runtime .runExecutable('cmd', ['/C', temp.path], stderrEncoding: utf8, stdoutEncoding: utf8) .then((ProcessResult result) { print(result.stdout); String error = result.stderr; if (error.isNotEmpty) { print( '=============== Error ===============\r\n${result.stderr}\r\n\r\nr\n=============== Script ===============\r\n${message.toString()}'); } }); await temp.delete(); return simpleFuture; } } class _PrinterUnix extends Printer { final SystemRuntime runtime; _PrinterUnix(this.runtime); @override String getStyle(String message, {Color? color, Color? background, Style? style}) { var combine = super .getStyle(message, color: color, background: background, style: style); return '\\e[${combine}m$message\\e[0m'; } @override Future printCLI(List printList) async { StringBuffer message = StringBuffer(); message.write('echo -e "'); for (var item in printList) { message.writeln(item); } message.write('"'); var temp = await getTempFile(message.toString(), 'sh'); var shellExe = runtime.isMacOS ? 'zsh' : 'bash'; await runtime .runExecutable( shellExe, [temp.path], stdoutEncoding: utf8, stderrEncoding: utf8, ) .then((ProcessResult result) { print(result.stdout); }); await temp.delete(); return simpleFuture; } }