diff --git a/cmd/commands/repo/repo.go b/cmd/commands/repo/repo.go new file mode 100644 index 0000000..43daf55 --- /dev/null +++ b/cmd/commands/repo/repo.go @@ -0,0 +1,19 @@ +package repo + +import ( + "github.com/craftamap/bb/cmd/commands/repo/view" + "github.com/craftamap/bb/cmd/options" + "github.com/spf13/cobra" +) + +func Add(rootCmd *cobra.Command, globalOpts *options.GlobalOptions) { + repoCommand := cobra.Command{ + Use: "repo", + Long: "Work with repositories", + Short: "Manage your repository", + } + + view.Add(&repoCommand, globalOpts) + + rootCmd.AddCommand(&repoCommand) +} diff --git a/cmd/commands/repo/view/view.go b/cmd/commands/repo/view/view.go new file mode 100644 index 0000000..2013396 --- /dev/null +++ b/cmd/commands/repo/view/view.go @@ -0,0 +1,78 @@ +package view + +import ( + "fmt" + + "github.com/charmbracelet/glamour" + "github.com/craftamap/bb/cmd/options" + "github.com/craftamap/bb/internal" + "github.com/logrusorgru/aurora" + "github.com/pkg/browser" + "github.com/spf13/cobra" +) + +var ( + Web bool +) + +func Add(repoCmd *cobra.Command, globalOpts *options.GlobalOptions) { + viewCmd := &cobra.Command{ + Use: "view", + Short: "View a pull request", + Long: "Display the title, body, and other information about a pull request.", + Annotations: map[string]string{ + "RequiresClient": "true", + "RequiresRepository": "true", + }, + + Run: func(cmd *cobra.Command, args []string) { + c := globalOpts.Client + bbrepo := globalOpts.BitbucketRepo + + repo, err := c.RepositoryGet(bbrepo.RepoOrga, bbrepo.RepoSlug) + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occured: "), err) + return + } + if Web { + err := browser.OpenURL(repo.Links["html"].(map[string]interface{})["href"].(string)) + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occured: "), err) + return + } + return + } + + readme, err := c.GetReadmeContent(bbrepo.RepoOrga, bbrepo.RepoSlug, repo.MainBranch.Name) + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occured: "), err) + return + } + + PrintSummary(repo, readme) + }, + } + + viewCmd.Flags().BoolVar(&Web, "web", false, "view this repository in your web browser") + repoCmd.AddCommand(viewCmd) + +} + +func PrintSummary(repo *internal.Repository, readme string) { + fmt.Println(aurora.Bold(repo.FullName)) + if repo.Description != "" { + fmt.Println(aurora.Bold("Description:"), repo.Description) + } + fmt.Println(aurora.Bold("Project:"), repo.Project.Name, fmt.Sprintf("(%s)", repo.Project.Key)) + if readme != "" { + out, err := glamour.Render(readme, "dark") + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occured: "), err) + return + } + fmt.Println(out) + } + footer := aurora.Index(242, fmt.Sprintf("View this repository on Bitbucket.org: %s", repo.Links["html"].(map[string]interface{})["href"].(string))).String() + fmt.Println(footer) + +} diff --git a/cmd/root.go b/cmd/root.go index 026f1dc..316b187 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -9,6 +9,7 @@ import ( "github.com/craftamap/bb/cmd/commands/auth" "github.com/craftamap/bb/cmd/commands/downloads" "github.com/craftamap/bb/cmd/commands/pr" + "github.com/craftamap/bb/cmd/commands/repo" "github.com/craftamap/bb/cmd/options" bbgit "github.com/craftamap/bb/git" "github.com/craftamap/bb/internal" @@ -94,6 +95,7 @@ func init() { api.Add(rootCmd, &globalOpts) downloads.Add(rootCmd, &globalOpts) auth.Add(rootCmd, &globalOpts) + repo.Add(rootCmd, &globalOpts) } func initConfig() { diff --git a/internal/repository.go b/internal/repository.go index 10aad21..8bb3a1c 100644 --- a/internal/repository.go +++ b/internal/repository.go @@ -1,6 +1,8 @@ package internal import ( + "strings" + "github.com/ktrysmt/go-bitbucket" "github.com/mitchellh/mapstructure" ) @@ -74,3 +76,42 @@ func (c Client) GetDefaultReviewers(repoOrga string, repoSlug string) (*DefaultR return &defaultReviewers, nil } + +func (c Client) GetReadmeContent(repoOrga string, repoSlug string, branch string) (string, error) { + client := bitbucket.NewBasicAuth(c.Username, c.Password) + + allRootFiles, err := client.Repositories.Repository.ListFiles(&bitbucket.RepositoryFilesOptions{ + Owner: repoOrga, + RepoSlug: repoSlug, + Ref: branch, + }) + if err != nil { + return "", err + } + + potentialReadmes := []bitbucket.RepositoryFile{} + + for _, rootFile := range allRootFiles { + if strings.HasPrefix(strings.ToLower(rootFile.Path), "readme") { + potentialReadmes = append(potentialReadmes, rootFile) + } + } + + if len(potentialReadmes) <= 0 { + return "", nil + } + + fileName := potentialReadmes[0].Path + + fileBlob, err := client.Repositories.Repository.GetFileBlob(&bitbucket.RepositoryBlobOptions{ + Owner: repoOrga, + RepoSlug: repoSlug, + Ref: branch, + Path: fileName, + }) + if err != nil { + return "", err + } + + return fileBlob.String(), nil +}