package manifest import ( "fmt" "mccl/pkg/retriever" "mccl/pkg/util" "os" "path" "runtime" "strings" ) type Library struct { Downloads struct { Artifact util.File `json:"artifact"` Classifiers map[string]util.File `json:"classifiers"` } `json:"downloads"` Name string `json:"name"` Url string `json:"url"` Rules []Rule `json:"rules"` } func (l *Library) Path() string { if l.Downloads.Artifact.Path != "" { return l.Downloads.Artifact.Path } return l.pathFromName() } func (l *Library) ToFile() []util.File { var f []util.File if l.Downloads.Artifact.Url != "" { f = append(f, l.Downloads.Artifact) } else if l.Url != "" { lf := util.File{ Id: l.Name, Url: path.Join(l.Url, l.pathFromName()), Size: -1, Path: l.pathFromName(), } f = append(f, lf) } if natives := l.Natives(); natives != nil { f = append(f, *natives) } return f } func (l *Library) pathFromName() string { parts := strings.Split(l.Name, ":") parts = append(strings.Split(parts[0], "."), parts[1:]...) pth := path.Join(parts...) jarName := strings.Join([]string{parts[len(parts)-2], parts[len(parts)-1]}, "-") + ".jar" return path.Join(pth, jarName) } func RetrieveLibrary(item retriever.Retrievable, destDir string) (int, error) { l := item.(util.File) p := path.Join(destDir, l.Path) if s, err := os.Stat(p); err == nil && s.Size() == l.Size { return int(l.Size), nil } data, err := item.Retrieve() if err != nil { return 0, err } if err := os.MkdirAll(path.Dir(p), 0777); err != nil { return 0, err } tf, err := os.Create(p) if err != nil { return 0, err } defer tf.Close() written, err := tf.Write(data) if err != nil { return 0, err } else if written != len(data) { return 0, fmt.Errorf("written bytes length mismatch. %d != %d", written, len(data)) } return written, nil } func (l *Library) CheckRules() bool { if strings.Contains(l.Name, "natives") { nat := strings.SplitAfter(l.Name, ":")[3] nats := strings.Split(nat, "-") archR := Rule{Action: ActionAllow} if len(nats) == 3 { archR.Os.Arch = nats[2] l.Rules = append(l.Rules, archR) } } for _, r := range l.Rules { if ok, _ := r.Check(); !ok { return false } } return true } func (l *Library) Natives() *util.File { if !l.CheckRules() { return nil } var nativeOs string switch v := runtime.GOOS; v { case "windows": fallthrough case "linux": nativeOs = "natives-" + v case "darwin": nativeOs = "natives-macos" } if len(l.Downloads.Classifiers) > 0 { if v, ok := l.Downloads.Classifiers[nativeOs]; ok { return &v } } return nil }