1{
2 lib,
3 fetchgit,
4 fetchzip,
5}:
6
7lib.makeOverridable (
8 # gitlab example
9 {
10 owner,
11 repo,
12 rev ? null,
13 tag ? null,
14 protocol ? "https",
15 domain ? "gitlab.com",
16 name ? "source",
17 group ? null,
18 fetchSubmodules ? false,
19 leaveDotGit ? false,
20 deepClone ? false,
21 forceFetchGit ? false,
22 sparseCheckout ? [ ],
23 ... # For hash agility
24 }@args:
25
26 assert (
27 lib.assertMsg (lib.xor (tag == null) (
28 rev == null
29 )) "fetchFromGitLab requires one of either `rev` or `tag` to be provided (not both)."
30 );
31
32 let
33 slug = lib.concatStringsSep "/" (
34 (lib.optional (group != null) group)
35 ++ [
36 owner
37 repo
38 ]
39 );
40 revWithTag = if tag != null then "refs/tags/" + tag else rev;
41 escapedSlug = lib.replaceStrings [ "." "/" ] [ "%2E" "%2F" ] slug;
42 escapedRevWithTag = lib.replaceStrings [ "+" "%" "/" ] [ "%2B" "%25" "%2F" ] revWithTag;
43 passthruAttrs = removeAttrs args [
44 "protocol"
45 "domain"
46 "owner"
47 "group"
48 "repo"
49 "rev"
50 "tag"
51 "fetchSubmodules"
52 "forceFetchGit"
53 "leaveDotGit"
54 "deepClone"
55 ];
56
57 useFetchGit =
58 fetchSubmodules || leaveDotGit || deepClone || forceFetchGit || (sparseCheckout != [ ]);
59 fetcher = if useFetchGit then fetchgit else fetchzip;
60
61 gitRepoUrl = "${protocol}://${domain}/${slug}.git";
62
63 fetcherArgs =
64 (
65 if useFetchGit then
66 {
67 inherit
68 rev
69 deepClone
70 tag
71 fetchSubmodules
72 sparseCheckout
73 leaveDotGit
74 ;
75 url = gitRepoUrl;
76 }
77 else
78 {
79 url = "${protocol}://${domain}/api/v4/projects/${escapedSlug}/repository/archive.tar.gz?sha=${escapedRevWithTag}";
80
81 passthru = {
82 inherit gitRepoUrl;
83 };
84 }
85 )
86 // passthruAttrs
87 // {
88 inherit name;
89 };
90 in
91
92 fetcher fetcherArgs
93 // {
94 meta.homepage = "${protocol}://${domain}/${slug}/";
95 inherit
96 tag
97 owner
98 repo
99 ;
100 rev = revWithTag;
101 }
102)