aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2022-07-24 10:07:41 +0200
committerQuentin Dufour <quentin@deuxfleurs.fr>2022-07-24 10:08:21 +0200
commit11574aeb19cd971b20d37353111c4f37ffdfb7f5 (patch)
tree5d9939a08ec11986eff360f41684ec53a35ac7e0
parentba8042a21a8552f132cac6d0a45cf8e08d885f08 (diff)
downloadguichet-nix.tar.gz
guichet-nix.zip
Remove vendoring of gomod2nixnix
-rw-r--r--default.nix8
-rw-r--r--nix/builder/default.nix387
-rw-r--r--nix/builder/fetch.sh13
-rw-r--r--nix/builder/install/install.go57
-rw-r--r--nix/builder/parser.nix141
-rw-r--r--nix/builder/symlink/symlink.go110
6 files changed, 7 insertions, 709 deletions
diff --git a/default.nix b/default.nix
index 3cafd8c..cf40d93 100644
--- a/default.nix
+++ b/default.nix
@@ -4,10 +4,16 @@ let
url = "https://github.com/NixOS/nixpkgs/archive/d2db10786f27619d5519b12b03fb10dc8ca95e59.tar.gz";
sha256 = "0s9gigs3ylnq5b94rfcmxvrmmr3kzhs497gksajf638d5bv7zcl5";
};
+ gomod2nix = fetchGit {
+ url = "https://github.com/tweag/gomod2nix.git";
+ ref = "master";
+ rev = "40d32f82fc60d66402eb0972e6e368aeab3faf58";
+ };
+
pkgs = import pkgsSrc {
overlays = [
(self: super: {
- gomod = super.callPackage ./nix/builder { };
+ gomod = super.callPackage "${gomod2nix}/builder/" { };
})
];
};
diff --git a/nix/builder/default.nix b/nix/builder/default.nix
deleted file mode 100644
index 8b8ae19..0000000
--- a/nix/builder/default.nix
+++ /dev/null
@@ -1,387 +0,0 @@
-{ stdenv
-, stdenvNoCC
-, runCommand
-, buildEnv
-, lib
-, fetchgit
-, removeReferencesTo
-, jq
-, cacert
-, pkgs
-, pkgsBuildBuild
-}:
-let
-
- inherit (builtins) substring toJSON hasAttr trace split readFile elemAt;
- inherit (lib)
- concatStringsSep replaceStrings removePrefix optionalString pathExists
- optional concatMapStrings fetchers filterAttrs mapAttrs mapAttrsToList
- warnIf optionalAttrs platforms
- ;
-
- parseGoMod = import ./parser.nix;
-
- removeExpr = refs: ''remove-references-to ${concatMapStrings (ref: " -t ${ref}") refs}'';
-
- # Internal only build-time attributes
- internal =
- let
- mkInternalPkg = name: src: pkgsBuildBuild.runCommand "gomod2nix-${name}"
- {
- inherit (pkgsBuildBuild.go) GOOS GOARCH;
- nativeBuildInputs = [ pkgsBuildBuild.go ];
- } ''
- export HOME=$(mktemp -d)
- cp ${src} src.go
- go build -o $out src.go
- '';
- in
- {
-
- # Create a symlink tree of vendored sources
- symlink = mkInternalPkg "symlink" ./symlink/symlink.go;
-
- # Install development dependencies from tools.go
- install = mkInternalPkg "symlink" ./install/install.go;
-
- };
-
- fetchGoModule =
- { hash
- , goPackagePath
- , version
- , go ? pkgs.go
- }:
- stdenvNoCC.mkDerivation {
- name = "${baseNameOf goPackagePath}_${version}";
- builder = ./fetch.sh;
- inherit goPackagePath version;
- nativeBuildInputs = [ go jq ];
- outputHashMode = "recursive";
- outputHashAlgo = null;
- outputHash = hash;
- SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt";
- impureEnvVars = fetchers.proxyImpureEnvVars ++ [ "GOPROXY" ];
- };
-
- mkVendorEnv =
- { go
- , modulesStruct
- , localReplaceCommands ? [ ]
- , defaultPackage ? ""
- , goMod
- , pwd
- }:
- let
- localReplaceCommands =
- let
- localReplaceAttrs = filterAttrs (n: v: hasAttr "path" v) goMod.replace;
- commands = (
- mapAttrsToList
- (name: value: (
- ''
- mkdir -p $(dirname vendor/${name})
- ln -s ${pwd + "/${value.path}"} vendor/${name}
- ''
- ))
- localReplaceAttrs);
- in
- if goMod != null then commands else [ ];
-
- sources = mapAttrs
- (goPackagePath: meta: fetchGoModule {
- goPackagePath = meta.replaced or goPackagePath;
- inherit (meta) version hash;
- inherit go;
- })
- modulesStruct.mod;
- in
- runCommand "vendor-env"
- {
- nativeBuildInputs = [ go ];
- json = toJSON (filterAttrs (n: _: n != defaultPackage) modulesStruct.mod);
-
- sources = toJSON (filterAttrs (n: _: n != defaultPackage) sources);
-
- passthru = {
- inherit sources;
- };
-
- passAsFile = [ "json" "sources" ];
- }
- (
- ''
- mkdir vendor
-
- export GOCACHE=$TMPDIR/go-cache
- export GOPATH="$TMPDIR/go"
-
- ${internal.symlink}
- ${concatStringsSep "\n" localReplaceCommands}
-
- mv vendor $out
- ''
- );
-
- # Select Go attribute based on version specified in go.mod
- selectGo = attrs: goMod: attrs.go or (if goMod == null then pkgs.go else
- (
- let
- goVersion = goMod.go;
- goAttr = "go_" + (replaceStrings [ "." ] [ "_" ] goVersion);
- in
- (
- if hasAttr goAttr pkgs then pkgs.${goAttr}
- else trace "go.mod specified Go version ${goVersion} but doesn't exist. Falling back to ${pkgs.go.version}." pkgs.go
- )
- ));
-
- # Strip the rubbish that Go adds to versions, and fall back to a version based on the date if it's a placeholder value
- stripVersion = version:
- let
- parts = elemAt (split "(\\+|-)" (removePrefix "v" version));
- v = parts 0;
- d = parts 2;
- in
- if v != "0.0.0" then v else "unstable-" + (concatStringsSep "-" [
- (substring 0 4 d)
- (substring 4 2 d)
- (substring 6 2 d)
- ]);
-
- mkGoEnv =
- { pwd
- }@attrs:
- let
- goMod = parseGoMod (readFile "${toString pwd}/go.mod");
- modulesStruct = fromTOML (readFile "${toString pwd}/gomod2nix.toml");
-
- go = selectGo attrs goMod;
-
- vendorEnv = mkVendorEnv {
- inherit go modulesStruct pwd goMod;
- };
-
- in
- stdenv.mkDerivation (removeAttrs attrs [ "pwd" ] // {
- name = "${baseNameOf goMod.module}-env";
-
- dontUnpack = true;
- dontConfigure = true;
- dontInstall = true;
-
- propagatedNativeBuildInputs = [ go ];
-
- GO_NO_VENDOR_CHECKS = "1";
-
- GO111MODULE = "on";
- GOFLAGS = "-mod=vendor";
-
- preferLocalBuild = true;
-
- buildPhase = ''
- mkdir $out
-
- export GOCACHE=$TMPDIR/go-cache
- export GOPATH="$out"
- export GOSUMDB=off
- export GOPROXY=off
-
- '' + optionalString (pathExists (pwd + "/tools.go")) ''
- mkdir source
- cp ${pwd + "/go.mod"} source/go.mod
- cp ${pwd + "/go.sum"} source/go.sum
- cp ${pwd + "/tools.go"} source/tools.go
- cd source
- ln -s ${vendorEnv} vendor
-
- ${internal.install}
- '';
- });
-
- buildGoApplication =
- { modules ? pwd + "/gomod2nix.toml"
- , src ? pwd
- , pwd ? null
- , nativeBuildInputs ? [ ]
- , allowGoReference ? false
- , meta ? { }
- , passthru ? { }
- , tags ? [ ]
-
- # needed for buildFlags{,Array} warning
- , buildFlags ? ""
- , buildFlagsArray ? ""
-
- , ...
- }@attrs:
- let
- modulesStruct = fromTOML (readFile modules);
-
- goModPath = "${toString pwd}/go.mod";
-
- goMod =
- if pwd != null && pathExists goModPath
- then parseGoMod (readFile goModPath)
- else null;
-
- go = selectGo attrs goMod;
-
- removeReferences = [ ] ++ optional (!allowGoReference) go;
-
- defaultPackage = modulesStruct.goPackagePath or "";
-
- vendorEnv = mkVendorEnv {
- inherit go modulesStruct defaultPackage goMod pwd;
- };
-
- in
- warnIf (buildFlags != "" || buildFlagsArray != "")
- "Use the `ldflags` and/or `tags` attributes instead of `buildFlags`/`buildFlagsArray`"
- stdenv.mkDerivation
- (optionalAttrs (defaultPackage != "")
- {
- pname = attrs.pname or baseNameOf defaultPackage;
- version = stripVersion (modulesStruct.mod.${defaultPackage}).version;
- src = vendorEnv.passthru.sources.${defaultPackage};
- } // optionalAttrs (hasAttr "subPackages" modulesStruct) {
- subPackages = modulesStruct.subPackages;
- } // attrs // {
- nativeBuildInputs = [ removeReferencesTo go ] ++ nativeBuildInputs;
-
- inherit (go) GOOS GOARCH;
-
- GO_NO_VENDOR_CHECKS = "1";
-
- GO111MODULE = "on";
- GOFLAGS = "-mod=vendor";
-
- configurePhase = attrs.configurePhase or ''
- runHook preConfigure
-
- export GOCACHE=$TMPDIR/go-cache
- export GOPATH="$TMPDIR/go"
- export GOSUMDB=off
- export GOPROXY=off
- cd "$modRoot"
- if [ -n "${vendorEnv}" ]; then
- rm -rf vendor
- ln -s ${vendorEnv} vendor
- fi
-
- runHook postConfigure
- '';
-
- buildPhase = attrs.buildPhase or ''
- runHook preBuild
-
- exclude='\(/_\|examples\|Godeps\|testdata'
- if [[ -n "$excludedPackages" ]]; then
- IFS=' ' read -r -a excludedArr <<<$excludedPackages
- printf -v excludedAlternates '%s\\|' "''${excludedArr[@]}"
- excludedAlternates=''${excludedAlternates%\\|} # drop final \| added by printf
- exclude+='\|'"$excludedAlternates"
- fi
- exclude+='\)'
-
- buildGoDir() {
- local d; local cmd;
- cmd="$1"
- d="$2"
- . $TMPDIR/buildFlagsArray
- local OUT
- if ! OUT="$(go $cmd $buildFlags "''${buildFlagsArray[@]}" ''${tags:+-tags=${concatStringsSep "," tags}} ''${ldflags:+-ldflags="$ldflags"} -v -p $NIX_BUILD_CORES $d 2>&1)"; then
- if echo "$OUT" | grep -qE 'imports .*?: no Go files in'; then
- echo "$OUT" >&2
- return 1
- fi
- if ! echo "$OUT" | grep -qE '(no( buildable| non-test)?|build constraints exclude all) Go (source )?files'; then
- echo "$OUT" >&2
- return 1
- fi
- fi
- if [ -n "$OUT" ]; then
- echo "$OUT" >&2
- fi
- return 0
- }
-
- getGoDirs() {
- local type;
- type="$1"
- if [ -n "$subPackages" ]; then
- echo "$subPackages" | sed "s,\(^\| \),\1./,g"
- else
- find . -type f -name \*$type.go -exec dirname {} \; | grep -v "/vendor/" | sort --unique | grep -v "$exclude"
- fi
- }
-
- if (( "''${NIX_DEBUG:-0}" >= 1 )); then
- buildFlagsArray+=(-x)
- fi
-
- if [ ''${#buildFlagsArray[@]} -ne 0 ]; then
- declare -p buildFlagsArray > $TMPDIR/buildFlagsArray
- else
- touch $TMPDIR/buildFlagsArray
- fi
- if [ -z "$enableParallelBuilding" ]; then
- export NIX_BUILD_CORES=1
- fi
- for pkg in $(getGoDirs ""); do
- echo "Building subPackage $pkg"
- buildGoDir install "$pkg"
- done
- '' + optionalString (stdenv.hostPlatform != stdenv.buildPlatform) ''
- # normalize cross-compiled builds w.r.t. native builds
- (
- dir=$GOPATH/bin/${go.GOOS}_${go.GOARCH}
- if [[ -n "$(shopt -s nullglob; echo $dir/*)" ]]; then
- mv $dir/* $dir/..
- fi
- if [[ -d $dir ]]; then
- rmdir $dir
- fi
- )
- '' + ''
- runHook postBuild
- '';
-
- doCheck = attrs.doCheck or true;
- checkPhase = attrs.checkPhase or ''
- runHook preCheck
-
- for pkg in $(getGoDirs test); do
- buildGoDir test $checkFlags "$pkg"
- done
-
- runHook postCheck
- '';
-
- installPhase = attrs.installPhase or ''
- runHook preInstall
-
- mkdir -p $out
- dir="$GOPATH/bin"
- [ -e "$dir" ] && cp -r $dir $out
-
- runHook postInstall
- '';
-
- preFixup = (attrs.preFixup or "") + ''
- find $out/{bin,libexec,lib} -type f 2>/dev/null | xargs -r ${removeExpr removeReferences} || true
- '';
-
- strictDeps = true;
-
- disallowedReferences = optional (!allowGoReference) go;
-
- passthru = { inherit go vendorEnv; } // passthru;
-
- meta = { platforms = go.meta.platforms or platforms.all; } // meta;
- });
-
-in
-{
- inherit buildGoApplication mkGoEnv;
-}
diff --git a/nix/builder/fetch.sh b/nix/builder/fetch.sh
deleted file mode 100644
index 8c6bdb3..0000000
--- a/nix/builder/fetch.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-source $stdenv/setup
-
-export HOME=$(mktemp -d)
-
-# Call once first outside of subshell for better error reporting
-go mod download "$goPackagePath@$version"
-
-dir=$(go mod download --json "$goPackagePath@$version" | jq -r .Dir)
-
-chmod -R +w $dir
-find $dir -iname ".ds_store" | xargs -r rm -rf
-
-cp -r $dir $out
diff --git a/nix/builder/install/install.go b/nix/builder/install/install.go
deleted file mode 100644
index 4f770b0..0000000
--- a/nix/builder/install/install.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package main
-
-import (
- "fmt"
- "go/parser"
- "go/token"
- "io"
- "os"
- "os/exec"
- "strconv"
-)
-
-const filename = "tools.go"
-
-func main() {
- fset := token.NewFileSet()
-
- var src []byte
- {
- f, err := os.Open(filename)
- if err != nil {
- panic(err)
- }
-
- src, err = io.ReadAll(f)
- if err != nil {
- panic(err)
- }
- }
-
- f, err := parser.ParseFile(fset, filename, src, parser.ImportsOnly)
- if err != nil {
- fmt.Println(err)
- return
- }
-
- for _, s := range f.Imports {
- path, err := strconv.Unquote(s.Path.Value)
- if err != nil {
- panic(err)
- }
-
- cmd := exec.Command("go", "install", path)
-
- fmt.Printf("Executing '%s'\n", cmd)
-
- err = cmd.Start()
- if err != nil {
- panic(err)
- }
-
- err = cmd.Wait()
- if err != nil {
- panic(err)
- }
- }
-}
diff --git a/nix/builder/parser.nix b/nix/builder/parser.nix
deleted file mode 100644
index eb6f75e..0000000
--- a/nix/builder/parser.nix
+++ /dev/null
@@ -1,141 +0,0 @@
-# Parse go.mod in Nix
-# Returns a Nix structure with the contents of the go.mod passed in
-# in normalised form.
-
-let
- inherit (builtins) elemAt mapAttrs split foldl' match filter typeOf hasAttr length;
-
- # Strip lines with comments & other junk
- stripStr = s: elemAt (split "^ *" (elemAt (split " *$" s) 0)) 2;
- stripLines = initialLines: foldl' (acc: f: f acc) initialLines [
- # Strip comments
- (lines: map
- (l: stripStr (elemAt (splitString "//" l) 0))
- lines)
-
- # Strip leading tabs characters
- (lines: map (l: elemAt (match "(\t)?(.*)" l) 1) lines)
-
- # Filter empty lines
- (filter (l: l != ""))
- ];
-
- # Parse lines into a structure
- parseLines = lines: (foldl'
- (acc: l:
- let
- m = match "([^ )]*) *(.*)" l;
- directive = elemAt m 0;
- rest = elemAt m 1;
-
- # Maintain parser state (inside parens or not)
- inDirective =
- if rest == "(" then directive
- else if rest == ")" then null
- else acc.inDirective
- ;
-
- in
- {
- data = (acc.data // (
- if directive == "" && rest == ")" then { }
- else if inDirective != null && rest == "(" && ! hasAttr inDirective acc.data then {
- ${inDirective} = { };
- }
- else if rest == "(" || rest == ")" then { }
- else if inDirective != null then {
- ${inDirective} = acc.data.${inDirective} // { ${directive} = rest; };
- } else if directive == "replace" then
- (
- let
- segments = split " => " rest;
- getSegment = elemAt segments;
- in
- assert length segments == 3; {
- replace = acc.data.replace // {
- ${getSegment 0} = "=> ${getSegment 2}";
- };
- }
- )
- else {
- ${directive} = rest;
- }
- )
- );
- inherit inDirective;
- })
- {
- inDirective = null;
- data = {
- require = { };
- replace = { };
- exclude = { };
- };
- }
- lines
- ).data;
-
- normaliseDirectives = data: (
- let
- normaliseString = s:
- let
- m = builtins.match "([^ ]+) (.+)" s;
- in
- {
- ${elemAt m 0} = elemAt m 1;
- };
- require = data.require or { };
- replace = data.replace or { };
- exclude = data.exclude or { };
- in
- data // {
- require =
- if typeOf require == "string" then normaliseString require
- else require;
- replace =
- if typeOf replace == "string" then normaliseString replace
- else replace;
- }
- );
-
- parseVersion = ver:
- let
- m = elemAt (match "([^-]+)-?([^-]*)-?([^-]*)" ver);
- v = elemAt (match "([^+]+)\\+?(.*)" (m 0));
- in
- {
- version = v 0;
- versionSuffix = v 1;
- date = m 1;
- rev = m 2;
- };
-
- parseReplace = data: (
- data // {
- replace =
- mapAttrs
- (_: v:
- let
- m = match "=> ([^ ]+) (.+)" v;
- m2 = match "=> (.*+)" v;
- in
- if m != null then {
- goPackagePath = elemAt m 0;
- version = elemAt m 1;
- } else {
- path = elemAt m2 0;
- })
- data.replace;
- }
- );
-
- splitString = sep: s: filter (t: t != [ ]) (split sep s);
-
-in
-contents:
-foldl' (acc: f: f acc) (splitString "\n" contents) [
- stripLines
- parseLines
- normaliseDirectives
- parseReplace
-]
diff --git a/nix/builder/symlink/symlink.go b/nix/builder/symlink/symlink.go
deleted file mode 100644
index 3dbb383..0000000
--- a/nix/builder/symlink/symlink.go
+++ /dev/null
@@ -1,110 +0,0 @@
-package main
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "sort"
-)
-
-type Package struct {
- GoPackagePath string `json:"-"`
- Version string `json:"version"`
- Hash string `json:"hash"`
- ReplacedPath string `json:"replaced,omitempty"`
-}
-
-// type Output struct {
-// SchemaVersion int `json:"schema"`
-// Mod map[string]*Package `json:"mod"`
-// }
-
-func main() {
-
- // var output Output
- sources := make(map[string]string)
- pkgs := make(map[string]*Package)
-
- {
- b, err := ioutil.ReadFile(os.Getenv("sourcesPath"))
- if err != nil {
- panic(err)
- }
-
- err = json.Unmarshal(b, &sources)
- if err != nil {
- panic(err)
- }
- }
-
- {
- b, err := ioutil.ReadFile(os.Getenv("jsonPath"))
- if err != nil {
- panic(err)
- }
-
- err = json.Unmarshal(b, &pkgs)
- if err != nil {
- panic(err)
- }
- }
-
- keys := make([]string, 0, len(pkgs))
- for key := range pkgs {
- keys = append(keys, key)
- }
- sort.Strings(keys)
-
- // Iterate, in reverse order
- for i := len(keys) - 1; i >= 0; i-- {
- key := keys[i]
- src := sources[key]
-
- paths := []string{key}
-
- for _, path := range paths {
-
- vendorDir := filepath.Join("vendor", filepath.Dir(path))
- if err := os.MkdirAll(vendorDir, 0755); err != nil {
- panic(err)
- }
-
- if _, err := os.Stat(filepath.Join("vendor", path)); err == nil {
- files, err := ioutil.ReadDir(src)
- if err != nil {
- panic(err)
- }
-
- for _, f := range files {
- innerSrc := filepath.Join(src, f.Name())
- dst := filepath.Join("vendor", path, f.Name())
- if err := os.Symlink(innerSrc, dst); err != nil {
- // assume it's an existing directory, try to link the directory content instead.
- // TODO should we do this recursively
- files, err := ioutil.ReadDir(innerSrc)
- if err != nil {
- panic(err)
- }
- for _, f := range files {
- if err := os.Symlink(filepath.Join(innerSrc, f.Name()), filepath.Join(dst, f.Name())); err != nil {
- fmt.Println("ignore symlink error", filepath.Join(innerSrc, f.Name()), filepath.Join(dst, f.Name()))
- }
- }
- }
- }
-
- continue
- }
-
- // If the file doesn't already exist, just create a simple symlink
- err := os.Symlink(src, filepath.Join("vendor", path))
- if err != nil {
- panic(err)
- }
-
- }
- }
-
-}