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