From efe45f5ffe5ca670fa9a8ece18ecdf4cbc40b19d Mon Sep 17 00:00:00 2001 From: Gabriele Modena Date: Thu, 24 Oct 2024 16:14:10 +0200 Subject: [PATCH 1/2] remotes: add gpg-import option. Adds an option to declare imports of a GPG key from file. Refactor remotes helper functions in modules/remotes.nix. --- .github/workflows/test.yml | 7 +---- modules/installer.nix | 25 +++------------ modules/options.nix | 5 +++ modules/overrides.jq | 64 +++++++++++++++++++------------------- modules/remotes.nix | 33 ++++++++++++++++++++ test.sh | 15 +++++++++ tests/remotes-test.nix | 19 +++++++++++ 7 files changed, 109 insertions(+), 59 deletions(-) create mode 100644 modules/remotes.nix create mode 100755 test.sh create mode 100644 tests/remotes-test.nix diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 66bba99..fe65e21 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,10 +24,5 @@ jobs: - run: nix flake check - name: Run Nix tests run: | - cd tests/ - result=$(nix eval --impure --expr 'import ./ref-test.nix {}') - if [ "$result" != "[ ]" ]; then - echo "Test failed: Expected [], but got $result" - exit 1 - fi + ./test.sh shell: bash diff --git a/modules/installer.nix b/modules/installer.nix index c0f5b40..9ab510a 100644 --- a/modules/installer.nix +++ b/modules/installer.nix @@ -2,6 +2,7 @@ let utils = import ./ref.nix { inherit lib; }; + remotes = import ./remotes.nix { inherit pkgs; }; flatpakrefCache = builtins.foldl' (acc: package: @@ -168,30 +169,12 @@ let in installCmd + "\n" + pinCommitOrUpdate; - flatpakAddRemotesCmd = installation: { name, location, args ? null, ... }: '' - ${pkgs.flatpak}/bin/flatpak remote-add --${installation} --if-not-exists ${if args == null then "" else args} ${name} ${location} - ''; - flatpakAddRemote = installation: remotes: map (flatpakAddRemotesCmd installation) remotes; - - flatpakDeleteRemotesCmd = installation: uninstallUnmanaged: {}: '' - # Delete all remotes that are present in the old state but not the new one - # $OLD_STATE and $NEW_STATE are globals, declared in the output of pkgs.writeShellScript. - # If uninstallUnmanagedState is true, then the remotes will be deleted forcefully. - ${pkgs.jq}/bin/jq -r -n \ - --argjson old "$OLD_STATE" \ - --argjson new "$NEW_STATE" \ - '(($old.remotes // []) - ($new.remotes // []))[]' \ - | while read -r REMOTE_NAME; do - ${pkgs.flatpak}/bin/flatpak remote-delete ${if uninstallUnmanaged then " --force " else " " } --${installation} $REMOTE_NAME - - done - ''; - - flatpakInstall = installation: update: packages: map (flatpakInstallCmd installation update) packages; mkFlatpakInstallCmd = installation: update: packages: builtins.foldl' (x: y: x + y) '''' (flatpakInstall installation update packages); - mkFlatpakAddRemotesCmd = installation: remotes: builtins.foldl' (x: y: x + y) '''' (flatpakAddRemote installation remotes); + + flatpakDeleteRemotesCmd = remotes.flatpakDeleteRemotesCmd; + mkFlatpakAddRemotesCmd = remotes.mkFlatpakAddRemotesCmd; in pkgs.writeShellScript "flatpak-managed-install" '' # This script is triggered at build time by a transient systemd unit. diff --git a/modules/options.nix b/modules/options.nix index 6efcc55..f9a6822 100644 --- a/modules/options.nix +++ b/modules/options.nix @@ -13,6 +13,11 @@ let description = lib.mdDoc "The remote location. Must be a valid URL of a flatpak repo."; default = "https://dl.flathub.org/repo/flathub.flatpakrepo"; }; + gpg-import = mkOption { + type = types.nullOr types.str; + description = "Import GPG key from FILE"; + default = null; + }; args = mkOption { type = types.nullOr types.str; description = "Extra arguments to pass to flatpak remote-add."; diff --git a/modules/overrides.jq b/modules/overrides.jq index 0da9f02..a1fb880 100644 --- a/modules/overrides.jq +++ b/modules/overrides.jq @@ -1,42 +1,42 @@ # Convert entry value into array -def values($value): if ($value | type) == "string" then [$value] else ($value // []) end; +def values ($value): if ($value | type) == "string" then [$value] else ($value // []) end; # State aliases - ($old_state.overrides[$app_id] // {}) as $old +($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(. != []) - )} - )[] +. 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)"), "" diff --git a/modules/remotes.nix b/modules/remotes.nix new file mode 100644 index 0000000..856c3a7 --- /dev/null +++ b/modules/remotes.nix @@ -0,0 +1,33 @@ +{ pkgs }: + +let + flatpakAddRemotesCmd = installation: { name, location, gpg-import ? null, args ? null, ... }: + let + gpg-import-flag = ''${if gpg-import == null then "" else "--gpg-import=${gpg-import}" }''; + args-flag = ''${if args == null then "" else args}''; + in + '' + ${pkgs.flatpak}/bin/flatpak remote-add --${installation} --if-not-exists ${args-flag} ${gpg-import-flag} ${name} ${location} + ''; + + flatpakAddRemote = installation: remotes: map (flatpakAddRemotesCmd installation) remotes; + + flatpakDeleteRemotesCmd = installation: uninstallUnmanaged: {}: '' + # Delete all remotes that are present in the old state but not the new one + # $OLD_STATE and $NEW_STATE are globals, declared in the output of pkgs.writeShellScript. + # If uninstallUnmanagedState is true, then the remotes will be deleted forcefully. + ${pkgs.jq}/bin/jq -r -n \ + --argjson old "$OLD_STATE" \ + --argjson new "$NEW_STATE" \ + '(($old.remotes // []) - ($new.remotes // []))[]' \ + | while read -r REMOTE_NAME; do + ${pkgs.flatpak}/bin/flatpak remote-delete ${if uninstallUnmanaged then " --force " else " " } --${installation} $REMOTE_NAME + + done + ''; + + mkFlatpakAddRemotesCmd = installation: remotes: builtins.foldl' (x: y: x + y) '''' (flatpakAddRemote installation remotes); +in +{ + inherit mkFlatpakAddRemotesCmd flatpakDeleteRemotesCmd; +} diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..5af2192 --- /dev/null +++ b/test.sh @@ -0,0 +1,15 @@ +cd tests/ + +test_count=0 +for test_file in *-test.nix; do + echo "Collecting results for... ${test_file}" + result=$(nix eval --show-trace --impure --expr "import ./${test_file} {}") + + if [ "$result" != "[ ]" ]; then + echo "Test failed: Expected [], but got $result in $test_file" + exit 1 + fi + ((test_count++)) +done + +echo "All tests in ${test_count} suites passed." diff --git a/tests/remotes-test.nix b/tests/remotes-test.nix new file mode 100644 index 0000000..8756aa5 --- /dev/null +++ b/tests/remotes-test.nix @@ -0,0 +1,19 @@ +{ pkgs ? import { } }: + +let + inherit (pkgs) lib; + inherit (lib) runTests; + installation = "system"; + installer = import ../modules/remotes.nix { inherit pkgs; }; +in +runTests { + testMkFlatpakAddRemotesCmd = { + expr = installer.mkFlatpakAddRemotesCmd installation [{ name = "flathub"; location = "http://flathub"; }]; + expected = "${pkgs.flatpak}/bin/flatpak remote-add --system --if-not-exists flathub http://flathub\n"; + }; + + testMkFlatpakAddRemotesCmdCmdWithTrustedKeys = { + expr = installer.mkFlatpakAddRemotesCmd installation [{ name = "flathub"; location = "http://flathub"; gpg-import = "trustedkeys.gpg"; }]; + expected = "${pkgs.flatpak}/bin/flatpak remote-add --system --if-not-exists --gpg-import=trustedkeys.gpg flathub http://flathub\n"; + }; +} From 53c3f55dffe15964205b54a40e1d079a3927a3eb Mon Sep 17 00:00:00 2001 From: Gabriele Modena Date: Thu, 24 Oct 2024 16:25:32 +0200 Subject: [PATCH 2/2] overrides.jq: undo formatting. --- modules/overrides.jq | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/modules/overrides.jq b/modules/overrides.jq index a1fb880..0da9f02 100644 --- a/modules/overrides.jq +++ b/modules/overrides.jq @@ -1,42 +1,42 @@ # Convert entry value into array -def values ($value): if ($value | type) == "string" then [$value] else ($value // []) end; +def values($value): if ($value | type) == "string" then [$value] else ($value // []) end; # State aliases -($old_state.overrides[$app_id] // {}) as $old + ($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(. != []) -)} -)[] + . 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)"), ""