-
Notifications
You must be signed in to change notification settings - Fork 10
/
common.clj
146 lines (123 loc) · 5.92 KB
/
common.clj
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
(ns flower.tracker.tfs.common
(:require [clj-http.client :as client]
[clojure.data.json :as json]
[flower.macros :as macros]
[flower.tracker.proto :as proto]))
;;
;; Public definitions
;;
(macros/public-definition get-tfs-workitems-inner cached)
(macros/public-definition get-tfs-workitems-partial-inner)
(macros/public-definition get-tfs-query-inner cached)
(macros/public-definition get-tfs-workitem-comments-inner cached)
(macros/public-definition get-tfs-iterations-inner cached)
(macros/public-definition get-tfs-capacity-inner cached)
(macros/public-definition set-tfs-workitem-inner!)
;;
;; Macros
;;
(defmacro with-tfs-auth [full-url query-params key & body]
`(let [response# (client/get ~full-url {:basic-auth [~'login (or ~'token
~'password)]
:content-type :json
:accept :json
:query-params ~query-params})
response-body# (get response# :body "{}")
~'result (get (json/read-str response-body#
:key-fn keyword)
~key [])]
~@body))
(defmacro with-tfs-function [tracker project? url query-params key & body]
(let [full-url (if project?
`(str (proto/get-project-url ~tracker) ~@url)
`(str (proto/get-tracker-url ~tracker) ~@url))]
`(let [tracker-component# (proto/get-tracker-component ~tracker)
auth# (get-in tracker-component# [:auth] {})
context# (get-in tracker-component# [:context] {})
skip-on-exception# (get context# :skip-on-exception true)
~'login (get auth# :tfs-login)
~'password (get auth# :tfs-password)
~'token (get auth# :tfs-token)]
(try
(with-tfs-auth ~full-url ~query-params ~key
~@body)
(catch Exception e#
(when-not skip-on-exception#
(throw e#)))))))
;;
;; Private definitions
;;
(defn- private-get-tfs-workitems-inner [tracker task-ids]
(if-not (empty? (filter identity task-ids))
(let [query-string {:ids (clojure.string/join "," task-ids)}]
(with-tfs-function tracker false ("/_apis/wit/workitems") query-string :value
result))))
(defn- private-get-tfs-workitems-partial-inner [tracker task-ids]
(let [partitioned-ids (partition-all 10 task-ids)]
(apply concat
(for [patitioned-task-ids partitioned-ids
:let [workitems (get-tfs-workitems-inner tracker patitioned-task-ids)]]
(if (< (count workitems)
(count patitioned-task-ids))
(for [task-id patitioned-task-ids]
(first (get-tfs-workitems-inner tracker [task-id])))
workitems)))))
(defn- private-get-tfs-query-inner [tracker query-id]
(if (re-find #"(?i)[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}" query-id)
(with-tfs-function tracker false ("/_apis/wit/wiql/" query-id) {} :workItems
(private-get-tfs-workitems-partial-inner tracker
(map :id result)))
(with-tfs-function tracker true ("/_apis/wit/queries/" query-id) {} :id
(private-get-tfs-query-inner tracker result))))
(defn- private-get-tfs-workitem-comments-inner [tracker task-id]
(with-tfs-function tracker false ("/_apis/wit/workitems/" task-id "/comments") {} :comments
result))
(defn- private-get-tfs-iterations-inner [tracker]
(with-tfs-function tracker true ("/_apis/work/teamsettings") {} :_links
(with-tfs-auth (get-in result [:teamIterations :href]) {} :value
result)))
(defn- private-get-tfs-capacity-inner [tracker iteration]
(with-tfs-function tracker true ("/_apis/work/teamsettings") {} :_links
(with-tfs-auth (get-in result [:teamIterations :href]) {} :value
(if-let [iteration-url (-> (filter (fn [iteration-inner]
(= 0 (compare (proto/get-iteration-id iteration)
(get iteration-inner :id))))
result)
(first)
(get :url))]
(with-tfs-auth iteration-url {} :_links
(with-tfs-auth (get-in result [:capacity :href]) {} :value
result))))))
(defn- private-set-tfs-workitem-inner! [tracker task-id fields]
(let [auth (get-in (proto/get-tracker-component tracker)
[:auth]
{})
login (get auth :tfs-login)
password (get auth :tfs-password)
token (get auth :tfs-token)
wit (get fields :System.WorkItemType "Task")
operations (map (fn [[key value]] {:op :add
:path (str "/fields/" (name key))
:value value})
fields)
operations-str (json/write-str operations :escape-slash false)
task-url (str (if task-id
(proto/get-tracker-url tracker)
(proto/get-project-url tracker))
"/_apis/wit/workitems/"
(if (integer? task-id)
(str task-id)
(if-not (empty? task-id)
task-id
(str "$" wit)))
"?api-version=1.0")]
(if (empty? operations)
{:id task-id}
(let [response (client/patch task-url
{:basic-auth [login (or token
password)]
:content-type :json-patch+json
:accept :json
:body operations-str})
response-body (get response :body "{}")]
(json/read-str response-body :key-fn keyword)))))