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}