diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 885a303..66bba99 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,3 +22,12 @@ jobs: with: github_access_token: ${{ secrets.GITHUB_TOKEN }} - 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 + shell: bash diff --git a/modules/installer.nix b/modules/installer.nix index 5091ec0..8fa7f1d 100644 --- a/modules/installer.nix +++ b/modules/installer.nix @@ -1,7 +1,7 @@ { cfg, pkgs, lib, installation ? "system", ... }: let - utils = import ./ref.nix { inherit pkgs lib; }; + utils = import ./ref.nix { inherit lib; }; flatpakrefCache = builtins.foldl' (acc: package: @@ -10,26 +10,6 @@ let { } (builtins.filter (package: utils.isFlatpakref package) cfg.packages); - # Extract the remote name from a package that declares a flatpakref: - # 1. if the package sets an origin, use that as label for the remote url. - # 2. if the package does not set an origin, use the remote name suggested by the flatpakref. - # 3. if the package does not set an origin and the flatpakref does not suggest a remote name, sanitize application Name. - getRemoteNameFromFlatpakref = origin: cache: - let - remoteName = origin; - in - if remoteName == null - then - let - flatpakrefdName = - if builtins.hasAttr "SuggestRemoteName" cache - then cache.SuggestRemoteName - else "${lib.toLower cache.Name}-origin"; - in - flatpakrefdName - else - remoteName; - # Get the appId from the flatpakref file or the flatpakref URL to pass to flatpak commands. # As of 2024-10 Flatpak will fail to reinstall from flatpakref URL (https://github.com/flatpak/flatpak/issues/5460). # This function will return the appId if the package is already installed, otherwise it will return the flatpakref URL. @@ -84,7 +64,7 @@ let # Add remotes extracted from flatpakref URLs in packages map (package: - getRemoteNameFromFlatpakref package.origin flatpakrefCache.${(utils.sanitizeUrl package.flatpakref)}) + utils.getRemoteNameFromFlatpakref package.origin flatpakrefCache.${(utils.sanitizeUrl package.flatpakref)}) (builtins.filter (package: utils.isFlatpakref package) cfg.packages); }); diff --git a/modules/ref.nix b/modules/ref.nix index eb0fbe7..936d9e4 100644 --- a/modules/ref.nix +++ b/modules/ref.nix @@ -1,16 +1,36 @@ # utiliy function to manage flatpakref files -{ pkgs, lib, ... }: +{ lib, ... }: let # check if a value is a string isString = value: builtins.typeOf value == "string"; # Check if a package declares a flatpakref - isFlatpakref = { flatpakref, ... }: + isFlatpakref = { flatpakref ? null, ... }: flatpakref != null && isString flatpakref; # sanitize a URL to be used as a key in an attrset. sanitizeUrl = url: builtins.replaceStrings [ "https://" "/" "." ":" ] [ "https_" "_" "_" "_" ] url; + # Extract the remote name from a package that declares a flatpakref: + # 1. if the package sets an origin, use that as label for the remote url. + # 2. if the package does not set an origin, use the remote name suggested by the flatpakref. + # 3. if the package does not set an origin and the flatpakref does not suggest a remote name, sanitize application Name. + getRemoteNameFromFlatpakref = origin: cache: + let + remoteName = origin; + in + if remoteName == null + then + let + flatpakrefdName = + if builtins.hasAttr "SuggestRemoteName" cache + then cache.SuggestRemoteName + else "${lib.toLower cache.Name}-origin"; + in + flatpakrefdName + else + remoteName; + # Fetch and convert an ini-like flatpakref file into an attrset, and cache it for future use # within the same activation. # We piggyback on builtins.fetchurl to fetch and cache flatpakref file. Pure nix evaluations @@ -39,5 +59,5 @@ let updatedCache; in { - inherit isFlatpakref sanitizeUrl flatpakrefToAttrSet; + inherit isFlatpakref sanitizeUrl flatpakrefToAttrSet getRemoteNameFromFlatpakref; } diff --git a/tests/fixtures/package.flatpakref b/tests/fixtures/package.flatpakref new file mode 100644 index 0000000..2d3a6f4 --- /dev/null +++ b/tests/fixtures/package.flatpakref @@ -0,0 +1,8 @@ +[Flatpak Ref] +Title=gedit +Name=org.gnome.gedit +Branch=stable +Url=http://sdk.gnome.org/repo-apps/ +IsRuntime=false +GPGKey=REDACTED +DeployCollectionID=org.gnome.Apps diff --git a/tests/ref-test.nix b/tests/ref-test.nix new file mode 100644 index 0000000..6a25b0b --- /dev/null +++ b/tests/ref-test.nix @@ -0,0 +1,77 @@ +{ pkgs ? import { } }: + +let + inherit (pkgs) lib; + inherit (lib) runTests; + ref = import ../modules/ref.nix { inherit lib; }; + + pwd = builtins.getEnv "PWD"; + fixturePath = "file://${pwd}/fixtures/package.flatpakref"; + fixtureHash = "040iig2yg2i28s5xc9cvp5syaaqq165idy3nhlpv8xn4f6zh4h1f"; +in +runTests { + testSanitizeUrl = { + expr = ref.sanitizeUrl "https://example.local"; + expected = "https_example_local"; + }; + + testIsFlatpakref = { + expr = ref.isFlatpakref { flatpakref = "https://example.local/package.flatpakref"; }; + expected = true; + }; + + testIsFlatpakrefWithNull = { + expr = ref.isFlatpakref { flatpakref = null; }; + expected = false; + }; + + testIsFlatpakrefWithMissing = { + expr = ref.isFlatpakref { appId = "local.example.Package"; }; + expected = false; + }; + + testGetRemoteNameFromFlatpakrefWithOrigin = { + expr = ref.getRemoteNameFromFlatpakref "example" { SuggestRemoteName = "local"; }; + expected = "example"; + }; + + testGetRemoteNameWithSuggestedName = { + expr = ref.getRemoteNameFromFlatpakref null { SuggestRemoteName = "local"; }; + expected = "local"; + }; + + testGetRemoteNameWithPackageName = { + expr = ref.getRemoteNameFromFlatpakref null { Name = "Example"; }; + expected = "example-origin"; + }; + + testFlatpakrefToAttrSet = { + expr = ref.flatpakrefToAttrSet { flatpakref = fixturePath; sha256 = null; } { }; + expected = { + ${ref.sanitizeUrl fixturePath} = { + Title = "gedit"; + Name = "org.gnome.gedit"; + Branch = "stable"; + Url = "http://sdk.gnome.org/repo-apps/"; + IsRuntime = "false"; + GPGKey = "REDACTED"; + DeployCollectionID = "org.gnome.Apps"; + }; + }; + }; + + testFlatpakrefToAttrSetWithSha256 = { + expr = ref.flatpakrefToAttrSet { flatpakref = fixturePath; sha256 = fixtureHash; } { }; + expected = { + ${ref.sanitizeUrl fixturePath} = { + Title = "gedit"; + Name = "org.gnome.gedit"; + Branch = "stable"; + Url = "http://sdk.gnome.org/repo-apps/"; + IsRuntime = "false"; + GPGKey = "REDACTED"; + DeployCollectionID = "org.gnome.Apps"; + }; + }; + }; +}