|
1 | 1 | module mcl.commands.config; |
2 | 2 |
|
3 | | -import std.stdio : writeln, write; |
4 | | -import std.conv : to; |
5 | | -import std.json : JSONValue; |
6 | | -import std.format : fmt = format; |
7 | | -import std.exception : enforce; |
8 | | -import std.range : front; |
9 | | -import std.string : indexOf, strip; |
10 | | -import std.logger: errorf; |
11 | | -import core.stdc.stdlib: exit; |
12 | | -import std.algorithm : each; |
| 3 | +import std.algorithm : canFind; |
13 | 4 | import std.array : array; |
14 | | -import std.process : Redirect, ProcessPipes, wait; |
| 5 | +import std.process : ProcessPipes, Redirect, wait, environment; |
| 6 | +import std.range : drop, front; |
| 7 | +import std.stdio : writeln; |
| 8 | +import std.string : indexOf; |
15 | 9 |
|
16 | 10 | import mcl.utils.env : optional, parseEnv; |
17 | 11 | import mcl.utils.fetch : fetchJson; |
18 | | -import mcl.utils.nix : queryStorePath, nix; |
19 | | -import mcl.utils.string : camelCaseToCapitalCase; |
| 12 | +import mcl.utils.log : errorAndExit; |
| 13 | +import mcl.utils.nix : nix, queryStorePath; |
20 | 14 | import mcl.utils.process : execute; |
| 15 | +import mcl.utils.string : camelCaseToCapitalCase; |
21 | 16 |
|
22 | | -export void config(string[] args) |
23 | | -{ |
24 | | - if (args.length == 0) |
25 | | - { |
26 | | - |
27 | | - errorf("Usage: mcl config <subcommand> [args]"); |
28 | | - exit(1); |
| 17 | +export void config(string[] args) { |
| 18 | + if (args.length == 0) { |
| 19 | + errorAndExit("Usage: mcl config <subcommand> [args]"); |
29 | 20 | } |
30 | | - if (!checkRepo()) |
31 | | - { |
32 | | - errorf("This command must be run from a repository containing a NixOS machine configuration"); |
33 | | - exit(1); |
| 21 | + if (!checkRepo()) { |
| 22 | + errorAndExit("This command must be run from a repository containing a NixOS machine configuration"); |
34 | 23 | } |
35 | | - switch (args.front) { |
| 24 | + |
| 25 | + string subcommand = args.front; |
| 26 | + |
| 27 | + switch (subcommand) { |
36 | 28 | case "sys": |
37 | | - sys(args[1..$]); |
| 29 | + sys(args.drop(1)); |
38 | 30 | break; |
39 | 31 | case "home": |
40 | | - home(args[1..$]); |
| 32 | + home(args.drop(1)); |
41 | 33 | break; |
42 | 34 | case "start-vm": |
43 | | - startVM(args[1..$]); |
| 35 | + startVM(args.drop(1)); |
44 | 36 | break; |
45 | 37 | default: |
46 | | - errorf("Unknown config subcommand" ~ args.front ~ ". Supported subcommands: sys, home, start-vm"); |
| 38 | + errorAndExit("Unknown config subcommand " ~ subcommand ~ ". Supported subcommands: sys, home, start-vm"); |
| 39 | + break; |
47 | 40 | } |
48 | 41 | } |
49 | 42 |
|
50 | 43 | bool checkRepo() |
51 | 44 | { |
| 45 | + const string[] validRepos = ["nixos-machine-config", "infra-lido"]; |
52 | 46 | string remoteOriginUrl = execute(["git", "config", "--get", "remote.origin.url"], false); |
53 | | - return remoteOriginUrl.indexOf("nixos-machine-config") != -1 || remoteOriginUrl.indexOf("infra-lido") != -1; |
| 47 | + |
| 48 | + foreach (string repo; validRepos) { |
| 49 | + if (remoteOriginUrl.indexOf(repo) != -1) { |
| 50 | + return true; |
| 51 | + } |
| 52 | + } |
| 53 | + return false; |
| 54 | +} |
| 55 | + |
| 56 | +void executeCommand(string command) { |
| 57 | + auto exec = execute!ProcessPipes(command, true, false, Redirect.stderrToStdout); |
| 58 | + wait(exec.pid); |
| 59 | +} |
| 60 | + |
| 61 | +void edit(string type, string path) { |
| 62 | + string editor = environment.get("EDITOR", "vim"); |
| 63 | + string user = environment.get("USER", "root"); |
| 64 | + writeln("Editing " ~ path ~ " configuration from: ", path); |
| 65 | + final switch (type) { |
| 66 | + case "system": |
| 67 | + executeCommand(editor ~ " machines/*/" ~ path ~ "/*.nix"); |
| 68 | + break; |
| 69 | + case "user": |
| 70 | + executeCommand(editor~ " users/" ~ user ~ "/gitconfig " ~ "users/" ~ user ~ "/*.nix " ~ "users/" ~ user ~ "/home-"~path~"/*.nix"); |
| 71 | + break; |
| 72 | + } |
54 | 73 | } |
55 | 74 |
|
56 | 75 | void sys(string[] args) |
57 | 76 | { |
58 | | - if ((args.length < 1 || args.length > 2) && args.front != "apply") |
| 77 | + if ((args.length < 1 || args.length > 2) && !["apply", "edit"].canFind(args.front)) |
59 | 78 | { |
60 | | - errorf("Usage: mcl config sys apply or mcl config sys apply <machine-name>"); |
61 | | - exit(1); |
| 79 | + errorAndExit("Usage: mcl config sys apply or mcl config sys apply <machine-name>\n"~ |
| 80 | + " mcl config sys edit or mcl config sys edit <machine-name>"); |
| 81 | + } |
| 82 | + |
| 83 | + string machineName = args.length > 1 ? args[1] : ""; |
| 84 | + final switch (args.front) { |
| 85 | + case "apply": |
| 86 | + writeln("Applying system configuration from: ", machineName); |
| 87 | + executeCommand("just switch-system " ~ machineName); |
| 88 | + break; |
| 89 | + case "edit": |
| 90 | + edit("system", machineName); |
| 91 | + break; |
62 | 92 | } |
63 | | - else { |
64 | | - string machineName = args.length > 1 ? args[1] : ""; |
65 | | - writeln("Applying system configuration from: ", machineName); |
66 | | - auto exec = execute!ProcessPipes( "just switch-system " ~ machineName, true, false, Redirect.stderrToStdout); |
67 | | - wait(exec.pid); |
68 | | - }; |
69 | 93 | } |
70 | 94 |
|
71 | 95 | void home(string[] args) |
72 | 96 | { |
73 | 97 | if ((args.length != 2) && args.front != "apply") |
74 | 98 | { |
75 | | - errorf("Usage: mcl config home apply <desktop/server>"); |
76 | | - exit(1); |
| 99 | + errorAndExit("Usage: mcl config home apply <desktop/server>\n"~ |
| 100 | + " mcl config home edit <desktop/server>"); |
77 | 101 | } |
78 | | - else { |
79 | | - auto type = args[1]; |
80 | | - writeln("Applying home configuration from: ", type); |
81 | | - auto exec = execute!ProcessPipes( ["just", "switch-home", type], true, false, Redirect.stderrToStdout); |
82 | | - wait(exec.pid); |
| 102 | + |
| 103 | + auto type = args[1]; |
| 104 | + final switch (args.front) { |
| 105 | + case "apply": |
| 106 | + writeln("Applying home configuration from: ", type); |
| 107 | + executeCommand("just switch-home " ~ type); |
| 108 | + break; |
| 109 | + case "edit": |
| 110 | + edit("user", type); |
| 111 | + break; |
83 | 112 | } |
84 | 113 | } |
85 | 114 |
|
86 | 115 | void startVM(string[] args) |
87 | 116 | { |
88 | | - if (args.length < 1 || args.length > 1) |
| 117 | + if (args.length != 1) |
89 | 118 | { |
90 | | - errorf("Usage: mcl config start-vm <vm-name>"); |
91 | | - exit(1); |
| 119 | + errorAndExit("Usage: mcl config start-vm <vm-name>"); |
92 | 120 | } |
93 | | - else { |
94 | | - string vmName = args.front; |
95 | | - writeln("Starting VM: ", vmName); |
96 | | - execute(["just", "start-vm", vmName]); |
97 | | - }; |
| 121 | + |
| 122 | + string vmName = args.front; |
| 123 | + writeln("Starting VM: ", vmName); |
| 124 | + executeCommand("just start-vm " ~ vmName); |
98 | 125 | } |
0 commit comments