-
Notifications
You must be signed in to change notification settings - Fork 12
/
metadata.clj
104 lines (93 loc) · 4.83 KB
/
metadata.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
(ns metav.metadata
(:require [metav.git :as git :refer [pwd]]
[metav.repo :refer [monorepo? dedicated-repo?]]
[metav.maven];;require seems to be necessary when invoking dynamic resolve in the main function from the CLI
[metav.semver]
[clojure.tools.logging :as log]
[clojure.string :as string]
[me.raynes.fs :as fs])
(:import [java.util Date TimeZone]
[java.text DateFormat SimpleDateFormat]))
(def ^:dynamic *scheme* "semver")
(def ^:dynamic *separator* "-")
(defn module-name
"Determine the name for the project by analyzing the environment, path until the git root or folder name if just under the root"
([] (module-name (pwd) nil))
([working-dir module-name-override]
(if (not (string/blank? module-name-override)) module-name-override
(if (dedicated-repo? working-dir)
(-> (git/toplevel working-dir)
(fs/split)
(last))
;;monorepo
(let [name (clojure.string/replace (git/prefix working-dir) "/" "-")]
(subs name 0 (dec (count name))))))))
(defn- version-scheme-fn [scheme]
(ns-resolve (the-ns 'metav.metadata) (symbol (str "metav." scheme "/version"))))
(defn prefix
"return the prefix used before the version in tag (not to be confused with the git prefix even if we deduce the tag prefix with the git prefix)"
[working-dir module-name]
(if (monorepo? working-dir)
(str module-name "-")
"v";in case of dedicated repo the prefix is just a "v"
))
(defn version
"Determine the version for the project by dynamically interrogating the environment,
you can choose the \"maven\" or \"semver\" version scheme"
([] (version nil nil :scheme "semver"));default value is semver
([working-dir module-name & {:keys [scheme separator]
:or {scheme *scheme*}}]
(let [version-scheme-fn (version-scheme-fn (string/lower-case scheme))
state (git/working-copy-description working-dir :prefix (prefix working-dir module-name) :min-sha-length 4)]
(when-not version-scheme-fn
(throw (Exception. (str "No version scheme " scheme " found! version scheme currently supported are: \"maven\" or \"semver\" "))))
(when-not state
(log/warn "No Git data available in directory "working-dir"! is it a git repository?
is there a proper .git dir? if so is there any commits? return default starting version"))
(apply version-scheme-fn state))))
(defn invocation-context
"execution context: working-dir, module-name, version"
([{:keys [version-scheme module-name-override] :as options}] (invocation-context options nil))
([{:keys [version-scheme module-name-override] :as options} working-dir]
(let [version-scheme (or version-scheme *scheme*)
working-dir (or working-dir (str (pwd)))
module-name (module-name working-dir module-name-override)
version (version working-dir module-name :scheme version-scheme)]
(merge options
{:working-dir working-dir
:module-name module-name
:version version}))))
(defn tag
"in case of monorepo return the tag as the module name concatenated with the version"
[working-dir module-name version]
(str (prefix working-dir module-name) version))
(defn artefact-name
([] (artefact-name (pwd) nil))
([working-dir module-name & {:keys [scheme separator] :or {scheme *scheme*}}]
(str (prefix working-dir module-name) (version working-dir module-name :scheme scheme))))
(defn iso-now []
(let [tz (TimeZone/getTimeZone "UTC")
df (SimpleDateFormat. "yyyy-MM-dd'T'HH:mm:ss'Z'")]
(.setTimeZone df tz)
(.format df (Date.))))
(defn metadata-as-edn
"return a map of the repo metadata: version, name, path, etc."
[{:keys [working-dir module-name] :as invocation-context} version]
(let [tag (tag working-dir module-name version)]
{:module-name module-name
:tag tag
:version (str version)
:generated-at (iso-now);(git/tag-timestamp working-dir (git/last-sha working-dir))
:path (if-let [prefix (git/prefix working-dir)] prefix ".")}))
(defn metadata-as-code
[{:keys [working-dir namespace] :as invocation-context} version]
(let [{:keys [sha module-name path version tag generated-at]} (metadata-as-edn invocation-context version)]
(string/join "\n" [";; This code was automatically generated by the 'metav' library."
(str "(ns " namespace ")") ""
; (format "(def sha \"%s\")" sha)
(format "(def module-name \"%s\")" module-name)
(format "(def path \"%s\")" path)
(format "(def version \"%s\")" version)
(format "(def tag \"%s\")" tag)
(format "(def generated-at \"%s\")" generated-at)
""])))