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 }