-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathredmine.go
157 lines (134 loc) · 4.49 KB
/
redmine.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package redmine
import (
"io"
"net/url"
"sync"
redmine "github.com/nixys/nxs-go-redmine/v5"
)
// API is an interface for Redmine API
type API interface {
ProjectSingleGet(identifier string, req redmine.ProjectSingleGetRequest) (redmine.ProjectObject, redmine.StatusCode, error)
UserCurrentGet(req redmine.UserCurrentGetRequest) (redmine.UserObject, redmine.StatusCode, error)
IssueCreate(req redmine.IssueCreate) (redmine.IssueObject, redmine.StatusCode, error)
IssueUpdate(id int64, req redmine.IssueUpdate) (redmine.StatusCode, error)
IssueSingleGet(id int64, req redmine.IssueSingleGetRequest) (redmine.IssueObject, redmine.StatusCode, error)
IssueDelete(id int64) (redmine.StatusCode, error)
AttachmentUpload(filePath string) (redmine.AttachmentUploadObject, redmine.StatusCode, error)
AttachmentUploadStream(f io.Reader, fileName string) (redmine.AttachmentUploadObject, redmine.StatusCode, error)
Del(in, out any, uri url.URL, statusExpected redmine.StatusCode) (redmine.StatusCode, error)
Post(in, out any, uri url.URL, statusExpected redmine.StatusCode) (redmine.StatusCode, error)
}
// Redmine is a Redmine client
type Redmine struct {
wg sync.WaitGroup
cfg *Config
}
// New creates a new Redmine client
func New(options ...Option) (*Redmine, error) {
cfg := NewConfig(options...)
r := &Redmine{cfg: cfg}
if !cfg.Enabled() {
return r, nil
}
if cfg.ProjectID == 0 {
if err := r.UpdateProject(); err != nil {
return r, err
}
}
if cfg.UserID == 0 {
if err := r.UpdateUser(); err != nil {
return r, err
}
}
return r, nil
}
// GetAPI returns the underlying API object from the github.com/nixys/nxs-go-redmine package (actual version may vary)
// it's useful for calling methods that are not exposed by this package
// WARNING: it CAN return nil (API interface is defined for tests only, but this method does type casting, so if the type is wrong, it will return nil)
func (r *Redmine) GetAPI() *redmine.Context {
if r.cfg == nil {
return nil
}
if r.cfg.api == nil {
return nil
}
typed, ok := r.cfg.api.(*redmine.Context)
if !ok {
return nil
}
return typed
}
// GetHost returns the Redmine host
func (r *Redmine) GetHost() string {
return r.cfg.Host
}
// GetAPIKey returns the Redmine API key
func (r *Redmine) GetAPIKey() string {
return r.cfg.APIKey
}
// GetProjectIdentifier returns the Redmine project identifier
func (r *Redmine) GetProjectIdentifier() string {
return r.cfg.ProjectIdentifier
}
// GetProjectID returns the Redmine project ID
func (r *Redmine) GetProjectID() int64 {
return r.cfg.ProjectID
}
// GetUserID returns the Redmine user ID
func (r *Redmine) GetUserID() int64 {
return r.cfg.UserID
}
// GetTrackerID returns the Redmine tracker ID
func (r *Redmine) GetTrackerID() int64 {
return r.cfg.TrackerID
}
// GetNewStatusID returns the Redmine new status ID
func (r *Redmine) GetWaitingForOperatorStatusID() int64 {
return r.cfg.WaitingForOperatorStatusID
}
// GetWaitingForCustomerStatusID returns the Redmine waiting for customer status ID
func (r *Redmine) GetWaitingForCustomerStatusID() int64 {
return r.cfg.WaitingForCustomerStatusID
}
// GetDoneStatusID returns the Redmine done status ID
func (r *Redmine) GetDoneStatusID() int64 {
return r.cfg.DoneStatusID
}
// Enabled returns true if the Redmine client is enabled
func (r *Redmine) Enabled() bool {
return r.cfg.Enabled()
}
// Configure applies the new configuration options in runtime
// It is advisable to call UpdateUser() (if API key and/or host was changed), and UpdatePorject() (if project identifier was changed) after this method
func (r *Redmine) Configure(options ...Option) *Redmine {
r.cfg.apply(options...)
return r
}
// UpdateUser updates the current user ID,
// it should be called after changing the API key and/or host
func (r *Redmine) UpdateUser() error {
user, err := RetryResult(r.cfg.Log, func() (redmine.UserObject, redmine.StatusCode, error) {
return r.cfg.api.UserCurrentGet(redmine.UserCurrentGetRequest{})
})
if err != nil {
return err
}
r.cfg.UserID = user.ID
return nil
}
// UpdateProject updates the project ID,
// it should be called after changing the project identifier
func (r *Redmine) UpdateProject() error {
project, err := RetryResult(r.cfg.Log, func() (redmine.ProjectObject, redmine.StatusCode, error) {
return r.cfg.api.ProjectSingleGet(r.cfg.ProjectIdentifier, redmine.ProjectSingleGetRequest{})
})
if err != nil {
return err
}
r.cfg.ProjectID = project.ID
return nil
}
// Shutdown waits for all goroutines to finish
func (r *Redmine) Shutdown() {
r.wg.Wait()
}