import 'dart:io'; import 'package:dart_framework/utils/system_util.dart'; import '../../../oto/core/system_runtime.dart'; class RegistPath { final SystemRuntime runtime; RegistPath([this.runtime = const DefaultSystemRuntime()]); static RegistPath? _instance; // ignore: library_private_types_in_public_api, non_constant_identifier_names static RegistPath? get OS { if (_instance == null) { const defaultRuntime = DefaultSystemRuntime(); if (defaultRuntime.isMacOS) { _instance = _RegistPathOSX(defaultRuntime); } else if (defaultRuntime.isLinux) { _instance = _RegistPathLinux(defaultRuntime); } else { _instance = _RegistPathWindows(defaultRuntime); } } return _instance; } factory RegistPath.create( {SystemRuntime runtime = const DefaultSystemRuntime()}) { if (runtime.isMacOS) { return _RegistPathOSX(runtime); } else if (runtime.isLinux) { return _RegistPathLinux(runtime); } else { return _RegistPathWindows(runtime); } } Future add(String path) async { return await _instance?.add(path); } Future remove(String path) async { return await _instance?.remove(path); } } /// ************* MAC *************** class _RegistPathOSX extends RegistPath { _RegistPathOSX(super.runtime); String getTargetPath(String targetPath) { return 'export PATH=\${PATH}:$targetPath'; } String get zprofile { var userPath = runtime.environment['HOME']; return '$userPath/.zprofile'; } String get bprofile { var userPath = runtime.environment['HOME']; return '$userPath/.bash_profile'; } @override Future add(String path) async { await addProfile(zprofile, path); await addProfile(bprofile, path); await runtime .runShell(StringBuffer('source $zprofile && source $bprofile')); return simpleFuture; } Future addProfile(String profilePath, String targetPath) async { var file = File(profilePath); var contents = ''; if (file.existsSync()) { contents = await file.readAsString(); } else { file.createSync(); } if (contents.lastIndexOf('\n') != contents.length - 1) { contents += '\n'; } var addItem = getTargetPath(targetPath); if (!contents.contains(addItem)) { contents += addItem; } await file.writeAsString(contents, flush: true); return simpleFuture; } @override Future remove(String path) async { await removeProfile(zprofile, path); await removeProfile(bprofile, path); await runtime .runShell(StringBuffer('source $zprofile && source $bprofile')); return simpleFuture; } Future removeProfile(String profilePath, String targetPath) async { var file = File(profilePath); var contents = ''; if (file.existsSync()) { contents = await file.readAsString(); var removeItem = getTargetPath(targetPath); if (contents.contains(removeItem)) { contents = contents.replaceAll(removeItem, ''); await file.writeAsString(contents, flush: true); } } return simpleFuture; } } /// ************* LINUX *************** class _RegistPathLinux extends RegistPath { _RegistPathLinux(super.runtime); @override Future add(String path) async { return null; } @override Future remove(String path) async { return null; } } /// ************* WINDOWS *************** class _RegistPathWindows extends RegistPath { _RegistPathWindows(super.runtime); var setUserPath = ''' @echo off set "PathUser=" for /F "skip=2 tokens=1,2*" %%G in ('%SystemRoot%\\System32\\reg.exe query "HKCU\\Environment" /v "Path" 2^>nul') do if /I "%%G" == "Path" ( if /I "%%H" == "REG_EXPAND_SZ" (set "PathExpand=1" & set "PathUser=%%I") else if /I "%%H" == "REG_SZ" set "PathUser=%%I" ) '''; @override Future add(String path) async { var shell = StringBuffer(setUserPath); shell.writeln('setx path "%PathUser%;$path'); await runtime.runShell(shell); return simpleFuture; } @override Future remove(String path) async { var userPath = runtime.environment['UserProfile']; var pathTxt = File('$userPath/path.txt'); var shell = StringBuffer(setUserPath); shell.writeln('echo "%PathUser%" > ${pathTxt.path}'); await runtime.runShell(StringBuffer(shell)); await Future.delayed(Duration(seconds: 1)); if (pathTxt.existsSync()) { var contents = pathTxt.readAsStringSync(); contents = contents.replaceAll(';$path', ''); contents = contents.trimLeft(); contents = contents.trimRight(); print('New User Path =====> $contents'); await runtime.runShell(StringBuffer('setx path "$contents"')); pathTxt.deleteSync(); } return simpleFuture; } }