Skip to content

Commit

Permalink
refactor: use platform helpers to set defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
z0al committed Jan 2, 2025
1 parent 787e835 commit 4f317b2
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 93 deletions.
4 changes: 1 addition & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

outputs =
{ self
, nixpkgs
, nix-darwin
, flake-parts
, ...
}@inputs:
Expand All @@ -26,7 +24,7 @@
perSystem = { pkgs, system, ... }:
let
tests = import ./tests/setup.nix {
inherit pkgs inputs system;
inherit self pkgs inputs system;
};

docs = import ./docs {
Expand Down
72 changes: 28 additions & 44 deletions modules/_impl.nix
Original file line number Diff line number Diff line change
@@ -1,58 +1,28 @@
{ pkgs, lib, ... }:
{ config, lib, ... }:

let
writePlist = configuration: with lib;
purgePlist = defaults:
let
# We can only serialize values that are not null to *.plist files
# The rest will be mapped to deletion commands
writable = conf:
filterAttrs
(domain: attrs: attrs != { })
(mapAttrs
(domain: attrs:
(filterAttrs (n: v: v != null) attrs))
conf);

deletable = conf:
mapAttrs
lib.mapAttrs
(domain: attrs:
(filterAttrs (n: v: v == null) attrs))
conf;

toPlist = domain: attrs:
pkgs.writeText "${domain}.plist" (generators.toPlist { } attrs);

importAttrs = conf:
mapAttrsToList
(domain: attrs: ''
/usr/bin/defaults import '${
escapeShellArg domain
}' ${toPlist domain attrs}
'')
(lib.filterAttrs (n: v: v == null) attrs))
conf;

deleteAttrs = conf:
flatten (
mapAttrsToList
lib.flatten (
lib.mapAttrsToList
(domain: attrs:
mapAttrsToList
lib.mapAttrsToList
(key: _value: ''
/usr/bin/defaults delete '${
escapeShellArg domain
}' '${escapeShellArg key}' &> /dev/null || true
lib.escapeShellArg domain
}' '${lib.escapeShellArg key}' &> /dev/null || true
'')
attrs)
conf);
in
concatLines (
(importAttrs (writable configuration)) ++
(deleteAttrs (deletable configuration))
);

reload = ''
# Reload settings
/System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings -u
'';
lib.concatLines (deleteAttrs (deletable defaults));
in

{
Expand All @@ -67,15 +37,29 @@ in
str
]))
);
description = ''
Holds all user defaults assignment made by plist-manager. Its value gets
assigned to either nix-darwin's `system.defaults.*` or home-manager's
`targets.darwin.default.*`.
'';
default = { };
internal = true;
visible = false;
apply = value: ''
set -e
};

${writePlist value}
${reload}
purgeScript = mkOption {
type = types.lines;
description = ''
A script to purge all the unset user defaults. This won't be taken care
of by default by either nix-darwin or home-manager
'';
default = "";
internal = true;
visible = false;
};
};

config = {
plist.purgeScript = purgePlist config.plist.out;
};
}
16 changes: 8 additions & 8 deletions targets/darwin.nix
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{ config, pkgs, ... }:

let
script = pkgs.writeShellScript "plist-darwin-activate" config.plist.out;
fail = msg: "(printf '\\033[0;31m${msg}\\033[0m\n' && exit 1)";
in
{ config, ... }:

{
imports = [
../modules
];

system.defaults.CustomUserPreferences = config.plist.out;

system.activationScripts.postActivation.text = ''
echo "Activating plistManager"
echo "└── Using ${script}"
${script} || ${fail "Failed to run ${script}"}
${config.plist.purgeScript}
# Reload settings
/System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings -u
'';
}
16 changes: 8 additions & 8 deletions targets/home-manager.nix
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{ config, pkgs, lib, ... }:

let
script = pkgs.writeShellScript "plist-home-activate" config.plist.out;
fail = msg: "(printf '\\033[0;31m${msg}\\033[0m\n' && exit 1)";
in
{ config, lib, ... }:

{
imports = [
../modules
];

targets.darwin.defaults = config.plist.out;

home.activation.plistManager = lib.hm.dag.entryAfter [ "setDarwinDefaults" ] ''
echo "└── Using ${script}"
run ${script} || ${fail "Failed to run ${script}"}
set -e
${config.plist.purgeScript}
# Reload settings
/System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings -u
'';
}
56 changes: 26 additions & 30 deletions tests/setup.nix
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{ pkgs
{ self
, pkgs
, inputs
, system
}:

let
lib = pkgs.lib;
with pkgs.lib;

let
buildFromConfig = configuration: sel: sel
(import inputs.nix-darwin {
inherit (inputs) nixpkgs;
Expand All @@ -19,15 +20,23 @@ let
makeTest = name: test:
let
configuration =
{ config, pkgs, lib, ... }:
{ config, pkgs, ... }:

let
defaults = builtins.toJSON
config.system.defaults.CustomUserPreferences;

purgeScript = config.plist.purgeScript;
in

{
imports = [
../modules/_impl.nix
self.darwinModules.default
test
];

options.test = lib.mkOption {
type = lib.types.lines;
options.test = mkOption {
type = types.lines;
};

config = {
Expand All @@ -37,20 +46,17 @@ let
{
nativeBuildInputs = with pkgs; [
jq
jc
ripgrep
];
}
''
set -e
echo ${lib.escapeShellArg config.plist.out} > $out
mkdir -p $out
echo ${escapeShellArg defaults} > $out/defaults.json
echo ${escapeShellArg purgeScript} > $out/purge.sh
# Holds domain context
d=""
# Holds path to the plist file for the domain (if any)
f=""
function Domain {
if [[ -n "$d" ]]; then
echo "Domain end"
Expand All @@ -60,20 +66,10 @@ let
echo ""
echo "Domain start: '$d'"
f=$(rg -PNo "'$d' (/nix/.*plist)" $out -r '$1' || echo None)
echo "Imports -> $f"
}
function Set {
if ! test -e "$f"; then
echo ""
echo "Assertion failed for '$1'. No imports to domain '$d'"
echo ""
exit 1
fi
v=$(cat $f | jc --plist | jq ".\"$1\"")
v=$(cat $out/defaults.json | jq ".\"$d\".\"$1\"")
if [[ "$v" != "$2" ]]; then
echo ""
Expand All @@ -87,20 +83,20 @@ let
echo ""
echo "Full output:"
echo ""
cat $out | sed 's/^/ /'
jq . $out/defaults.json | sed 's/^/ /'
echo ""
exit 1
fi
}
function Del {
if ! grep -q "defaults delete '$d' '$1'" $out; then
if ! grep -q "defaults delete '$d' '$1'" $out/purge.sh; then
echo ""
echo "Expected attribute '$d'.'$1' to be deleted."
echo ""
echo "Actual output:"
echo ""
cat $out | sed 's/^/ /'
cat $out/purge.sh | sed 's/^/ /'
echo ""
exit 1
fi
Expand All @@ -115,10 +111,10 @@ let
buildFromConfig configuration (config: config.system.build.run-test);
in

lib.listToAttrs (map
listToAttrs (map
(file: rec {
name = testName file;
value = makeTest name file;
})
(lib.fileset.toList
(lib.fileset.fileFilter (file: lib.hasPrefix "test-" file.name) ./.)))
(fileset.toList
(fileset.fileFilter (file: hasPrefix "test-" file.name) ./.)))

0 comments on commit 4f317b2

Please sign in to comment.