gomod2nix/fetch/fetch.go

135 lines
2.5 KiB
Go
Raw Normal View History

2020-07-20 11:38:32 +00:00
package fetch
2020-07-20 10:52:58 +00:00
import (
"bytes"
2020-07-20 10:52:58 +00:00
"encoding/json"
"fmt"
"io"
2020-07-20 11:29:04 +00:00
"io/ioutil"
2020-07-20 10:52:58 +00:00
"os/exec"
"path"
"strings"
log "github.com/sirupsen/logrus"
"github.com/tweag/gomod2nix/types"
"golang.org/x/mod/modfile"
2020-07-20 10:52:58 +00:00
)
2020-07-20 11:38:32 +00:00
type packageJob struct {
importPath string
goPackagePath string
sumVersion string
2020-07-20 10:52:58 +00:00
}
2020-07-20 11:38:32 +00:00
type packageResult struct {
pkg *types.Package
err error
}
type goModDownload struct {
Path string
Version string
Info string
GoMod string
Zip string
Dir string
Sum string
GoModSum string
2020-07-20 11:38:32 +00:00
}
func FetchPackages(goModPath string, goSumPath string, goMod2NixPath string, numWorkers int, keepGoing bool) ([]*types.Package, error) {
2020-07-20 10:52:58 +00:00
2020-07-21 09:42:32 +00:00
log.WithFields(log.Fields{
"modPath": goModPath,
}).Info("Parsing go.mod")
2020-07-20 11:29:04 +00:00
// Read go.mod
data, err := ioutil.ReadFile(goModPath)
if err != nil {
return nil, err
}
// Parse go.mod
mod, err := modfile.Parse(goModPath, data, nil)
if err != nil {
return nil, err
}
// Map repos -> replacement repo
replace := make(map[string]string)
for _, repl := range mod.Replace {
replace[repl.New.Path] = repl.Old.Path
2020-07-20 11:29:04 +00:00
}
var modDownloads []*goModDownload
{
log.WithFields(log.Fields{
"sumPath": goSumPath,
}).Info("Downloading dependencies")
stdout, err := exec.Command(
"go", "mod", "download", "--json",
).Output()
if err != nil {
return nil, err
2020-07-20 11:29:04 +00:00
}
dec := json.NewDecoder(bytes.NewReader(stdout))
for {
var dl *goModDownload
err := dec.Decode(&dl)
if err == io.EOF {
break
2020-07-20 11:29:04 +00:00
}
modDownloads = append(modDownloads, dl)
2020-07-20 11:29:04 +00:00
}
log.WithFields(log.Fields{
"sumPath": goSumPath,
}).Info("Done downloading dependencies")
}
packages := []*types.Package{}
for _, dl := range modDownloads {
goPackagePath, hasReplace := replace[dl.Path]
if !hasReplace {
goPackagePath = dl.Path
}
var storePath string
{
stdout, err := exec.Command(
"nix", "eval", "--impure", "--expr",
fmt.Sprintf("builtins.path { name = \"%s_%s\"; path = \"%s\"; }", path.Base(goPackagePath), dl.Version, dl.Dir),
).Output()
if err != nil {
return nil, err
}
storePath = string(stdout)[1 : len(stdout)-2]
}
2020-07-21 09:42:32 +00:00
stdout, err := exec.Command(
"nix-store", "--query", "--hash", storePath,
).Output()
if err != nil {
return nil, err
}
hash := strings.TrimSpace(string(stdout))
pkg := &types.Package{
GoPackagePath: goPackagePath,
Version: dl.Version,
Hash: hash,
}
if hasReplace {
pkg.ReplacedPath = dl.Path
2020-07-22 11:57:13 +00:00
}
packages = append(packages, pkg)
}
return packages, nil
2020-07-20 10:52:58 +00:00
}