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 (*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 return conf, nil
67}
68
69func (*Launchpad) ValidateConfig(conf core.Configuration) error {
70 if _, ok := conf[keyProject]; !ok {
71 return fmt.Errorf("missing %s key", keyProject)
72 }
73
74 if _, ok := conf[core.KeyTarget]; !ok {
75 return fmt.Errorf("missing %s key", core.KeyTarget)
76 }
77
78 return nil
79}
80
81func promptProjectName() (string, error) {
82 for {
83 fmt.Print("Launchpad project name: ")
84
85 line, err := bufio.NewReader(os.Stdin).ReadString('\n')
86 if err != nil {
87 return "", err
88 }
89
90 line = strings.TrimRight(line, "\n")
91
92 if line == "" {
93 fmt.Println("Project name is empty")
94 continue
95 }
96
97 return line, nil
98 }
99}
100
101func validateProject(project string) (bool, error) {
102 url := fmt.Sprintf("%s/%s", apiRoot, project)
103
104 client := &http.Client{
105 Timeout: defaultTimeout,
106 }
107
108 resp, err := client.Get(url)
109 if err != nil {
110 return false, err
111 }
112
113 return resp.StatusCode == http.StatusOK, nil
114}
115
116// extract project name from url
117func splitURL(url string) (string, error) {
118 re, err := regexp.Compile(`launchpad\.net[\/:]([^\/]*[a-z]+)`)
119 if err != nil {
120 panic("regexp compile:" + err.Error())
121 }
122
123 res := re.FindStringSubmatch(url)
124 if res == nil {
125 return "", ErrBadProjectURL
126 }
127
128 return res[1], nil
129}