package main import ( "errors" "fmt" "os" "path/filepath" "strconv" "strings" "go.wit.com/lib/config" "go.wit.com/lib/protobuf/zoopb" "go.wit.com/log" ) func moveOutOfIncoming(fullname string, repopath string) error { _, filename := filepath.Split(fullname) parts := strings.Split(filename, "_") if len(parts) != 3 { // todo: add more filename checking here (check for ".deb") return errors.New(log.Sprintf("bad filenae %s", filename)) } packageName := parts[0] letteredDir := log.Sprintf("%1.1s", filename) newfilename := filepath.Join(repopath, letteredDir, packageName, filename) destDir := filepath.Dir(newfilename) if err := os.MkdirAll(destDir, 0755); err != nil { s := log.Sprintf("Failed to create destination directory(%s) err(%v)", destDir, err) return errors.New(s) } develfilename := filepath.Join("pool/devel", letteredDir, packageName, filename) if IsDevelFilename(fullname) { log.Info("GOING TO MOVE TO DEVEL", develfilename) destDir = filepath.Dir(develfilename) if err := os.MkdirAll(destDir, 0755); err != nil { s := log.Sprintf("Failed to create destination directory(%s) err(%v)", destDir, err) return errors.New(s) } data, _ := os.ReadFile(fullname) os.WriteFile(develfilename, data, 0644) } else { log.Info("NOT GOING TO MOVE TO DEVEL", develfilename) } // log.Printf("%s move incoming oldname %s newname: %s\n", packageName, fullname, newfilename) if config.Exists(newfilename) { log.Info("DEBIAN POLICY: YOU CAN NEVER REBUILD THE SAME FILE. APT WILL NOT REINSTALL IT. AUTO REMOVE: ", fullname) return os.Remove(fullname) } // file can be moved os.Rename(fullname, newfilename) log.Printf("%s moved incoming oldname %s newname: %s\n", packageName, fullname, newfilename) return nil } // newver(0.25.101-1+b10) // a == 0 // b == 25 // c == 101 // pnum == 1 // bnum == 10 type vers struct { a int // major b int c int pnum int bnum int } func tokenVersions(ver string) (*vers, error) { var err error tok := new(vers) parts := strings.Split(ver, "-") if len(parts) != 2 { return nil, errors.New(fmt.Sprintf("len != 2 %v", parts)) } abc := strings.Split(parts[0], ".") if len(abc) != 3 { return nil, errors.New(fmt.Sprintf("len != 3 parts(%v) abc(%v)", parts, abc)) } tok.a, err = strconv.Atoi(abc[0]) if err != nil { return nil, errors.Join(err, errors.New(fmt.Sprintf("parts(%v) abc(%v)", parts, abc))) } tok.b, err = strconv.Atoi(abc[1]) if err != nil { return nil, errors.Join(err, errors.New(fmt.Sprintf("parts(%v) abc(%v)", parts, abc))) } tok.c, err = strconv.Atoi(abc[2]) if err != nil { return nil, errors.Join(err, errors.New(fmt.Sprintf("parts(%v) abc(%v)", parts, abc))) } bb := strings.Split(parts[1], "+") if len(bb) != 2 { return nil, errors.Join(err, errors.New(fmt.Sprintf("parts(%v) abc(%v)", parts, abc))) } tok.pnum, err = strconv.Atoi(bb[0]) if err != nil { return nil, errors.Join(err, errors.New(fmt.Sprintf("parts(%v) abc(%v)", parts, abc))) } tok.bnum, err = strconv.Atoi(strings.TrimPrefix(bb[1], "b")) if err != nil { return nil, errors.Join(err, errors.New(fmt.Sprintf("parts(%v) abc(%v)", parts, abc))) } return tok, nil } // compares newver(0.25.101-1+b10) curver(0.25.101-5+b1) func compareVersions(newver string, curver string) (bool, error) { newtok, err1 := tokenVersions(newver) curtok, err2 := tokenVersions(curver) if (newtok == nil) || (curtok == nil) { s := log.Sprintf("token on the railroad failed (%v) to curver (%v) err(%v)(%v)", newtok, curtok, err1, err2) return false, errors.New(s) } // CHECK A if newtok.a > curtok.a { return true, nil } if curtok.a > newtok.a { return false, errors.New(log.Sprintf("A.x.x lower (%v) to curver (%v)", newver, curver)) } // CHECK B if newtok.b > curtok.b { return true, nil } if curtok.b > newtok.b { return false, errors.New(log.Sprintf("x.B.x lower (%v) to curver (%v)", newver, curver)) } // CHECK C if newtok.c > curtok.c { return true, nil } if curtok.c > newtok.c { return false, errors.New(log.Sprintf("x.x.C lower (%v) to curver (%v)", newver, curver)) } // CHECK PATCH # if newtok.pnum > curtok.pnum { return true, nil } if curtok.pnum > newtok.pnum { return false, errors.New(log.Sprintf("patch # lower (%v) to curver (%v)", newver, curver)) } // CHECK BUILD # if newtok.bnum > curtok.bnum { return true, nil } if curtok.bnum > newtok.bnum { return false, errors.New(log.Sprintf("build # lower (%v) to curver (%v)", newver, curver)) } // CHECK IS EQUAL if curtok.bnum == newtok.bnum { return false, errors.New(log.Sprintf("new is equal (%v) to curver (%v)", newver, curver)) } return false, errors.New(log.Sprintf("compare should not have gotten here (%v) to curver (%v)", newver, curver)) } func moveToBad(packageName string, fullname string, err error) string { _, filename := filepath.Split(fullname) baddir := filepath.Join(me.pb.BaseDir, "badincoming") os.MkdirAll(baddir, 0755) newbadname := filepath.Join(baddir, filename) os.Rename(fullname, newbadname) return newbadname } func tokenVersionByFilename(fullname string) *vers { _, filename := filepath.Split(fullname) parts := strings.Split(filename, "_") if len(parts) != 3 { // todo: add more filename checking here (check for ".deb") // return errors.New(log.Sprintf("bad filenae %s", filename)) return nil } version := parts[1] curtok, err := tokenVersions(version) if err != nil { return nil } return curtok } func IsDevelFilename(fullname string) bool { tok := tokenVersionByFilename(fullname) if tok == nil { return true } if tok.pnum != 0 { return true } if tok.bnum != 0 { return true } return false } // true if package is actually newer func checkAgainstNewest(fullname string, newest *zoopb.Packages) bool { _, filename := filepath.Split(fullname) parts := strings.Split(filename, "_") if len(parts) != 3 { // todo: add more filename checking here (check for ".deb") // return errors.New(log.Sprintf("bad filenae %s", filename)) return false } packageName := parts[0] version := parts[1] p := newest.FindByPackage(packageName) if p == nil { log.Info("NEW PACKAGE NAME", packageName, version, fullname) return false } _, filename = filepath.Split(p.Filename) parts = strings.Split(filename, "_") if len(parts) != 3 { // this should never happen return false } curversion := parts[1] if ok, err := compareVersions(version, curversion); ok { // log.Printf("IS NEW: %s err=(%v)\n", packageName, err) return true } else { // log.Printf("IS BAD: %s err=(%v)\n", packageName, err) badname := moveToBad(packageName, fullname, err) log.Printf("IS BAD: %s err=(%v) %s\n", packageName, err, badname) } return false } func doIncoming(pb *zoopb.Packages) (string, error) { if err := os.Chdir(me.pb.BaseDir); err != nil { return "no dir " + me.pb.BaseDir, err } newest := doGetNewest("amd64") globPattern := "/home/mirrors/wit/incoming/*.deb" files, err := filepath.Glob(globPattern) if err != nil { return "glob error", err } for _, filename := range files { if checkAgainstNewest(filename, newest) { moveOutOfIncoming(filename, "pool/main") } } globPattern = "/home/mirrors/wit/incoming-devel/*.deb" files, err = filepath.Glob(globPattern) if err != nil { return "glob error", err } for _, filename := range files { if checkAgainstNewest(filename, newest) { moveOutOfIncoming(filename, "pool/main") } } s := log.Sprintf("scanned (%d) in incoming", len(files)) return s, err }