1lib: self:
2
3let
4 inherit (lib) elemAt;
5
6 matchForgeRepo = builtins.match "(.+)/(.+)";
7
8 fetchers = lib.mapAttrs (_: fetcher: self.callPackage fetcher { }) {
9 github =
10 { fetchFromGitHub }:
11 {
12 repo ? null,
13 ...
14 }:
15 { sha256, commit, ... }:
16 let
17 m = matchForgeRepo repo;
18 in
19 assert m != null;
20 fetchFromGitHub {
21 owner = elemAt m 0;
22 repo = elemAt m 1;
23 rev = commit;
24 inherit sha256;
25 };
26
27 gitlab =
28 { fetchFromGitLab }:
29 {
30 repo ? null,
31 ...
32 }:
33 { sha256, commit, ... }:
34 let
35 m = matchForgeRepo repo;
36 in
37 assert m != null;
38 fetchFromGitLab {
39 owner = elemAt m 0;
40 repo = elemAt m 1;
41 rev = commit;
42 inherit sha256;
43 };
44
45 git = (
46 { fetchgit }:
47 {
48 url ? null,
49 ...
50 }:
51 { sha256, commit, ... }:
52 (fetchgit {
53 rev = commit;
54 inherit sha256 url;
55 }).overrideAttrs
56 (_: {
57 GIT_SSL_NO_VERIFY = true;
58 })
59 );
60
61 bitbucket =
62 { fetchhg }:
63 {
64 repo ? null,
65 ...
66 }:
67 { sha256, commit, ... }:
68 fetchhg {
69 rev = commit;
70 url = "https://bitbucket.com/${repo}";
71 inherit sha256;
72 };
73
74 hg =
75 { fetchhg }:
76 {
77 url ? null,
78 ...
79 }:
80 { sha256, commit, ... }:
81 fetchhg {
82 rev = commit;
83 inherit sha256 url;
84 };
85
86 sourcehut =
87 { fetchzip }:
88 {
89 repo ? null,
90 ...
91 }:
92 { sha256, commit, ... }:
93 fetchzip {
94 url = "https://git.sr.ht/~${repo}/archive/${commit}.tar.gz";
95 inherit sha256;
96 };
97
98 codeberg =
99 { fetchzip }:
100 {
101 repo ? null,
102 ...
103 }:
104 { sha256, commit, ... }:
105 fetchzip {
106 url = "https://codeberg.org/${repo}/archive/${commit}.tar.gz";
107 inherit sha256;
108 };
109 };
110
111in
112{
113
114 melpaDerivation =
115 variant:
116 {
117 ename,
118 fetcher,
119 commit ? null,
120 sha256 ? null,
121 ...
122 }@args:
123 let
124 sourceArgs = args.${variant};
125 version = sourceArgs.version or null;
126 deps = sourceArgs.deps or null;
127 error = sourceArgs.error or args.error or null;
128 hasSource = lib.hasAttr variant args;
129 pname = builtins.replaceStrings [ "@" ] [ "at" ] ename;
130 broken = error != null;
131 in
132 if hasSource then
133 lib.nameValuePair ename (
134 self.callPackage (
135 { melpaBuild, fetchurl, ... }@pkgargs:
136 melpaBuild {
137 inherit pname ename;
138 inherit (sourceArgs) commit;
139 version = lib.optionalString (version != null) (
140 lib.concatStringsSep "." (
141 map toString
142 # Hack: Melpa archives contains versions with parse errors such as [ 4 4 -4 413 ] which should be 4.4-413
143 # This filter method is still technically wrong, but it's computationally cheap enough and tapers over the issue
144 (builtins.filter (n: n >= 0) version)
145 )
146 );
147 # TODO: Broken should not result in src being null (hack to avoid eval errors)
148 src = if (sha256 == null || broken) then null else fetchers.${fetcher} args sourceArgs;
149 recipe =
150 if commit == null then
151 null
152 else
153 fetchurl {
154 name = pname + "-recipe";
155 url = "https://raw.githubusercontent.com/melpa/melpa/${commit}/recipes/${ename}";
156 inherit sha256;
157 };
158 packageRequires = lib.optionals (deps != null) (
159 map (dep: pkgargs.${dep} or self.${dep} or null) deps
160 );
161 meta = (sourceArgs.meta or { }) // {
162 inherit broken;
163 };
164 }
165 ) { }
166 )
167 else
168 null;
169
170}