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