bridge_configure.go

  1package commands
  2
  3import (
  4	"bufio"
  5	"fmt"
  6	"os"
  7	"strconv"
  8	"strings"
  9
 10	"github.com/spf13/cobra"
 11
 12	"github.com/MichaelMure/git-bug/bridge"
 13	"github.com/MichaelMure/git-bug/bridge/core"
 14	"github.com/MichaelMure/git-bug/cache"
 15	"github.com/MichaelMure/git-bug/repository"
 16	"github.com/MichaelMure/git-bug/util/interrupt"
 17)
 18
 19const (
 20	defaultName = "default"
 21)
 22
 23var (
 24	bridgeConfigureName   string
 25	bridgeConfigureTarget string
 26	bridgeParams          core.BridgeParams
 27)
 28
 29func runBridgeConfigure(cmd *cobra.Command, args []string) error {
 30	backend, err := cache.NewRepoCache(repo)
 31	if err != nil {
 32		return err
 33	}
 34	defer backend.Close()
 35	interrupt.RegisterCleaner(backend.Close)
 36
 37	if (bridgeParams.TokenStdin || bridgeParams.Token != "") && (bridgeConfigureName == "" || bridgeConfigureTarget == "") {
 38		return fmt.Errorf("you must provide a bridge name and target to configure a bridge with a token")
 39	}
 40
 41	if bridgeConfigureTarget == "" {
 42		bridgeConfigureTarget, err = promptTarget()
 43		if err != nil {
 44			return err
 45		}
 46	}
 47
 48	if bridgeConfigureName == "" {
 49		bridgeConfigureName, err = promptName(repo)
 50		if err != nil {
 51			return err
 52		}
 53	}
 54
 55	b, err := bridge.NewBridge(backend, bridgeConfigureTarget, bridgeConfigureName)
 56	if err != nil {
 57		return err
 58	}
 59
 60	err = b.Configure(bridgeParams)
 61	if err != nil {
 62		return err
 63	}
 64
 65	fmt.Printf("Successfully configured bridge: %s\n", bridgeConfigureName)
 66	return nil
 67}
 68
 69func promptTarget() (string, error) {
 70	targets := bridge.Targets()
 71
 72	for {
 73		for i, target := range targets {
 74			fmt.Printf("[%d]: %s\n", i+1, target)
 75		}
 76		fmt.Printf("target: ")
 77
 78		line, err := bufio.NewReader(os.Stdin).ReadString('\n')
 79
 80		if err != nil {
 81			return "", err
 82		}
 83
 84		line = strings.TrimRight(line, "\n")
 85
 86		index, err := strconv.Atoi(line)
 87		if err != nil || index <= 0 || index > len(targets) {
 88			fmt.Println("invalid input")
 89			continue
 90		}
 91
 92		return targets[index-1], nil
 93	}
 94}
 95
 96func promptName(repo repository.RepoCommon) (string, error) {
 97	for {
 98		fmt.Printf("name [%s]: ", defaultName)
 99
100		line, err := bufio.NewReader(os.Stdin).ReadString('\n')
101		if err != nil {
102			return "", err
103		}
104
105		line = strings.TrimRight(line, "\n")
106
107		name := line
108		if name == "" {
109			name = defaultName
110		}
111
112		if !core.BridgeExist(repo, name) {
113			return name, nil
114		}
115
116		fmt.Println("a bridge with the same name already exist")
117	}
118}
119
120var bridgeConfigureCmd = &cobra.Command{
121	Use:   "configure",
122	Short: "Configure a new bridge.",
123	Long: `	Configure a new bridge by passing flags or/and using interactive terminal prompts. You can avoid all the terminal prompts by passing all the necessary flags to configure your bridge.
124	Repository configuration can be made by passing either the --url flag or the --project and --owner flags. If the three flags are provided git-bug will use --project and --owner flags.
125	Token configuration can be directly passed with the --token flag or in the terminal prompt. If you don't already have one you can use the interactive procedure to generate one.`,
126	Example: `# Interactive example
127[1]: github
128[2]: launchpad-preview
129target: 1
130name [default]: default
131
132Detected projects:
133[1]: github.com/a-hilaly/git-bug
134[2]: github.com/MichaelMure/git-bug
135
136[0]: Another project
137
138Select option: 1
139
140[1]: user provided token
141[2]: interactive token creation
142Select option: 1
143
144You can generate a new token by visiting https://github.com/settings/tokens.
145Choose 'Generate new token' and set the necessary access scope for your repository.
146
147The access scope depend on the type of repository.
148Public:
149	- 'public_repo': to be able to read public repositories
150Private:
151	- 'repo'       : to be able to read private repositories
152
153Enter token: 87cf5c03b64029f18ea5f9ca5679daa08ccbd700
154Successfully configured bridge: default
155
156# For GitHub
157git bug bridge configure \
158    --name=default \
159    --target=github \
160    --owner=$(OWNER) \
161    --project=$(PROJECT) \
162    --token=$(TOKEN)
163
164# For Launchpad
165git bug bridge configure \
166    --name=default \
167    --target=launchpad-preview \
168	--url=https://bugs.launchpad.net/ubuntu/
169
170# For Gitlab
171git bug bridge configure \
172    --name=default \
173    --target=github \
174    --url=https://github.com/michaelmure/git-bug \
175    --token=$(TOKEN)`,
176	PreRunE: loadRepo,
177	RunE:    runBridgeConfigure,
178}
179
180func init() {
181	bridgeCmd.AddCommand(bridgeConfigureCmd)
182	bridgeConfigureCmd.Flags().StringVarP(&bridgeConfigureName, "name", "n", "", "A distinctive name to identify the bridge")
183	bridgeConfigureCmd.Flags().StringVarP(&bridgeConfigureTarget, "target", "t", "",
184		fmt.Sprintf("The target of the bridge. Valid values are [%s]", strings.Join(bridge.Targets(), ",")))
185	bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.URL, "url", "u", "", "The URL of the target repository")
186	bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Owner, "owner", "o", "", "The owner of the target repository")
187	bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Token, "token", "T", "", "The authentication token for the API")
188	bridgeConfigureCmd.Flags().BoolVar(&bridgeParams.TokenStdin, "token-stdin", false, "Will read the token from stdin and ignore --token")
189	bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Project, "project", "p", "", "The name of the target repository")
190	bridgeConfigureCmd.Flags().SortFlags = false
191}