config.go

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