package forgepb import ( "fmt" "os" "path/filepath" "regexp" "strings" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/log" ) func (f *Forge) NewGoRepo(gopath string, url string) (*gitpb.Repo, error) { fullpath := filepath.Join(f.GetGoSrc(), gopath) test := f.Repos.FindByFullPath(fullpath) if test != nil { return test, nil } repo, err := f.Repos.NewGoRepo(fullpath, gopath) if err != nil { log.Info("WARNING. NEW FAILED", fullpath) return nil, err } // slices.Reverse(f.Repos.Repos) repo.URL = url f.VerifyBranchNames(repo) if f.Config.IsReadOnly(repo.GetGoPath()) { repo.ReadOnly = true } repo.Reload() return repo, nil } func isValidSemVer(version string) bool { // Regular expression for semantic versioning regex := `^v(\d+)\.(\d+)\.(\d+)$` matched, _ := regexp.MatchString(regex, version) return matched } // golang versions MUST be vX.X.X // it can not be vX.X and it also can not be v0.0.0 // verifies the version is format v3.2.1 // this is retardedly wrong. it needs to be done right func (f *Forge) ValidGoVersion(ver string) (bool, error) { return ValidGoVersion(ver) } func ValidGoVersion(ver string) (bool, error) { if ver == "v0.0.0" { return false, fmt.Errorf("golang does not allow version v0.0.0") } if !strings.HasPrefix(ver, "v") { return false, fmt.Errorf("(%s) invalid. golang versions must start with a 'v'", ver) } xver := ver[1:] parts := strings.Split(xver, ".") if len(parts) != 3 { return false, fmt.Errorf("(%s) invalid. golang versions must have exactly 3 numbers (v1.2.3)", ver) } if isValidSemVer(ver) { return true, nil } return false, nil } // figure out what the name of the git master branch is // also check the forge config func (f *Forge) findMasterBranch(repo *gitpb.Repo) { // check the forge config first if bname := f.Config.FindMasterBranch(repo.GetGoPath()); bname != "" { log.Info("Using master branch name from forge config:", bname) repo.SetMasterBranchName(bname) return } // todo: fix this after .git parsing is better or libgit2 is being used headfile := filepath.Join(repo.GetFullPath(), ".git/refs/remotes/origin/HEAD") if data, err := os.ReadFile(headfile); err == nil { s := string(data) if strings.HasPrefix(s, "ref: ") { fields := strings.Fields(s) _, bname := filepath.Split(fields[1]) // log.Info("Using master branch name from .git/ HEAD:", bname) repo.SetMasterBranchName(bname) return } } // try to guess what the 'master' branch is if repo.IsBranch("master") { repo.SetMasterBranchName("master") return } if repo.IsBranch("main") { repo.SetMasterBranchName("main") return } // TODO: figure out the name from git repo.SetMasterBranchName("master") /* no longer checkout on Init() if repo.CheckoutMaster() { } else { cmd := []string{"git", "branch", "master"} repo.Run(cmd) } */ } // figure out what the name of the git devel branch is // also check the forge config func (f *Forge) findDevelBranch(repo *gitpb.Repo) { // check the forge config first if bname := f.Config.FindDevelBranch(repo.GetGoPath()); bname != "" { repo.SetDevelBranchName(bname) /* no longer checkout on Init() if repo.CheckoutDevel() { } else { cmd := []string{"git", "branch", bname} repo.Run(cmd) } */ return } if repo.IsBranch("devel") { repo.SetDevelBranchName("devel") return } repo.SetDevelBranchName("devel") /* no longer checkout on Init() if repo.CheckoutDevel() { } else { cmd := []string{"git", "branch", "devel"} repo.Run(cmd) } */ } // this is still in flux func (f *Forge) VerifyBranchNames(repo *gitpb.Repo) { // log.Info("init worked for", repo.GoPath) if repo.GetMasterBranchName() == "" { f.findMasterBranch(repo) } if repo.GetDevelBranchName() == "" { f.findDevelBranch(repo) } if repo.GetUserBranchName() == "" { uname := f.configUserBranchName(repo) if repo.IsBranch(uname) { repo.SetUserBranchName(uname) } else { // forcing for now. todo: warn users repo.SetUserBranchName(uname) /* no longer checkout on Init() if repo.CheckoutUser() { } else { cmd := []string{"git", "branch", uname} repo.Run(cmd) } */ } } } // what name should be used for the user branch? func (f *Forge) configUserBranchName(repo *gitpb.Repo) string { // look in the repo record for the username uname := repo.GetUserBranchName() if uname != "" { return uname } // query the the forge config for a custom User Branch Name uname = f.Config.FindUserBranch(repo.GetGoPath()) if uname != "" { return uname } // use the os.Username uname = f.Config.Username return uname } // todo: check the forge config func (f *Forge) configDevelBranchName(repo *gitpb.Repo) string { if repo.GetDevelBranchName() != "" { return repo.GetDevelBranchName() } if repo.IsBranch("guidevel") { return "guidevel" } if repo.IsBranch("devel") { return "devel" } return "devel" } func (f *Forge) AddFullPath(fulldir string) *gitpb.Repo { repo := f.Repos.FindByFullPath(fulldir) if repo != nil { return repo } log.Info("don't know how to add full paths yet", fulldir) return nil } func (f *Forge) FindByGoPath(gopath string) *gitpb.Repo { fullpath := filepath.Join(f.GetGoSrc(), gopath) return f.Repos.FindByFullPath(fullpath) } // tries any parent func (f *Forge) FindAnyPath(dir string) *gitpb.Repo { dir = filepath.Clean(dir) repo := f.Repos.FindByFullPath(dir) if repo != nil { log.Info("FindAnyPath() worked = ", dir) return repo } if dir == "" { return nil } if dir == "/" { return nil } basedir, newdir := filepath.Split(dir) if newdir == "" { // is this correct? not sure what stupid windows does return nil } return f.FindAnyPath(basedir) } func (f *Forge) DeleteByGoPath(gopath string) bool { fullpath := filepath.Join(f.GetGoSrc(), gopath) return f.Repos.DeleteByFullPath(fullpath) }