Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add overrides management #24

Merged
merged 3 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions modules/installer.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ let
else "\${XDG_STATE_HOME:-$HOME/.local/state}/home-manager/gcroots";
stateFile = pkgs.writeText "flatpak-state.json" (builtins.toJSON {
packages = map (builtins.getAttr "appId") cfg.packages;
overrides = cfg.overrides;
});
statePath = "${gcroots}/${stateFile.name}";

Expand Down Expand Up @@ -42,6 +43,40 @@ let
fi
'';

overridesDir =
if (installation == "system")
then "/var/lib/flatpak/overrides"
else "\${XDG_DATA_HOME:-$HOME/.local/share}/flatpak/overrides";
flatpakOverridesCmd = installation: {}: ''
# Update overrides that are managed by this module (both old and new)
mkdir -p ${overridesDir}
${pkgs.jq}/bin/jq -r -n \
--argjson old "$OLD_STATE" \
--argjson new "$NEW_STATE" \
'$new.overrides + $old.overrides | keys[]' \
| while read -r APP_ID; do
OVERRIDES_PATH=${overridesDir}/$APP_ID

# Transform the INI-like Flatpak overrides file into a workable JSON
if [[ -f $OVERRIDES_PATH ]]; then
ACTIVE=$(cat $OVERRIDES_PATH \
| ${pkgs.jc}/bin/jc --ini \
| ${pkgs.jq}/bin/jq 'map_values(map_values(split(";") | select(. != []) // ""))')
else
ACTIVE={}
fi

# Generate and save the updated overrides file
${pkgs.jq}/bin/jq -r -n \
--arg app_id "$APP_ID" \
--argjson active "$ACTIVE" \
--argjson old_state "$OLD_STATE" \
--argjson new_state "$NEW_STATE" \
--from-file ${./overrides.jq} \
>$OVERRIDES_PATH
done
'';

flatpakInstallCmd = installation: update: { appId, origin ? "flathub", commit ? null, ... }: ''
${pkgs.flatpak}/bin/flatpak --${installation} --noninteractive --no-auto-pin install \
${if update && commit == null then ''--or-update'' else ''''} ${origin} ${appId}
Expand Down Expand Up @@ -86,6 +121,9 @@ pkgs.writeShellScript "flatpak-managed-install" ''
# Install packages
${mkFlatpakInstallCmd installation updateApplications cfg.packages}

# Configure overrides
${flatpakOverridesCmd installation {}}

# Save state
ln -sf ${stateFile} ${statePath}
''
17 changes: 17 additions & 0 deletions modules/options.nix
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,23 @@ in
'';
};

overrides = mkOption {
type = with types; attrsOf (attrsOf (attrsOf (either str (listOf str))));
default = {};
description = lib.mdDoc ''
Applies the provided attribute set into a Flatpak overrides file with the
same structure, keeping externally applied changes
'';
example = literalExpression ''
{
# Array entries will be merged with externally applied values
"com.visualstudio.code".Context.sockets = ["wayland" "!x11" "!fallback-x11"];
# String entries will override externally applied values
global.Environment.LC_ALL = "C.UTF-8";
};
'';
};

update = mkOption {
type = with types; submodule updateOptions;
default = { onActivation = false; auto = { enable = false; onCalendar = "weekly"; }; };
Expand Down
42 changes: 42 additions & 0 deletions modules/overrides.jq
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Convert entry value into array
def values($value): if ($value | type) == "string" then [$value] else ($value // []) end;

# State aliases
($old_state.overrides[$app_id] // {}) as $old
| ($new_state.overrides[$app_id] // {}) as $new

# Map sections that exist in either active or new state (ignore old)
| $active + $new | keys | map (
. as $section | {"section_key": $section, "section_value": (

# Map entries that exist in either active or new state (ignore old)
($active[$section] // {}) + ($new[$section] // {}) | keys | map (
. as $entry | { "entry_key": $entry, "entry_value": (

# Entry value aliases
$active[$section][$entry] as $active_value
| $new[$section][$entry] as $new_value
| $old[$section][$entry] as $old_value

# Use new value if it is a string
| if ($new_value | type) == "string" then $new_value
else
# Otherwise remove old values from the active ones, and add the new ones
values($active_value) - values($old_value) + values($new_value)

# Remove empty arrays and duplicate values
| select(. != []) | unique

# Convert array into Flatpak string array format
| join(";")
end
)}
)

# Remove empty arrays
| select(. != [])
)}
)[]

# Generate the final overrides file
| "[\(.section_key)]", (.section_value[] | "\(.entry_key)=\(.entry_value)"), ""
Loading