From 700f022790395a1f1c456ce84d334c237226359e Mon Sep 17 00:00:00 2001 From: decentral1se Date: Mon, 20 Sep 2021 09:38:51 +0200 Subject: [PATCH] WIP: use repo metadata not existing catalogue --- cli/catalogue/generate.go | 45 +++++++-------- pkg/catalogue/catalogue.go | 110 +++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 26 deletions(-) diff --git a/cli/catalogue/generate.go b/cli/catalogue/generate.go index 51fea34b..0a7670dd 100644 --- a/cli/catalogue/generate.go +++ b/cli/catalogue/generate.go @@ -4,7 +4,6 @@ import ( "encoding/json" "io/ioutil" "path" - "strings" "coopcloud.tech/abra/pkg/catalogue" "coopcloud.tech/abra/pkg/config" @@ -50,53 +49,47 @@ var catalogueGenerateCommand = &cli.Command{ ArgsUsage: "[]", BashComplete: func(c *cli.Context) {}, Action: func(c *cli.Context) error { - recipes, err := catalogue.ReadRecipeCatalogue() + recipeName := c.Args().First() + + repos, err := catalogue.ReadReposMetadata() if err != nil { logrus.Fatal(err) } - recipeName := c.Args().First() - if recipeName != "" { - recipeMeta, exists := recipes[recipeName] - if !exists { - logrus.Fatalf("'%s' does not exist?", recipeName) - } - recipes = map[string]catalogue.RecipeMeta{recipeName: recipeMeta} - } + logrus.Debugf("ensuring '%v' recipe(s) are locally present and up-to-date", len(repos)) - logrus.Debugf("ensuring '%v' recipe(s) are locally present and up-to-date", len(recipes)) - - ch := make(chan string, len(recipes)) - for recipeName, recipeMeta := range recipes { - go func(rn string, rm catalogue.RecipeMeta) { - if _, exists := CatalogueSkipList[rn]; exists { - ch <- rn + ch := make(chan string, len(repos)) + for _, repoMeta := range repos { + go func(rm catalogue.RepoMeta) { + if recipeName != "" && recipeName != rm.Name { + ch <- rm.Name return } - if rm.Repository == "" { - logrus.Warnf("'%s' has no git clone URL, skipping", rn) - ch <- rn + if _, exists := CatalogueSkipList[rm.Name]; exists { + ch <- rm.Name return } - recipeDir := path.Join(config.ABRA_DIR, "apps", strings.ToLower(rn)) - if err := git.Clone(recipeDir, rm.Repository); err != nil { + recipeDir := path.Join(config.ABRA_DIR, "apps", rm.Name) + + if err := git.Clone(recipeDir, rm.SSHURL); err != nil { logrus.Fatal(err) } if err := git.EnsureUpToDate(recipeDir); err != nil { logrus.Fatal(err) } - ch <- rn - }(recipeName, recipeMeta) + + ch <- rm.Name + }(repoMeta) } - for range recipes { + for range repos { <-ch // wait for everything } catl := make(catalogue.RecipeCatalogue) - for recipeName := range recipes { + for recipeName := range repos { // TODO: gather more metadata catl[recipeName] = catalogue.RecipeMeta{ Name: recipeName, diff --git a/pkg/catalogue/catalogue.go b/pkg/catalogue/catalogue.go index 97ab4db4..ccd1b071 100644 --- a/pkg/catalogue/catalogue.go +++ b/pkg/catalogue/catalogue.go @@ -21,6 +21,9 @@ import ( // RecipeCatalogueURL is the only current recipe catalogue available. const RecipeCatalogueURL = "https://apps.coopcloud.tech" +// ReposMetadataURL is the recipe repository metadata +const ReposMetadataURL = "https://git.coopcloud.tech/api/v1/orgs/coop-cloud/repos" + // image represents a recipe container image. type image struct { Image string `json:"image"` @@ -255,3 +258,110 @@ func GetRecipeMeta(recipeName string) (RecipeMeta, error) { return recipeMeta, nil } + +// RepoMeta is a single recipe repo metadata. +type RepoMeta struct { + ID int `json:"id"` + Owner Owner + Name string `json:"name"` + FullName string `json:"full_name"` + Description string `json:"description"` + Empty bool `json:"empty"` + Private bool `json:"private"` + Fork bool `json:"fork"` + Template bool `json:"template"` + Parent interface{} `json:"parent"` + Mirror bool `json:"mirror"` + Size int `json:"size"` + HTMLURL string `json:"html_url"` + SSHURL string `json:"ssh_url"` + CloneURL string `json:"clone_url"` + OriginalURL string `json:"original_url"` + Website string `json:"website"` + StarsCount int `json:"stars_count"` + ForksCount int `json:"forks_count"` + WatchersCount int `json:"watchers_count"` + OpenIssuesCount int `json:"open_issues_count"` + OpenPRCount int `json:"open_pr_counter"` + ReleaseCounter int `json:"release_counter"` + DefaultBranch string `json:"default_branch"` + Archived bool `json:"archived"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + Permissions Permissions + HasIssues bool `json:"has_issues"` + InternalTracker InternalTracker + HasWiki bool `json:"has_wiki"` + HasPullRequests bool `json:"has_pull_requests"` + HasProjects bool `json:"has_projects"` + IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` + AllowMergeCommits bool `json:"allow_merge_commits"` + AllowRebase bool `json:"allow_rebase"` + AllowRebaseExplicit bool `json:"allow_rebase_explicit"` + AllowSquashMerge bool `json:"allow_squash_merge"` + AvatarURL string `json:"avatar_url"` + Internal bool `json:"internal"` + MirrorInterval string `json:"mirror_interval"` +} + +// Owner is the repo organisation owner metadata. +type Owner struct { + ID int `json:"id"` + Login string `json:"login"` + FullName string `json:"full_name"` + Email string `json:"email"` + AvatarURL string `json:"avatar_url"` + Language string `json:"language"` + IsAdmin bool `json:"is_admin"` + LastLogin string `json:"last_login"` + Created string `json:"created"` + Restricted bool `json:"restricted"` + Username string `json:"username"` +} + +// Permissions is perms metadata for a repo. +type Permissions struct { + Admin bool `json:"admin"` + Push bool `json:"push"` + Pull bool `json:"pull"` +} + +// InternalTracker is issue tracker metadata for a repo. +type InternalTracker struct { + EnableTimeTracker bool `json:"enable_time_tracker"` + AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"` + EnableIssuesDependencies bool `json:"enable_issue_dependencies"` +} + +// RepoCatalogue represents all the recipe repo metadata. +type RepoCatalogue map[string]RepoMeta + +// ReadReposMetadata retrieves coop-cloud/... repo metadata from Gitea. +func ReadReposMetadata() (RepoCatalogue, error) { + reposMeta := make(RepoCatalogue) + + pageIdx := 1 + for { + var reposList []RepoMeta + + pagedURL := fmt.Sprintf("%s?page=%v", ReposMetadataURL, pageIdx) + + logrus.Debugf("fetching repo metadata from '%s'", pagedURL) + + if err := web.ReadJSON(pagedURL, &reposList); err != nil { + return reposMeta, err + } + + if len(reposList) == 0 { + break + } + + for idx, repo := range reposList { + reposMeta[repo.Name] = reposList[idx] + } + + pageIdx++ + } + + return reposMeta, nil +}