mccl/internal/manifest/library.go

137 lines
2.7 KiB
Go
Raw Permalink Normal View History

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
}