Author SHA1 Message Date
Domen KožarandGitHub 57a3171f94 programs/devenv: init module (#1834) 2026-07-19 22:34:20 +00:00
Anish Pallati c1403be257 programs/devenv: init module
Signed-off-by: Anish Pallati <i@anish.land>
2026-07-19 00:17:39 -04:00
SamandGitHub b4cccbd4bc darwin-rebuild: add flake options to zsh completions (#1669) 2026-07-18 08:19:57 +00:00
Angel J 1543ae0852 darwin-rebuild: add flake options to zsh completions
Signed-off-by: Angel J <78835633+Iamanaws@users.noreply.github.com>
2026-07-17 22:20:27 -07:00
Michael HoangandGitHub a4cf1d1085 mas: add module for Mac App Store management (#1668) 2026-07-15 13:58:56 +00:00
SamandGitHub d5bd9cd77a bump nixpkgs to fix manual/website builds (#1822) 2026-07-07 03:45:56 +00:00
zowoq b2217f8051 flake.lock: Update
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/8c3cede7ddc26bd659d2d383b5610efbd2c7a16e?narHash=sha256-rppURzHviaQN131F%2BnLiLdGfcb0uCd9gGP0E5%2Biw9MI%3D' (2026-06-08)
  → 'github:NixOS/nixpkgs/f205b5574fd0cb7da5b702a2da51507b7f4fdd1b?narHash=sha256-/NAkDSsve%2BGNM0Bt6tleJdCGfsTlK89nPjkVOzZMo0s%3D' (2026-07-05)
2026-07-07 13:03:24 +10:00
SamandGitHub 08920bcfd1 manualHTML: adopt to nixos/nixpkgs#537810 (#1818) 2026-07-07 01:06:54 +00:00
Yifei Sun 320cbf535b manualHTML: adopt to nixos/nixpkgs#537810 2026-07-04 12:51:44 +02:00
Angel J deadc7204c mas: add module for Mac App Store management
Signed-off-by: Angel J <78835633+Iamanaws@users.noreply.github.com>
2026-06-25 18:43:32 -07:00
SamandGitHub a1fa429e94 homebrew: pass extraEnv to cleanup checks (#1804) 2026-06-18 05:49:52 +00:00
Bryan Lai d8a6661f78 homebrew: use brewBundleCmd also for system.checks 2026-06-18 11:00:29 +08:00
Bryan Lai 5138eaf896 homebrew: mv PATH & sudo setup to brewBundleCmd
This should be a trivial refactor, which enables us to reuse
`brewBundleCmd` in the future for `brew bundle cleanup` as well.
2026-06-18 09:35:18 +08:00
Bryan Lai e636bf1664 homebrew: pass onActivation.extraEnv to checks
When onActivation.cleanup == "check", a separate `brew bundle cleanup`
command is run in the system.checks phase before the actual activation.

This `brew bundle cleanup` invocation should use the same `extraEnv`
as the main `brew bundle [install]` command, for consistency.

For example, when $XDG_CONFIG_HOME is set in `extraEnv`, it should also
be picked up by `brew bundle cleanup` in the system.checks phase.
2026-06-18 09:35:18 +08:00
SamandGitHub ee9c7b96c9 homebrew: address new CLI flag requirements (#1789) 2026-06-17 16:57:21 +00:00
Yifei Sun cd7cf09aa3 homebrew: set trusted flag in Brewfile directly
Suggested-by: Austin Horstman <khaneliman12@gmail.com>
Reviewed-by: Sam <30577766+Samasaur1@users.noreply.github.com>
2026-06-17 18:23:19 +02:00
SamandGitHub ee20edc445 users: realpath home dirs before comparison (#1803) 2026-06-17 16:21:08 +00:00
Yifei Sun bb9c29c193 homebrew: address bundle command new CLI flag requirements 2026-06-17 18:15:07 +02:00
Ihar Hrachyshka 08278afff6 users: realpath home dirs before comparison
When we create users with homedir under /var, they end up with
NFSHomeDirectory under /private/var because /var is a symlink. This
breaks consequent activations and requires that user overrides their
home dir attribute with /private/var/... to pass the activation
precheck.

`realpath` should normalize the discrepancy.
2026-06-14 20:54:47 -10:00
SamandGitHub aabb2037ed flake.lock: update nixpkgs (#1799) 2026-06-12 05:33:53 +00:00
SamandGitHub 0bddd7a5ed time: remove double condition (#1800) 2026-06-12 05:32:59 +00:00
SandroandGitHub 9f8122dd2b time: remove double condition 2026-06-11 20:52:34 +02:00
ben 818b88b75f flake.lock: update nixpkgs 2026-06-11 10:06:13 -07:00
SamandGitHub d0d0978f34 Fix typo (#1798) 2026-06-11 16:43:09 +00:00
SandroandGitHub ace757665e Fix typo 2026-06-11 17:58:55 +02:00
SamandGitHub d9ffa378a6 github-runner: remove node20 runtime from defaults (#1796) 2026-06-11 15:00:05 +00:00
Yuriy Taraday b317d77bbf github-runner: remove node20 runtime from defaults
It's marked as insecure starting with 26.05, and now github-runner package defaults to supporting only node24
See https://github.com/NixOS/nixpkgs/pull/524856
2026-06-11 14:02:39 +02:00
SamandGitHub f73cbf1f65 (feature) Add swapEscapeAndCapsLock and swapRightCommandAndRightOption (#1706) 2026-06-11 06:46:22 +00:00
SamandGitHub 958c16ba9a spacebar: add default package (#1786) 2026-06-11 05:59:41 +00:00
Ethan Carter Edwards 4bcdd687ca spacebar: add default package
Upstream should be the default.

Signed-off-by: Ethan Carter Edwards <ethan@ethancedwards.com>
2026-06-08 11:41:05 -07:00
Gaetan Lepage 3f0f0ece39 feat(keyboard): add swapRightCommandAndRightOption 2026-06-08 10:42:29 +02:00
Gaetan Lepage 57ff7cbd20 feat(keyboard): add swapCapsLockAndEscape 2026-06-08 10:42:29 +02:00
SamandGitHub 6a771120d6 version: bump to 26.11 (#1782) 2026-06-07 01:23:23 +00:00
Sam f8531f95fe tests/github-runners: limit to supported node runtimes 2026-05-26 08:50:22 -07:00
Sam 7c3d11b160 modules/terminfo: update list of packages with terminfo 2026-05-26 08:29:42 -07:00
Sam 8073b91aa3 scripts/release: init
This script has not yet been tested in its entirety, but the file
editing operations were used for #1781 and #1782
2026-05-26 08:29:18 -07:00
Sam ae3e2b18d3 flake.lock: update
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/af84f9d270d404c17699522fab95bbf928a2d92f' (2025-12-17)
  → 'github:NixOS/nixpkgs/d849bb215dcdf71bce3e686839ccdb4219e84b2f' (2026-05-24)
2026-05-25 13:16:30 -07:00
Sam 82325d90a1 version: bump to 26.11 2026-05-25 13:08:31 -07:00
25 changed files with 844 additions and 56 deletions
+2 -2
View File
@@ -4,10 +4,10 @@ on:
merge_group:
push:
branches:
- nix-darwin-26.05
- master
env:
NIXPKGS_BRANCH: nixpkgs-26.05-darwin
NIXPKGS_BRANCH: nixpkgs-unstable
NIX_VERSION: 2.24.11
jobs:
+1 -1
View File
@@ -156,7 +156,7 @@
`nix.daemonIONice` was renamed to `nix.daemonIOLowPriority`, and
`nix.daemonNiceLevel` was removed in favor a new option
`nix.nix.daemonProcessType`.
`nix.daemonProcessType`.
2021-01-16
- Added `homebrew` module, to manage formulas installed by Homebrew via `brew bundle`.
+228 -1
View File
@@ -1,3 +1,230 @@
[<img src="https://github.com/user-attachments/assets/0e1a77ac-6739-4153-bd24-abd3a5e143f5" width="200px" alt="logo" />](https://github.com/nix-darwin/nix-darwin)
# nix-darwin
This is the 26.05 release branch of nix-darwin. See [the main readme](https://github.com/nix-darwin/nix-darwin#readme) for documentation
[![Test](https://github.com/nix-darwin/nix-darwin/actions/workflows/test.yml/badge.svg)](https://github.com/nix-darwin/nix-darwin/actions/workflows/test.yml)
Nix modules for darwin, `/etc/nixos/configuration.nix` for macOS.
This project aims to bring the convenience of a declarative system approach to macOS.
nix-darwin is built up around [Nixpkgs](https://github.com/NixOS/nixpkgs), quite similar to [NixOS](https://nixos.org/).
## Prerequisites
The only prerequisite is a Nix implementation; both Nix and Lix are supported.
As the official Nix installer does not include an automated uninstaller, and manual uninstallation on macOS is a complex process, we recommend using the [Lix installer](https://lix.systems/install/#on-any-other-linuxmacos-system), which supports both flake-based and channel-based setups.
The installer you use doesn't affect which Nix interpreter your system will use later on. nix-darwin manages the Nix installation by default and will default to upstream Nix. If you wish to use Lix instead of Nix, set `nix.package = pkgs.lix` in your configuration.
## Getting started
Despite being an experimental feature in Nix currently, nix-darwin recommends that beginners use flakes to manage their nix-darwin configurations.
<details>
<summary>Flakes (Recommended for beginners)</summary>
### Step 1. Creating `flake.nix`
<details>
<summary>Getting started from scratch</summary>
<p></p>
If you don't have an existing `configuration.nix`, you can run the following commands to generate a basic `flake.nix` inside `/etc/nix-darwin`:
```bash
sudo mkdir -p /etc/nix-darwin
sudo chown $(id -nu):$(id -ng) /etc/nix-darwin
cd /etc/nix-darwin
# To use Nixpkgs unstable:
nix flake init -t nix-darwin/master
# To use Nixpkgs 26.05:
nix flake init -t nix-darwin/nix-darwin-26.05
sed -i '' "s/simple/$(scutil --get LocalHostName)/" flake.nix
```
Make sure to check if `nixpkgs.hostPlatform` is set to either `x86_64-darwin` for Intel or `aarch64-darwin` for Apple Silicon.
</details>
<details>
<summary>Migrating from an existing configuration.nix</summary>
<p></p>
Add the following to `flake.nix` in the same folder as `configuration.nix`:
```nix
{
description = "John's darwin system";
inputs = {
# Use `github:NixOS/nixpkgs/nixpkgs-26.05-darwin` to use Nixpkgs 26.05.
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
# Use `github:nix-darwin/nix-darwin/nix-darwin-26.05` to use Nixpkgs 26.05.
nix-darwin.url = "github:nix-darwin/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = inputs@{ self, nix-darwin, nixpkgs }: {
darwinConfigurations."Johns-MacBook" = nix-darwin.lib.darwinSystem {
modules = [ ./configuration.nix ];
};
};
}
```
Make sure to replace `Johns-MacBook` with your hostname which you can find by running `scutil --get LocalHostName`.
Make sure to set `nixpkgs.hostPlatform` in your `configuration.nix` to either `x86_64-darwin` (Intel) or `aarch64-darwin` (Apple Silicon).
</details>
### Step 2. Installing `nix-darwin`
Unlike NixOS, `nix-darwin` does not have an installer, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command:
```bash
# To use Nixpkgs unstable:
sudo nix run nix-darwin/master#darwin-rebuild -- switch
# To use Nixpkgs 26.05:
sudo nix run nix-darwin/nix-darwin-26.05#darwin-rebuild -- switch
```
### Step 3. Using `nix-darwin`
After installing, you can run `darwin-rebuild` to apply changes to your system:
```bash
sudo darwin-rebuild switch
```
#### Using flake inputs
Inputs from the flake can also be passed into `darwinSystem`. These inputs are then
accessible as an argument `inputs`, similar to `pkgs` and `lib`, inside the configuration.
```nix
# in flake.nix
nix-darwin.lib.darwinSystem {
modules = [ ./configuration.nix ];
specialArgs = { inherit inputs; };
}
```
```nix
# in configuration.nix
{ pkgs, lib, inputs }:
# inputs.self, inputs.nix-darwin, and inputs.nixpkgs can be accessed here
```
</details>
<details>
<summary>Channels</summary>
### Step 1. Creating `configuration.nix`
Copy the [simple](./modules/examples/simple.nix) example to `/etc/nix-darwin/configuration.nix`.
### Step 2. Adding `nix-darwin` channel
```bash
# If you use Nixpkgs unstable (the default):
sudo nix-channel --add https://github.com/nix-darwin/nix-darwin/archive/master.tar.gz darwin
# If you use Nixpkgs 26.05:
sudo nix-channel --add https://github.com/nix-darwin/nix-darwin/archive/nix-darwin-26.05.tar.gz darwin
sudo nix-channel --update
```
### Step 3. Installing `nix-darwin`
To install `nix-darwin`, you can just run `darwin-rebuild switch` to install nix-darwin. As `darwin-rebuild` won't be installed in your `PATH` yet, you can use the following command:
```bash
nix-build '<darwin>' -A darwin-rebuild
sudo ./result/bin/darwin-rebuild switch -I darwin-config=/etc/nix-darwin/configuration.nix
```
### Step 4. Using `nix-darwin`
After installing, you can run `darwin-rebuild` to apply changes to your system:
```bash
sudo darwin-rebuild switch
```
### Step 5. Updating `nix-darwin`
You can update Nixpkgs and `nix-darwin` using the following command:
```bash
sudo nix-channel --update
```
</details>
## Documentation
The reference documentation is available:
* Online: [nix-darwin reference](https://nix-darwin.github.io/nix-darwin/manual/index.html)
* Locally in your browser via the `darwin-help` command
* As a manual page via `man 5 configuration.nix`
## Uninstalling
To run the latest version of the uninstaller, you can run the following command:
```
sudo nix --extra-experimental-features "nix-command flakes" run nix-darwin#darwin-uninstaller
```
If that command doesn't work for you, you can try the locally installed uninstaller:
```
sudo darwin-uninstaller
```
## Tests
There are basic tests that run sanity checks for some of the modules,
you can run them like this:
```bash
# run all tests
nix-build release.nix -A tests
# or just a subset
nix-build release.nix -A tests.environment-path
```
## Contributing
Let's make Nix on macOS awesome!
Don't hesitate to contribute modules or open an issue.
To build your configuration with local changes you can run this. This
flag can also be used to override darwin-config or nixpkgs, for more
information on the `-I` flag look at the nix-build [manpage](https://nixos.org/manual/nix/stable/command-ref/nix-build.html).
```bash
sudo darwin-rebuild switch -I darwin=.
```
If you're adding a module, please add yourself to `meta.maintainers`, for example
```nix
meta.maintainers = [
lib.maintainers.alice or "alice"
];
options.services.alicebot = # ...
```
The `or` operator takes care of graceful degradation when `lib` from Nixpkgs
goes out of sync.
Feel free to contact us on Matrix if you have questions:
* **User support:** [#macos:nixos.org](https://matrix.to/#/#macos:nixos.org)
* **Development discussion:** [#nix-darwin-dev:nixos.org](https://matrix.to/#/#nix-darwin-dev:nixos.org)
+1 -2
View File
@@ -94,8 +94,7 @@ in rec {
--stylesheet highlightjs/mono-blue.css \
--script ./highlightjs/highlight.pack.js \
--script ./highlightjs/loader.js \
--toc-depth 1 \
--chunk-toc-depth 1 \
--sidebar-depth 1 \
./manual.md \
$dst/index.html
Generated
+4 -4
View File
@@ -2,16 +2,16 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1779622335,
"narHash": "sha256-ViA62qtL5za7V3d5I8OA9q9JcFhsVAiL5jVHwEclWqk=",
"lastModified": 1783279667,
"narHash": "sha256-/NAkDSsve+GNM0Bt6tleJdCGfsTlK89nPjkVOzZMo0s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "705e9929918b43bd7b715dc0a878ac870449bb03",
"rev": "f205b5574fd0cb7da5b702a2da51507b7f4fdd1b",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-26.05-darwin",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
+1 -1
View File
@@ -2,7 +2,7 @@
description = "A collection of darwin modules";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-26.05-darwin";
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
};
outputs = { self, nixpkgs }: let
+2 -2
View File
@@ -2,8 +2,8 @@
description = "Example nix-darwin system flake";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-26.05-darwin";
nix-darwin.url = "github:nix-darwin/nix-darwin/nix-darwin-26.05";
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
nix-darwin.url = "github:nix-darwin/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
};
+23 -22
View File
@@ -151,7 +151,7 @@ let
};
description = ''
Extra environment variables to set when {command}`nix-darwin` invokes
{command}`brew bundle [install]` during system activation.
{command}`brew bundle [install]` during system checks and activation.
Useful for setting Homebrew's `HOMEBREW_NO_*` variables (e.g.,
`HOMEBREW_NO_ENV_HINTS`, `HOMEBREW_NO_ANALYTICS`, `HOMEBREW_NO_UPDATE_REPORT_NEW`)
@@ -172,18 +172,31 @@ let
'';
};
brewBundleCmd = mkInternalOption { type = types.str; };
brewBundleCmd = mkInternalOption { type = types.functionTo types.str; };
};
config = {
brewBundleCmd = concatStringsSep " " (
optional (!config.autoUpdate) "HOMEBREW_NO_AUTO_UPDATE=1"
brewBundleCmd = { onlyCheck }: concatStringsSep " " (
[
''PATH="${cfg.prefix}/bin:${lib.makeBinPath [ pkgs.mas ]}:$PATH"''
"sudo"
"--preserve-env=PATH"
"--user=${escapeShellArg cfg.user}"
"--set-home"
"env"
]
++ optional (onlyCheck || !config.autoUpdate) "HOMEBREW_NO_AUTO_UPDATE=1"
++ mapAttrsToList (k: v: "${k}=${escapeShellArg v}") config.extraEnv
++ [ "brew bundle --file='${brewfileFile}'" ]
++ optional (!config.upgrade) "--no-upgrade"
++ optional (config.cleanup == "uninstall") "--force-cleanup"
++ optional (config.cleanup == "zap") "--zap --force-cleanup"
++ config.extraFlags
++ (
if onlyCheck then
[ "cleanup 2>&1" ]
else
optional (!config.upgrade) "--no-upgrade"
++ optional (config.cleanup == "uninstall") "--force-cleanup"
++ optional (config.cleanup == "zap") "--zap --force-cleanup"
++ config.extraFlags
)
);
};
};
@@ -995,13 +1008,7 @@ in
system.checks.text = mkIf (cfg.enable && cfg.onActivation.cleanup == "check") ''
if [ -f "${cfg.prefix}/bin/brew" ]; then
homebrewCleanupExitCode=0
homebrewCleanupResult=$(PATH="${cfg.prefix}/bin:${lib.makeBinPath [ pkgs.mas ]}:$PATH" \
sudo \
--preserve-env=PATH \
--user=${escapeShellArg cfg.user} \
--set-home \
env HOMEBREW_NO_AUTO_UPDATE=1 \
brew bundle cleanup --file='${brewfileFile}' 2>&1) || homebrewCleanupExitCode=$?
homebrewCleanupResult=$(${cfg.onActivation.brewBundleCmd { onlyCheck = true; }}) || homebrewCleanupExitCode=$?
if [ "$homebrewCleanupExitCode" -eq 1 ]; then
printf >&2 '\e[1;31merror: found Homebrew packages not listed in the Brewfile, aborting activation\e[0m\n'
printf >&2 '%s\n' "$homebrewCleanupResult"
@@ -1023,13 +1030,7 @@ in
# Homebrew Bundle
echo >&2 "Homebrew bundle..."
if [ -f "${cfg.prefix}/bin/brew" ]; then
PATH="${cfg.prefix}/bin:${lib.makeBinPath [ pkgs.mas ]}:$PATH" \
sudo \
--preserve-env=PATH \
--user=${escapeShellArg cfg.user} \
--set-home \
env \
${cfg.onActivation.brewBundleCmd}
${cfg.onActivation.brewBundleCmd { onlyCheck = false; }}
else
echo -e "\e[1;31merror: Homebrew is not installed, skipping...\e[0m" >&2
fi
+2
View File
@@ -108,10 +108,12 @@
./programs/_1password-gui.nix
./programs/arqbackup.nix
./programs/bash
./programs/devenv.nix
./programs/direnv.nix
./programs/fish.nix
./programs/gnupg.nix
./programs/man.nix
./programs/mas.nix
./programs/info
./programs/nix-index
./programs/ssh.nix
+1 -1
View File
@@ -138,7 +138,7 @@ in
type = configType;
description = ''
Global configuration for Nixpkgs.
The complete list of [Nixpkgs configuration options](https://nixos.org/manual/nixpkgs/stable/#sec-config-options-reference) is in the [Nixpkgs manual section on global configuration](https://nixos.org/manual/nixpkgs/stable/#chap-packageconfig).
The complete list of [Nixpkgs configuration options](https://nixos.org/manual/nixpkgs/unstable/#sec-config-options-reference) is in the [Nixpkgs manual section on global configuration](https://nixos.org/manual/nixpkgs/unstable/#chap-packageconfig).
Ignored when {option}`nixpkgs.pkgs` is set.
'';
+53
View File
@@ -0,0 +1,53 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.devenv;
hook = shell: "${lib.getExe cfg.package} hook ${shell}";
in
{
meta.maintainers = [
lib.maintainers.domenkozar or "domenkozar"
lib.maintainers.sandydoo or "sandydoo"
lib.maintainers.anish or "anish"
];
options.programs.devenv = {
enable = lib.mkEnableOption "devenv, fast, declarative, reproducible and composable developer environments";
package = lib.mkPackageOption pkgs "devenv" { };
enableBashIntegration = lib.mkEnableOption "auto-activation of devenv environments in Bash" // {
default = true;
};
enableFishIntegration = lib.mkEnableOption "auto-activation of devenv environments in Fish" // {
default = true;
};
enableZshIntegration = lib.mkEnableOption "auto-activation of devenv environments in Zsh" // {
default = true;
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
programs.bash.interactiveShellInit = lib.mkIf cfg.enableBashIntegration ''
eval "$(${hook "bash"})"
'';
programs.fish.interactiveShellInit = lib.mkIf cfg.enableFishIntegration ''
${hook "fish"} | source
'';
programs.zsh.interactiveShellInit = lib.mkIf cfg.enableZshIntegration ''
eval "$(${hook "zsh"})"
'';
};
}
+209
View File
@@ -0,0 +1,209 @@
{
config,
lib,
options,
pkgs,
...
}:
let
inherit (lib)
attrValues
concatStringsSep
escapeShellArg
getExe
literalExpression
mapAttrsToList
mkEnableOption
mkIf
mkOption
mkOptionDefault
mkPackageOption
optionalString
types
;
cfg = config.programs.mas;
apps = mapAttrsToList (name: id: { inherit name id; }) cfg.packages;
desiredIds = map (app: toString app.id) apps;
homebrewIds = map toString (attrValues config.homebrew.masApps);
hasWork = cfg.update || cfg.packages != { } || cfg.cleanup || homebrewIds != [ ];
activationScript =
if hasWork then
''
echo >&2 "setting up App Store apps (mas)..."
runAsUser() {
sudo \
--preserve-env=PATH \
--set-home \
--user=${escapeShellArg cfg.user} \
"$@"
}
listStatus=0
listOutput=$(
runAsUser ${getExe cfg.package} list 2>&1
) || listStatus=$?
if (( listStatus != 0 )); then
echo >&2 "warning: mas list failed (exit ''${listStatus}):"
echo >&2 "''${listOutput}"
if echo "''${listOutput}" | grep -qi "not signed in"; then
echo >&2 "login required; skipping App Store installs/updates/cleanup"
exit 0
fi
fi
# Only emit cleanup-only shell variables when cleanup is enabled; otherwise shellcheck
# treats them as unused and fails the activation script build.
installedIds=()
${if cfg.cleanup then
''
# Parse mas list output: "ID AppName (version)"
declare -A installedApps
while IFS= read -r line; do
[[ -z "$line" ]] && continue
line="''${line#"''${line%%[![:space:]]*}"}"
id="''${line%% *}"
rest="''${line#"$id"}"
rest="''${rest#"''${rest%%[![:space:]]*}"}"
name="''${rest% (*}"
name="''${name%"''${name##*[![:space:]]}"}"
[[ -n "$id" ]] && {
installedIds+=( "$id" )
installedApps["$id"]="$name"
}
done <<<"$listOutput"
''
else
''
while IFS= read -r line; do
[[ -z "$line" ]] && continue
line="''${line#"''${line%%[![:space:]]*}"}"
id="''${line%% *}"
[[ -n "$id" ]] && installedIds+=( "$id" )
done <<<"$listOutput"
''}
${optionalString cfg.update ''
runAsUser ${getExe cfg.package} update || true
''}
desiredIds=(
${concatStringsSep "\n " desiredIds}
)
is_installed() {
local needle=$1
for id in "''${installedIds[@]}"; do
if [[ "$id" == "$needle" ]]; then
return 0
fi
done
return 1
}
${optionalString (cfg.packages != { }) ''
for appId in "''${desiredIds[@]}"; do
if is_installed "$appId"; then
continue
fi
runAsUser ${getExe cfg.package} install "$appId" || true
done
''}
${optionalString cfg.cleanup ''
homebrewIds=(
${concatStringsSep "\n " homebrewIds}
)
keepIds=( "''${desiredIds[@]}" "''${homebrewIds[@]}" )
for installedId in "''${installedIds[@]}"; do
keep=false
for keepId in "''${keepIds[@]}"; do
if [[ "$installedId" == "$keepId" ]]; then
keep=true
break
fi
done
if ! $keep; then
appName="''${installedApps[$installedId]:-$installedId}"
echo >&2 "removing $appName from App Store"
runAsUser ${getExe cfg.package} uninstall "$installedId" || true
fi
done
''}
''
else
"";
in
{
options.programs.mas = {
enable = mkEnableOption "managing Mac App Store apps with mas";
user = mkOption {
type = types.str;
default = config.system.primaryUser;
defaultText = literalExpression "config.system.primaryUser";
description = ''
The user account that runs {command}`mas`. This user must be signed into the Mac App Store
for installs or updates to succeed.
'';
};
package = mkPackageOption pkgs "mas" { };
packages = mkOption {
type = types.attrsOf types.ints.positive;
default = { };
example = literalExpression ''
{
Xcode = 497799835;
"1Password for Safari" = 1569813296;
}
'';
description = ''
Applications to install from the Mac App Store. Attribute names are only for readability;
values must be the numeric identifiers used by {command}`mas`.
'';
};
update = mkOption {
type = types.bool;
default = true;
description = ''
Whether to run {command}`mas update` during system activation in addition to installing the
configured apps.
'';
};
cleanup = mkOption {
type = types.bool;
default = false;
description = ''
Whether to uninstall Mac App Store apps that are currently installed but not listed in
{option}`programs.mas.packages`. Apps listed in {option}`homebrew.masApps` are also preserved.
This runs before install/update; any app id not in either set will be removed.
'';
};
};
config = {
system.requiresPrimaryUser =
mkIf (cfg.enable && options.programs.mas.user.highestPrio == (mkOptionDefault { }).priority)
[
"programs.mas.enable"
];
environment.systemPackages = mkIf cfg.enable [ cfg.package ];
system.activationScripts.mas.text = mkIf cfg.enable activationScript;
};
}
+1
View File
@@ -27,6 +27,7 @@ in
services.spacebar.package = mkOption {
type = path;
default = pkgs.spacebar;
description = "The spacebar package to use.";
};
+1
View File
@@ -134,6 +134,7 @@ in
${cfg.activationScripts.keyboard.text}
${cfg.activationScripts.fonts.text}
${cfg.activationScripts.nvram.text}
${cfg.activationScripts.mas.text}
${cfg.activationScripts.homebrew.text}
${cfg.activationScripts.postActivation.text}
+28
View File
@@ -38,6 +38,18 @@ in
description = "Whether to swap the left Command key and left Alt key.";
};
system.keyboard.swapRightCommandAndRightOption = mkOption {
type = types.bool;
default = false;
description = "Whether to swap the right Command key and right Option key.";
};
system.keyboard.swapCapsLockAndEscape = mkOption {
type = types.bool;
default = false;
description = "Whether to swap the Caps Lock key and Escape key.";
};
system.keyboard.swapLeftCtrlAndFn = mkOption {
type = types.bool;
default = false;
@@ -64,6 +76,14 @@ in
(mkIf cfg.remapCapsLockToControl { HIDKeyboardModifierMappingSrc = 30064771129; HIDKeyboardModifierMappingDst = 30064771296; })
(mkIf cfg.remapCapsLockToEscape { HIDKeyboardModifierMappingSrc = 30064771129; HIDKeyboardModifierMappingDst = 30064771113; })
(mkIf cfg.nonUS.remapTilde { HIDKeyboardModifierMappingSrc = 30064771172; HIDKeyboardModifierMappingDst = 30064771125; })
(mkIf cfg.swapCapsLockAndEscape {
HIDKeyboardModifierMappingSrc = 30064771129;
HIDKeyboardModifierMappingDst = 30064771113;
})
(mkIf cfg.swapCapsLockAndEscape {
HIDKeyboardModifierMappingSrc = 30064771113;
HIDKeyboardModifierMappingDst = 30064771129;
})
(mkIf cfg.swapLeftCommandAndLeftAlt {
HIDKeyboardModifierMappingSrc = 30064771299;
HIDKeyboardModifierMappingDst = 30064771298;
@@ -72,6 +92,14 @@ in
HIDKeyboardModifierMappingSrc = 30064771298;
HIDKeyboardModifierMappingDst = 30064771299;
})
(mkIf cfg.swapRightCommandAndRightOption {
HIDKeyboardModifierMappingSrc = 30064771303;
HIDKeyboardModifierMappingDst = 30064771302;
})
(mkIf cfg.swapRightCommandAndRightOption {
HIDKeyboardModifierMappingSrc = 30064771302;
HIDKeyboardModifierMappingDst = 30064771303;
})
(mkIf cfg.swapLeftCtrlAndFn {
HIDKeyboardModifierMappingSrc = 30064771296;
HIDKeyboardModifierMappingDst = 1095216660483;
+6 -13
View File
@@ -3,19 +3,8 @@
with lib;
let
cfg = config.time;
timeZone = optionalString (cfg.timeZone != null) ''
if ! systemsetup -listtimezones | grep -q "^ ${cfg.timeZone}$"; then
echo "${cfg.timeZone} is not a valid timezone. The command 'listtimezones' will show a list of valid time zones." >&2
false
fi
systemsetup -settimezone "${cfg.timeZone}" 2>/dev/null 1>&2
'';
in
{
options = {
@@ -37,8 +26,12 @@ in
system.activationScripts.time.text = mkIf (cfg.timeZone != null) ''
# Set defaults
echo "configuring time..." >&2
${timeZone}
if ! systemsetup -listtimezones | grep -q "^ ${cfg.timeZone}$"; then
echo "${cfg.timeZone} is not a valid timezone. The command 'listtimezones' will show a list of valid time zones." >&2
false
fi
systemsetup -settimezone "${cfg.timeZone}" 2>/dev/null 1>&2
'';
};
@@ -21,6 +21,17 @@ _arguments \
'(--keep-going -k)'{--keep-going,-k}"[keep going until all builds are finished]"\
'(--keep-failed -K)'{--keep-failed,-K}'[keep failed builds (usually in /tmp)]'\
'--fallback[If binary download fails, fall back on building from source]'\
'--flake[Build from the given flake URI]:flake uri:'\
'--no-flake[Disable implicit flake detection]'\
'(-L --print-build-logs)'{-L,--print-build-logs}'[Print build logs during the build]'\
'--refresh[Refresh flake inputs]'\
'--impure[Allow impure evaluation for flakes]'\
'--recreate-lock-file[Recreate flake.lock from scratch]'\
'*--update-input[Update a specific flake input]:input name:'\
'*--override-input[Override a flake input]:input name: :flake url: '\
'--offline[Do not access the network]'\
'--dry-run[Show what would be done without making changes]'\
'-Q[Only print the resulting store path]'\
'--show-trace[Print stack trace of evaluation errors]'\
'*--option[set Nix configuration option]:options:_nix_options:value:_nix_options_value'\
'*--arg[argument to pass to the Nix function]:Name:_nix_complete_function_arg:Value: '\
+3
View File
@@ -94,7 +94,10 @@ in {
tests.nix-enable = makeTest ./tests/nix-enable.nix;
tests.nixpkgs-overlays = makeTest ./tests/nixpkgs-overlays.nix;
tests.nixpkgs-config-allow-unfree = makeTest ./tests/nixpkgs-config-allow-unfree.nix;
tests.programs-devenv = makeTest ./tests/programs-devenv.nix;
tests.programs-gnupg = makeTest ./tests/programs-gnupg.nix;
tests.programs-mas = makeTest ./tests/programs-mas.nix;
tests.programs-mas-no-cleanup = makeTest ./tests/programs-mas-no-cleanup.nix;
tests.programs-ssh = makeTest ./tests/programs-ssh.nix;
tests.programs-tmux = makeTest ./tests/programs-tmux.nix;
tests.programs-zsh = makeTest ./tests/programs-zsh.nix;
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
set -euo pipefail
git checkout master
git pull
version=$(jq -r .release version.json)
# branch off ${version}
echo "Cutting nix-darwin-${version} release branch"
git checkout -b "nix-darwin-${version}"
sed -i -e "s!- master!- nix-darwin-${version}!" .github/workflows/test.yml
sed -i -e "s!NIXPKGS_BRANCH: nixpkgs-unstable!NIXPKGS_BRANCH: nixpkgs-${version}-darwin!" .github/workflows/test.yml
sed -i -e "s!nixpkgs-unstable!nixpkgs-${version}-darwin!" modules/examples/flake/flake.nix
sed -i -e "s!github:nix-darwin/nix-darwin/master!github:nix-darwin/nix-darwin/nix-darwin-${version}!" modules/examples/flake/flake.nix
sed -i -e "s!nixpkgs/unstable!nixpkgs/stable!g" modules/nix/nixpkgs.nix
sed -i -e "s!nixpkgs-unstable!nixpkgs-${version}-darwin!" flake.nix
nix flake lock
cat <<EOF > README.md
# nix-darwin
This is the ${version} release branch of nix-darwin. See [the main readme](https://github.com/nix-darwin/nix-darwin#readme) for documentation
EOF
cat <<EOF > version.json
{
"release": "${version}",
"isReleaseBranch": true
}
EOF
git add .
git commit -m "version: branch off ${version}"
# update master
echo "Updating master to point to next version"
git checkout master
## update version.json to point to the next version
IFS='.' read -r major minor <<< "$version"
if [[ "$minor" = "11" ]]; then
major=$(( major + 1 ))
minor="05"
else
minor="11"
fi
cat <<EOF > version.json
{
"release": "${major}.${minor}",
"isReleaseBranch": false
}
EOF
## update readme so that instructions refer to the version we're cutting (our supported stable version)
sed -i -e "s![0-9][0-9]\.[0-9][0-9]!${version}!g" README.md
git add .
git commit -m "version: bump to ${major}.${minor}"
nix flake update
git add .
git commit -m "flake.lock: update"
+9 -5
View File
@@ -1,5 +1,9 @@
{ config, ... }:
let
brewBundleInstallCmd = config.homebrew.onActivation.brewBundleCmd { onlyCheck = false; };
in
{
homebrew.enable = true;
homebrew.user = "test-homebrew-user";
@@ -7,12 +11,12 @@
test = ''
echo "checking that cleanup check is present in system checks" >&2
grep 'brew bundle cleanup --file=' ${config.out}/activate
grep "brew bundle --file='.*-Brewfile' cleanup" ${config.out}/activate
echo "checking that brew bundle command does not have --cleanup flag" >&2
if echo "${config.homebrew.onActivation.brewBundleCmd}" | grep -F -- '--cleanup' > /dev/null; then
echo "Expected no --cleanup flag in brewBundleCmd"
echo "Actual: ${config.homebrew.onActivation.brewBundleCmd}"
echo "checking that brew bundle [install] command does not have --cleanup flag" >&2
if echo "${brewBundleInstallCmd}" | grep -F -- '--cleanup' > /dev/null; then
echo "Expected no --cleanup flag in brewBundleInstallCmd"
echo "Actual: ${brewBundleInstallCmd}"
exit 1
fi
'';
+42
View File
@@ -0,0 +1,42 @@
{
config,
lib,
pkgs,
...
}:
let
devenv =
pkgs.runCommand "devenv-0.0.0" { } ''
mkdir -p $out/bin
cat > $out/bin/devenv <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
chmod +x $out/bin/devenv
''
// {
meta.mainProgram = "devenv";
};
in
{
programs.bash.enable = true;
programs.zsh.enable = true;
programs.fish.enable = true;
programs.devenv = {
enable = true;
package = devenv;
};
test = ''
echo >&2 "checking devenv bash integration in /etc/bashrc"
grep 'devenv hook bash' ${config.out}/etc/bashrc
echo >&2 "checking devenv zsh integration in /etc/zshrc"
grep 'devenv hook zsh' ${config.out}/etc/zshrc
echo >&2 "checking devenv fish integration in /etc/fish/config.fish"
grep 'devenv hook fish' ${config.out}/etc/fish/config.fish
'';
}
+60
View File
@@ -0,0 +1,60 @@
{
config,
pkgs,
...
}:
let
mas =
pkgs.runCommand "mas-0.0.0" { } ''
mkdir -p $out/bin
cat > $out/bin/mas <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
chmod +x $out/bin/mas
''
// {
meta.mainProgram = "mas";
};
in
{
system.primaryUser = "primary-mas-user";
programs.mas = {
enable = true;
user = "test-mas-user";
package = mas;
update = true;
cleanup = false;
packages = {
Xcode = 497799835;
};
};
homebrew.masApps = {
"KeepFromHomebrew" = 424242;
};
test = ''
echo "checking mas present in systemPackages" >&2
test -x ${config.out}/sw/bin/mas
echo "checking mas activation script still installs and updates apps" >&2
grep 'desiredIds=(' ${config.out}/activate
grep '497799835' ${config.out}/activate
grep 'mas install \"$appId\"' ${config.out}/activate
grep 'mas update' ${config.out}/activate
echo "checking cleanup-only variables are omitted" >&2
if grep 'declare -A installedApps' ${config.out}/activate; then
echo "unexpected installedApps declaration when cleanup is disabled" >&2
exit 1
fi
if grep 'keepIds=(' ${config.out}/activate; then
echo "unexpected keepIds declaration when cleanup is disabled" >&2
exit 1
fi
'';
}
+71
View File
@@ -0,0 +1,71 @@
{
config,
lib,
pkgs,
...
}:
let
mas =
pkgs.runCommand "mas-0.0.0" { } ''
mkdir -p $out/bin
cat > $out/bin/mas <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
chmod +x $out/bin/mas
''
// {
meta.mainProgram = "mas";
};
in
{
system.primaryUser = "primary-mas-user";
programs.mas = {
enable = true;
user = "test-mas-user";
package = mas;
update = true;
cleanup = true;
packages = {
"1Password for Safari" = 1569813296;
Xcode = 497799835;
};
};
homebrew.masApps = {
"KeepFromHomebrew" = 424242;
};
test = ''
echo "checking mas present in systemPackages" >&2
test -x ${config.out}/sw/bin/mas
echo "checking mas activation script uses requested user" >&2
grep -- '--user=test-mas-user' ${config.out}/activate
echo "checking mas desired ids are present" >&2
grep 'desiredIds=(' ${config.out}/activate
grep '1569813296' ${config.out}/activate
grep '497799835' ${config.out}/activate
echo "checking mas install loop exists" >&2
grep 'mas install \"$appId\"' ${config.out}/activate
echo "checking mas update is triggered" >&2
grep 'mas update' ${config.out}/activate
echo "checking mas parses installedApps from mas list" >&2
grep 'declare -A installedApps' ${config.out}/activate
grep 'installedApps\[' ${config.out}/activate
echo "checking mas cleanup log and uninstall" >&2
grep 'removing .* from App Store' ${config.out}/activate
grep 'runAsUser .*/mas uninstall' ${config.out}/activate
echo "checking homebrew.masApps ids are kept during cleanup" >&2
grep 'homebrewIds=(' ${config.out}/activate
grep '424242' ${config.out}/activate
'';
}
+8
View File
@@ -5,20 +5,28 @@
system.keyboard.remapCapsLockToControl = true;
system.keyboard.remapCapsLockToEscape = true;
system.keyboard.nonUS.remapTilde = true;
system.keyboard.swapCapsLockAndEscape = true;
system.keyboard.swapLeftCommandAndLeftAlt = true;
system.keyboard.swapRightCommandAndRightOption = true;
system.keyboard.swapLeftCtrlAndFn = true;
test = ''
echo checking keyboard mappings in /activate >&2
grep "hidutil property --set '{\"UserKeyMapping\":.*}'" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingSrc\":30064771129" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingSrc\":30064771113" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingSrc\":30064771172" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771113" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771125" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771129" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771296" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771298" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771299" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771296" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingSrc\":30064771303" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingSrc\":30064771302" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771302" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":30064771303" ${config.out}/activate
grep "\"HIDKeyboardModifierMappingDst\":1095216660483" ${config.out}/activate
'';
}
+2 -2
View File
@@ -1,4 +1,4 @@
{
"release": "26.05",
"isReleaseBranch": true
"release": "26.11",
"isReleaseBranch": false
}