config.go

  1package launchpad
  2
  3import (
  4	"bufio"
  5	"errors"
  6	"fmt"
  7	"net/http"
  8	"os"
  9	"regexp"
 10	"strings"
 11	"time"
 12
 13	"github.com/MichaelMure/git-bug/bridge/core"
 14	"github.com/MichaelMure/git-bug/repository"
 15)
 16
 17var ErrBadProjectURL = errors.New("bad Launchpad project URL")
 18
 19const (
 20	target         = "launchpad-preview"
 21	keyProject     = "project"
 22	keyTarget      = "target"
 23	defaultTimeout = 60 * time.Second
 24)
 25
 26func (*Launchpad) Configure(repo repository.RepoCommon, params core.BridgeParams) (core.Configuration, error) {
 27	if params.Token != "" {
 28		fmt.Println("warning: --token is ineffective for a Launchpad bridge")
 29	}
 30	if params.Owner != "" {
 31		fmt.Println("warning: --owner is ineffective for a Launchpad bridge")
 32	}
 33
 34	conf := make(core.Configuration)
 35	var err error
 36	var project string
 37
 38	if params.Project != "" {
 39		project = params.Project
 40
 41	} else if params.URL != "" {
 42		// get project name from url
 43		project, err = splitURL(params.URL)
 44		if err != nil {
 45			return nil, err
 46		}
 47
 48	} else {
 49		// get project name from terminal prompt
 50		project, err = promptProjectName()
 51		if err != nil {
 52			return nil, err
 53		}
 54	}
 55
 56	// verify project
 57	ok, err := validateProject(project)
 58	if err != nil {
 59		return nil, err
 60	}
 61	if !ok {
 62		return nil, fmt.Errorf("project doesn't exist")
 63	}
 64
 65	conf[keyProject] = project
 66	conf[keyTarget] = target
 67	return conf, nil
 68}
 69
 70func (*Launchpad) ValidateConfig(conf core.Configuration) error {
 71	if _, ok := conf[keyProject]; !ok {
 72		return fmt.Errorf("missing %s key", keyProject)
 73	}
 74
 75	if _, ok := conf[keyTarget]; !ok {
 76		return fmt.Errorf("missing %s key", keyTarget)
 77	}
 78
 79	return nil
 80}
 81
 82func promptProjectName() (string, error) {
 83	for {
 84		fmt.Print("Launchpad project name: ")
 85
 86		line, err := bufio.NewReader(os.Stdin).ReadString('\n')
 87		if err != nil {
 88			return "", err
 89		}
 90
 91		line = strings.TrimRight(line, "\n")
 92
 93		if line == "" {
 94			fmt.Println("Project name is empty")
 95			continue
 96		}
 97
 98		return line, nil
 99	}
100}
101
102func validateProject(project string) (bool, error) {
103	url := fmt.Sprintf("%s/%s", apiRoot, project)
104
105	client := &http.Client{
106		Timeout: defaultTimeout,
107	}
108
109	resp, err := client.Get(url)
110	if err != nil {
111		return false, err
112	}
113
114	return resp.StatusCode == http.StatusOK, nil
115}
116
117// extract project name from url
118func splitURL(url string) (string, error) {
119	re, err := regexp.Compile(`launchpad\.net[\/:]([^\/]*[a-z]+)`)
120	if err != nil {
121		panic("regexp compile:" + err.Error())
122	}
123
124	res := re.FindStringSubmatch(url)
125	if res == nil {
126		return "", ErrBadProjectURL
127	}
128
129	return res[1], nil
130}