2020-07-20 11:38:32 +00:00
|
|
|
package fetch
|
2020-07-20 10:52:58 +00:00
|
|
|
|
|
|
|
import (
|
2022-05-27 15:55:43 +00:00
|
|
|
"bytes"
|
2020-07-20 10:52:58 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2022-05-27 15:55:43 +00:00
|
|
|
"io"
|
2020-07-20 11:29:04 +00:00
|
|
|
"io/ioutil"
|
2020-07-20 10:52:58 +00:00
|
|
|
"os/exec"
|
2022-05-27 15:55:43 +00:00
|
|
|
"path"
|
2020-07-20 13:42:52 +00:00
|
|
|
"strings"
|
2022-02-15 10:10:22 +00:00
|
|
|
|
|
|
|
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
|
2020-07-22 09:24:36 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2022-05-26 11:06:01 +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 {
|
2020-07-22 10:09:08 +00:00
|
|
|
replace[repl.New.Path] = repl.Old.Path
|
2020-07-20 11:29:04 +00:00
|
|
|
}
|
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
var modDownloads []*goModDownload
|
|
|
|
{
|
|
|
|
log.WithFields(log.Fields{
|
|
|
|
"sumPath": goSumPath,
|
|
|
|
}).Info("Downloading dependencies")
|
2020-07-22 09:24:36 +00:00
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
stdout, err := exec.Command(
|
|
|
|
"go", "mod", "download", "--json",
|
|
|
|
).Output()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2020-07-20 11:29:04 +00:00
|
|
|
}
|
|
|
|
|
2022-05-27 15:55:43 +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
|
|
|
}
|
2022-05-27 15:55:43 +00:00
|
|
|
modDownloads = append(modDownloads, dl)
|
2020-07-20 11:29:04 +00:00
|
|
|
}
|
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
log.WithFields(log.Fields{
|
|
|
|
"sumPath": goSumPath,
|
|
|
|
}).Info("Done downloading dependencies")
|
2020-07-22 09:24:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
packages := []*types.Package{}
|
|
|
|
for _, dl := range modDownloads {
|
2020-07-22 09:24:36 +00:00
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
goPackagePath, hasReplace := replace[dl.Path]
|
|
|
|
if !hasReplace {
|
|
|
|
goPackagePath = dl.Path
|
|
|
|
}
|
2020-07-22 09:24:36 +00:00
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
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
|
2020-07-20 15:46:51 +00:00
|
|
|
}
|
2022-05-27 15:55:43 +00:00
|
|
|
storePath = string(stdout)[1 : len(stdout)-2]
|
2020-07-20 15:46:51 +00:00
|
|
|
}
|
2020-07-21 09:42:32 +00:00
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
stdout, err := exec.Command(
|
|
|
|
"nix-store", "--query", "--hash", storePath,
|
|
|
|
).Output()
|
2020-07-20 13:42:52 +00:00
|
|
|
if err != nil {
|
2022-05-27 15:55:43 +00:00
|
|
|
return nil, err
|
2020-07-20 13:42:52 +00:00
|
|
|
}
|
2022-05-27 15:55:43 +00:00
|
|
|
hash := strings.TrimSpace(string(stdout))
|
2020-07-20 13:42:52 +00:00
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
pkg := &types.Package{
|
|
|
|
GoPackagePath: goPackagePath,
|
|
|
|
Version: dl.Version,
|
|
|
|
Hash: hash,
|
|
|
|
}
|
|
|
|
if hasReplace {
|
|
|
|
pkg.ReplacedPath = dl.Path
|
2020-07-22 11:57:13 +00:00
|
|
|
}
|
2022-05-27 15:55:43 +00:00
|
|
|
|
|
|
|
packages = append(packages, pkg)
|
2020-07-22 10:09:08 +00:00
|
|
|
}
|
|
|
|
|
2022-05-27 15:55:43 +00:00
|
|
|
return packages, nil
|
2020-07-20 10:52:58 +00:00
|
|
|
|
|
|
|
}
|