1 module served.io.git_build; 2 3 import served.types; 4 5 import std.conv : to; 6 import std.path : buildPath; 7 import std.string : join; 8 9 import rm.rf; 10 11 import fs = std.file; 12 13 bool compileDependency(string cwd, string name, string gitURI, string[][] commands) 14 { 15 import std.process : pipe, spawnProcess, Config, tryWait, wait; 16 17 int run(string[] cmd, string cwd) 18 { 19 import core.thread : Thread, Fiber; 20 21 rpc.notifyMethod("coded/logInstall", "> " ~ cmd.join(" ")); 22 auto stdin = pipe(); 23 auto stdout = pipe(); 24 auto pid = spawnProcess(cmd, stdin.readEnd, stdout.writeEnd, 25 stdout.writeEnd, null, Config.none, cwd); 26 stdin.writeEnd.close(); 27 size_t i; 28 string[] lines; 29 bool done; 30 new Thread({ 31 scope (exit) 32 done = true; 33 foreach (line; stdout.readEnd.byLine) 34 lines ~= line.idup; 35 }).start(); 36 while (!pid.tryWait().terminated || !done || i < lines.length) 37 { 38 if (i < lines.length) 39 { 40 rpc.notifyMethod("coded/logInstall", lines[i++]); 41 } 42 Fiber.yield(); 43 } 44 return pid.wait; 45 } 46 47 rpc.notifyMethod("coded/logInstall", "Installing into " ~ cwd); 48 try 49 { 50 auto newCwd = buildPath(cwd, name); 51 if (fs.exists(newCwd)) 52 { 53 rpc.notifyMethod("coded/logInstall", "Deleting old installation from " ~ newCwd); 54 try 55 { 56 rmdirRecurseForce(newCwd); 57 } 58 catch (Exception) 59 { 60 rpc.notifyMethod("coded/logInstall", "WARNING: Failed to delete " ~ newCwd); 61 } 62 } 63 auto ret = run([ 64 anyConfig.git.userPath, "clone", "--recursive", "--depth=1", gitURI, 65 name 66 ], cwd); 67 if (ret != 0) 68 throw new Exception("git ended with error code " ~ ret.to!string); 69 foreach (command; commands) 70 run(command, newCwd); 71 return true; 72 } 73 catch (Exception e) 74 { 75 rpc.notifyMethod("coded/logInstall", "Failed to install " ~ name); 76 rpc.notifyMethod("coded/logInstall", e.toString); 77 return false; 78 } 79 }