System.hx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package runci;
  2. import haxe.Timer;
  3. import sys.io.Process;
  4. import runci.Config.*;
  5. using StringTools;
  6. enum Failure {
  7. Fail;
  8. }
  9. class System {
  10. static public var success(default, null) = true;
  11. static public function successMsg(msg:String):Void {
  12. Sys.println('\x1b[32m' + msg + '\x1b[0m');
  13. }
  14. static public function failMsg(msg:String):Void {
  15. Sys.println('\x1b[31m' + msg + '\x1b[0m');
  16. }
  17. static public function infoMsg(msg:String):Void {
  18. Sys.println('\x1b[36m' + msg + '\x1b[0m');
  19. }
  20. static public function commandSucceed(cmd:String, args:Array<String>):Bool {
  21. return try {
  22. var p = new Process(cmd, args);
  23. var succeed = p.exitCode() == 0;
  24. p.close();
  25. succeed;
  26. } catch(e:Dynamic) false;
  27. }
  28. static public function commandResult(cmd:String, args:Array<String>):{
  29. stdout:String,
  30. stderr:String,
  31. exitCode:Int
  32. } {
  33. var p = new Process(cmd, args);
  34. var out = {
  35. stdout: p.stdout.readAll().toString(),
  36. stderr: p.stderr.readAll().toString(),
  37. exitCode: p.exitCode()
  38. }
  39. p.close();
  40. return out;
  41. }
  42. /**
  43. Run a command using `Sys.command()`.
  44. If the command exits with non-zero code, exit the whole script with the same code.
  45. If `useRetry` is `true`, the command will be re-run if it exits with non-zero code (3 trials).
  46. It is useful for running network-dependent commands.
  47. */
  48. static public function runCommand(cmd:String, ?args:Array<String>, useRetry:Bool = false, allowFailure:Bool = false):Void {
  49. var trials = useRetry ? 3 : 1;
  50. var exitCode:Int = 1;
  51. var cmdStr = cmd + (args == null ? '' : ' $args');
  52. while (trials-->0) {
  53. infoMsg('Command: $cmdStr');
  54. var t = Timer.stamp();
  55. exitCode = Sys.command(cmd, args);
  56. var dt = Math.round(Timer.stamp() - t);
  57. if (exitCode == 0) {
  58. successMsg('Command exited with $exitCode in ${dt}s: $cmdStr');
  59. return;
  60. }
  61. else
  62. failMsg('Command exited with $exitCode in ${dt}s: $cmdStr');
  63. if (trials > 0) {
  64. infoMsg('Command will be re-run...');
  65. }
  66. }
  67. if (!allowFailure)
  68. fail();
  69. }
  70. /**
  71. * Recursively delete a directory.
  72. * @return Int Exit code of a system command executed to perform deletion.
  73. */
  74. static public function deleteDirectoryRecursively(dir:String):Int {
  75. return switch (Sys.systemName()) {
  76. case "Windows":
  77. Sys.command("rmdir", ["/S", "/Q", StringTools.replace(sys.FileSystem.fullPath(dir), "/", "\\")]);
  78. case _:
  79. Sys.command("rm", ["-rf", dir]);
  80. }
  81. }
  82. static public function fail():Void {
  83. success = false;
  84. throw Fail;
  85. }
  86. static public function addToPATH(path:String):Void {
  87. switch (systemName) {
  88. case "Windows":
  89. Sys.putEnv("PATH", path + ";" + Sys.getEnv("PATH"));
  90. case "Mac", "Linux":
  91. Sys.putEnv("PATH", path + ":" + Sys.getEnv("PATH"));
  92. }
  93. }
  94. static public function haxelibInstallGit(account:String, repository:String, ?branch:String, ?srcPath:String, useRetry:Bool = false, ?altName:String):Void {
  95. var name:String = (altName == null) ? repository : altName;
  96. try {
  97. getHaxelibPath(name);
  98. infoMsg('$name has already been installed.');
  99. } catch (e:Dynamic) {
  100. var args:Array<String> = ["git", name, 'https://github.com/$account/$repository'];
  101. if (branch != null) {
  102. args.push(branch);
  103. }
  104. if (srcPath != null) {
  105. args.push(srcPath);
  106. }
  107. runCommand("haxelib", args, useRetry);
  108. }
  109. }
  110. static public function haxelibInstall(library:String):Void {
  111. try {
  112. getHaxelibPath(library);
  113. infoMsg('$library has already been installed.');
  114. } catch (e:Dynamic) {
  115. runCommand("haxelib", ["install", library]);
  116. }
  117. }
  118. static public function haxelibRun(args:Array<String>, useRetry:Bool = false):Void {
  119. runCommand("haxelib", ["run"].concat(args), useRetry);
  120. }
  121. static public function getHaxelibPath(libName:String) {
  122. var proc = new Process("haxelib", ["path", libName]);
  123. var result;
  124. var code = proc.exitCode();
  125. do {
  126. result = proc.stdout.readLine();
  127. if (!result.startsWith("-L")) {
  128. break;
  129. }
  130. } while(true);
  131. proc.close();
  132. if (code != 0) {
  133. throw 'Failed to get haxelib path ($result)';
  134. }
  135. return result;
  136. }
  137. static public function changeDirectory(path:String) {
  138. Sys.println('Changing directory to $path');
  139. Sys.setCwd(path);
  140. }
  141. }