diff --git a/cmd_fetch.go b/cmd_fetch.go new file mode 100644 index 0000000000000000000000000000000000000000..b61b12ec168602eb50bb27a55cd40e15cd1d4aa1 --- /dev/null +++ b/cmd_fetch.go @@ -0,0 +1,90 @@ +package main + +import ( + "fmt" + "io" + "log" + "os" + "strings" + + "github.com/mitchellh/go-homedir" + "github.com/nektro/go-util/util" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(&cobra.Command{ + Use: "fetch", + Short: "Read the current zig.mod and generate a zig.mod.zig that can be imported in build.zig.", + Long: `zigmod fetch`, + Run: func(cmd *cobra.Command, args []string) { + hd, err := homedir.Dir() + util.DieOnError(err) + dir := hd + "/.cache/zigmod/deps" + fetchDeps(dir, "./zig.mod") + + out, err := os.Create("./deps.zig") + fmt.Fprintln(out, `const std = @import("std");`) + fmt.Fprintln(out, `const Pkg = std.build.Pkg;`) + fmt.Fprintln(out, ``) + fmt.Fprintln(out, `const home = "`+hd+`";`) + fmt.Fprintln(out, `const cache = home ++ "/.cache/zigmod/deps";`) + fmt.Fprintln(out, ``) + fmt.Fprint(out, `pub const packages = `) + printDeps(out, dir, readModFile("./zig.mod"), 0) + fmt.Fprintln(out, `;`) + }, + }) +} + +func fetchDeps(dpath, fpath string) { + m := readModFile(fpath) + for _, item := range m.Deps { + switch item.Type { + case DepTypeGit: + log.Println("fetch:", m.Name+":", item.Type+":", item.Path) + p := dpath + "/" + item.cleanPath() + if !util.DoesDirectoryExist(p) { + runCmd("", "git", "clone", item.Path, p) + } else { + runCmd(p, "git", "fetch") + runCmd(p, "git", "pull") + } + default: + assert(false, join("invalid dependency type detected:", item.Type, "in package:", m.Name)) + } + // + switch item.Type { + case DepTypeGit: + p := dpath + "/" + item.cleanPath() + "/zig.mod" + fetchDeps(dpath, p) + } + } +} + +func printDeps(w io.Writer, dir string, m *ModFile, tabs int) { + if len(m.Deps) == 0 { + fmt.Fprint(w, `null`) + return + } + fmt.Fprintln(w, `&[_]Pkg{`) + t := " " + r := strings.Repeat(t, tabs) + for _, item := range m.Deps { + switch item.Type { + default: + continue + case DepTypeGit: + p := dir + "/" + item.cleanPath() + n := readModFile(p + "/zig.mod") + fmt.Fprintln(w, r+t+`Pkg{`) + fmt.Fprintln(w, r+t+t+`.name = "`+n.Name+`",`) + fmt.Fprintln(w, r+t+t+`.path = cache ++ "/`+item.cleanPath()+`/`+n.Main+`",`) + fmt.Fprint(w, r+t+t+`.dependencies = `) + printDeps(w, dir, n, tabs+2) + fmt.Fprintln(w, ",") + fmt.Fprintln(w, r+t+`},`) + } + } + fmt.Fprint(w, r+`}`) +} diff --git a/main.go b/main.go index b456edde6c97d11c779e2e8a57d47e2b3ea9179f..a6be9176bbafe91cada3edbca1de03678de965cc 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,9 @@ package main import ( + "os/exec" + "strings" + "github.com/nektro/go-util/util" "github.com/spf13/cobra" ) @@ -25,3 +28,15 @@ var rootCmd = &cobra.Command{ func assert(x bool, msg string) { util.DieOnError(util.Assert(x, msg)) } + +func runCmd(dir, cm string, args ...string) { + c := exec.Command(cm, args...) + if len(dir) > 0 { + c.Dir = dir + } + util.DieOnError(c.Run()) +} + +func join(a ...string) string { + return strings.Join(a, " ") +}