/
github_tag.clj
86 lines (76 loc) · 2.7 KB
/
github_tag.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
(ns antq.ver.github-tag
(:require
[antq.log :as log]
[antq.util.git :as u.git]
[antq.util.ver :as u.ver]
[antq.ver :as ver]
[cheshire.core :as json]
[clojure.string :as str]
[version-clj.core :as version]))
(defonce ^:private failed-to-fetch-from-api
(atom false))
(defn tag-api-url
[dep]
(format "https://api.github.com/repos/%s/tags"
(str/join "/" (take 2 (str/split (:name dep) #"/")))))
(defn get-sorted-versions-by-ls-remote*
[dep]
(let [url (format "https://github.com/%s"
(str/join "/" (take 2 (str/split (:name dep) #"/"))))]
(->> (u.git/tags-by-ls-remote url)
(filter (comp u.ver/sem-ver? u.ver/normalize-version))
(sort (fn [& args]
(apply version/version-compare
(map u.ver/normalize-version args))))
(reverse))))
(def get-sorted-versions-by-ls-remote
(memoize get-sorted-versions-by-ls-remote*))
(defn get-sorted-versions-by-url*
[url]
(-> url
(slurp)
(json/parse-string true)
(->> (map :name)
(filter (comp u.ver/sem-ver? u.ver/normalize-version))
(sort (fn [& args]
(apply version/version-compare
(map u.ver/normalize-version args))))
(reverse))))
(def get-sorted-versions-by-url
(memoize get-sorted-versions-by-url*))
(defn- fallback-to-ls-remote
[dep]
(try
(get-sorted-versions-by-ls-remote dep)
(catch Exception ex
(log/error (str "Failed to fetch versions from GitHub: "
(.getMessage ex))))))
(defmethod ver/get-sorted-versions :github-tag
[dep]
(if @failed-to-fetch-from-api
(fallback-to-ls-remote dep)
(try
(-> dep
(tag-api-url)
(get-sorted-versions-by-url))
(catch Exception ex
(reset! failed-to-fetch-from-api true)
(log/error (str "Failed to fetch versions from GitHub, so fallback to `git ls-remote`: "
(.getMessage ex)))
(fallback-to-ls-remote dep)))))
(defn- nth-newer?
[current-ver-seq latest-ver-seq index]
(let [current (nth (first current-ver-seq) index nil)
latest (nth (first latest-ver-seq) index nil)]
(and current latest
(>= current latest))))
(defmethod ver/latest? :github-tag
[dep]
(let [current (some-> dep :version u.ver/normalize-version version/version->seq)
latest (some-> dep :latest-version u.ver/normalize-version version/version->seq)]
(when (and current latest)
(case (count (first current))
1 (nth-newer? current latest 0)
2 (and (nth-newer? current latest 0)
(nth-newer? current latest 1))
(<= 0 (version/version-seq-compare current latest))))))