|
7 | 7 | [clojure.tools.cli :refer [parse-opts]]
|
8 | 8 | [nl.jomco.apie.report :as report]
|
9 | 9 | [nl.jomco.apie.spider :as spider]
|
10 |
| - [ring.util.codec :as codec])) |
| 10 | + [ring.util.codec :as codec]) |
| 11 | + (:import java.net.URI)) |
11 | 12 |
|
12 | 13 | (defn- parse-header
|
13 | 14 | [s]
|
|
20 | 21 | [headers [k v]]
|
21 | 22 | (update-in headers [k] spider/merge-header-values v))
|
22 | 23 |
|
| 24 | +(defn- parse-seed |
| 25 | + [base-url s] |
| 26 | + (let [s (string/replace s base-url "") |
| 27 | + u (URI. s) |
| 28 | + q (.getRawQuery u)] |
| 29 | + (cond-> {:method "get" |
| 30 | + :path (.getRawPath u)} |
| 31 | + q |
| 32 | + (assoc :query-params |
| 33 | + ;; FIXME: this fails when param has no value: "/foo?bar&this=that" |
| 34 | + (into {} |
| 35 | + (map (fn [p] |
| 36 | + (mapv codec/percent-decode (string/split p #"=" 2))) |
| 37 | + (string/split q #"[&;]"))))))) |
| 38 | + |
23 | 39 | (def cli-options
|
24 | 40 | [["-u" "--base-url BASE-URL" "Base URL of service to validate."
|
25 | 41 | :missing "BASE-URL is missing"]
|
|
58 | 74 | ["-v" "--version"
|
59 | 75 | "Print version and exit."
|
60 | 76 | :id :print-version?]
|
| 77 | + [nil "--help" |
| 78 | + "Print usage information and exit."] |
61 | 79 | ["-a" "--basic-auth 'USER:PASS'" "Send basic authentication header."
|
62 | 80 | :default nil
|
63 | 81 | :parse-fn (fn [s]
|
|
67 | 85 | {:user user
|
68 | 86 | :pass pass}))]])
|
69 | 87 |
|
| 88 | +(defn usage |
| 89 | + [summary] |
| 90 | + (->> ["Apie 🙈 Service Validator" |
| 91 | + "" |
| 92 | + "A command-line tool to spider API endpoints and validate" |
| 93 | + "against OpenAPI v3 specs." |
| 94 | + "" |
| 95 | + "Usage: apie OPTIONS SEEDS*" |
| 96 | + "" |
| 97 | + "OPTIONS:" |
| 98 | + summary |
| 99 | + "" |
| 100 | + "If SEEDS are not provided, uses seeds in profile." |
| 101 | + "" |
| 102 | + "To validate all reachable paths from a service, use" |
| 103 | + "apie --profile=some/profile.edn --base-url=http://example.com" |
| 104 | + "" |
| 105 | + "To validate one specific path, use" |
| 106 | + "apie -M1 --profile=some/profile.edn --base-url=http://example.com '/some/path?param=val'"] |
| 107 | + (string/join "\n"))) |
| 108 | + |
70 | 109 | (defn version
|
71 | 110 | "Return app version"
|
72 | 111 | []
|
|
144 | 183 |
|
145 | 184 | (defn -main
|
146 | 185 | [& args]
|
147 |
| - (let [{:keys [errors summary options]} (parse-opts args cli-options)] |
| 186 | + (let [{:keys [errors summary options arguments]} (parse-opts args cli-options)] |
| 187 | + (when (:help options) |
| 188 | + (println (usage summary)) |
| 189 | + (System/exit 0)) |
148 | 190 | (when (:print-version? options)
|
149 | 191 | (println (version))
|
150 | 192 | (System/exit 0))
|
151 | 193 | (when (seq errors)
|
152 | 194 | (run! println errors)
|
153 | 195 | (println summary)
|
154 | 196 | (System/exit 1))
|
155 |
| - (main options))) |
| 197 | + |
| 198 | + (let [options (if (seq arguments) |
| 199 | + (assoc options :seeds (map #(parse-seed (:base-url options) %) arguments)) |
| 200 | + options)] |
| 201 | + (main options)))) |
156 | 202 |
|
157 | 203 | (comment
|
158 | 204 |
|
|
0 commit comments