├── .assets ├── NGI0_tag.png ├── nlnet-banner.png └── tweag.png ├── .envrc ├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .mergify.yml ├── LICENSE ├── README.md ├── builder ├── default.nix ├── fetch.sh ├── install │ └── install.go ├── parser.nix └── symlink │ └── symlink.go ├── default.nix ├── docs ├── getting-started.md └── nix-reference.md ├── flake.lock ├── flake.nix ├── go.mod ├── go.sum ├── gomod2nix.toml ├── internal ├── cmd │ └── root.go ├── generate │ ├── generate.go │ └── temp.go ├── lib │ ├── executor.go │ └── executor_test.go └── schema │ └── schema.go ├── main.go ├── overlay.nix ├── shell.nix ├── templates └── app │ ├── .gitignore │ ├── default.nix │ ├── flake.nix │ ├── go.mod │ ├── gomod2nix.toml │ ├── main.go │ └── shell.nix └── tests ├── Makefile ├── README.md ├── cli-args ├── default.nix └── script ├── cross └── default.nix ├── default.nix ├── ethermint ├── cmd │ └── main.go ├── crypto │ └── hd │ │ └── algorithm.go ├── default.nix ├── go.mod └── go.sum ├── helm ├── default.nix ├── go.mod └── go.sum ├── minikube ├── default.nix ├── go.mod └── go.sum ├── mkgoenv ├── default.nix ├── go.mod ├── go.sum └── tools.go ├── run.go └── vendored-modules ├── default.nix └── script /.assets/NGI0_tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/gomod2nix/2cbd7fdd6eeab65c494cc426e18f4e4d2a5e35c0/.assets/NGI0_tag.png -------------------------------------------------------------------------------- /.assets/nlnet-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/gomod2nix/2cbd7fdd6eeab65c494cc426e18f4e4d2a5e35c0/.assets/nlnet-banner.png -------------------------------------------------------------------------------- /.assets/tweag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nix-community/gomod2nix/2cbd7fdd6eeab65c494cc426e18f4e4d2a5e35c0/.assets/tweag.png -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use nix 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | paths-ignore: 6 | - '**.md' 7 | push: 8 | paths-ignore: 9 | - '**.md' 10 | branches: 11 | - master 12 | 13 | jobs: 14 | nixpkgs-fmt: 15 | runs-on: ubuntu-latest 16 | env: 17 | NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz" 18 | steps: 19 | - uses: cachix/install-nix-action@v31 20 | - uses: actions/checkout@v4 21 | - name: Check format 22 | run: nix-shell --run 'nixpkgs-fmt --check .' 23 | 24 | golangci-lint: 25 | runs-on: ubuntu-latest 26 | env: 27 | NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz" 28 | steps: 29 | - uses: cachix/install-nix-action@v31 30 | - uses: actions/checkout@v4 31 | - name: Run golangci-lint 32 | run: nix-shell --run 'golangci-lint run' 33 | 34 | gomod2nix_toml: 35 | runs-on: ubuntu-latest 36 | env: 37 | NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz" 38 | steps: 39 | - uses: cachix/install-nix-action@v31 40 | - uses: actions/checkout@v4 41 | - name: "Build gomod2nix" 42 | run: nix-shell --run "go build" 43 | - name: Run gomod2nix 44 | run: nix-shell --run gomod2nix 45 | - name: Check diff 46 | run: git diff --exit-code gomod2nix.toml 47 | 48 | list-jobs: 49 | runs-on: ubuntu-latest 50 | outputs: 51 | matrix: ${{ steps.set-matrix.outputs.matrix }} 52 | steps: 53 | - uses: actions/checkout@v4 54 | - uses: cachix/install-nix-action@v31 55 | with: 56 | nix_path: nixpkgs=channel:nixos-unstable 57 | - id: set-matrix 58 | run: | 59 | set -euo pipefail 60 | matrix="$(go run tests/run.go list | jq --raw-input --slurp -rcM '{attr: split("\n")[:-1], os: ["ubuntu-latest"]}')" 61 | echo "::set-output name=matrix::$matrix" 62 | 63 | builds: 64 | needs: list-jobs 65 | runs-on: ${{ matrix.os }} 66 | strategy: 67 | matrix: ${{fromJSON(needs.list-jobs.outputs.matrix)}} 68 | steps: 69 | - uses: actions/checkout@v4 70 | - uses: cachix/install-nix-action@v31 71 | with: 72 | nix_path: nixpkgs=channel:nixos-unstable 73 | - name: "Build gomod2nix" 74 | run: nix-shell --run "go build" 75 | - name: "Run test: ${{ matrix.attr }}" 76 | run: nix-shell --run "go run tests/run.go run ${{ matrix.attr }}" 77 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /gomod2nix 2 | result* 3 | /tests/*/gomod2nix.toml 4 | /tests/*/go.mod 5 | .idea 6 | -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | queue_rules: 2 | - name: default 3 | queue_conditions: 4 | - base=master 5 | - label~=merge-queue|dependencies 6 | merge_conditions: 7 | - check-success=builds (cli-args, ubuntu-latest) 8 | - check-success=builds (ethermint, ubuntu-latest) 9 | - check-success=builds (mkgoenv, ubuntu-latest) 10 | - check-success=builds (vendored-modules, ubuntu-latest) 11 | - check-success=golangci-lint 12 | - check-success=gomod2nix_toml 13 | - check-success=list-jobs 14 | - check-success=nixpkgs-fmt 15 | merge_method: rebase 16 | 17 | pull_request_rules: 18 | - name: merge using the merge queue 19 | conditions: [] 20 | actions: 21 | queue: 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Tweag I/O 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gomod2nix 2 | Convert applications using Go modules -> Nix 3 | 4 | ## Usage 5 | From the Go project directory execute: 6 | ``` bash 7 | $ gomod2nix 8 | ``` 9 | 10 | This will create `gomod2nix.toml` that's used like so 11 | ``` nix 12 | let 13 | pkgs = import { 14 | overlays = [ 15 | (self: super: { 16 | buildGoApplication = super.callPackage ./builder { }; 17 | }) 18 | ]; 19 | }; 20 | in pkgs.buildGoApplication { 21 | pname = "gomod2nix-example"; 22 | version = "0.1"; 23 | src = ./.; 24 | modules = ./gomod2nix.toml; 25 | } 26 | ``` 27 | 28 | For more in-depth usage check the [Getting Started](./docs/getting-started.md) and the [Nix API reference](./docs/nix-reference.md) docs. 29 | 30 | ## Motivation 31 | 32 | The [announcement blog post](https://www.tweag.io/blog/2021-03-04-gomod2nix/) contains comparisons with other Go build systems for Nix and additional notes on the design choices made. 33 | 34 | ## License 35 | 36 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) 37 | file for details. 38 | 39 | ## About the project 40 | The developmentent of Trustix (which Gomod2nix is a part of) has been sponsored by [Tweag I/O](https://tweag.io/) and funded by the [NLNet foundation](https://nlnet.nl/project/Trustix) and the European Commission’s [Next Generation Internet programme](https://www.ngi.eu/funded_solution/trustix-nix/) through the NGI Zero PET (privacy and trust enhancing technologies) fund. 41 | 42 | ![NGI0 logo](./.assets/NGI0_tag.png) 43 | ![NLNet banner](./.assets/nlnet-banner.png) 44 | ![Tweag logo](./.assets/tweag.png) 45 | -------------------------------------------------------------------------------- /builder/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv 2 | , stdenvNoCC 3 | , runCommand 4 | , buildEnv 5 | , lib 6 | , fetchgit 7 | , jq 8 | , cacert 9 | , pkgsBuildBuild 10 | , buildPackages 11 | , runtimeShell 12 | , writeScript 13 | , gomod2nix 14 | , rsync 15 | }: 16 | let 17 | 18 | inherit (builtins) substring toJSON hasAttr trace split readFile elemAt; 19 | inherit (lib) 20 | concatStringsSep replaceStrings removePrefix optionalString pathExists 21 | optional concatMapStrings fetchers filterAttrs mapAttrs mapAttrsToList 22 | warnIf optionalAttrs platforms 23 | ; 24 | 25 | parseGoMod = import ./parser.nix; 26 | 27 | # Internal only build-time attributes 28 | internal = 29 | let 30 | mkInternalPkg = name: src: pkgsBuildBuild.runCommand "gomod2nix-${name}" 31 | { 32 | inherit (pkgsBuildBuild.go) GOOS GOARCH; 33 | nativeBuildInputs = [ pkgsBuildBuild.go ]; 34 | } '' 35 | export HOME=$(mktemp -d) 36 | go build -o $out ${src} 37 | ''; 38 | in 39 | { 40 | 41 | # Create a symlink tree of vendored sources 42 | symlink = mkInternalPkg "symlink" ./symlink/symlink.go; 43 | 44 | # Install development dependencies from tools.go 45 | install = mkInternalPkg "symlink" ./install/install.go; 46 | 47 | }; 48 | 49 | fetchGoModule = 50 | { hash 51 | , goPackagePath 52 | , version 53 | , go 54 | }: 55 | stdenvNoCC.mkDerivation { 56 | name = "${baseNameOf goPackagePath}_${version}"; 57 | builder = ./fetch.sh; 58 | inherit goPackagePath version; 59 | nativeBuildInputs = [ 60 | go 61 | jq 62 | cacert 63 | ]; 64 | outputHashMode = "recursive"; 65 | outputHashAlgo = null; 66 | outputHash = hash; 67 | impureEnvVars = fetchers.proxyImpureEnvVars ++ [ "GOPROXY" ]; 68 | }; 69 | 70 | mkVendorEnv = 71 | { go 72 | , modulesStruct 73 | , localReplaceCommands ? [ ] 74 | , defaultPackage ? "" 75 | , goMod 76 | , pwd 77 | }: 78 | let 79 | localReplaceCommands = 80 | let 81 | localReplaceAttrs = filterAttrs (n: v: hasAttr "path" v) goMod.replace; 82 | commands = ( 83 | mapAttrsToList 84 | (name: value: ( 85 | '' 86 | mkdir -p $(dirname vendor/${name}) 87 | ln -s ${pwd + "/${value.path}"} vendor/${name} 88 | '' 89 | )) 90 | localReplaceAttrs); 91 | in 92 | if goMod != null then commands else [ ]; 93 | 94 | sources = mapAttrs 95 | (goPackagePath: meta: fetchGoModule { 96 | goPackagePath = meta.replaced or goPackagePath; 97 | inherit (meta) version hash; 98 | inherit go; 99 | }) 100 | modulesStruct.mod; 101 | in 102 | runCommand "vendor-env" 103 | { 104 | nativeBuildInputs = [ go ]; 105 | json = toJSON (filterAttrs (n: _: n != defaultPackage) modulesStruct.mod); 106 | 107 | sources = toJSON (filterAttrs (n: _: n != defaultPackage) sources); 108 | 109 | passthru = { 110 | inherit sources; 111 | }; 112 | 113 | passAsFile = [ "json" "sources" ]; 114 | } 115 | ( 116 | '' 117 | mkdir vendor 118 | 119 | export GOCACHE=$TMPDIR/go-cache 120 | export GOPATH="$TMPDIR/go" 121 | 122 | ${internal.symlink} 123 | ${concatStringsSep "\n" localReplaceCommands} 124 | 125 | mv vendor $out 126 | '' 127 | ); 128 | 129 | # Return a Go attribute and error out if the Go version is older than was specified in go.mod. 130 | selectGo = attrs: goMod: attrs.go or (if goMod == null then buildPackages.go else 131 | ( 132 | let 133 | goVersion = goMod.go; 134 | goAttrs = lib.reverseList (builtins.filter 135 | ( 136 | attr: 137 | lib.hasPrefix "go_" attr && 138 | (let try = builtins.tryEval buildPackages.${attr}; in try.success && try.value ? version) && 139 | lib.versionAtLeast buildPackages.${attr}.version goVersion 140 | ) 141 | (lib.attrNames buildPackages)); 142 | goAttr = elemAt goAttrs 0; 143 | in 144 | ( 145 | if goAttrs != [ ] 146 | then buildPackages.${goAttr} 147 | else throw "go.mod specified Go version ${goVersion}, but no compatible Go attribute could be found." 148 | ) 149 | )); 150 | 151 | # Strip extra data that Go adds to versions, and fall back to a version based on the date if it's a placeholder value. 152 | # This is data that Nix can't handle in the version attribute. 153 | stripVersion = version: 154 | let 155 | parts = elemAt (split "(\\+|-)" (removePrefix "v" version)); 156 | v = parts 0; 157 | d = parts 2; 158 | in 159 | if v != "0.0.0" then v else "unstable-" + (concatStringsSep "-" [ 160 | (substring 0 4 d) 161 | (substring 4 2 d) 162 | (substring 6 2 d) 163 | ]); 164 | 165 | mkGoEnv = 166 | { pwd 167 | , toolsGo ? pwd + "/tools.go" 168 | , modules ? pwd + "/gomod2nix.toml" 169 | , ... 170 | }@attrs: 171 | let 172 | goMod = parseGoMod (readFile "${toString pwd}/go.mod"); 173 | modulesStruct = fromTOML (readFile modules); 174 | 175 | go = selectGo attrs goMod; 176 | 177 | vendorEnv = mkVendorEnv { 178 | inherit go modulesStruct pwd goMod; 179 | }; 180 | 181 | in 182 | stdenv.mkDerivation (removeAttrs attrs [ "pwd" ] // { 183 | name = "${baseNameOf goMod.module}-env"; 184 | 185 | dontUnpack = true; 186 | dontConfigure = true; 187 | dontInstall = true; 188 | 189 | CGO_ENABLED = attrs.CGO_ENABLED or go.CGO_ENABLED; 190 | 191 | nativeBuildInputs = [ rsync ]; 192 | 193 | propagatedBuildInputs = [ go ]; 194 | 195 | GO_NO_VENDOR_CHECKS = "1"; 196 | 197 | GO111MODULE = "on"; 198 | GOFLAGS = "-mod=vendor"; 199 | 200 | preferLocalBuild = true; 201 | 202 | buildPhase = '' 203 | mkdir $out 204 | 205 | export GOCACHE=$TMPDIR/go-cache 206 | export GOPATH="$out" 207 | export GOSUMDB=off 208 | export GOPROXY=off 209 | 210 | '' + optionalString (pathExists toolsGo) '' 211 | mkdir source 212 | cp ${pwd + "/go.mod"} source/go.mod 213 | cp ${pwd + "/go.sum"} source/go.sum 214 | cp ${toolsGo} source/tools.go 215 | cd source 216 | 217 | rsync -a -K --ignore-errors ${vendorEnv}/ vendor 218 | 219 | ${internal.install} 220 | ''; 221 | }); 222 | 223 | buildGoApplication = 224 | { modules ? pwd + "/gomod2nix.toml" 225 | , src ? pwd 226 | , pwd ? null 227 | , nativeBuildInputs ? [ ] 228 | , allowGoReference ? false 229 | , meta ? { } 230 | , passthru ? { } 231 | , tags ? [ ] 232 | , ldflags ? [ ] 233 | 234 | , ... 235 | }@attrs: 236 | let 237 | modulesStruct = if modules == null then { } else fromTOML (readFile modules); 238 | 239 | goModPath = "${toString pwd}/go.mod"; 240 | 241 | goMod = 242 | if pwd != null && pathExists goModPath 243 | then parseGoMod (readFile goModPath) 244 | else null; 245 | 246 | go = selectGo attrs goMod; 247 | 248 | defaultPackage = modulesStruct.goPackagePath or ""; 249 | 250 | vendorEnv = mkVendorEnv { 251 | inherit go modulesStruct defaultPackage goMod pwd; 252 | }; 253 | 254 | pname = attrs.pname or baseNameOf defaultPackage; 255 | 256 | in 257 | stdenv.mkDerivation 258 | (optionalAttrs (defaultPackage != "") 259 | { 260 | inherit pname; 261 | version = stripVersion (modulesStruct.mod.${defaultPackage}).version; 262 | src = vendorEnv.passthru.sources.${defaultPackage}; 263 | } // optionalAttrs (hasAttr "subPackages" modulesStruct) { 264 | subPackages = modulesStruct.subPackages; 265 | } // attrs // { 266 | nativeBuildInputs = [ rsync go ] ++ nativeBuildInputs; 267 | 268 | inherit (go) GOOS GOARCH; 269 | 270 | GO_NO_VENDOR_CHECKS = "1"; 271 | CGO_ENABLED = attrs.CGO_ENABLED or go.CGO_ENABLED; 272 | 273 | GO111MODULE = "on"; 274 | GOFLAGS = [ "-mod=vendor" ] ++ lib.optionals (!allowGoReference) [ "-trimpath" ]; 275 | 276 | configurePhase = attrs.configurePhase or '' 277 | runHook preConfigure 278 | 279 | export GOCACHE=$TMPDIR/go-cache 280 | export GOPATH="$TMPDIR/go" 281 | export GOSUMDB=off 282 | export GOPROXY=off 283 | cd "$modRoot" 284 | 285 | ${optionalString (modulesStruct != { }) '' 286 | if [ -n "${vendorEnv}" ]; then 287 | rm -rf vendor 288 | rsync -a -K --ignore-errors ${vendorEnv}/ vendor 289 | fi 290 | ''} 291 | 292 | runHook postConfigure 293 | ''; 294 | 295 | buildPhase = attrs.buildPhase or '' 296 | runHook preBuild 297 | 298 | exclude='\(/_\|examples\|Godeps\|testdata' 299 | if [[ -n "$excludedPackages" ]]; then 300 | IFS=' ' read -r -a excludedArr <<<$excludedPackages 301 | printf -v excludedAlternates '%s\\|' "''${excludedArr[@]}" 302 | excludedAlternates=''${excludedAlternates%\\|} # drop final \| added by printf 303 | exclude+='\|'"$excludedAlternates" 304 | fi 305 | exclude+='\)' 306 | 307 | buildGoDir() { 308 | local cmd="$1" dir="$2" 309 | 310 | . $TMPDIR/buildFlagsArray 311 | 312 | declare -a flags 313 | flags+=($buildFlags "''${buildFlagsArray[@]}") 314 | flags+=(''${tags:+-tags=${lib.concatStringsSep "," tags}}) 315 | flags+=(''${ldflags:+-ldflags="$ldflags"}) 316 | flags+=("-v" "-p" "$NIX_BUILD_CORES") 317 | 318 | if [ "$cmd" = "test" ]; then 319 | flags+=(-vet=off) 320 | flags+=($checkFlags) 321 | fi 322 | 323 | local OUT 324 | if ! OUT="$(go $cmd "''${flags[@]}" $dir 2>&1)"; then 325 | if echo "$OUT" | grep -qE 'imports .*?: no Go files in'; then 326 | echo "$OUT" >&2 327 | return 1 328 | fi 329 | if ! echo "$OUT" | grep -qE '(no( buildable| non-test)?|build constraints exclude all) Go (source )?files'; then 330 | echo "$OUT" >&2 331 | return 1 332 | fi 333 | fi 334 | if [ -n "$OUT" ]; then 335 | echo "$OUT" >&2 336 | fi 337 | return 0 338 | } 339 | 340 | getGoDirs() { 341 | local type; 342 | type="$1" 343 | if [ -n "$subPackages" ]; then 344 | echo "$subPackages" | sed "s,\(^\| \),\1./,g" 345 | else 346 | find . -type f -name \*$type.go -exec dirname {} \; | grep -v "/vendor/" | sort --unique | grep -v "$exclude" 347 | fi 348 | } 349 | 350 | if (( "''${NIX_DEBUG:-0}" >= 1 )); then 351 | buildFlagsArray+=(-x) 352 | fi 353 | 354 | if [ ''${#buildFlagsArray[@]} -ne 0 ]; then 355 | declare -p buildFlagsArray > $TMPDIR/buildFlagsArray 356 | else 357 | touch $TMPDIR/buildFlagsArray 358 | fi 359 | if [ -z "$enableParallelBuilding" ]; then 360 | export NIX_BUILD_CORES=1 361 | fi 362 | for pkg in $(getGoDirs ""); do 363 | echo "Building subPackage $pkg" 364 | buildGoDir install "$pkg" 365 | done 366 | '' + optionalString (stdenv.hostPlatform != stdenv.buildPlatform) '' 367 | # normalize cross-compiled builds w.r.t. native builds 368 | ( 369 | dir=$GOPATH/bin/${go.GOOS}_${go.GOARCH} 370 | if [[ -n "$(shopt -s nullglob; echo $dir/*)" ]]; then 371 | mv $dir/* $dir/.. 372 | fi 373 | if [[ -d $dir ]]; then 374 | rmdir $dir 375 | fi 376 | ) 377 | '' + '' 378 | runHook postBuild 379 | ''; 380 | 381 | doCheck = attrs.doCheck or true; 382 | checkPhase = attrs.checkPhase or '' 383 | runHook preCheck 384 | 385 | # We do not set trimpath for tests, in case they reference test assets 386 | export GOFLAGS=''${GOFLAGS//-trimpath/} 387 | 388 | for pkg in $(getGoDirs test); do 389 | buildGoDir test "$pkg" 390 | done 391 | 392 | runHook postCheck 393 | ''; 394 | 395 | installPhase = attrs.installPhase or '' 396 | runHook preInstall 397 | 398 | mkdir -p $out 399 | dir="$GOPATH/bin" 400 | [ -e "$dir" ] && cp -r $dir $out 401 | 402 | runHook postInstall 403 | ''; 404 | 405 | strictDeps = true; 406 | 407 | disallowedReferences = optional (!allowGoReference) go; 408 | 409 | passthru = { 410 | inherit go vendorEnv; 411 | } // optionalAttrs (hasAttr "goPackagePath" modulesStruct) { 412 | 413 | updateScript = 414 | let 415 | generatorArgs = 416 | if hasAttr "subPackages" modulesStruct 417 | then 418 | concatStringsSep " " 419 | ( 420 | map (subPackage: modulesStruct.goPackagePath + "/" + subPackage) modulesStruct.subPackages 421 | ) 422 | else modulesStruct.goPackagePath; 423 | 424 | in 425 | writeScript "${pname}-updater" '' 426 | #!${runtimeShell} 427 | ${optionalString (pwd != null) "cd ${toString pwd}"} 428 | exec ${gomod2nix}/bin/gomod2nix generate ${generatorArgs} 429 | ''; 430 | 431 | } // passthru; 432 | 433 | inherit meta; 434 | }); 435 | 436 | in 437 | { 438 | inherit buildGoApplication mkGoEnv; 439 | } 440 | -------------------------------------------------------------------------------- /builder/fetch.sh: -------------------------------------------------------------------------------- 1 | source $stdenv/setup 2 | 3 | export HOME=$(mktemp -d) 4 | 5 | # Call once first outside of subshell for better error reporting 6 | go mod download "$goPackagePath@$version" 7 | 8 | dir=$(go mod download --json "$goPackagePath@$version" | jq -r .Dir) 9 | 10 | chmod -R +w $dir 11 | find $dir -iname ".ds_store" | xargs -r rm -rf 12 | 13 | cp -r $dir $out 14 | -------------------------------------------------------------------------------- /builder/install/install.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "go/parser" 6 | "go/token" 7 | "io" 8 | "os" 9 | "os/exec" 10 | "strconv" 11 | ) 12 | 13 | const filename = "tools.go" 14 | 15 | func main() { 16 | fset := token.NewFileSet() 17 | 18 | var src []byte 19 | { 20 | f, err := os.Open(filename) 21 | if err != nil { 22 | panic(err) 23 | } 24 | 25 | src, err = io.ReadAll(f) 26 | if err != nil { 27 | panic(err) 28 | } 29 | } 30 | 31 | f, err := parser.ParseFile(fset, filename, src, parser.ImportsOnly) 32 | if err != nil { 33 | fmt.Println(err) 34 | return 35 | } 36 | 37 | for _, s := range f.Imports { 38 | path, err := strconv.Unquote(s.Path.Value) 39 | if err != nil { 40 | panic(err) 41 | } 42 | 43 | cmd := exec.Command("go", "install", path) 44 | cmd.Stdout = os.Stdout 45 | cmd.Stderr = os.Stderr 46 | 47 | fmt.Printf("Executing '%s'\n", cmd) 48 | 49 | err = cmd.Start() 50 | if err != nil { 51 | panic(err) 52 | } 53 | 54 | err = cmd.Wait() 55 | if err != nil { 56 | panic(err) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /builder/parser.nix: -------------------------------------------------------------------------------- 1 | # Parse go.mod in Nix 2 | # Returns a Nix structure with the contents of the go.mod passed in 3 | # in normalised form. 4 | 5 | let 6 | inherit (builtins) elemAt mapAttrs split foldl' match filter typeOf hasAttr length; 7 | 8 | # Strip lines with comments & other junk 9 | stripStr = s: elemAt (split "^ *" (elemAt (split " *$" s) 0)) 2; 10 | stripLines = initialLines: foldl' (acc: f: f acc) initialLines [ 11 | # Strip comments 12 | (lines: map 13 | (l: stripStr (elemAt (splitString "//" l) 0)) 14 | lines) 15 | 16 | # Strip leading tabs characters 17 | (lines: map (l: elemAt (match "(\t)?(.*)" l) 1) lines) 18 | 19 | # Filter empty lines 20 | (filter (l: l != "")) 21 | ]; 22 | 23 | # Parse lines into a structure 24 | parseLines = lines: (foldl' 25 | (acc: l: 26 | let 27 | m = match "([^ )]*) *(.*)" l; # Match the current line 28 | directive = elemAt m 0; # The directive (replace, require & so on) 29 | rest = elemAt m 1; # The rest of the current line 30 | 31 | # Maintain parser state (inside parens or not) 32 | inDirective = 33 | if rest == "(" then directive 34 | else if rest == ")" then null 35 | else acc.inDirective 36 | ; 37 | 38 | in 39 | { 40 | data = (acc.data // ( 41 | # If a we're in a directive and it's closing, no-op 42 | if directive == "" && rest == ")" then { } 43 | 44 | # If a directive is opening create the directive attrset 45 | else if inDirective != null && rest == "(" && ! hasAttr inDirective acc.data then { 46 | ${inDirective} = { }; 47 | } 48 | 49 | # If we're closing any paren, no-op 50 | else if rest == "(" || rest == ")" then { } 51 | 52 | # If we're in a directive that has rest data assign it to the directive in the output 53 | else if inDirective != null then { 54 | ${inDirective} = acc.data.${inDirective} // { ${directive} = rest; }; 55 | } 56 | 57 | # Replace directive has unique structure and needs special casing 58 | else if directive == "replace" then 59 | ( 60 | let 61 | # Split `foo => bar` into segments 62 | segments = split " => " rest; 63 | getSegment = elemAt segments; 64 | in 65 | assert length segments == 3; { 66 | # Assert well formed 67 | replace = acc.data.replace // { 68 | # Structure segments into attrset 69 | ${getSegment 0} = "=> ${getSegment 2}"; 70 | }; 71 | } 72 | ) 73 | 74 | # The default operation is to just assign the value 75 | else { 76 | ${directive} = rest; 77 | } 78 | ) 79 | ); 80 | inherit inDirective; 81 | }) 82 | { 83 | # Default foldl' state 84 | inDirective = null; 85 | # The actual return data we're interested in (default empty structure) 86 | data = { 87 | require = { }; 88 | replace = { }; 89 | exclude = { }; 90 | }; 91 | } 92 | lines 93 | ).data; 94 | 95 | # Normalise directives no matter what syntax produced them 96 | # meaning that: 97 | # replace github.com/nix-community/trustix/packages/go-lib => ../go-lib 98 | # 99 | # and: 100 | # replace ( 101 | # github.com/nix-community/trustix/packages/go-lib => ../go-lib 102 | # ) 103 | # 104 | # gets the same structural representation. 105 | # 106 | # Addtionally this will create directives that are entirely missing from go.mod 107 | # as an empty attrset so it's output is more consistent. 108 | normaliseDirectives = data: ( 109 | let 110 | normaliseString = s: 111 | let 112 | m = builtins.match "([^ ]+) (.+)" s; 113 | in 114 | { 115 | ${elemAt m 0} = elemAt m 1; 116 | }; 117 | require = data.require or { }; 118 | replace = data.replace or { }; 119 | exclude = data.exclude or { }; 120 | in 121 | data // { 122 | require = 123 | if typeOf require == "string" then normaliseString require 124 | else require; 125 | replace = 126 | if typeOf replace == "string" then normaliseString replace 127 | else replace; 128 | } 129 | ); 130 | 131 | # Parse versions and dates from go.mod version string 132 | parseVersion = ver: 133 | let 134 | m = elemAt (match "([^-]+)-?([^-]*)-?([^-]*)" ver); 135 | v = elemAt (match "([^+]+)\\+?(.*)" (m 0)); 136 | in 137 | { 138 | version = v 0; 139 | versionSuffix = v 1; 140 | date = m 1; 141 | rev = m 2; 142 | }; 143 | 144 | # Parse package paths & versions from replace directives 145 | parseReplace = data: ( 146 | data // { 147 | replace = 148 | mapAttrs 149 | (_: v: 150 | let 151 | m = match "=> ([^ ]+) (.+)" v; 152 | m2 = match "=> ([^ ]+)" v; 153 | in 154 | if m != null then { 155 | goPackagePath = elemAt m 0; 156 | version = elemAt m 1; 157 | } else { 158 | path = elemAt m2 0; 159 | }) 160 | data.replace; 161 | } 162 | ); 163 | 164 | splitString = sep: s: filter (t: t != [ ]) (split sep s); 165 | 166 | in 167 | contents: 168 | foldl' (acc: f: f acc) (splitString "\n" contents) [ 169 | stripLines 170 | parseLines 171 | normaliseDirectives 172 | parseReplace 173 | ] 174 | -------------------------------------------------------------------------------- /builder/symlink/symlink.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | "sort" 9 | ) 10 | 11 | type Package struct { 12 | GoPackagePath string `json:"-"` 13 | Version string `json:"version"` 14 | Hash string `json:"hash"` 15 | ReplacedPath string `json:"replaced,omitempty"` 16 | } 17 | 18 | type Sources map[string]string 19 | 20 | func populateStruct(path string, data interface{}) { 21 | pathVal := os.Getenv(path) 22 | if len(path) == 0 { 23 | panic(fmt.Sprintf("env var '%s' was unset", path)) 24 | } 25 | path = pathVal 26 | 27 | b, err := os.ReadFile(path) 28 | if err != nil { 29 | panic(err) 30 | } 31 | 32 | err = json.Unmarshal(b, &data) 33 | if err != nil { 34 | panic(err) 35 | } 36 | } 37 | 38 | func main() { 39 | sources := make(Sources) 40 | pkgs := make(map[string]*Package) 41 | 42 | populateStruct("sourcesPath", &sources) 43 | 44 | populateStruct("jsonPath", &pkgs) 45 | 46 | keys := make([]string, 0, len(pkgs)) 47 | for key := range pkgs { 48 | keys = append(keys, key) 49 | } 50 | sort.Strings(keys) 51 | 52 | makeSymlinks(keys, sources) 53 | } 54 | 55 | func makeSymlinks(keys []string, sources Sources) { 56 | // Iterate, in reverse order 57 | for i := len(keys) - 1; i >= 0; i-- { 58 | key := keys[i] 59 | src := sources[key] 60 | 61 | paths := []string{key} 62 | 63 | for _, path := range paths { 64 | vendorDir := filepath.Join("vendor", filepath.Dir(path)) 65 | if err := os.MkdirAll(vendorDir, 0o755); err != nil { 66 | panic(err) 67 | } 68 | 69 | vendorPath := filepath.Join("vendor", path) 70 | if _, err := os.Stat(vendorPath); err == nil { 71 | populateVendorPath(vendorPath, src) 72 | continue 73 | } 74 | 75 | // If the file doesn't already exist, just create a simple symlink 76 | err := os.Symlink(src, vendorPath) 77 | if err != nil { 78 | panic(err) 79 | } 80 | } 81 | } 82 | } 83 | 84 | func populateVendorPath(vendorPath string, src string) { 85 | files, err := os.ReadDir(src) 86 | if err != nil { 87 | panic(err) 88 | } 89 | 90 | for _, f := range files { 91 | innerSrc := filepath.Join(src, f.Name()) 92 | dst := filepath.Join(vendorPath, f.Name()) 93 | if err := os.Symlink(innerSrc, dst); err != nil { 94 | fmt.Println("symlink error, trying", innerSrc, err) 95 | populateVendorPath(dst, innerSrc); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { stdenv 2 | , callPackage 3 | , go 4 | , lib 5 | , makeWrapper 6 | , installShellFiles 7 | , fetchFromGitHub 8 | , buildGoApplication 9 | , mkGoEnv 10 | }: 11 | 12 | buildGoApplication { 13 | pname = "gomod2nix"; 14 | version = "dev"; 15 | 16 | modules = ./gomod2nix.toml; 17 | 18 | src = lib.cleanSourceWith { 19 | filter = name: type: builtins.foldl' (v: s: v && ! lib.hasSuffix s name) true [ 20 | "tests" 21 | "builder" 22 | "templates" 23 | ]; 24 | src = lib.cleanSource ./.; 25 | }; 26 | 27 | inherit go; 28 | 29 | allowGoReference = true; 30 | 31 | subPackages = [ "." ]; 32 | 33 | nativeBuildInputs = [ makeWrapper installShellFiles ]; 34 | 35 | passthru = { 36 | inherit buildGoApplication mkGoEnv; 37 | }; 38 | 39 | postInstall = lib.optionalString (stdenv.buildPlatform == stdenv.targetPlatform) '' 40 | installShellCompletion --cmd gomod2nix \ 41 | --bash <($out/bin/gomod2nix completion bash) \ 42 | --fish <($out/bin/gomod2nix completion fish) \ 43 | --zsh <($out/bin/gomod2nix completion zsh) 44 | '' + '' 45 | wrapProgram $out/bin/gomod2nix --prefix PATH : ${lib.makeBinPath [ go ]} 46 | ''; 47 | 48 | meta = { 49 | description = "Convert applications using Go modules -> Nix"; 50 | homepage = "https://github.com/nix-community/gomod2nix"; 51 | license = lib.licenses.mit; 52 | maintainers = [ lib.maintainers.adisbladis ]; 53 | }; 54 | } 55 | -------------------------------------------------------------------------------- /docs/getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting started with Gomod2nix 2 | 3 | ## Installation 4 | 5 | ### Using Niv 6 | 7 | First initialize Niv: 8 | ``` bash 9 | $ niv init --latest 10 | $ niv add nix-community/gomod2nix 11 | ``` 12 | 13 | Create a `shell.nix` used for development: 14 | ``` nix 15 | { pkgs ? ( 16 | let 17 | sources = import ./nix/sources.nix; 18 | in 19 | import sources.nixpkgs { 20 | overlays = [ 21 | (import "${sources.gomod2nix}/overlay.nix") 22 | ]; 23 | } 24 | ) 25 | }: 26 | 27 | let 28 | goEnv = pkgs.mkGoEnv { pwd = ./.; }; 29 | in 30 | pkgs.mkShell { 31 | packages = [ 32 | goEnv 33 | pkgs.gomod2nix 34 | pkgs.niv 35 | ]; 36 | } 37 | ``` 38 | 39 | And a `default.nix` for building your package 40 | ``` nix 41 | { pkgs ? ( 42 | let 43 | sources = import ./nix/sources.nix; 44 | in 45 | import sources.nixpkgs { 46 | overlays = [ 47 | (import "${sources.gomod2nix}/overlay.nix") 48 | ]; 49 | } 50 | ) 51 | }: 52 | 53 | pkgs.buildGoApplication { 54 | pname = "myapp"; 55 | version = "0.1"; 56 | pwd = ./.; 57 | src = ./.; 58 | modules = ./gomod2nix.toml; 59 | } 60 | ``` 61 | 62 | ### Using Flakes 63 | 64 | The quickest way to get started if using Nix Flakes is to use the Flake template: 65 | ``` bash 66 | $ nix flake init -t github:nix-community/gomod2nix#app 67 | ``` 68 | 69 | ## Basic usage 70 | 71 | After you have entered your development shell you can generate a `gomod2nix.toml` using: 72 | ``` bash 73 | $ gomod2nix generate 74 | ``` 75 | 76 | To speed up development and avoid downloading dependencies again in the Nix store you can import them directly from the Go cache using: 77 | ``` bash 78 | $ gomod2nix import 79 | ``` 80 | -------------------------------------------------------------------------------- /docs/nix-reference.md: -------------------------------------------------------------------------------- 1 | # Gomod2nix Nix API 2 | 3 | ## Public functions 4 | 5 | ### buildGoApplication 6 | 7 | Arguments: 8 | 9 | - **modules** Path to `gomod2nix.toml` (\_default: `pwd + "/gomod2nix.toml"`). 10 | - **src** Path to sources (\_default: `pwd`). 11 | - **pwd** Path to working directory (\_default: `null`). 12 | - **go** The Go compiler to use (can be omitted). 13 | - **subPackages** Only build these specific sub packages. 14 | - **allowGoReference** Allow references to the Go compiler in the output closure (\_default: `false`). 15 | - **tags** A list of tags to pass the Go compiler during the build (\_default: `[ ]`). 16 | - **ldflags** A list of `ldflags` to pass the Go compiler during the build (\_default: `[ ]`). 17 | - **nativeBuildInputs** A list of packages to include in the build derivation (\_default: `[ ]`). 18 | 19 | All other arguments are passed verbatim to `stdenv.mkDerivation`. 20 | 21 | ### mkGoEnv 22 | 23 | Arguments: 24 | 25 | - **pwd** Path to working directory. 26 | - **modules** Path to `gomod2nix.toml` (\_default: `pwd + "/gomod2nix.toml"`). 27 | - **toolsGo** Path to `tools.go` (\_default: `pwd + "/tools.go"`). 28 | 29 | All other arguments are passed verbatim to `stdenv.mkDerivation`. 30 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1694529238, 9 | "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1658285632, 24 | "narHash": "sha256-zRS5S/hoeDGUbO+L95wXG9vJNwsSYcl93XiD0HQBXLk=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "5342fc6fb59d0595d26883c3cadff16ce58e44f3", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "master", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "root": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nixpkgs": "nixpkgs" 41 | } 42 | }, 43 | "systems": { 44 | "locked": { 45 | "lastModified": 1681028828, 46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 47 | "owner": "nix-systems", 48 | "repo": "default", 49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 50 | "type": "github" 51 | }, 52 | "original": { 53 | "owner": "nix-systems", 54 | "repo": "default", 55 | "type": "github" 56 | } 57 | } 58 | }, 59 | "root": "root", 60 | "version": 7 61 | } 62 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Convert go.mod/go.sum to Nix packages"; 3 | 4 | inputs.nixpkgs.url = "github:NixOS/nixpkgs/master"; 5 | inputs.flake-utils.url = "github:numtide/flake-utils"; 6 | 7 | outputs = { self, nixpkgs, flake-utils }: 8 | { 9 | overlays.default = import ./overlay.nix; 10 | 11 | templates = { 12 | app = { 13 | path = ./templates/app; 14 | description = "Gomod2nix packaged application"; 15 | }; 16 | }; 17 | defaultTemplate = self.templates.app; 18 | 19 | } 20 | // (flake-utils.lib.eachSystem 21 | [ 22 | "aarch64-linux" 23 | "aarch64-darwin" 24 | "x86_64-darwin" 25 | "x86_64-linux" 26 | "riscv64-linux" 27 | ] 28 | ( 29 | system: 30 | let 31 | pkgs = nixpkgs.legacyPackages.${system}; 32 | 33 | # The current default sdk for macOS fails to compile go projects, so we use a newer one for now. 34 | # This has no effect on other platforms. 35 | callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage; 36 | 37 | inherit (callPackage ./builder { 38 | inherit gomod2nix; 39 | }) mkGoEnv buildGoApplication; 40 | gomod2nix = callPackage ./default.nix { 41 | inherit mkGoEnv buildGoApplication; 42 | }; 43 | in 44 | { 45 | packages.default = gomod2nix; 46 | legacyPackages = { 47 | # we cannot put them in packages because they are builder functions 48 | inherit mkGoEnv buildGoApplication; 49 | # just have this here for convenience 50 | inherit gomod2nix; 51 | }; 52 | devShells.default = callPackage ./shell.nix { 53 | inherit mkGoEnv gomod2nix; 54 | }; 55 | } 56 | ) 57 | ); 58 | } 59 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nix-community/gomod2nix 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/BurntSushi/toml v1.4.0 7 | github.com/nix-community/go-nix v0.0.0-20220612195009-5f5614f7ca47 8 | github.com/sirupsen/logrus v1.9.3 9 | github.com/spf13/cobra v1.9.1 10 | golang.org/x/mod v0.23.0 11 | golang.org/x/tools/go/vcs v0.1.0-deprecated 12 | ) 13 | 14 | require ( 15 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 16 | github.com/spf13/pflag v1.0.6 // indirect 17 | golang.org/x/sys v0.14.0 // indirect 18 | ) 19 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= 4 | github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= 5 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 6 | github.com/alecthomas/kong v0.5.0/go.mod h1:uzxf/HUh0tj43x1AyJROl3JT7SgsZ5m+icOv1csRhc0= 7 | github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= 8 | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 9 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 10 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 11 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 12 | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 13 | github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= 14 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 15 | github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= 16 | github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= 17 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 18 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 19 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 20 | github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= 21 | github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= 22 | github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= 23 | github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= 24 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 25 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 26 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 27 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 28 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 29 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 30 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 31 | github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 32 | github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 33 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 34 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 35 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 36 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 37 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 38 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 39 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 40 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 41 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 42 | github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= 43 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 44 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 45 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 46 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 47 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 48 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 49 | github.com/nix-community/go-nix v0.0.0-20220612195009-5f5614f7ca47 h1:K270nNzKXBOJjEtPe91yAN+7NqMqgDt/D2gR5OCotxg= 50 | github.com/nix-community/go-nix v0.0.0-20220612195009-5f5614f7ca47/go.mod h1:eE1NFc/GHPnxAhTTuxIfB6JSvRQdMVQCMQqRrGRWWfQ= 51 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 52 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 53 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 54 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 55 | github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= 56 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 57 | github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= 58 | github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 59 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 60 | github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 61 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 62 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 63 | github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= 64 | github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= 65 | github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= 66 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 67 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 68 | github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= 69 | github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 70 | github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= 71 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 72 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 73 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 74 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 75 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 76 | github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= 77 | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= 78 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 79 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 80 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 81 | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= 82 | golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 83 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 84 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 85 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 86 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 87 | golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= 88 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 89 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 90 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 91 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 92 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 93 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 94 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 95 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 96 | golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 97 | golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= 98 | golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 99 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 100 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 101 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 102 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 103 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 104 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 105 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 106 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 107 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 108 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 109 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 110 | golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 111 | golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= 112 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 113 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 114 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 115 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 116 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 117 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 118 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 119 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 120 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 121 | golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= 122 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 123 | golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 124 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 125 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 126 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 127 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 128 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 129 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 130 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 131 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 132 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 133 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 134 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 135 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 136 | golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 137 | golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 138 | golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= 139 | golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 140 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 141 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 142 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 143 | golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 144 | golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= 145 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 146 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 147 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 148 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 149 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 150 | golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 151 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 152 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 153 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 154 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 155 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 156 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 157 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 158 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 159 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 160 | golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= 161 | golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= 162 | golang.org/x/tools/go/vcs v0.1.0-deprecated h1:cOIJqWBl99H1dH5LWizPa+0ImeeJq3t3cJjaeOWUAL4= 163 | golang.org/x/tools/go/vcs v0.1.0-deprecated/go.mod h1:zUrvATBAvEI9535oC0yWYsLsHIV4Z7g63sNPVMtuBy8= 164 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 165 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 166 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 167 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 168 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 169 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 170 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 171 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 172 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 173 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 174 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 175 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 176 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 177 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 178 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 179 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 180 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 181 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 182 | -------------------------------------------------------------------------------- /gomod2nix.toml: -------------------------------------------------------------------------------- 1 | schema = 3 2 | 3 | [mod] 4 | [mod."github.com/BurntSushi/toml"] 5 | version = "v1.4.0" 6 | hash = "sha256-3cr8hfVA4th/AfveHDxigmj8Eiiae0ZBnxAgy+7RYO4=" 7 | [mod."github.com/inconshreveable/mousetrap"] 8 | version = "v1.1.0" 9 | hash = "sha256-XWlYH0c8IcxAwQTnIi6WYqq44nOKUylSWxWO/vi+8pE=" 10 | [mod."github.com/nix-community/go-nix"] 11 | version = "v0.0.0-20220612195009-5f5614f7ca47" 12 | hash = "sha256-eBPzib8STUZnDpLFpWZz+F00thbp1P/98oiEE/XWE+M=" 13 | [mod."github.com/sirupsen/logrus"] 14 | version = "v1.9.3" 15 | hash = "sha256-EnxsWdEUPYid+aZ9H4/iMTs1XMvCLbXZRDyvj89Ebms=" 16 | [mod."github.com/spf13/cobra"] 17 | version = "v1.9.1" 18 | hash = "sha256-dzEqquABE3UqZmJuj99244QjvfojS8cFlsPr/MXQGj0=" 19 | [mod."github.com/spf13/pflag"] 20 | version = "v1.0.6" 21 | hash = "sha256-NjrK0FZPIfO/p2xtL1J7fOBQNTZAPZOC6Cb4aMMvhxI=" 22 | [mod."golang.org/x/mod"] 23 | version = "v0.23.0" 24 | hash = "sha256-8mlTcEyJy1ETxCO4g7RjZ4Z5nJvXRNwKLwAOoe2GChI=" 25 | [mod."golang.org/x/sys"] 26 | version = "v0.14.0" 27 | hash = "sha256-ReIRQmONicRW9idzGVPCBx5TTcKacmQTF1vPC3L4SxY=" 28 | [mod."golang.org/x/tools/go/vcs"] 29 | version = "v0.1.0-deprecated" 30 | hash = "sha256-57YB10tiRsVSRvJqKYST+iON6yZYGL7eRSzrFcImC8Y=" 31 | -------------------------------------------------------------------------------- /internal/cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | 8 | log "github.com/sirupsen/logrus" 9 | "github.com/spf13/cobra" 10 | generate "github.com/nix-community/gomod2nix/internal/generate" 11 | schema "github.com/nix-community/gomod2nix/internal/schema" 12 | ) 13 | 14 | const directoryDefault = "./" 15 | 16 | var ( 17 | flagDirectory string 18 | flagOutDir string 19 | maxJobs int 20 | ) 21 | 22 | func generateFunc(cmd *cobra.Command, args []string) { 23 | directory := flagDirectory 24 | outDir := flagOutDir 25 | 26 | // If we are dealing with a project packaged by passing packages on the command line 27 | // we need to create a temporary project. 28 | var tmpProj *generate.TempProject 29 | if len(args) > 0 { 30 | var err error 31 | 32 | if directory != directoryDefault { 33 | panic(fmt.Errorf("directory flag not supported together with import arguments")) 34 | } 35 | if outDir == "" { 36 | pwd, err := os.Getwd() 37 | if err != nil { 38 | panic(err) 39 | } 40 | 41 | outDir = pwd 42 | } 43 | 44 | tmpProj, err = generate.NewTempProject(args) 45 | if err != nil { 46 | panic(err) 47 | } 48 | defer func() { 49 | err := tmpProj.Remove() 50 | if err != nil { 51 | panic(err) 52 | } 53 | }() 54 | 55 | directory = tmpProj.Dir 56 | } else if outDir == "" { 57 | // Default out to current working directory if we are developing some software in the current repo. 58 | outDir = directory 59 | } 60 | 61 | // Write gomod2nix.toml 62 | { 63 | goMod2NixPath := filepath.Join(outDir, "gomod2nix.toml") 64 | outFile := goMod2NixPath 65 | pkgs, err := generate.GeneratePkgs(directory, goMod2NixPath, maxJobs) 66 | if err != nil { 67 | panic(fmt.Errorf("error generating pkgs: %v", err)) 68 | } 69 | 70 | var goPackagePath string 71 | var subPackages []string 72 | 73 | if tmpProj != nil { 74 | subPackages = tmpProj.SubPackages 75 | goPackagePath = tmpProj.GoPackagePath 76 | } 77 | 78 | output, err := schema.Marshal(pkgs, goPackagePath, subPackages) 79 | if err != nil { 80 | panic(fmt.Errorf("error marshaling output: %v", err)) 81 | } 82 | 83 | err = os.WriteFile(outFile, output, 0644) 84 | if err != nil { 85 | panic(fmt.Errorf("error writing file: %v", err)) 86 | } 87 | log.Info(fmt.Sprintf("Wrote: %s", outFile)) 88 | } 89 | } 90 | 91 | var rootCmd = &cobra.Command{ 92 | Use: "gomod2nix", 93 | Short: "Convert applications using Go modules -> Nix", 94 | Run: generateFunc, 95 | } 96 | 97 | var generateCmd = &cobra.Command{ 98 | Use: "generate", 99 | Short: "Run gomod2nix.toml generator", 100 | Run: generateFunc, 101 | } 102 | 103 | var importCmd = &cobra.Command{ 104 | Use: "import", 105 | Short: "Import Go sources into the Nix store", 106 | Run: func(cmd *cobra.Command, args []string) { 107 | err := generate.ImportPkgs(flagDirectory, maxJobs) 108 | if err != nil { 109 | panic(err) 110 | } 111 | }, 112 | } 113 | 114 | func init() { 115 | rootCmd.PersistentFlags().StringVar(&flagDirectory, "dir", "./", "Go project directory") 116 | rootCmd.PersistentFlags().StringVar(&flagOutDir, "outdir", "", "Output directory (defaults to project directory)") 117 | rootCmd.PersistentFlags().IntVar(&maxJobs, "jobs", 10, "Max number of concurrent jobs") 118 | 119 | rootCmd.AddCommand(generateCmd) 120 | rootCmd.AddCommand(importCmd) 121 | } 122 | 123 | func Execute() { 124 | err := rootCmd.Execute() 125 | if err != nil { 126 | os.Exit(1) 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /internal/generate/generate.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import ( 4 | "bytes" 5 | "crypto/sha256" 6 | "encoding/base64" 7 | "encoding/json" 8 | "fmt" 9 | "io" 10 | "os" 11 | "os/exec" 12 | "path/filepath" 13 | "sort" 14 | "strings" 15 | "sync" 16 | 17 | "github.com/nix-community/go-nix/pkg/nar" 18 | "github.com/nix-community/gomod2nix/internal/lib" 19 | schema "github.com/nix-community/gomod2nix/internal/schema" 20 | log "github.com/sirupsen/logrus" 21 | "golang.org/x/mod/modfile" 22 | ) 23 | 24 | type goModDownload struct { 25 | Path string 26 | Version string 27 | Info string 28 | GoMod string 29 | Zip string 30 | Dir string 31 | Sum string 32 | GoModSum string 33 | } 34 | 35 | func sourceFilter(name string, nodeType nar.NodeType) bool { 36 | return strings.ToLower(filepath.Base(name)) != ".ds_store" 37 | } 38 | 39 | func common(directory string) ([]*goModDownload, map[string]string, error) { 40 | goModPath := filepath.Join(directory, "go.mod") 41 | 42 | log.WithFields(log.Fields{ 43 | "modPath": goModPath, 44 | }).Info("Parsing go.mod") 45 | 46 | // Read go.mod 47 | data, err := os.ReadFile(goModPath) 48 | if err != nil { 49 | return nil, nil, err 50 | } 51 | 52 | // Parse go.mod 53 | mod, err := modfile.Parse(goModPath, data, nil) 54 | if err != nil { 55 | return nil, nil, err 56 | } 57 | 58 | // Map repos -> replacement repo 59 | replace := make(map[string]string) 60 | for _, repl := range mod.Replace { 61 | replace[repl.New.Path] = repl.Old.Path 62 | } 63 | 64 | var modDownloads []*goModDownload 65 | { 66 | log.Info("Downloading dependencies") 67 | 68 | cmd := exec.Command( 69 | "go", "mod", "download", "--json", 70 | ) 71 | cmd.Dir = directory 72 | stdout, err := cmd.Output() 73 | if err != nil { 74 | return nil, nil, err 75 | } 76 | 77 | dec := json.NewDecoder(bytes.NewReader(stdout)) 78 | for { 79 | var dl *goModDownload 80 | err := dec.Decode(&dl) 81 | if err == io.EOF { 82 | break 83 | } 84 | modDownloads = append(modDownloads, dl) 85 | } 86 | 87 | log.Info("Done downloading dependencies") 88 | } 89 | 90 | return modDownloads, replace, nil 91 | } 92 | 93 | func ImportPkgs(directory string, numWorkers int) error { 94 | modDownloads, _, err := common(directory) 95 | if err != nil { 96 | return err 97 | } 98 | 99 | executor := lib.NewParallelExecutor(numWorkers) 100 | for _, dl := range modDownloads { 101 | dl := dl 102 | executor.Add(func() error { 103 | log.WithFields(log.Fields{ 104 | "goPackagePath": dl.Path, 105 | }).Info("Importing sources") 106 | 107 | pathName := filepath.Base(dl.Path) + "_" + dl.Version 108 | 109 | cmd := exec.Command( 110 | "nix-instantiate", 111 | "--eval", 112 | "--expr", 113 | fmt.Sprintf(` 114 | builtins.filterSource (name: type: baseNameOf name != ".DS_Store") ( 115 | builtins.path { 116 | path = "%s"; 117 | name = "%s"; 118 | } 119 | ) 120 | `, dl.Dir, pathName), 121 | ) 122 | cmd.Stderr = os.Stderr 123 | 124 | err = cmd.Start() 125 | if err != nil { 126 | fmt.Println(cmd) 127 | return err 128 | } 129 | 130 | err = cmd.Wait() 131 | if err != nil { 132 | fmt.Println(cmd) 133 | return err 134 | } 135 | 136 | return nil 137 | }) 138 | } 139 | 140 | return executor.Wait() 141 | } 142 | 143 | func GeneratePkgs(directory string, goMod2NixPath string, numWorkers int) ([]*schema.Package, error) { 144 | modDownloads, replace, err := common(directory) 145 | if err != nil { 146 | return nil, err 147 | } 148 | 149 | executor := lib.NewParallelExecutor(numWorkers) 150 | var mux sync.Mutex 151 | 152 | cache := schema.ReadCache(goMod2NixPath) 153 | 154 | packages := []*schema.Package{} 155 | addPkg := func(pkg *schema.Package) { 156 | mux.Lock() 157 | packages = append(packages, pkg) 158 | mux.Unlock() 159 | } 160 | 161 | for _, dl := range modDownloads { 162 | dl := dl 163 | 164 | goPackagePath, hasReplace := replace[dl.Path] 165 | if !hasReplace { 166 | goPackagePath = dl.Path 167 | } 168 | 169 | cached, ok := cache[goPackagePath] 170 | if ok && cached.Version == dl.Version { 171 | addPkg(cached) 172 | continue 173 | } 174 | 175 | executor.Add(func() error { 176 | log.WithFields(log.Fields{ 177 | "goPackagePath": goPackagePath, 178 | }).Info("Calculating NAR hash") 179 | 180 | h := sha256.New() 181 | err := nar.DumpPathFilter(h, dl.Dir, sourceFilter) 182 | if err != nil { 183 | return err 184 | } 185 | digest := h.Sum(nil) 186 | 187 | pkg := &schema.Package{ 188 | GoPackagePath: goPackagePath, 189 | Version: dl.Version, 190 | Hash: "sha256-" + base64.StdEncoding.EncodeToString(digest), 191 | } 192 | if hasReplace { 193 | pkg.ReplacedPath = dl.Path 194 | } 195 | 196 | addPkg(pkg) 197 | 198 | log.WithFields(log.Fields{ 199 | "goPackagePath": goPackagePath, 200 | }).Info("Done calculating NAR hash") 201 | 202 | return nil 203 | }) 204 | } 205 | 206 | err = executor.Wait() 207 | if err != nil { 208 | return nil, err 209 | } 210 | 211 | sort.Slice(packages, func(i, j int) bool { 212 | return packages[i].GoPackagePath < packages[j].GoPackagePath 213 | }) 214 | 215 | return packages, nil 216 | 217 | } 218 | -------------------------------------------------------------------------------- /internal/generate/temp.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import ( 4 | "fmt" 5 | "go/ast" 6 | "go/printer" 7 | "go/token" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "strconv" 12 | "strings" 13 | 14 | log "github.com/sirupsen/logrus" 15 | "golang.org/x/mod/module" 16 | "golang.org/x/tools/go/vcs" // nolint:staticcheck 17 | ) 18 | 19 | type TempProject struct { 20 | Dir string 21 | SubPackages []string 22 | GoPackagePath string 23 | } 24 | 25 | func NewTempProject(packages []string) (*TempProject, error) { 26 | // Imports without version suffix 27 | install := make([]string, len(packages)) 28 | for i, imp := range packages { 29 | idx := strings.Index(imp, "@") 30 | if idx == -1 { 31 | idx = len(imp) 32 | } 33 | 34 | install[i] = imp[:idx] 35 | } 36 | 37 | var goPackagePath string 38 | 39 | for _, path := range install { 40 | log.WithFields(log.Fields{ 41 | "path": path, 42 | }).Info("Finding repo root for import path") 43 | 44 | repoRoot, err := vcs.RepoRootForImportPath(path, false) 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | _, versionSuffix, _ := module.SplitPathVersion(path) 50 | 51 | p := repoRoot.Root + versionSuffix 52 | 53 | if goPackagePath != "" && p != goPackagePath { 54 | return nil, fmt.Errorf("Mixed origin packages are not allowed") 55 | } 56 | 57 | goPackagePath = p 58 | } 59 | 60 | log.Info("Setting up temporary project") 61 | 62 | dir, err := os.MkdirTemp("", "gomod2nix-proj") 63 | if err != nil { 64 | return nil, err 65 | } 66 | 67 | log.WithFields(log.Fields{ 68 | "dir": dir, 69 | }).Info("Created temporary directory") 70 | 71 | // Create tools.go 72 | { 73 | log.WithFields(log.Fields{ 74 | "dir": dir, 75 | }).Info("Creating tools.go") 76 | 77 | astFile := &ast.File{ 78 | Name: ast.NewIdent("main"), 79 | Decls: []ast.Decl{ 80 | &ast.GenDecl{ 81 | Tok: token.IMPORT, 82 | Specs: func() []ast.Spec { 83 | specs := make([]ast.Spec, len(install)) 84 | 85 | i := 0 86 | for _, imp := range install { 87 | specs[i] = &ast.ImportSpec{ 88 | Name: ast.NewIdent("_"), 89 | Path: &ast.BasicLit{ 90 | ValuePos: token.NoPos, 91 | Kind: token.STRING, 92 | Value: strconv.Quote(imp), 93 | }, 94 | } 95 | 96 | i++ 97 | } 98 | 99 | return specs 100 | }(), 101 | }, 102 | }, 103 | } 104 | 105 | f, err := os.Create(filepath.Join(dir, "tools.go")) 106 | if err != nil { 107 | return nil, fmt.Errorf("Error creating tools.go: %v", err) 108 | } 109 | defer f.Close() 110 | 111 | fset := token.NewFileSet() 112 | err = printer.Fprint(f, fset, astFile) 113 | if err != nil { 114 | return nil, fmt.Errorf("error writing tools.go: %v", err) 115 | } 116 | 117 | log.WithFields(log.Fields{ 118 | "dir": dir, 119 | }).Info("Created tools.go") 120 | } 121 | 122 | // Set up go module 123 | { 124 | log.WithFields(log.Fields{ 125 | "dir": dir, 126 | }).Info("Initializing go.mod") 127 | 128 | cmd := exec.Command("go", "mod", "init", "gomod2nix/dummy/package") 129 | cmd.Dir = dir 130 | cmd.Stderr = os.Stderr 131 | 132 | _, err := cmd.Output() 133 | if err != nil { 134 | return nil, fmt.Errorf("error creating go module: %v", err) 135 | } 136 | 137 | log.WithFields(log.Fields{ 138 | "dir": dir, 139 | }).Info("Done initializing go.mod") 140 | 141 | // For every dependency fetch it 142 | { 143 | log.WithFields(log.Fields{ 144 | "dir": dir, 145 | }).Info("Getting dependencies") 146 | 147 | args := []string{"get", "-d"} 148 | args = append(args, packages...) 149 | 150 | cmd := exec.Command("go", args...) 151 | cmd.Dir = dir 152 | cmd.Stderr = os.Stderr 153 | 154 | _, err := cmd.Output() 155 | if err != nil { 156 | return nil, fmt.Errorf("error fetching: %v", err) 157 | } 158 | 159 | log.WithFields(log.Fields{ 160 | "dir": dir, 161 | }).Info("Done getting dependencies") 162 | } 163 | } 164 | 165 | subPackages := []string{} 166 | { 167 | prefix, versionSuffix, _ := module.SplitPathVersion(goPackagePath) 168 | for _, path := range install { 169 | p := strings.TrimPrefix(path, prefix) 170 | p = strings.TrimSuffix(p, versionSuffix) 171 | p = strings.TrimPrefix(p, "/") 172 | 173 | if p == "" { 174 | continue 175 | } 176 | 177 | subPackages = append(subPackages, p) 178 | } 179 | } 180 | 181 | return &TempProject{ 182 | Dir: dir, 183 | SubPackages: subPackages, 184 | GoPackagePath: goPackagePath, 185 | }, nil 186 | } 187 | 188 | func (t *TempProject) Remove() error { 189 | return os.RemoveAll(t.Dir) 190 | } 191 | -------------------------------------------------------------------------------- /internal/lib/executor.go: -------------------------------------------------------------------------------- 1 | package lib 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | // ParallelExecutor - Execute callback functions in parallel 8 | type ParallelExecutor struct { 9 | errChan chan error 10 | wg *sync.WaitGroup 11 | mux *sync.Mutex 12 | guard chan struct{} 13 | 14 | // Error returned by Wait(), cached for other Wait() invocations 15 | err error 16 | done bool 17 | } 18 | 19 | func NewParallelExecutor(maxWorkers int) *ParallelExecutor { 20 | return &ParallelExecutor{ 21 | errChan: make(chan error), 22 | mux: new(sync.Mutex), 23 | wg: new(sync.WaitGroup), 24 | guard: make(chan struct{}, maxWorkers), 25 | 26 | err: nil, 27 | done: false, 28 | } 29 | } 30 | 31 | func (e *ParallelExecutor) Add(fn func() error) { 32 | e.wg.Add(1) 33 | 34 | go func() { 35 | e.guard <- struct{}{} // Block until a worker is available 36 | defer e.wg.Done() 37 | defer func() { 38 | <-e.guard 39 | }() 40 | 41 | err := fn() 42 | if err != nil { 43 | e.errChan <- err 44 | } 45 | }() 46 | } 47 | 48 | func (e *ParallelExecutor) Wait() error { 49 | e.mux.Lock() 50 | defer e.mux.Unlock() 51 | 52 | if e.done { 53 | return e.err 54 | } 55 | 56 | var err error 57 | 58 | // Ensure channel is closed 59 | go func() { 60 | e.wg.Wait() 61 | close(e.errChan) 62 | }() 63 | 64 | for err = range e.errChan { 65 | if err != nil { 66 | break 67 | } 68 | } 69 | 70 | e.done = true 71 | e.err = err 72 | 73 | return err 74 | } 75 | -------------------------------------------------------------------------------- /internal/lib/executor_test.go: -------------------------------------------------------------------------------- 1 | package lib 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | // TestParallelExecutor_fnAlwaysErrors ensures that the executor does not block 10 | // forever when there are more erroring functions than workers. This is a 11 | // regression test. 12 | func TestParallelExecutor_fnAlwaysErrors(t *testing.T) { 13 | const maxWorkers = 1 14 | executor := NewParallelExecutor(1) 15 | 16 | for i := 0; i < maxWorkers+1; i++ { 17 | executor.Add(func() error { 18 | return errors.New("testerror") 19 | }) 20 | } 21 | 22 | errCh := make(chan error) 23 | go func() { 24 | defer close(errCh) 25 | errCh <- executor.Wait() 26 | }() 27 | 28 | select { 29 | case err := <-errCh: 30 | if err == nil { 31 | t.Error("Expected error, got nil") 32 | } 33 | case <-time.After(10 * time.Second): 34 | t.Error("Timed out waiting for executor to finish: deadlock") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /internal/schema/schema.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "bytes" 5 | "github.com/BurntSushi/toml" 6 | "os" 7 | ) 8 | 9 | const SchemaVersion = 3 10 | 11 | type Package struct { 12 | GoPackagePath string `toml:"-"` 13 | Version string `toml:"version"` 14 | Hash string `toml:"hash"` 15 | ReplacedPath string `toml:"replaced,omitempty"` 16 | } 17 | 18 | type Output struct { 19 | SchemaVersion int `toml:"schema"` 20 | Mod map[string]*Package `toml:"mod"` 21 | 22 | // Packages with passed import paths trigger `go install` based on this list 23 | SubPackages []string `toml:"subPackages,omitempty"` 24 | 25 | // Packages with passed import paths has a "default package" which pname & version is inherit from 26 | GoPackagePath string `toml:"goPackagePath,omitempty"` 27 | } 28 | 29 | func Marshal(pkgs []*Package, goPackagePath string, subPackages []string) ([]byte, error) { 30 | out := &Output{ 31 | SchemaVersion: SchemaVersion, 32 | Mod: make(map[string]*Package), 33 | SubPackages: subPackages, 34 | GoPackagePath: goPackagePath, 35 | } 36 | 37 | for _, pkg := range pkgs { 38 | out.Mod[pkg.GoPackagePath] = pkg 39 | } 40 | 41 | var buf bytes.Buffer 42 | e := toml.NewEncoder(&buf) 43 | err := e.Encode(out) 44 | if err != nil { 45 | return nil, err 46 | } 47 | 48 | return buf.Bytes(), nil 49 | } 50 | 51 | func ReadCache(filePath string) map[string]*Package { 52 | ret := make(map[string]*Package) 53 | 54 | if filePath == "" { 55 | return ret 56 | } 57 | 58 | b, err := os.ReadFile(filePath) 59 | if err != nil { 60 | return ret 61 | } 62 | 63 | var output Output 64 | _, err = toml.Decode(string(b), &output) 65 | if err != nil { 66 | return ret 67 | } 68 | 69 | if output.SchemaVersion != SchemaVersion { 70 | return ret 71 | } 72 | 73 | for k, v := range output.Mod { 74 | v.GoPackagePath = k 75 | ret[k] = v 76 | } 77 | 78 | return ret 79 | } 80 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/nix-community/gomod2nix/internal/cmd" 4 | 5 | func main() { 6 | cmd.Execute() 7 | } 8 | -------------------------------------------------------------------------------- /overlay.nix: -------------------------------------------------------------------------------- 1 | final: prev: 2 | let 3 | # The current default sdk for macOS fails to compile go projects, so we use a newer one for now. 4 | # This has no effect on other platforms. 5 | callPackage = final.darwin.apple_sdk_11_0.callPackage or final.callPackage; 6 | in 7 | { 8 | inherit (callPackage ./builder { }) buildGoApplication mkGoEnv mkVendorEnv; 9 | gomod2nix = callPackage ./default.nix { }; 10 | } 11 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? ( 2 | let 3 | inherit (builtins) fetchTree fromJSON readFile; 4 | in 5 | import (fetchTree (fromJSON (readFile ./flake.lock)).nodes.nixpkgs.locked) { 6 | overlays = [ 7 | (import ./overlay.nix) 8 | ]; 9 | } 10 | ) 11 | , gomod2nix ? pkgs.gomod2nix 12 | , mkGoEnv ? pkgs.mkGoEnv 13 | }: 14 | 15 | pkgs.mkShell { 16 | NIX_PATH = "nixpkgs=${builtins.toString pkgs.path}"; 17 | nativeBuildInputs = [ 18 | pkgs.nixpkgs-fmt 19 | pkgs.golangci-lint 20 | gomod2nix 21 | (mkGoEnv { pwd = ./.; }) 22 | ]; 23 | } 24 | -------------------------------------------------------------------------------- /templates/app/.gitignore: -------------------------------------------------------------------------------- 1 | /gomod2nix-template 2 | -------------------------------------------------------------------------------- /templates/app/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? ( 2 | let 3 | inherit (builtins) fetchTree fromJSON readFile; 4 | inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix; 5 | in 6 | import (fetchTree nixpkgs.locked) { 7 | overlays = [ 8 | (import "${fetchTree gomod2nix.locked}/overlay.nix") 9 | ]; 10 | } 11 | ) 12 | , buildGoApplication ? pkgs.buildGoApplication 13 | }: 14 | 15 | buildGoApplication { 16 | pname = "myapp"; 17 | version = "0.1"; 18 | pwd = ./.; 19 | src = ./.; 20 | modules = ./gomod2nix.toml; 21 | } 22 | -------------------------------------------------------------------------------- /templates/app/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "A basic gomod2nix flake"; 3 | 4 | inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; 5 | inputs.flake-utils.url = "github:numtide/flake-utils"; 6 | inputs.gomod2nix.url = "github:nix-community/gomod2nix"; 7 | inputs.gomod2nix.inputs.nixpkgs.follows = "nixpkgs"; 8 | inputs.gomod2nix.inputs.flake-utils.follows = "flake-utils"; 9 | 10 | outputs = { self, nixpkgs, flake-utils, gomod2nix }: 11 | (flake-utils.lib.eachDefaultSystem 12 | (system: 13 | let 14 | pkgs = nixpkgs.legacyPackages.${system}; 15 | 16 | # The current default sdk for macOS fails to compile go projects, so we use a newer one for now. 17 | # This has no effect on other platforms. 18 | callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage; 19 | in 20 | { 21 | packages.default = callPackage ./. { 22 | inherit (gomod2nix.legacyPackages.${system}) buildGoApplication; 23 | }; 24 | devShells.default = callPackage ./shell.nix { 25 | inherit (gomod2nix.legacyPackages.${system}) mkGoEnv gomod2nix; 26 | }; 27 | }) 28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /templates/app/go.mod: -------------------------------------------------------------------------------- 1 | module example.com/gomod2nix-template 2 | 3 | go 1.17 4 | -------------------------------------------------------------------------------- /templates/app/gomod2nix.toml: -------------------------------------------------------------------------------- 1 | schema = 1 2 | 3 | [mod] 4 | -------------------------------------------------------------------------------- /templates/app/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Hello flake") 9 | } 10 | -------------------------------------------------------------------------------- /templates/app/shell.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? ( 2 | let 3 | inherit (builtins) fetchTree fromJSON readFile; 4 | inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix; 5 | in 6 | import (fetchTree nixpkgs.locked) { 7 | overlays = [ 8 | (import "${fetchTree gomod2nix.locked}/overlay.nix") 9 | ]; 10 | } 11 | ) 12 | , mkGoEnv ? pkgs.mkGoEnv 13 | , gomod2nix ? pkgs.gomod2nix 14 | }: 15 | 16 | let 17 | goEnv = mkGoEnv { pwd = ./.; }; 18 | in 19 | pkgs.mkShell { 20 | packages = [ 21 | goEnv 22 | gomod2nix 23 | ]; 24 | } 25 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | go run ./run.go 3 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Tests for gomod2nix 2 | 3 | These expressions have been copied from nixpkgs and adapted 4 | -------------------------------------------------------------------------------- /tests/cli-args/default.nix: -------------------------------------------------------------------------------- 1 | { runCommand, buildGoApplication }: 2 | 3 | let 4 | drv = buildGoApplication { 5 | pname = "stringer"; 6 | pwd = ./.; 7 | }; 8 | in 9 | assert drv.version == "0.1.11"; 10 | runCommand "cli-args-stringer-assert" { } '' 11 | if ! test -f ${drv}/bin/stringer; then 12 | echo "stringer command not found in env!" 13 | exit 1 14 | fi 15 | 16 | ln -s ${drv} $out 17 | '' 18 | -------------------------------------------------------------------------------- /tests/cli-args/script: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | cd "${0%/*}" 4 | exec $GOMOD2NIX generate "golang.org/x/tools/cmd/stringer@v0.1.11" 5 | -------------------------------------------------------------------------------- /tests/cross/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs }: 2 | pkgs.pkgsCross.aarch64-multiplatform.callPackage ../../. { } 3 | -------------------------------------------------------------------------------- /tests/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs ? import { } }: 2 | 3 | { 4 | helm = pkgs.callPackage ./helm { }; 5 | linkerd = pkgs.callPackage ./linkerd { }; 6 | minikube = pkgs.callPackage ./minikube { }; 7 | } 8 | -------------------------------------------------------------------------------- /tests/ethermint/cmd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | martian "github.com/google/martian/v3" 7 | "github.com/tharsis/ethermint/crypto/hd" 8 | "google.golang.org/grpc" 9 | ) 10 | 11 | func main() { 12 | fmt.Println(hd.NewExtendedKey()) 13 | fmt.Println(grpc.Version) 14 | fmt.Println(martian.Noop("")) 15 | } 16 | -------------------------------------------------------------------------------- /tests/ethermint/crypto/hd/algorithm.go: -------------------------------------------------------------------------------- 1 | package hd 2 | 3 | import ( 4 | "github.com/btcsuite/btcd/chaincfg" 5 | "github.com/btcsuite/btcutil/hdkeychain" 6 | ) 7 | 8 | // NewExtendedKey 9 | func NewExtendedKey() (*hdkeychain.ExtendedKey, error) { 10 | return hdkeychain.NewMaster([]byte{}, &chaincfg.MainNetParams) 11 | } 12 | -------------------------------------------------------------------------------- /tests/ethermint/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, buildGoApplication }: 2 | 3 | buildGoApplication rec { 4 | pname = "ethermint"; 5 | version = "0.0.1"; 6 | src = ./.; 7 | modules = ./gomod2nix.toml; 8 | doCheck = false; 9 | subPackages = [ "./cmd/main.go" ]; 10 | } 11 | -------------------------------------------------------------------------------- /tests/ethermint/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tharsis/ethermint 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/btcsuite/btcd v0.22.1 7 | github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce 8 | github.com/google/martian/v3 v3.3.2 9 | google.golang.org/grpc v1.46.2 10 | ) 11 | 12 | require ( 13 | github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect 14 | github.com/golang/protobuf v1.5.2 // indirect 15 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect 16 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect 17 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect 18 | golang.org/x/text v0.3.3 // indirect 19 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect 20 | google.golang.org/protobuf v1.27.1 // indirect 21 | ) 22 | 23 | replace github.com/btcsuite/btcd/chaincfg/chainhash => github.com/yihuang/btcd/chaincfg/chainhash v1.0.2-0.20220517215929-cee92e09adcf 24 | -------------------------------------------------------------------------------- /tests/ethermint/go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 4 | github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= 5 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 6 | github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= 7 | github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= 8 | github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= 9 | github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= 10 | github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= 11 | github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= 12 | github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= 13 | github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= 14 | github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= 15 | github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= 16 | github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= 17 | github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= 18 | github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= 19 | github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= 20 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 21 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 22 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 23 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 24 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 25 | github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= 26 | github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 27 | github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 28 | github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 29 | github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 30 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 31 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 32 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 33 | github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= 34 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 35 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 36 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 37 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 38 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 39 | github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= 40 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 41 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 42 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 43 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 44 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 45 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 46 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 47 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 48 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 49 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 50 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 51 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 52 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 53 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 54 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 55 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 56 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 57 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 58 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 59 | github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= 60 | github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 61 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 62 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 63 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 64 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 65 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 66 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 67 | github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= 68 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 69 | github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= 70 | github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= 71 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 72 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 73 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 74 | github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 75 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 76 | github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= 77 | github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= 78 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 79 | github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 80 | github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 81 | github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 82 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 83 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 84 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= 85 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 86 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 87 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 88 | github.com/yihuang/btcd/chaincfg/chainhash v1.0.2-0.20220517215929-cee92e09adcf h1:YbZPcppZVkGHRcOzf1wap24ddyAMCZsot7f2O2qsY/c= 89 | github.com/yihuang/btcd/chaincfg/chainhash v1.0.2-0.20220517215929-cee92e09adcf/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= 90 | go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 91 | golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 92 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 93 | golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 94 | golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 95 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= 96 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 97 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 98 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 99 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 100 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 101 | golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 102 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 103 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 104 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 105 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 106 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 107 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 108 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 109 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 110 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 111 | golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= 112 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 113 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 114 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 115 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 116 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 117 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 118 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 119 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 120 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 121 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 122 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 123 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 124 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 125 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= 126 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 127 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 128 | golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= 129 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 130 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 131 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 132 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 133 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 134 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 135 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 136 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 137 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 138 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 139 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 140 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 141 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 142 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 143 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= 144 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 145 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 146 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 147 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 148 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 149 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= 150 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 151 | google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 152 | google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= 153 | google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= 154 | google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 155 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 156 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 157 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 158 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 159 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 160 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 161 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 162 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 163 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 164 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 165 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 166 | google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= 167 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 168 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 169 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 170 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 171 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 172 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 173 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 174 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 175 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 176 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 177 | -------------------------------------------------------------------------------- /tests/helm/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, buildGoApplication, fetchFromGitHub, installShellFiles }: 2 | 3 | buildGoApplication rec { 4 | pname = "helm"; 5 | version = "3.4.1"; 6 | 7 | src = fetchFromGitHub { 8 | owner = "helm"; 9 | repo = "helm"; 10 | rev = "v${version}"; 11 | sha256 = "13w0s11319qg9mmmxc24mlj0hrp0r529p3ny4gfzsl0vn3qzd6i2"; 12 | }; 13 | modules = ./gomod2nix.toml; 14 | 15 | doCheck = false; 16 | 17 | subPackages = [ "cmd/helm" ]; 18 | buildFlagsArray = [ "-ldflags=-w -s -X helm.sh/helm/v3/internal/version.version=v${version}" ]; 19 | 20 | nativeBuildInputs = [ installShellFiles ]; 21 | postInstall = '' 22 | $out/bin/helm completion bash > helm.bash 23 | $out/bin/helm completion zsh > helm.zsh 24 | installShellCompletion helm.{bash,zsh} 25 | ''; 26 | } 27 | -------------------------------------------------------------------------------- /tests/helm/go.mod: -------------------------------------------------------------------------------- 1 | module helm.sh/helm/v3 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/BurntSushi/toml v0.3.1 7 | github.com/DATA-DOG/go-sqlmock v1.5.0 8 | github.com/Masterminds/goutils v1.1.0 9 | github.com/Masterminds/semver/v3 v3.1.0 10 | github.com/Masterminds/sprig/v3 v3.1.0 11 | github.com/Masterminds/squirrel v1.4.0 12 | github.com/Masterminds/vcs v1.13.1 13 | github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 14 | github.com/containerd/containerd v1.3.4 15 | github.com/cyphar/filepath-securejoin v0.2.2 16 | github.com/deislabs/oras v0.8.1 17 | github.com/docker/distribution v2.7.1+incompatible 18 | github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce 19 | github.com/docker/go-units v0.4.0 20 | github.com/evanphx/json-patch v4.9.0+incompatible 21 | github.com/gobwas/glob v0.2.3 22 | github.com/gofrs/flock v0.8.0 23 | github.com/gosuri/uitable v0.0.4 24 | github.com/jessevdk/go-flags v1.4.0 // indirect 25 | github.com/jmoiron/sqlx v1.2.0 26 | github.com/lib/pq v1.8.0 27 | github.com/mattn/go-shellwords v1.0.10 28 | github.com/mitchellh/copystructure v1.0.0 29 | github.com/opencontainers/go-digest v1.0.0 30 | github.com/opencontainers/image-spec v1.0.1 31 | github.com/pkg/errors v0.9.1 32 | github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 33 | github.com/sirupsen/logrus v1.7.0 34 | github.com/spf13/cobra v1.0.0 35 | github.com/spf13/pflag v1.0.5 36 | github.com/stretchr/testify v1.6.1 37 | github.com/xeipuuv/gojsonschema v1.2.0 38 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 39 | k8s.io/api v0.19.3 40 | k8s.io/apiextensions-apiserver v0.19.3 41 | k8s.io/apimachinery v0.19.3 42 | k8s.io/cli-runtime v0.19.3 43 | k8s.io/client-go v0.19.3 44 | k8s.io/klog v1.0.0 45 | k8s.io/kubectl v0.19.3 46 | sigs.k8s.io/yaml v1.2.0 47 | ) 48 | 49 | replace ( 50 | github.com/Azure/go-autorest => github.com/Azure/go-autorest v13.3.2+incompatible 51 | github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d 52 | ) 53 | -------------------------------------------------------------------------------- /tests/minikube/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv 2 | , buildGoApplication 3 | , fetchFromGitHub 4 | , go-bindata 5 | , installShellFiles 6 | , pkg-config 7 | , which 8 | , libvirt 9 | , darwin 10 | }: 11 | 12 | buildGoApplication rec { 13 | pname = "minikube"; 14 | version = "1.15.0"; 15 | 16 | modules = ./gomod2nix.toml; 17 | 18 | doCheck = false; 19 | 20 | src = fetchFromGitHub { 21 | owner = "kubernetes"; 22 | repo = "minikube"; 23 | rev = "v${version}"; 24 | sha256 = "1n1jhsa0lrfpqvl7m5il37l3f22ffgg4zv8g42xq24cgna951a1z"; 25 | }; 26 | 27 | nativeBuildInputs = [ go-bindata installShellFiles pkg-config which ]; 28 | 29 | buildInputs = if stdenv.isDarwin then [ darwin.apple_sdk.frameworks.vmnet ] else if stdenv.isLinux then [ libvirt ] else null; 30 | 31 | buildPhase = '' 32 | make COMMIT=${src.rev} 33 | ''; 34 | 35 | installPhase = '' 36 | install out/minikube -Dt $out/bin 37 | 38 | export HOME=$PWD 39 | export MINIKUBE_WANTUPDATENOTIFICATION=false 40 | export MINIKUBE_WANTKUBECTLDOWNLOADMSG=false 41 | 42 | for shell in bash zsh fish; do 43 | $out/bin/minikube completion $shell > minikube.$shell 44 | installShellCompletion minikube.$shell 45 | done 46 | ''; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /tests/minikube/go.mod: -------------------------------------------------------------------------------- 1 | module k8s.io/minikube 2 | 3 | go 1.15 4 | 5 | require ( 6 | cloud.google.com/go/storage v1.8.0 7 | github.com/Azure/azure-sdk-for-go v42.3.0+incompatible 8 | github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 // indirect 9 | github.com/Parallels/docker-machine-parallels/v2 v2.0.1 10 | github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect 11 | github.com/VividCortex/godaemon v0.0.0-20201030160542-15e3f4925a21 12 | github.com/blang/semver v3.5.0+incompatible 13 | github.com/c4milo/gotoolkit v0.0.0-20170318115440-bcc06269efa9 // indirect 14 | github.com/cenkalti/backoff v2.2.1+incompatible 15 | github.com/cenkalti/backoff/v4 v4.1.0 16 | github.com/cheggaaa/pb/v3 v3.0.1 17 | github.com/cloudevents/sdk-go/v2 v2.1.0 18 | github.com/cloudfoundry-attic/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 19 | github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 // indirect 20 | github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57 // indirect 21 | github.com/docker/cli v0.0.0-20200303162255-7d407207c304 // indirect 22 | github.com/docker/docker v17.12.0-ce-rc1.0.20181225093023-5ddb1d410a8b+incompatible 23 | github.com/docker/go-units v0.4.0 24 | github.com/docker/machine v0.16.2 // v0.16.2^ 25 | github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f 26 | github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect 27 | github.com/evanphx/json-patch v4.5.0+incompatible // indirect 28 | github.com/go-logr/logr v0.3.0 // indirect 29 | github.com/go-ole/go-ole v1.2.4 // indirect 30 | github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 31 | github.com/google/go-cmp v0.5.2 32 | github.com/google/go-containerregistry v0.0.0-20200601195303-96cf69f03a3c 33 | github.com/google/go-github v17.0.0+incompatible 34 | github.com/google/go-github/v32 v32.1.0 35 | github.com/google/slowjam v0.0.0-20200530021616-df27e642fe7b 36 | github.com/google/uuid v1.1.1 37 | github.com/googleapis/gnostic v0.3.0 // indirect 38 | github.com/hashicorp/go-getter v1.4.2 39 | github.com/hashicorp/go-retryablehttp v0.6.6 40 | github.com/hooklift/assert v0.0.0-20170704181755-9d1defd6d214 // indirect 41 | github.com/hooklift/iso9660 v0.0.0-20170318115843-1cf07e5970d8 42 | github.com/intel-go/cpuid v0.0.0-20181003105527-1a4a6f06a1c6 // indirect 43 | github.com/johanneswuerbach/nfsexports v0.0.0-20200318065542-c48c3734757f 44 | github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c 45 | github.com/juju/errors v0.0.0-20190806202954-0232dcc7464d // indirect 46 | github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect 47 | github.com/juju/mutex v0.0.0-20180619145857-d21b13acf4bf 48 | github.com/juju/retry v0.0.0-20180821225755-9058e192b216 // indirect 49 | github.com/juju/testing v0.0.0-20190723135506-ce30eb24acd2 // indirect 50 | github.com/juju/utils v0.0.0-20180820210520-bf9cc5bdd62d // indirect 51 | github.com/juju/version v0.0.0-20180108022336-b64dbd566305 // indirect 52 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 53 | github.com/libvirt/libvirt-go v3.4.0+incompatible 54 | github.com/machine-drivers/docker-machine-driver-vmware v0.1.1 55 | github.com/mattn/go-isatty v0.0.12 56 | github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b 57 | github.com/moby/hyperkit v0.0.0-20171020124204-a12cd7250bcd 58 | github.com/olekukonko/tablewriter v0.0.4 59 | github.com/opencontainers/go-digest v1.0.0-rc1 60 | github.com/otiai10/copy v1.0.2 61 | github.com/pborman/uuid v1.2.0 62 | github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 63 | github.com/pkg/browser v0.0.0-20160118053552-9302be274faa 64 | github.com/pkg/errors v0.9.1 65 | github.com/pkg/profile v0.0.0-20161223203901-3a8809bd8a80 66 | github.com/pmezard/go-difflib v1.0.0 67 | github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6 // indirect 68 | github.com/samalba/dockerclient v0.0.0-20160414174713-91d7393ff859 // indirect 69 | github.com/shirou/gopsutil v2.18.12+incompatible 70 | github.com/spf13/cobra v1.0.0 71 | github.com/spf13/pflag v1.0.5 72 | github.com/spf13/viper v1.7.0 73 | github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect 74 | github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect 75 | github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f 76 | github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097 77 | golang.org/x/build v0.0.0-20190927031335-2835ba2e683f 78 | golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a 79 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 80 | golang.org/x/mod v0.3.0 81 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d 82 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a 83 | golang.org/x/sys v0.0.0-20200523222454-059865788121 84 | golang.org/x/text v0.3.2 85 | google.golang.org/api v0.25.0 86 | gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect 87 | gopkg.in/yaml.v2 v2.3.0 88 | gotest.tools/v3 v3.0.2 // indirect 89 | k8s.io/api v0.17.4 90 | k8s.io/apimachinery v0.17.4 91 | k8s.io/client-go v0.17.4 92 | k8s.io/klog/v2 v2.4.0 93 | k8s.io/kubectl v0.0.0 94 | k8s.io/kubernetes v1.18.5 95 | sigs.k8s.io/sig-storage-lib-external-provisioner v4.0.0+incompatible // indirect 96 | sigs.k8s.io/sig-storage-lib-external-provisioner/v5 v5.0.0 97 | ) 98 | 99 | replace ( 100 | git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20180902110319-2566ecd5d999 101 | github.com/docker/docker => github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7 102 | github.com/docker/machine => github.com/machine-drivers/machine v0.7.1-0.20200810185219-7d42fed1b770 103 | github.com/google/go-containerregistry => github.com/afbjorklund/go-containerregistry v0.0.0-20200902152226-fbad78ec2813 104 | github.com/hashicorp/go-getter => github.com/afbjorklund/go-getter v1.4.1-0.20201020145846-c0da14b4bffe 105 | github.com/samalba/dockerclient => github.com/sayboras/dockerclient v1.0.0 106 | k8s.io/api => k8s.io/api v0.17.3 107 | k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.17.3 108 | k8s.io/apimachinery => k8s.io/apimachinery v0.17.3 109 | k8s.io/apiserver => k8s.io/apiserver v0.17.3 110 | k8s.io/cli-runtime => k8s.io/cli-runtime v0.17.3 111 | k8s.io/client-go => k8s.io/client-go v0.17.3 112 | k8s.io/cloud-provider => k8s.io/cloud-provider v0.17.3 113 | k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.17.3 114 | k8s.io/code-generator => k8s.io/code-generator v0.17.3 115 | k8s.io/component-base => k8s.io/component-base v0.17.3 116 | k8s.io/cri-api => k8s.io/cri-api v0.17.3 117 | k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.17.3 118 | k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.17.3 119 | k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.17.3 120 | k8s.io/kube-proxy => k8s.io/kube-proxy v0.17.3 121 | k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.17.3 122 | k8s.io/kubectl => k8s.io/kubectl v0.17.3 123 | k8s.io/kubelet => k8s.io/kubelet v0.17.3 124 | k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.17.3 125 | k8s.io/metrics => k8s.io/metrics v0.17.3 126 | k8s.io/node-api => k8s.io/node-api v0.17.3 127 | k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.17.3 128 | k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.17.3 129 | k8s.io/sample-controller => k8s.io/sample-controller v0.17.3 130 | ) 131 | -------------------------------------------------------------------------------- /tests/mkgoenv/default.nix: -------------------------------------------------------------------------------- 1 | { runCommand, mkGoEnv, which }: 2 | 3 | let 4 | env = mkGoEnv { 5 | pwd = ./.; 6 | }; 7 | in 8 | runCommand "mkgoenv-assert" 9 | { 10 | nativeBuildInputs = [ which ]; 11 | buildInputs = [ env ]; # Trigger propagation 12 | } '' 13 | if ! test -f ${env}/bin/stringer; then 14 | echo "stringer command not found in env!" 15 | exit 1 16 | fi 17 | 18 | which go > /dev/null || echo "Go compiler not found in env!" 19 | 20 | ln -s ${env} $out 21 | '' 22 | -------------------------------------------------------------------------------- /tests/mkgoenv/go.mod: -------------------------------------------------------------------------------- 1 | module example.com/mkgoenv 2 | 3 | go 1.17 4 | 5 | require golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a 6 | 7 | require ( 8 | golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect 9 | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect 10 | golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /tests/mkgoenv/go.sum: -------------------------------------------------------------------------------- 1 | github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 2 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 3 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 4 | golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= 5 | golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= 6 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 7 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 8 | golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 9 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 10 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 11 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 12 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 13 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 14 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 15 | golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 16 | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= 17 | golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 18 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 19 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 20 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 21 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 22 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 23 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 24 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 25 | golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a h1:ofrrl6c6NG5/IOSx/R1cyiQxxjqlur0h/TvbUhkH0II= 26 | golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= 27 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 28 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 29 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 30 | golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= 31 | golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 32 | -------------------------------------------------------------------------------- /tests/mkgoenv/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | 3 | package main 4 | 5 | import ( 6 | _ "golang.org/x/tools/cmd/stringer" 7 | ) 8 | -------------------------------------------------------------------------------- /tests/run.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | "os/exec" 10 | "path" 11 | "path/filepath" 12 | "runtime" 13 | "sync" 14 | ) 15 | 16 | func runProcess(prefix string, env []string, command string, args ...string) error { 17 | fmt.Printf("%s: Executing %s %s\n", prefix, command, args) 18 | 19 | cmd := exec.Command(command, args...) 20 | 21 | if env != nil { 22 | cmd.Env = env 23 | } 24 | 25 | stdoutReader, err := cmd.StdoutPipe() 26 | if err != nil { 27 | return err 28 | } 29 | 30 | stderrReader, err := cmd.StderrPipe() 31 | if err != nil { 32 | return err 33 | } 34 | 35 | done := make(chan struct{}) 36 | 37 | go func() { 38 | reader := io.MultiReader(stdoutReader, stderrReader) 39 | scanner := bufio.NewScanner(reader) 40 | for scanner.Scan() { 41 | line := scanner.Bytes() 42 | fmt.Printf("%s: %s\n", prefix, line) 43 | } 44 | done <- struct{}{} 45 | }() 46 | 47 | err = cmd.Start() 48 | if err != nil { 49 | return err 50 | } 51 | 52 | <-done 53 | 54 | return cmd.Wait() 55 | } 56 | 57 | func contains(haystack []string, needle string) bool { 58 | for _, s := range haystack { 59 | if s == needle { 60 | return true 61 | } 62 | } 63 | return false 64 | } 65 | 66 | func runTest(rootDir string, testDir string) error { 67 | prefix := testDir 68 | testDir = filepath.Join(rootDir, testDir) 69 | cmdPath := filepath.Join(rootDir, "..", "gomod2nix") 70 | 71 | if _, err := os.Stat(filepath.Join(testDir, "script")); err == nil { 72 | env := append(os.Environ(), "GOMOD2NIX="+cmdPath) 73 | err := runProcess(prefix, env, filepath.Join(testDir, "script")) 74 | if err != nil { 75 | return err 76 | } 77 | 78 | } else { 79 | if _, err := os.Stat(filepath.Join(testDir, "go.mod")); err == nil { 80 | err := runProcess(prefix, nil, cmdPath, "--dir", testDir, "--outdir", testDir) 81 | if err != nil { 82 | return err 83 | } 84 | } 85 | } 86 | 87 | buildExpr := fmt.Sprintf("with (import { overlays = [ (import %s/../overlay.nix) ]; }); callPackage %s {}", rootDir, testDir) 88 | err := runProcess(prefix, nil, "nix-build", "--no-out-link", "--expr", buildExpr) 89 | if err != nil { 90 | return err 91 | } 92 | 93 | return nil 94 | } 95 | 96 | func getTestDirs(rootDir string) ([]string, error) { 97 | // Takes too long for Github Actions 98 | var blacklist []string 99 | if os.Getenv("GITHUB_ACTIONS") == "true" { 100 | blacklist = []string{ 101 | "helm", 102 | "minikube", 103 | "cross", 104 | } 105 | } 106 | 107 | files, err := os.ReadDir(rootDir) 108 | if err != nil { 109 | return nil, err 110 | } 111 | 112 | testDirs := []string{} 113 | for _, f := range files { 114 | if f.IsDir() && !contains(blacklist, f.Name()) { 115 | testDirs = append(testDirs, f.Name()) 116 | } 117 | } 118 | 119 | return testDirs, nil 120 | } 121 | 122 | func runTests(rootDir string, testDirs []string) error { 123 | var wg sync.WaitGroup 124 | cmdErrChan := make(chan error) 125 | for _, testDir := range testDirs { 126 | testDir := testDir 127 | fmt.Printf("Running test for: '%s'\n", testDir) 128 | wg.Add(1) 129 | go func() { 130 | defer wg.Done() 131 | err := runTest(rootDir, testDir) 132 | if err != nil { 133 | cmdErrChan <- fmt.Errorf("Test for '%s' failed: %w", testDir, err) 134 | } 135 | }() 136 | } 137 | 138 | go func() { 139 | wg.Wait() 140 | close(cmdErrChan) 141 | }() 142 | 143 | for cmdErr := range cmdErrChan { 144 | return cmdErr 145 | } 146 | 147 | return nil 148 | } 149 | 150 | func main() { 151 | 152 | var rootDir string 153 | { 154 | _, file, _, ok := runtime.Caller(0) 155 | if !ok { 156 | panic("Couldn't get test directory") 157 | } 158 | rootDir = path.Dir(file) 159 | } 160 | 161 | flag.Parse() 162 | 163 | nArgs := flag.NArg() 164 | 165 | action := "run" 166 | if nArgs >= 1 { 167 | action = flag.Arg(0) 168 | } 169 | 170 | switch action { 171 | case "list": 172 | testDirs, err := getTestDirs(rootDir) 173 | if err != nil { 174 | panic(err) 175 | } 176 | 177 | for _, testDir := range testDirs { 178 | fmt.Println(testDir) 179 | } 180 | 181 | return 182 | 183 | case "run": 184 | var testDirs []string 185 | var err error 186 | if nArgs > 1 { 187 | args := flag.Args() 188 | testDirs = args[1:nArgs] 189 | } else { 190 | testDirs, err = getTestDirs(rootDir) 191 | if err != nil { 192 | panic(err) 193 | } 194 | } 195 | 196 | err = runTests(rootDir, testDirs) 197 | if err != nil { 198 | panic(err) 199 | } 200 | 201 | return 202 | 203 | default: 204 | panic(fmt.Errorf("Unhandled action: %s", flag.Arg(0))) 205 | } 206 | 207 | } 208 | -------------------------------------------------------------------------------- /tests/vendored-modules/default.nix: -------------------------------------------------------------------------------- 1 | { runCommand, buildGoApplication, fetchFromGitHub }: 2 | 3 | let 4 | version = "0.23.1"; 5 | 6 | in 7 | buildGoApplication { 8 | pname = "dstask"; 9 | inherit version; 10 | 11 | src = fetchFromGitHub { 12 | owner = "naggie"; 13 | repo = "dstask"; 14 | rev = "v${version}"; 15 | sha256 = "0rfz8jim0xqcwdb5n28942v9r3hbvhjrwdgzvbwc9f9psqg2s8d2"; 16 | }; 17 | 18 | modules = null; 19 | 20 | ldflags = [ 21 | "-w" 22 | "-s" 23 | "-X github.com/naggie/dstask.VERSION=${version}" 24 | "-X github.com/naggie/dstask.GIT_COMMIT=v${version}" 25 | ]; 26 | 27 | subPackages = [ "cmd/dstask.go" ]; 28 | } 29 | -------------------------------------------------------------------------------- /tests/vendored-modules/script: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # No-op 3 | --------------------------------------------------------------------------------