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