Add an import subcommand

That imports sources from the local Go sources into the Nix store.
This commit is contained in:
adisbladis 2022-06-13 23:14:13 +08:00
parent 2792ae6af4
commit ab0d607923
2 changed files with 91 additions and 12 deletions

View file

@ -20,18 +20,33 @@ var (
var rootCmd = &cobra.Command{
Use: "gomod2nix",
Short: "Convert applications using Go modules -> Nix",
RunE: func(cmd *cobra.Command, args []string) error {
return generateInternal(flagDirectory, flagOutDir, flagMaxJobs)
Run: func(cmd *cobra.Command, args []string) {
err := generateInternal(flagDirectory, flagOutDir, flagMaxJobs)
if err != nil {
panic(err)
}
},
}
var generateCmd = &cobra.Command{
Use: "generate",
Short: "Run gomod2nix.toml generator",
RunE: func(cmd *cobra.Command, args []string) error {
Run: func(cmd *cobra.Command, args []string) {
err := generateInternal(flagDirectory, flagOutDir, flagMaxJobs)
if err != nil {
panic(err)
}
},
}
return generateInternal(flagDirectory, flagOutDir, flagMaxJobs)
var importCmd = &cobra.Command{
Use: "import",
Short: "Import Go sources into the Nix store",
Run: func(cmd *cobra.Command, args []string) {
err := generate.ImportPkgs(flagDirectory, flagMaxJobs)
if err != nil {
panic(err)
}
},
}
@ -41,6 +56,7 @@ func init() {
rootCmd.PersistentFlags().IntVar(&flagMaxJobs, "jobs", 10, "Max number of concurrent jobs")
rootCmd.AddCommand(generateCmd)
rootCmd.AddCommand(importCmd)
}
func Execute() {

View file

@ -5,8 +5,10 @@ import (
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"sort"
@ -31,7 +33,11 @@ type goModDownload struct {
GoModSum string
}
func GeneratePkgs(directory string, goMod2NixPath string, numWorkers int) ([]*schema.Package, error) {
func sourceFilter(name string, nodeType nar.NodeType) bool {
return strings.ToLower(filepath.Base(name)) != ".ds_store"
}
func common(directory string) ([]*goModDownload, map[string]string, error) {
goModPath := filepath.Join(directory, "go.mod")
log.WithFields(log.Fields{
@ -41,13 +47,13 @@ func GeneratePkgs(directory string, goMod2NixPath string, numWorkers int) ([]*sc
// Read go.mod
data, err := ioutil.ReadFile(goModPath)
if err != nil {
return nil, err
return nil, nil, err
}
// Parse go.mod
mod, err := modfile.Parse(goModPath, data, nil)
if err != nil {
return nil, err
return nil, nil, err
}
// Map repos -> replacement repo
@ -66,7 +72,7 @@ func GeneratePkgs(directory string, goMod2NixPath string, numWorkers int) ([]*sc
cmd.Dir = directory
stdout, err := cmd.Output()
if err != nil {
return nil, err
return nil, nil, err
}
dec := json.NewDecoder(bytes.NewReader(stdout))
@ -82,6 +88,65 @@ func GeneratePkgs(directory string, goMod2NixPath string, numWorkers int) ([]*sc
log.Info("Done downloading dependencies")
}
return modDownloads, replace, nil
}
func ImportPkgs(directory string, numWorkers int) error {
modDownloads, _, err := common(directory)
if err != nil {
return err
}
executor := lib.NewParallellExecutor(numWorkers)
for _, dl := range modDownloads {
dl := dl
executor.Add(func() error {
log.WithFields(log.Fields{
"goPackagePath": dl.Path,
}).Info("Importing sources")
pathName := filepath.Base(dl.Path) + "_" + dl.Version
cmd := exec.Command(
"nix-instantiate",
"--eval",
"--expr",
fmt.Sprintf(`
builtins.filterSource (name: type: baseNameOf name != ".DS_Store") (
builtins.path {
path = "%s";
name = "%s";
}
)
`, dl.Dir, pathName),
)
cmd.Stderr = os.Stderr
err = cmd.Start()
if err != nil {
fmt.Println(cmd)
return err
}
err = cmd.Wait()
if err != nil {
fmt.Println(cmd)
return err
}
return nil
})
}
return executor.Wait()
}
func GeneratePkgs(directory string, goMod2NixPath string, numWorkers int) ([]*schema.Package, error) {
modDownloads, replace, err := common(directory)
if err != nil {
return nil, err
}
executor := lib.NewParallellExecutor(numWorkers)
var mux sync.Mutex
@ -114,9 +179,7 @@ func GeneratePkgs(directory string, goMod2NixPath string, numWorkers int) ([]*sc
}).Info("Calculating NAR hash")
h := sha256.New()
err := nar.DumpPathFilter(h, dl.Dir, func(name string, nodeType nar.NodeType) bool {
return strings.ToLower(filepath.Base(name)) != ".ds_store"
})
err := nar.DumpPathFilter(h, dl.Dir, sourceFilter)
if err != nil {
return err
}