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