blob: 4322610aad59d49e02618ce8faa834520269dd1e (
plain) (
blame)
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
#! /usr/bin/env dash
# shellcheck source=/dev/null
SHELL_LIBRARY_VERSION="2.1.2" . %SHELL_LIBRARY_PATH
UPDATE_SCRIPT_NAME="update.sh"
CONFIG_DIRECTORY_PATH="$HOME/.local/share/flake-update"
# Both are used in version()
# shellcheck disable=SC2034
AUTHORS="Soispha"
# shellcheck disable=SC2034
YEARS="2023"
UPDATE_SCRIPT_NOT_WANTED=false
# Searches upward for a `UPDATE_SCRIPT_NAME` script
# Returns a path to the script if it exists, otherwise nothing is returned
check_for_update_script() {
dirname="$(search_upward_files "$UPDATE_SCRIPT_NAME")"
if [ "$dirname" ]; then
printf "%s/%s" "$dirname" "$UPDATE_SCRIPT_NAME"
fi
}
# Checks if a given path to the update script is allowed.
# Takes the path as input
# Return 0, if allowed, 1 if not.
check_for_allowed_update_script() {
update_script="$1"
config_path="${CONFIG_DIRECTORY_PATH}${update_script}"
update_script_hash="$(sha256sum "$update_script")"
if [ -f "$config_path" ]; then
if [ "$(cat "$config_path")" = "$update_script_hash" ]; then
dbg "Recorded hash matches"
return 0
else
dbg "Recorded hash \'$(cat "$config_path")\' does not match real hash \'$update_script_hash\', assuming not allowed"
return 1
fi
else
dbg "Path \'$config_path\' does not exist, assuming not allowed"
return 1
fi
}
# Asks the user if they want to allow a given script.
# Takes the path as input
ask_to_allow_update_script() {
update_script="$1"
config_path="${CONFIG_DIRECTORY_PATH}${update_script}"
update_script_hash="$(sha256sum "$update_script")"
println "\033[2J" # clear the screen
cat "$update_script"
readp "Do you want to allow this script?[N/y]: " allow
# shellcheck disable=SC2154
dbg "allow is: $allow"
case "$allow" in
[yY])
dbg "allowed script"
dbg "storing contents in: $config_path"
mkdir --parents "$(dirname "$config_path")"
print "$update_script_hash" >"$config_path"
;;
*)
UPDATE_SCRIPT_NOT_ALLOWED=true
;;
esac
}
# Runs the provided script and continues to update the nix flake
# Takes the path to the script and the directory to the flake as arguments
# If the path to the update script is empty, it will be ignored
update() {
update_script="$1"
flake_base_dir="$2"
shift 2
dbg "Provided following args to update script: '$*'"
cd "$flake_base_dir" || die "Provided dir \'$flake_base_dir\' can not be accessed"
dbg "changed directory to: $flake_base_dir"
nix flake update
if ! [ "$update_script" = "" ] && ! [ "$UPDATE_SCRIPT_NOT_WANTED" = "true" ]; then
"$update_script" "$@"
fi
if grep '[^0-9]_[0-9]' flake.lock >/dev/null; then
batgrep '[^0-9]_[0-9]' flake.lock
die "Your flake.nix contains duplicate inputs!"
fi
}
help() {
cat <<EOF
This is a Nix flake update manager.
USAGE:
$NAME [--help | --version] [flake [--no-script] | <some other command>]
OPTIONS:
--help | -h
Display this help and exit.
--version | -v
Display version and copyright information and exit.
--no-script
Avoid running the 'update.sh' script
COMMANDS:
flake
update the flake project
<some other command>
runs a executable called "update-<some other command>", if it exists
EOF
}
main() {
if ! [ "$UPDATE_SCRIPT_NOT_ALLOWED" = true ]; then
update_script="$(check_for_update_script)"
flake_base_dir="$(search_flake_base_dir)" # Assume, that the update script is in the base dir
dbg "update_script is: $update_script"
dbg "flake_base_dir is: $flake_base_dir"
if [ "$update_script" = "" ]; then
update "" "$flake_base_dir" "$@"
elif check_for_allowed_update_script "$update_script" && ! [ "$update_script" = "" ]; then
update "$update_script" "$flake_base_dir" "$@"
else
ask_to_allow_update_script "$update_script"
main "$@"
fi
fi
}
if [ "$#" -eq 0 ]; then
main
exit 0
fi
for input in "$@"; do
case "$input" in
"--help" | "-h")
help
exit 0
;;
"--version" | "-v")
version
exit 0
;;
"--no-script" | "-n")
UPDATE_SCRIPT_NOT_WANTED=true
;;
"--")
end_of_cli_options=true
# Stop processing args after that marker.
break
;;
esac
[ "$end_of_cli_options" = "true" ] && break
done
case "$1" in
"flake")
shift 1
# Filter out fupdate specific flags
while [ "$1" != "--" ]; do
# FIXME: This check allows to add a flag multiple times, but this should probably
# not be allowed <2024-03-29>
case "$1" in
"--no-script" | "-n")
shift 1
;;
*)
break
;;
esac
done
[ "$1" = "--" ] && shift 1
main "$@"
;;
*)
command="$1"
shift 1
[ "$1" = "--" ] && shift 1
if which update-"$command" >/dev/null 2>&1; then
update-"$command" "$@"
else
die "command \"update-$command\" is not executable, or does not exist"
fi
;;
esac
|