nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 fetchurl,
5 snapshotPath,
6 autoPatchelfHook,
7 python3,
8 libxcrypt-legacy,
9 tcl-8_6,
10 tclPackages,
11}:
12
13let
14 # Mapping from GCS component architecture names to Nix architecture names
15 arches = {
16 x86 = "i686";
17 x86_64 = "x86_64";
18 arm = "aarch64";
19 };
20
21 # Mapping from GCS component operating systems to Nix operating systems
22 oses = {
23 LINUX = "linux";
24 MACOSX = "darwin";
25 WINDOWS = "windows";
26 CYGWIN = "cygwin";
27 };
28
29 # Convert an archicecture + OS to a Nix platform
30 toNixPlatform =
31 arch: os:
32 let
33 arch' = arches.${arch} or (throw "unsupported architecture '${arch}'");
34 os' = oses.${os} or (throw "unsupported OS '${os}'");
35 in
36 "${arch'}-${os'}";
37
38 # All architectures that are supported by GCS
39 allArches = builtins.attrNames arches;
40
41 # A description of all available google-cloud-sdk components.
42 # It's a JSON file with a list of components, along with some metadata
43 snapshot = lib.importJSON snapshotPath;
44
45 # Generate a snapshot file for a single component. It has the same format as
46 # `snapshot`, but only contains a single component. These files are
47 # installed with google-cloud-sdk to let it know which components are
48 # available.
49 snapshotFromComponent =
50 {
51 component,
52 revision,
53 schema_version,
54 version,
55 }:
56 builtins.toJSON {
57 components = [ component ];
58 inherit revision schema_version version;
59 };
60
61 # Generate a set of components from a JSON file describing these components
62 componentsFromSnapshot =
63 {
64 components,
65 revision,
66 schema_version,
67 version,
68 ...
69 }:
70 lib.fix (
71 self:
72 builtins.listToAttrs (
73 map (component: {
74 name = component.id;
75 value = componentFromSnapshot self {
76 inherit
77 component
78 revision
79 schema_version
80 version
81 ;
82 };
83 }) components
84 )
85 );
86
87 # Generate a single component from its snapshot, along with a set of
88 # available dependencies to choose from.
89 componentFromSnapshot =
90 # Component derivations that can be used as dependencies
91 components:
92 # This component's snapshot
93 {
94 component,
95 revision,
96 schema_version,
97 version,
98 }@attrs:
99 let
100 baseUrl = dirOf schema_version.url;
101 # Architectures supported by this component. Defaults to all available
102 # architectures.
103 architectures = builtins.filter (arch: builtins.elem arch (builtins.attrNames arches)) (
104 lib.attrByPath [ "platform" "architectures" ] allArches component
105 );
106 # Operating systems supported by this component
107 operating_systems = builtins.filter (
108 os: builtins.elem os (builtins.attrNames oses)
109 ) component.platform.operating_systems;
110 in
111 mkComponent {
112 pname = component.id;
113 version = component.version.version_string;
114 src = lib.optionalString (lib.hasAttrByPath [
115 "data"
116 "source"
117 ] component) "${baseUrl}/${component.data.source}";
118 sha256 = lib.attrByPath [ "data" "checksum" ] "" component;
119 dependencies = map (dep: builtins.getAttr dep components) component.dependencies;
120 platforms =
121 if component.platform == { } then
122 lib.platforms.all
123 else
124 builtins.concatMap (arch: map (os: toNixPlatform arch os) operating_systems) architectures;
125 snapshot = snapshotFromComponent attrs;
126 };
127
128 # Filter out dependencies not supported by current system
129 filterForSystem = builtins.filter (drv: lib.meta.availableOn stdenv.hostPlatform drv);
130
131 # Make a google-cloud-sdk component
132 mkComponent =
133 {
134 pname,
135 version,
136 # Source tarball, if any
137 src ? "",
138 # Checksum for the source tarball, if there is a source
139 sha256 ? "",
140 # Other components this one depends on
141 dependencies ? [ ],
142 # Short text describing the component
143 description ? "",
144 # Platforms supported
145 platforms ? lib.platforms.all,
146 # The snapshot corresponding to this component
147 snapshot,
148 }:
149 stdenv.mkDerivation {
150 inherit pname version snapshot;
151 src = lib.optionalString (src != "") (fetchurl {
152 url = src;
153 inherit sha256;
154 });
155 dontUnpack = true;
156 installPhase = ''
157 mkdir -p $out/google-cloud-sdk/.install
158
159 # If there is a source, unpack it
160 if [ ! -z "$src" ]; then
161 tar -xf $src -C $out/google-cloud-sdk/
162
163 # If the source has binaries, link them to `$out/bin`
164 if [ -d "$out/google-cloud-sdk/bin" ]; then
165 mkdir $out/bin
166 find $out/google-cloud-sdk/bin/ -type f -exec ln -s {} $out/bin/ \;
167 fi
168 fi
169
170 # Write the snapshot file to the `.install` folder
171 cp $snapshotPath $out/google-cloud-sdk/.install/${pname}.snapshot.json
172 '';
173 nativeBuildInputs = [
174 python3
175 stdenv.cc.cc
176 ]
177 ++ lib.optionals stdenv.hostPlatform.isLinux [
178 autoPatchelfHook
179 ];
180 buildInputs = [
181 libxcrypt-legacy
182 tcl-8_6
183 tclPackages.tk
184 ];
185 passthru = {
186 dependencies = filterForSystem dependencies;
187 };
188 passAsFile = [ "snapshot" ];
189 meta = {
190 inherit description platforms;
191 };
192 };
193in
194componentsFromSnapshot snapshot