-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsetup.py
More file actions
executable file
·173 lines (144 loc) · 4.53 KB
/
setup.py
File metadata and controls
executable file
·173 lines (144 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/usr/bin/env python3
import argparse
import os
import re
import subprocess
def command_output(command):
env = os.environ.copy()
env["NIX_CONFIG"] = "experimental-features = flakes nix-command"
return subprocess.check_output(command, shell=True, env=env).decode().strip()
def get_value_by_key(nix_content, key):
pattern = f' {re.escape(key)} = "([^"]+)";'
match = re.search(pattern, nix_content)
assert match is not None, (
f"Key '{key}' not found, please run setup.py with '--bootstrap'"
)
return match.group(1)
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument(
"--build",
action="store_true",
help="build profile without switch (default to switch)",
default=False,
)
parser.add_argument(
"--dry",
action="store_true",
help="dry run (do not execute the command)",
default=False,
)
# bootstrap related arguments
parser.add_argument(
"--bootstrap",
action="store_true",
help="generate bootstrap configuration (config/default.nix)",
default=False,
)
# following arguments will be ignored when --bootstrap is not set
parser.add_argument(
"--profile",
type=str,
choices=["home", "darwin", "nixos"],
help="profile type",
)
parser.add_argument(
"--username",
type=str,
help="unix user name (default to $USER)",
)
parser.add_argument(
"--hostname",
type=str,
help="unix host name (default to $(hostname))",
)
parser.add_argument(
"--fullname",
type=str,
help="display name (for git config, default to USERNAME)",
)
parser.add_argument(
"--email",
type=str,
help="email address (for git config, default to USERNAME@HOSTNAME)",
)
parser.add_argument("remainder", nargs="*")
args = parser.parse_args()
args.dir = command_output("dirname " + __file__)
if args.bootstrap:
args.profile = args.profile or "home"
args.username = args.username or command_output("printenv USER")
args.hostname = args.hostname or command_output("hostname")
return args
if args.profile or args.username or args.hostname or args.fullname or args.email:
print(
"Warning: The following arguments require --bootstrap to be enabled to be effective:\n"
" * --profile\n"
" * --username\n"
" * --hostname\n"
" * --fullname\n"
" * --email\n"
)
config = open(args.dir + "/config/default.nix").read()
args.profile = get_value_by_key(config, "profile")
args.username = get_value_by_key(config, "username")
args.hostname = get_value_by_key(config, "hostname")
return args
def write_config(args):
if args.profile == "nixos":
hardware_config = command_output(
"nixos-generate-config --show-hardware-config || true"
)
if hardware_config != "":
with open(args.dir + "/system/nixos/hardware.nix", "w") as f:
f.write(hardware_config)
config = {
"system": command_output(
"nix eval --impure --expr 'builtins.currentSystem'"
).strip('"'),
"profile": args.profile,
"directory": args.dir,
"username": args.username,
"hostname": args.hostname,
"fullname": args.fullname or args.username,
"email": args.email or f"{args.username}@{args.hostname}",
}
with open(args.dir + "/config/default.nix", "w") as f:
config_str = "\n".join([f' {k} = "{v}";' for k, v in config.items()])
f.write("{\n" + config_str + "\n}\n")
def get_command():
args = parse_args()
if args.bootstrap and not args.dry:
write_config(args)
def get_derivation():
if args.profile == "home":
return f"#{args.username}"
else:
return f"#{args.hostname}"
cmd = [
"nix",
"run",
f"{args.dir}",
"--show-trace",
"--",
"build" if args.build else "switch",
"--show-trace",
"--flake",
args.dir + get_derivation(),
*args.remainder,
]
if not args.build:
if args.profile == "home":
cmd += ["-b", "backup"]
else:
cmd = ["sudo"] + cmd
if args.dry:
cmd = ["echo"] + cmd
else:
print(cmd)
return cmd
def main():
cmd = get_command()
os.execvp(cmd[0], cmd)
if __name__ == "__main__":
main()