bridge_configure.go

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