| ... | ... | @@ -0,0 +1,90 @@ |
| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | 	"fmt" |
| 5 | 	"io" |
| 6 | 	"log" |
| 7 | 	"os" |
| 8 | 	"strings" |
| 9 | |
| 10 | 	"github.com/mitchellh/go-homedir" |
| 11 | 	"github.com/nektro/go-util/util" |
| 12 | 	"github.com/spf13/cobra" |
| 13 | ) |
| 14 | |
| 15 | func init() { |
| 16 | 	rootCmd.AddCommand(&cobra.Command{ |
| 17 | 		Use: "fetch", |
| 18 | 		Short: "Read the current zig.mod and generate a zig.mod.zig that can be imported in build.zig.", |
| 19 | 		Long: `zigmod fetch`, |
| 20 | 		Run: func(cmd *cobra.Command, args []string) { |
| 21 | 			hd, err := homedir.Dir() |
| 22 | 			util.DieOnError(err) |
| 23 | 			dir := hd + "/.cache/zigmod/deps" |
| 24 | 			fetchDeps(dir, "./zig.mod") |
| 25 | |
| 26 | 			out, err := os.Create("./deps.zig") |
| 27 | 			fmt.Fprintln(out, `const std = @import("std");`) |
| 28 | 			fmt.Fprintln(out, `const Pkg = std.build.Pkg;`) |
| 29 | 			fmt.Fprintln(out, ``) |
| 30 | 			fmt.Fprintln(out, `const home = "`+hd+`";`) |
| 31 | 			fmt.Fprintln(out, `const cache = home ++ "/.cache/zigmod/deps";`) |
| 32 | 			fmt.Fprintln(out, ``) |
| 33 | 			fmt.Fprint(out, `pub const packages = `) |
| 34 | 			printDeps(out, dir, readModFile("./zig.mod"), 0) |
| 35 | 			fmt.Fprintln(out, `;`) |
| 36 | 		}, |
| 37 | 	}) |
| 38 | } |
| 39 | |
| 40 | func fetchDeps(dpath, fpath string) { |
| 41 | 	m := readModFile(fpath) |
| 42 | 	for _, item := range m.Deps { |
| 43 | 		switch item.Type { |
| 44 | 		case DepTypeGit: |
| 45 | 			log.Println("fetch:", m.Name+":", item.Type+":", item.Path) |
| 46 | 			p := dpath + "/" + item.cleanPath() |
| 47 | 			if !util.DoesDirectoryExist(p) { |
| 48 | 				runCmd("", "git", "clone", item.Path, p) |
| 49 | 			} else { |
| 50 | 				runCmd(p, "git", "fetch") |
| 51 | 				runCmd(p, "git", "pull") |
| 52 | 			} |
| 53 | 		default: |
| 54 | 			assert(false, join("invalid dependency type detected:", item.Type, "in package:", m.Name)) |
| 55 | 		} |
| 56 | 		// |
| 57 | 		switch item.Type { |
| 58 | 		case DepTypeGit: |
| 59 | 			p := dpath + "/" + item.cleanPath() + "/zig.mod" |
| 60 | 			fetchDeps(dpath, p) |
| 61 | 		} |
| 62 | 	} |
| 63 | } |
| 64 | |
| 65 | func printDeps(w io.Writer, dir string, m *ModFile, tabs int) { |
| 66 | 	if len(m.Deps) == 0 { |
| 67 | 		fmt.Fprint(w, `null`) |
| 68 | 		return |
| 69 | 	} |
| 70 | 	fmt.Fprintln(w, `&[_]Pkg{`) |
| 71 | 	t := " " |
| 72 | 	r := strings.Repeat(t, tabs) |
| 73 | 	for _, item := range m.Deps { |
| 74 | 		switch item.Type { |
| 75 | 		default: |
| 76 | 			continue |
| 77 | 		case DepTypeGit: |
| 78 | 			p := dir + "/" + item.cleanPath() |
| 79 | 			n := readModFile(p + "/zig.mod") |
| 80 | 			fmt.Fprintln(w, r+t+`Pkg{`) |
| 81 | 			fmt.Fprintln(w, r+t+t+`.name = "`+n.Name+`",`) |
| 82 | 			fmt.Fprintln(w, r+t+t+`.path = cache ++ "/`+item.cleanPath()+`/`+n.Main+`",`) |
| 83 | 			fmt.Fprint(w, r+t+t+`.dependencies = `) |
| 84 | 			printDeps(w, dir, n, tabs+2) |
| 85 | 			fmt.Fprintln(w, ",") |
| 86 | 			fmt.Fprintln(w, r+t+`},`) |
| 87 | 		} |
| 88 | 	} |
| 89 | 	fmt.Fprint(w, r+`}`) |
| 90 | } |