@@ -4,21 +4,27 @@ set -euo pipefail
4
4
# # Configuration
5
5
6
6
readonly libexec_dir=" ${0%/* } "
7
- readonly format_dir=$libexec_dir /formats
8
7
9
8
configuration=${NIXOS_CONFIG:- $libexec_dir / configuration.nix}
10
9
flake_uri=
11
10
flake_attr=
11
+ format=
12
12
format_path=
13
13
target_system=
14
14
cores=
15
15
run=
16
+ list_formats=false
17
+ show_format_search_path=false
16
18
nix_args=(
17
19
" $libexec_dir /nixos-generate.nix"
18
20
)
19
21
has_outlink=false
20
22
nix_build_args=()
21
23
24
+ # `printf' rather than `<<<' to avoid introducing a spurious trailing newline
25
+ mapfile -t -d : format_dirs < <( printf -- ' %s' " ${NIXOS_GENERATORS_FORMAT_SEARCH_PATH:- } " )
26
+ format_dirs+=(" $libexec_dir /formats" )
27
+
22
28
# # Functions
23
29
24
30
showUsage () {
@@ -34,7 +40,11 @@ Options:
34
40
selects the nixos configuration to build, using flake uri like "~/dotfiles#my-config"
35
41
* -f, --format NAME: select one of the pre-determined formats
36
42
* --format-path PATH: pass a custom format
43
+ * --format-search-path DIR:
44
+ prepend a directory to the list of directories ${0##*/ } searches for format definitions
37
45
* --list: list the available built-in formats
46
+ * --show-format-search-path:
47
+ list the directories ${0##*/ } searches for format files
38
48
* --run: runs the configuration in a VM
39
49
only works for the "vm" and "vm-nogui" formats
40
50
* --show-trace: show more detailed nix evaluation location information
@@ -47,11 +57,70 @@ USAGE
47
57
}
48
58
49
59
listFormats () {
50
- for format in " $format_dir " /* .nix; do
51
- basename " $format " " .nix"
60
+ local -A formats
61
+ local format_dir format_file format
62
+
63
+ for format_dir in " ${format_dirs[@]} " ; do
64
+ if [[ -n $format_dir ]]; then
65
+ for format_file in " $format_dir " /* .nix; do
66
+ if [[ -f " $format_file " ]]; then
67
+ format=$( basename " $format_file " " .nix" )
68
+ formats[" $format " ]=1
69
+ fi
70
+ done
71
+ fi
72
+ done
73
+
74
+ for format in " ${! formats[@]} " ; do
75
+ printf -- ' %s\n' " $format "
76
+ done | sort
77
+ }
78
+
79
+ showFormatSearchPath () {
80
+ local -i pos=1
81
+ local format_dir
82
+
83
+ for format_dir in " ${format_dirs[@]} " ; do
84
+ if [[ -n $format_dir ]]; then
85
+ printf -- ' %d. "%q"\n' " $(( pos++ )) " " $format_dir "
86
+ fi
52
87
done
53
88
}
54
89
90
+ validateFormat () {
91
+ case " ${1:- } " in
92
+ * /* | ' ' )
93
+ abort " not a valid format name: ${1:- <empty>} "
94
+ return 1
95
+ ;;
96
+ esac
97
+ }
98
+
99
+ findFormat () {
100
+ local format=" ${1?} "
101
+ shift
102
+
103
+ validateFormat " $format " || return
104
+
105
+ local -n ref_var=" ${1:- format_file} "
106
+ shift
107
+
108
+ local format_dir maybe_format_file
109
+
110
+ for format_dir in " ${format_dirs[@]} " ; do
111
+ if [[ -n $format_dir ]]; then
112
+ maybe_format_file=" ${format_dir} /${format} .nix"
113
+
114
+ if [[ -f " $maybe_format_file " ]]; then
115
+ ref_var=" $maybe_format_file "
116
+ return
117
+ fi
118
+ fi
119
+ done
120
+
121
+ abort " unable to locate file for format: $format "
122
+ }
123
+
55
124
abort () {
56
125
echo " aborted: $* " >&2
57
126
exit 1
@@ -84,27 +153,33 @@ while [[ $# -gt 0 ]]; do
84
153
shift 2
85
154
;;
86
155
-f | --format)
87
- format_path= $format_dir / $2 .nix
156
+ format= " $2 "
88
157
shift
89
158
;;
90
159
--format-path)
91
160
format_path=$2
92
161
shift
93
162
;;
163
+ --format-search-path)
164
+ format_dirs=(" $2 " " ${format_dirs[@]} " )
165
+ shift
166
+ ;;
94
167
--help)
95
168
showUsage
96
169
exit
97
170
;;
98
171
--list)
99
- listFormats
100
- exit
172
+ list_formats=true
173
+ show_format_search_path=false
174
+ ;;
175
+ --show-format-search-path)
176
+ list_formats=false
177
+ show_format_search_path=true
101
178
;;
102
179
--run)
103
180
run=1
104
181
# default to the VM format
105
- if [[ -z $format_path ]]; then
106
- format_path=$format_dir /vm.nix
107
- fi
182
+ format=" ${format:- vm} "
108
183
;;
109
184
--show-trace)
110
185
nix_args+=(--show-trace)
@@ -129,11 +204,23 @@ while [[ $# -gt 0 ]]; do
129
204
shift
130
205
done
131
206
207
+ if $list_formats ; then
208
+ listFormats
209
+ exit
210
+ elif $show_format_search_path ; then
211
+ showFormatSearchPath
212
+ exit
213
+ fi
214
+
132
215
if ! $has_outlink ; then
133
216
nix_build_args+=(--no-out-link)
134
217
fi
135
218
136
219
if [[ -z $format_path ]]; then
220
+ if [[ -n $format ]] ; then
221
+ findFormat " $format " format_path
222
+ fi
223
+
137
224
abort " missing format. use --help for more details"
138
225
fi
139
226
0 commit comments