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