diff --git a/devel-importer/main.go b/devel-importer/main.go index aab30fd..ab65662 100644 --- a/devel-importer/main.go +++ b/devel-importer/main.go @@ -23,9 +23,11 @@ import ( "errors" "flag" "fmt" + "io/fs" "log" "os" "os/exec" + "path" "path/filepath" "slices" "strings" @@ -274,24 +276,39 @@ func importRepos(packages []string) { // check that nothing is broken with the update if slices.Contains(remotes, "factory") { // check which branch is ahead - branches := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkgName, "branch", "-r"), "\n") + branches, err := fs.ReadDir(os.DirFS(path.Join(git.GetPath(), pkgName, ".git/refs/remotes")), "factory") + if err != nil { + log.Panicln(" *** factory has no branches?", branches) + } pool_branch := "factory" - if slices.Contains(branches, "factory/devel") && slices.Contains(branches, "factory/factory") { + has_factory_devel := false + has_factory_factory := false + + for _, branch := range branches { + if branch.Name() == "factory" { + has_factory_factory = true + } else if branch.Name() == "devel" { + has_factory_devel = true + } + } + log.Println(branches) + + if has_factory_devel && has_factory_factory { if len(common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkgName, "rev-list", "^factory/factory", "factory/devel"), "\n")) > 0 { log.Println(" *** pool branch devel ahead. Switching branches.") pool_branch = "devel" } - } else if slices.Contains(branches, "factory/devel") && !slices.Contains(branches, "factory/factory") { + } else if has_factory_devel && !has_factory_factory { pool_branch = "devel" - } else if !slices.Contains(branches, "factory/devel") && slices.Contains(branches, "factory/factory") { + } else if !has_factory_devel && has_factory_factory { } else { log.Panicln("branches screwed up for pkg", pkgName, branches) } // find tree object in factory branch - tree := strings.TrimSpace(git.GitExecWithOutputOrPanic(pkgName, "rev-list", "-1", "--format=%T", "--no-commit-header", "factory/"+import_branch)) + tree := strings.TrimSpace(git.GitExecWithOutputOrPanic(pkgName, "rev-list", "-1", "--format=%T", "--no-commit-header", "factory/"+pool_branch)) log.Println("tree", tree) import_tree_commits := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkgName, "rev-list", "--format=%H %T", "--no-commit-header", import_branch), "\n") found := false @@ -305,7 +322,7 @@ func importRepos(packages []string) { cherry_picks := common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(pkgName, "rev-list", "--reverse", "--ancestry-path", commit_tree[0]+".."+import_branch), "\n") log.Println("cherry picks", cherry_picks) - git.GitExecOrPanic(pkgName, "checkout", "-B", "main", pool_branch) + git.GitExecOrPanic(pkgName, "checkout", "-B", "main", "factory/"+pool_branch) for _, pick := range cherry_picks { git.GitExecOrPanic(pkgName, "cherry-pick", pick) } @@ -315,10 +332,10 @@ func importRepos(packages []string) { if !found { log.Println("*** WARNING: Cannot find same tree for pkg", pkgName, "Will use current import instead") - git.GitExecOrPanic(pkgName, "checkout", "-B", "main", import_branch) + git.GitExecOrPanic(pkgName, "checkout", "-B", "main", "heads/"+import_branch) } } else { - git.GitExecOrPanic(pkgName, "checkout", "-B", "main", import_branch) + git.GitExecOrPanic(pkgName, "checkout", "-B", "main", "heads/"+import_branch) } } @@ -467,7 +484,10 @@ func importRepos(packages []string) { } } -func syncOrgTeams(groupName string, teamMembers []common.PersonRepoMeta) []string { +func syncOrgTeams(groupName string, origTeam []common.PersonRepoMeta) []string { + teamMembers := make([]common.PersonRepoMeta, len(origTeam)) + copy(teamMembers, origTeam) + missing := []string{} if DebugMode { log.Println("syncOrgTeams", groupName, " -> ", teamMembers) @@ -548,8 +568,10 @@ func syncOrgOwners(uids []common.PersonRepoMeta) []string { return syncOrgTeams("Owners", append(uids, common.PersonRepoMeta{UserID: "autogits-devel"})) } -func syncPackageCollaborators(pkg string, uids []common.PersonRepoMeta) []string { +func syncPackageCollaborators(pkg string, orig_uids []common.PersonRepoMeta) []string { missing := []string{} + uids := make([]common.PersonRepoMeta, len(orig_uids)) + copy(uids, orig_uids) collab, err := client.Repository.RepoListCollaborators(repository.NewRepoListCollaboratorsParams().WithOwner(org).WithRepo(pkg), r.DefaultAuthentication) if err != nil { log.Panicln(err) @@ -597,6 +619,7 @@ func syncMaintainersToGitea(pkgs []string) { } missingDevs := []string{} + devs := []string{} for _, group := range prjMeta.Groups { teamMembers, err := obs.GetGroupMeta(group.GroupID) @@ -608,13 +631,16 @@ func syncMaintainersToGitea(pkgs []string) { log.Println("syncing", group.GroupID, teamMembers.Persons) } missingDevs = append(missingDevs, syncOrgTeams(group.GroupID, teamMembers.Persons.Persons)...) - devs := []string{} for _, m := range teamMembers.Persons.Persons { devs = append(devs, m.UserID) } - maintainers.Data[""] = devs } + for _, p := range prjMeta.Persons { + devs = append(devs, p.UserID) + } + missingDevs = append(missingDevs, syncOrgOwners(prjMeta.Persons)...) + maintainers.Data[""] = devs for _, pkg := range pkgs { pkgMeta, err := obs.GetPackageMeta(prj, pkg) @@ -630,17 +656,61 @@ func syncMaintainersToGitea(pkgs []string) { maintainers.Data[pkg] = devs } - slices.Sort(missingDevs) - file, err := os.Create(common.MaintainershipFile) + createPrjGit() + + file, err := os.Create(path.Join(git.GetPath(), common.DefaultGitPrj, common.MaintainershipFile)) if err != nil { log.Println(" *** Cannot create maintainership file:", err) } else { maintainers.WriteMaintainershipFile(file) file.Close() + + status, err := git.GitStatus(common.DefaultGitPrj) + if err != nil { + log.Panicln(err) + } + + for _, s := range(status) { + if s.Path == common.MaintainershipFile && s.Status == common.GitStatus_Untracked { + git.GitExecOrPanic(common.DefaultGitPrj, "add", common.MaintainershipFile) + git.GitExecOrPanic(common.DefaultGitPrj, "commit", "-m", "Initial sync of maintainership with OBS") + git.GitExecOrPanic(common.DefaultGitPrj, "push") + } + } + if l := len(common.SplitStringNoEmpty(git.GitExecWithOutputOrPanic(common.DefaultGitPrj, "status", "--porcelain=2"), "\n")); l > 0 { + } } + + slices.Sort(missingDevs) log.Println("Users without Gitea accounts:", slices.Compact(missingDevs)) } +func createPrjGit() { + if _, err := os.Stat(path.Join(git.GetPath(), common.DefaultGitPrj)); errors.Is(err, os.ErrNotExist) { + if err := git.GitExec("", "clone", "gitea@src.opensuse.org:"+org+"/_ObsPrj.git", common.DefaultGitPrj); err != nil { + repoName := common.DefaultGitPrj + _, err := client.Organization.CreateOrgRepo(organization.NewCreateOrgRepoParams().WithOrg(org).WithBody( + &models.CreateRepoOption{ + AutoInit: false, + Name: &repoName, + ObjectFormatName: "sha256", + }), r.DefaultAuthentication) + if err != nil { + log.Panicln(err) + } + + git.GitExecOrPanic("", "clone", "gitea@src.opensuse.org:"+org+"/_ObsPrj.git", common.DefaultGitPrj) + file, err := os.Create(path.Join(git.GetPath(), common.DefaultGitPrj, "project.build")) + if err != nil { + log.Panicln(err) + } + file.Write([]byte(obs.HomeProject)) + file.Close() + git.GitExecOrPanic(common.DefaultGitPrj, "add", "project.build") + } + } +} + var client *apiclient.GiteaAPI var r *transport.Runtime var git common.Git @@ -704,6 +774,13 @@ func main() { prj = flags.Arg(0) org = flags.Arg(1) packages, err := runObsCommand("ls", prj) + for i := 0; i < len(packages); { + if strings.Contains(packages[i], ":") { + packages = slices.Delete(packages, i, i+1) + } else { + i++ + } + } /* for _, pkg := range packages {