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 support for patches #302

Open
fooker opened this issue Dec 30, 2020 · 2 comments
Open

Add support for patches #302

fooker opened this issue Dec 30, 2020 · 2 comments
Labels
enhancement New feature or request

Comments

@fooker
Copy link

fooker commented Dec 30, 2020

niv should allow to apply local patches for sources. This would avoid to maintain a tree for sources that exist only to track patches.

I can think of multiple ways to implement this:

  • By providing a wrapper for each source derivation that allow to apply patches (something like sources.nixpkgs.patched [ ./path/to.patch ]
  • By adding a config option listing the patches to be applied

I would prefer the first option and would be happy to work on an implementation if this is an acceptable approach.

@refnil refnil added the enhancement New feature or request label Aug 14, 2021
@jskrzypek
Copy link

Is this using the applyPatches approach? I can imagine having also a patches.json for remote patches as well that specify patches for fetchurl, and follow a similar pattern to sources.json. niv could also add a niv patch add --source nixpkgs --pull XXX to point to a for a PR and find the correct patch-diff url & sha256 for the patch.

@jskrzypek
Copy link

jskrzypek commented Nov 20, 2024

For any followers, if you need to support patches, you can apply the patch below to your nix/sources.nix file, and add a nix/patches.json file that contains entries like:

{
    "nixpkgs-pull-346698":{
        "source": "nixpkgs",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "pull": "346698",
        "type": "file",
        "builtin": true,
        "issue_url": "https://github.com/NixOS/nixpkgs/pull/346698",
        "sha256": "1g079rghwgccj3gs4dhi9qn7c1hkjfd46pl9yq2bskx15mdl1998",
        "title": "deskflow: init at 1.17.1",
        "url": "https://patch-diff.githubusercontent.com/NixOS/nixpkgs/pull/346698.patch",
        "url_template": "https://patch-diff.githubusercontent.com/<owner>/<repo>/pull/<pull>.patch"
    }
}
diff --git i/nix/sources.nix w/nix/sources.nix
--- i/nix/sources.nix
+++ w/nix/sources.nix
@@ -222,27 +222,66 @@ let
     else
       fetchurl attrs;
 
+  mkPatched = config: name: src: patches:
+    config.pkgs.applyPatches {
+      name = name + "-patched";
+      inherit patches src;
+    };
+
+  assertNoCollisions = specType: names: spec:
+    if builtins.any (n: builtins.hasAttr n spec) names
+    then
+      abort
+        "The values in ${specType}.json should not have attributes with names ${names}."
+    else
+      spec;
+
   # Create the final "sources" from the config
   mkSources = config:
-    mapAttrs
+    let
+      patchesBySource =
+        builtins.mapAttrs
+          (_: v: builtins.map
+            (name: {inherit name; value = config.patches.${name};})
+            v)
+          (builtins.groupBy
+            (n: config.patches.${n}.source)
+            (builtins.attrNames config.patches));
+    in mapAttrs
       (
         name: spec:
-          if builtins.hasAttr "outPath" spec
-          then
-            abort
-              "The values in sources.json should not have an 'outPath' attribute"
-          else
-            spec // { outPath = replace name (fetch config.pkgs name spec); }
+          (assertNoCollisions 
+            "sources"
+            [ "outPath" "patched" "patches" ]
+            spec) // rec {
+            outPath = replace name (fetch config.pkgs name spec);
+            patched = mkPatched config name outPath;
+          } // (
+              let
+                patchesForSource = patchesBySource."${name}" or [];
+              in optionalAttrs
+                (builtins.length patchesForSource != 0)
+                {
+                  patches = builtins.map
+                    ({name, value}: value // {outPath = replace name (fetch config.pkgs name value);})
+                    patchesForSource;
+                }
+          )
       )
       config.sources;
 
   # The "config" used by the fetchers
   mkConfig =
-    { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
+    { patchesFile ? if builtins.pathExists ./patches.json then ./patches.json else null
+    , patches ? if patchesFile == null then { } else builtins.fromJSON (builtins.readFile patchesFile)
+    , sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
     , sources ? if sourcesFile == null then { } else builtins.fromJSON (builtins.readFile sourcesFile)
     , system ? builtins.currentSystem
     , pkgs ? mkPkgs sources system
-    }: rec {
+    }: {
+      # The patches, i.e. the attribute set of patch name to patch spec
+      inherit patches;
+
       # The sources, i.e. the attribute set of spec name to spec
       inherit sources;
 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants