2016-12-12 17:34:43 +01:00
|
|
|
#! @shell@
|
|
|
|
set -e
|
|
|
|
set -o pipefail
|
|
|
|
export PATH=@path@:$PATH
|
|
|
|
|
|
|
|
|
|
|
|
showSyntax() {
|
2019-06-05 22:59:23 +02:00
|
|
|
echo "darwin-rebuild [--help] {edit | switch | activate | build | check | changelog}" >&2
|
2017-10-20 21:45:31 +02:00
|
|
|
echo " [--list-generations] [{--profile-name | -p} name] [--rollback]" >&2
|
|
|
|
echo " [{--switch-generation | -G} generation] [--verbose...] [-v...]" >&2
|
2023-07-02 01:11:16 +10:00
|
|
|
echo " [-Q] [{--max-jobs | -j} number] [--cores number] [--dry-run]" >&2
|
2017-10-20 21:45:31 +02:00
|
|
|
echo " [--keep-going] [-k] [--keep-failed] [-K] [--fallback] [--show-trace]" >&2
|
|
|
|
echo " [-I path] [--option name value] [--arg name value] [--argstr name value]" >&2
|
2023-07-15 11:02:13 +10:00
|
|
|
echo " [--flake flake] [--no-flake] [--update-input input flake] [--impure]" >&2
|
|
|
|
echo " [--recreate-lock-file] [--no-update-lock-file] [--refresh]" >&2
|
2024-04-06 19:32:48 +03:00
|
|
|
echo " [--offline] [--substituters substituters-list] ..." >&2
|
2016-12-15 21:52:53 +01:00
|
|
|
exit 1
|
2016-12-12 17:34:43 +01:00
|
|
|
}
|
|
|
|
|
2023-12-22 14:40:13 +00:00
|
|
|
sudo() {
|
|
|
|
if command sudo --help | grep -- --preserve-env= >/dev/null; then
|
|
|
|
command sudo -H --preserve-env=PATH env "$@"
|
|
|
|
else
|
|
|
|
command sudo -H "$@"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-12-12 17:34:43 +01:00
|
|
|
# Parse the command line.
|
|
|
|
origArgs=("$@")
|
2022-10-10 19:14:05 +08:00
|
|
|
extraMetadataFlags=()
|
2016-12-20 00:05:01 +01:00
|
|
|
extraBuildFlags=()
|
2020-10-18 14:22:54 +02:00
|
|
|
extraLockFlags=()
|
2017-05-15 21:16:09 +02:00
|
|
|
extraProfileFlags=()
|
2016-12-20 00:05:01 +01:00
|
|
|
profile=@profile@
|
2016-12-12 17:34:43 +01:00
|
|
|
action=
|
2020-10-18 14:22:54 +02:00
|
|
|
flake=
|
2023-07-15 11:02:13 +10:00
|
|
|
noFlake=
|
2016-12-12 17:34:43 +01:00
|
|
|
|
2020-02-03 22:47:55 +01:00
|
|
|
while [ $# -gt 0 ]; do
|
2019-06-05 21:35:58 +02:00
|
|
|
i=$1; shift 1
|
|
|
|
case $i in
|
2016-12-15 21:52:53 +01:00
|
|
|
--help)
|
|
|
|
showSyntax
|
|
|
|
;;
|
2019-06-05 22:59:23 +02:00
|
|
|
edit|switch|activate|build|check|changelog)
|
2019-06-05 21:35:58 +02:00
|
|
|
action=$i
|
2016-12-15 21:52:53 +01:00
|
|
|
;;
|
2024-05-18 16:25:53 +03:00
|
|
|
--show-trace|--keep-going|--keep-failed|--verbose|-v|-vv|-vvv|-vvvv|-vvvvv|--fallback|--offline)
|
2022-10-10 19:14:05 +08:00
|
|
|
extraMetadataFlags+=("$i")
|
|
|
|
extraBuildFlags+=("$i")
|
|
|
|
;;
|
|
|
|
--no-build-hook|--dry-run|-k|-K|-Q)
|
2016-12-20 00:05:01 +01:00
|
|
|
extraBuildFlags+=("$i")
|
|
|
|
;;
|
2017-01-24 21:47:34 +01:00
|
|
|
-j[0-9]*)
|
|
|
|
extraBuildFlags+=("$i")
|
|
|
|
;;
|
2016-12-20 00:05:01 +01:00
|
|
|
--max-jobs|-j|--cores|-I)
|
2020-02-03 22:47:55 +01:00
|
|
|
if [ $# -lt 1 ]; then
|
|
|
|
echo "$0: '$i' requires an argument"
|
2016-12-20 00:05:01 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
2019-06-05 21:35:58 +02:00
|
|
|
j=$1; shift 1
|
2016-12-20 00:05:01 +01:00
|
|
|
extraBuildFlags+=("$i" "$j")
|
|
|
|
;;
|
|
|
|
--arg|--argstr|--option)
|
2020-02-03 22:47:55 +01:00
|
|
|
if [ $# -lt 2 ]; then
|
|
|
|
echo "$0: '$i' requires two arguments"
|
2016-12-20 00:05:01 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
2019-06-05 21:35:58 +02:00
|
|
|
j=$1
|
|
|
|
k=$2
|
|
|
|
shift 2
|
2022-10-10 19:14:05 +08:00
|
|
|
extraMetadataFlags+=("$i" "$j" "$k")
|
2016-12-20 00:05:01 +01:00
|
|
|
extraBuildFlags+=("$i" "$j" "$k")
|
|
|
|
;;
|
2020-10-18 14:22:54 +02:00
|
|
|
--flake)
|
|
|
|
flake=$1
|
|
|
|
shift 1
|
|
|
|
;;
|
2023-07-15 11:02:13 +10:00
|
|
|
--no-flake)
|
|
|
|
noFlake=1
|
|
|
|
;;
|
2023-06-28 12:47:31 -04:00
|
|
|
-L|-vL|--print-build-logs|--impure|--recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file|--refresh)
|
2020-10-18 14:22:54 +02:00
|
|
|
extraLockFlags+=("$i")
|
|
|
|
;;
|
|
|
|
--update-input)
|
|
|
|
j="$1"; shift 1
|
|
|
|
extraLockFlags+=("$i" "$j")
|
|
|
|
;;
|
|
|
|
--override-input)
|
|
|
|
j="$1"; shift 1
|
|
|
|
k="$1"; shift 1
|
|
|
|
extraLockFlags+=("$i" "$j" "$k")
|
|
|
|
;;
|
2017-10-20 21:45:31 +02:00
|
|
|
--list-generations)
|
|
|
|
action="list"
|
|
|
|
extraProfileFlags=("$i")
|
|
|
|
;;
|
2017-05-15 21:16:09 +02:00
|
|
|
--rollback)
|
|
|
|
action="rollback"
|
|
|
|
extraProfileFlags=("$i")
|
|
|
|
;;
|
|
|
|
--switch-generation|-G)
|
|
|
|
action="rollback"
|
2020-02-03 22:47:55 +01:00
|
|
|
if [ $# -lt 1 ]; then
|
|
|
|
echo "$0: '$i' requires an argument"
|
2017-05-15 21:16:09 +02:00
|
|
|
exit 1
|
|
|
|
fi
|
2019-06-05 21:35:58 +02:00
|
|
|
j=$1; shift 1
|
2017-05-15 21:16:09 +02:00
|
|
|
extraProfileFlags=("$i" "$j")
|
|
|
|
;;
|
2016-12-20 00:05:01 +01:00
|
|
|
--profile-name|-p)
|
|
|
|
if [ -z "$1" ]; then
|
2020-02-03 22:47:55 +01:00
|
|
|
echo "$0: '$i' requires an argument"
|
2016-12-20 00:05:01 +01:00
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
if [ "$1" != system ]; then
|
|
|
|
profile="/nix/var/nix/profiles/system-profiles/$1"
|
|
|
|
mkdir -p -m 0755 "$(dirname "$profile")"
|
|
|
|
fi
|
|
|
|
shift 1
|
|
|
|
;;
|
2024-04-06 19:30:01 +03:00
|
|
|
--substituters)
|
|
|
|
if [ -z "$1" ]; then
|
|
|
|
echo "$0: '$i' requires an argument"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
j=$1; shift 1
|
|
|
|
extraMetadataFlags+=("$i" "$j")
|
|
|
|
extraBuildFlags+=("$i" "$j")
|
|
|
|
;;
|
2016-12-15 21:52:53 +01:00
|
|
|
*)
|
2020-02-03 22:47:55 +01:00
|
|
|
echo "$0: unknown option '$i'"
|
2016-12-15 21:52:53 +01:00
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
2016-12-12 17:34:43 +01:00
|
|
|
done
|
|
|
|
|
|
|
|
if [ -z "$action" ]; then showSyntax; fi
|
|
|
|
|
2022-02-04 16:16:08 +08:00
|
|
|
flakeFlags=(--extra-experimental-features 'nix-command flakes')
|
2020-10-18 14:22:54 +02:00
|
|
|
|
2023-07-15 11:02:13 +10:00
|
|
|
# Use /etc/nix-darwin/flake.nix if it exists. It can be a symlink to the
|
|
|
|
# actual flake.
|
|
|
|
if [[ -z $flake && -e /etc/nix-darwin/flake.nix && -z $noFlake ]]; then
|
|
|
|
flake="$(dirname "$(readlink -f /etc/nix-darwin/flake.nix)")"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# For convenience, use the hostname as the default configuration to
|
|
|
|
# build from the flake.
|
2020-10-18 14:22:54 +02:00
|
|
|
if [ -n "$flake" ]; then
|
2022-10-18 12:50:14 -06:00
|
|
|
# Offical regex from https://www.rfc-editor.org/rfc/rfc3986#appendix-B
|
|
|
|
if [[ "${flake}" =~ ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? ]]; then
|
2023-01-21 15:23:40 +01:00
|
|
|
scheme=${BASH_REMATCH[1]} # eg. http:
|
|
|
|
authority=${BASH_REMATCH[3]} # eg. //www.ics.uci.edu
|
2023-01-21 15:01:07 +01:00
|
|
|
path=${BASH_REMATCH[5]} # eg. /pub/ietf/uri/
|
2022-10-18 12:50:14 -06:00
|
|
|
queryWithQuestion=${BASH_REMATCH[6]}
|
|
|
|
fragment=${BASH_REMATCH[9]}
|
|
|
|
|
2023-01-21 15:23:40 +01:00
|
|
|
flake=${scheme}${authority}${path}${queryWithQuestion}
|
2022-10-18 12:50:14 -06:00
|
|
|
flakeAttr=${fragment}
|
2020-10-18 14:22:54 +02:00
|
|
|
fi
|
|
|
|
if [ -z "$flakeAttr" ]; then
|
2023-05-29 12:10:46 +02:00
|
|
|
flakeAttr=$(scutil --get LocalHostName)
|
2020-10-18 14:22:54 +02:00
|
|
|
fi
|
2021-07-09 10:12:23 +02:00
|
|
|
flakeAttr=darwinConfigurations.${flakeAttr}
|
2020-10-18 14:22:54 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$flake" ]; then
|
2021-03-23 09:49:47 +01:00
|
|
|
if nix "${flakeFlags[@]}" flake metadata --version &>/dev/null; then
|
2021-03-22 20:58:51 +01:00
|
|
|
cmd=metadata
|
|
|
|
else
|
|
|
|
cmd=info
|
|
|
|
fi
|
|
|
|
|
2022-10-18 12:50:14 -06:00
|
|
|
metadata=$(nix "${flakeFlags[@]}" flake "$cmd" --json "${extraMetadataFlags[@]}" "${extraLockFlags[@]}" -- "$flake")
|
|
|
|
flake=$(jq -r .url <<<"${metadata}")
|
|
|
|
|
|
|
|
if [ "$(jq -r .resolved.submodules <<<"${metadata}")" = "true" ]; then
|
|
|
|
if [[ "$flake" == *'?'* ]]; then
|
|
|
|
flake="${flake}&submodules=1"
|
|
|
|
else
|
|
|
|
flake="${flake}?submodules=1"
|
|
|
|
fi
|
|
|
|
fi
|
2020-10-18 14:22:54 +02:00
|
|
|
fi
|
|
|
|
|
2022-12-08 10:00:51 +01:00
|
|
|
if [ "$action" != build ]; then
|
2022-12-08 09:48:45 +01:00
|
|
|
if [ -n "$flake" ]; then
|
|
|
|
extraBuildFlags+=("--no-link")
|
|
|
|
else
|
|
|
|
extraBuildFlags+=("--no-out-link")
|
|
|
|
fi
|
2017-03-04 20:00:23 +01:00
|
|
|
fi
|
|
|
|
|
2018-08-03 20:14:28 +02:00
|
|
|
if [ "$action" = edit ]; then
|
2019-02-24 22:27:41 +01:00
|
|
|
darwinConfig=$(nix-instantiate --find-file darwin-config)
|
2020-10-18 14:22:54 +02:00
|
|
|
if [ -z "$flake" ]; then
|
|
|
|
exec "${EDITOR:-vi}" "$darwinConfig"
|
|
|
|
else
|
|
|
|
exec nix "${flakeFlags[@]}" edit "${extraLockFlags[@]}" -- "$flake#$flakeAttr"
|
|
|
|
fi
|
2018-08-03 20:14:28 +02:00
|
|
|
fi
|
|
|
|
|
2024-09-11 11:22:21 +02:00
|
|
|
if [ "$action" = switch ] || [ "$action" = build ] || [ "$action" = check ] || [ "$action" = changelog ]; then
|
2017-10-20 21:45:31 +02:00
|
|
|
echo "building the system configuration..." >&2
|
2020-10-18 14:22:54 +02:00
|
|
|
if [ -z "$flake" ]; then
|
|
|
|
systemConfig="$(nix-build '<darwin>' "${extraBuildFlags[@]}" -A system)"
|
|
|
|
else
|
2022-12-08 09:48:45 +01:00
|
|
|
systemConfig=$(nix "${flakeFlags[@]}" build --json \
|
|
|
|
"${extraBuildFlags[@]}" "${extraLockFlags[@]}" \
|
|
|
|
-- "$flake#$flakeAttr.system" \
|
|
|
|
| jq -r '.[0].outputs.out')
|
2020-10-18 14:22:54 +02:00
|
|
|
fi
|
2016-12-12 17:34:43 +01:00
|
|
|
fi
|
|
|
|
|
2020-10-18 14:22:54 +02:00
|
|
|
if [ "$action" = list ] || [ "$action" = rollback ]; then
|
|
|
|
if [ "$USER" != root ] && [ ! -w $(dirname "$profile") ]; then
|
2023-12-22 14:40:13 +00:00
|
|
|
sudo nix-env -p "$profile" "${extraProfileFlags[@]}"
|
2017-05-15 21:16:09 +02:00
|
|
|
else
|
2019-06-05 21:35:58 +02:00
|
|
|
nix-env -p "$profile" "${extraProfileFlags[@]}"
|
2017-05-15 21:16:09 +02:00
|
|
|
fi
|
2019-06-05 22:59:23 +02:00
|
|
|
fi
|
2017-05-15 21:16:09 +02:00
|
|
|
|
2019-07-01 22:42:44 +02:00
|
|
|
if [ "$action" = rollback ]; then
|
2017-05-15 21:16:09 +02:00
|
|
|
systemConfig="$(cat $profile/systemConfig)"
|
|
|
|
fi
|
|
|
|
|
2019-06-05 23:23:59 +02:00
|
|
|
if [ "$action" = activate ]; then
|
|
|
|
systemConfig=$(readlink -f "${0%*/sw/bin/darwin-rebuild}")
|
|
|
|
fi
|
|
|
|
|
2016-12-22 23:25:32 +01:00
|
|
|
if [ -z "$systemConfig" ]; then exit 0; fi
|
|
|
|
|
2016-12-12 17:34:43 +01:00
|
|
|
if [ "$action" = switch ]; then
|
2020-10-18 14:22:54 +02:00
|
|
|
if [ "$USER" != root ] && [ ! -w $(dirname "$profile") ]; then
|
2023-12-22 14:40:13 +00:00
|
|
|
sudo nix-env -p "$profile" --set "$systemConfig"
|
2016-12-15 21:52:53 +01:00
|
|
|
else
|
2019-06-05 21:35:58 +02:00
|
|
|
nix-env -p "$profile" --set "$systemConfig"
|
2016-12-15 21:52:53 +01:00
|
|
|
fi
|
2017-05-15 21:16:09 +02:00
|
|
|
fi
|
2016-12-14 15:45:45 +01:00
|
|
|
|
2020-10-18 14:22:54 +02:00
|
|
|
if [ "$action" = switch ] || [ "$action" = activate ] || [ "$action" = rollback ]; then
|
2019-06-05 21:35:58 +02:00
|
|
|
"$systemConfig/activate-user"
|
2017-05-11 21:36:57 +02:00
|
|
|
|
2016-12-15 21:52:53 +01:00
|
|
|
if [ "$USER" != root ]; then
|
2023-12-22 14:40:13 +00:00
|
|
|
sudo "$systemConfig/activate"
|
2016-12-15 21:52:53 +01:00
|
|
|
else
|
2019-06-05 21:35:58 +02:00
|
|
|
"$systemConfig/activate"
|
2016-12-15 21:52:53 +01:00
|
|
|
fi
|
2016-12-12 17:34:43 +01:00
|
|
|
fi
|
2017-07-23 18:02:08 +02:00
|
|
|
|
2017-07-24 23:08:26 +02:00
|
|
|
if [ "$action" = changelog ]; then
|
2024-09-11 11:22:21 +02:00
|
|
|
${PAGER:-less} -- "$systemConfig/darwin-changes"
|
2017-07-24 23:08:26 +02:00
|
|
|
fi
|
|
|
|
|
2017-07-23 18:02:08 +02:00
|
|
|
if [ "$action" = check ]; then
|
2017-07-24 23:08:26 +02:00
|
|
|
export checkActivation=1
|
2019-06-05 21:35:58 +02:00
|
|
|
"$systemConfig/activate-user"
|
2017-07-23 18:02:08 +02:00
|
|
|
fi
|