Skip to content

Commit

Permalink
fix #49 by improving tool invocation (#53)
Browse files Browse the repository at this point in the history
Signed-off-by: Sean Corfield <[email protected]>
  • Loading branch information
seancorfield authored Jan 13, 2024
1 parent 9b60585 commit 151ca1d
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# CHANGELOG

* v5.0.2 in progress
* Address [#49](https://github.com/clj-holmes/clj-watson/issues/49) by improving the `-T` invocation to support short names, symbols for strings, and all the defaults.
* Address [#48](https://github.com/clj-holmes/clj-watson/issues/48) by updating all of the project dependencies, including DependencyCheck to 9.0.8.
* Address [#47](https://github.com/clj-holmes/clj-watson/issues/47) by printing out the optional properties read from the `clj-watson.properties` file.
* Documentation improvements.
Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,19 @@ clojure -Tclj-watson scan :deps-edn-path '"deps.edn"' :output '"stdout"'
clojure -Tclj-watson scan '{:deps-edn-path "deps.edn" :output "stdout"}'
```

(this is somewhat verbose now but it will be improved over the next few releases)
The tool option keywords match the long-form CLI option names (see below)
but the abbreviations are also supported. In addition, any string option may
be specified as a bare Clojure symbol (if it is legally representable as such),
which means the above command-line can be simplified to just:

```bash
clojure -Tclj-watson scan :p deps.edn
```

`:output` can be omitted because it defaults to `stdout`, and `:deps-edn-path`
can be shortened to `:p` (matching the `-p` short form of `--deps-edn-path`).

> Note: `:aliases` (or `:a`) should be specified as a vector of keywords (or symbols), e.g., `:a '[:foo :bar]`, whereas it would be specified multiple times (as strings) in the regular CLI, `-a foo -a bar`.
# How it works

Expand Down Expand Up @@ -178,8 +190,13 @@ EDN-style options for the CLI tool which can be a bit unwieldy as present:

```bash
clojure -Tclj-watson scan '{:output "stdout" :fail-on-result true :deps-edn-path "deps.edn" :suggest-fix true :aliases ["*"] :database-strategy "dependency-check"}'
# or:
clojure -Tclj-watson scan :f true :p deps.edn :s true :a '[*]'
```

Both `:output` (`:o`) and `:database-strategy` (`:t`) can be omitted because
they default to `"stdout"` and `"dependency-check"` respectively.

In addition to the CLI tool install, shown above, it can also be invoked
directly via the Clojure CLI, by specifying `clj-watson` as a dependency
via `-Sdeps`:
Expand Down
45 changes: 5 additions & 40 deletions src/clj_watson/cli.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,11 @@
(:gen-class)
(:require
[cli-matic.core :as cli]
[clj-watson.cli-spec :refer [CONFIGURATION]]
[clj-watson.entrypoint :as entrypoint]))

(def CONFIGURATION
{:app {:command "clj-watson"
:description "run clj-holmes" :version (System/getProperty "clj-watson.version")}
:commands [{:command "scan"
:description "Performs a scan on a deps.edn file"
:opts [{:option "deps-edn-path" :short "p"
:type :string
:default :present
:as "path of deps.edn to scan."}
{:option "output" :short "o"
:type #{"json" "edn" "stdout" "stdout-simple" "sarif"} ; keep stdout type to avoid break current automations
:default "stdout"
:as "Output type."}
{:option "aliases" :short "a"
:type :string
:multiple true
:as "Specify a alias that will have the dependencies analysed alongside with the project deps.It's possible to provide multiple aliases. If a * is provided all the aliases are going to be analysed."}
{:option "dependency-check-properties" :short "d"
:type :string
:default nil
:as "[ONLY APPLIED IF USING DEPENDENCY-CHECK STRATEGY] Path of a dependency-check properties file. If not provided uses resources/dependency-check.properties."}
{:option "clj-watson-properties" :short "w"
:type :string
:default nil
:as "[ONLY APPLIED IF USING DEPENDENCY-CHECK STRATEGY] Path of an additional, optional properties file."}
{:option "database-strategy" :short "t"
:type #{"dependency-check" "github-advisory"}
:default "dependency-check"
:as "Vulnerability database strategy."}
{:option "suggest-fix" :short "s"
:type :with-flag
:default false
:as "Suggest a new deps.edn file fixing all vulnerabilities found."}
{:option "fail-on-result" :short "f"
:type :with-flag
:default false
:as "Enable or disable fail if results were found (useful for CI/CD)."}]
:runs entrypoint/scan}]})

(defn -main [& args]
(cli/run-cmd args CONFIGURATION))
(cli/run-cmd args
(update-in CONFIGURATION
[:commands 0]
(assoc :runs entrypoint/scan))))
76 changes: 76 additions & 0 deletions src/clj_watson/cli_spec.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
(ns clj-watson.cli-spec)

(def CONFIGURATION
{:app {:command "clj-watson"
:description "run clj-holmes" :version (System/getProperty "clj-watson.version")}
:commands [{:command "scan"
:description "Performs a scan on a deps.edn file"
:opts [{:option "deps-edn-path" :short "p"
:type :string
:default :present
:as "path of deps.edn to scan."}
{:option "output" :short "o"
:type #{"json" "edn" "stdout" "stdout-simple" "sarif"} ; keep stdout type to avoid break current automations
:default "stdout"
:as "Output type."}
{:option "aliases" :short "a"
:type :string
:multiple true
:as "Specify a alias that will have the dependencies analysed alongside with the project deps. It's possible to provide multiple aliases. If a * is provided all the aliases are going to be analysed."}
{:option "dependency-check-properties" :short "d"
:type :string
:default nil
:as "[ONLY APPLIED IF USING DEPENDENCY-CHECK STRATEGY] Path of a dependency-check properties file. If not provided uses resources/dependency-check.properties."}
{:option "clj-watson-properties" :short "w"
:type :string
:default nil
:as "[ONLY APPLIED IF USING DEPENDENCY-CHECK STRATEGY] Path of an additional, optional properties file."}
{:option "database-strategy" :short "t"
:type #{"dependency-check" "github-advisory"}
:default "dependency-check"
:as "Vulnerability database strategy."}
{:option "suggest-fix" :short "s"
:type :with-flag
:default false
:as "Suggest a new deps.edn file fixing all vulnerabilities found."}
{:option "fail-on-result" :short "f"
:type :with-flag
:default false
:as "Enable or disable fail if results were found (useful for CI/CD)."}]
;; injected by clj-watson.cli to avoid circular dependency:
:runs nil #_entrypoint/scan}]})

(def DEFAULTS
(into {}
(map (fn [{:keys [option default]}]
[(keyword option) (when-not (= default :present) default)]))
(-> CONFIGURATION :commands first :opts)))

(def ABBREVIATIONS
(into {}
(map (fn [{:keys [option short]}]
[(keyword short) (keyword option)]))
(-> CONFIGURATION :commands first :opts)))

(defn clean-options
"Implement defaults for tool invocation and allow for abbreviations and
symbols as strings."
[opts]
(into DEFAULTS
(comp (map (fn [[k v]] ; expand abbreviations first:
(if (and (contains? ABBREVIATIONS k)
(not (contains? opts (get ABBREVIATIONS k))))
[(get ABBREVIATIONS k) v]
[k v])))
(map (fn [[k v]] ; supply defaults:
(if (contains? DEFAULTS k)
[k (if (some? v) v (get DEFAULTS k))]
[k v])))
(map (fn [[k v]]
[k (if (symbol? v) (str v) v)])))
opts))

(comment
(clean-options {:p 'resources/deps.edn
:database-strategy 'dependency-check
:s true}))
2 changes: 1 addition & 1 deletion src/clj_watson/controller/dependency_check/scanner.clj
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
(if additional-properties-file-path
(->> add-props (.mergeProperties settings))
(some->> add-props slurp .getBytes ByteArrayInputStream. (.mergeProperties settings))))
(println "No additional properties found."))
(println "No additional properties found.\n"))
settings))

(defn ^:private build-engine [dependency-check-properties clj-watson-properties]
Expand Down
7 changes: 5 additions & 2 deletions src/clj_watson/entrypoint.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns clj-watson.entrypoint
(:require
[clj-watson.adapter.config :as adapter.config]
[clj-watson.cli-spec :as cli-spec]
[clj-watson.controller.dependency-check.scanner :as controller.dc.scanner]
[clj-watson.controller.dependency-check.vulnerability :as controller.dc.vulnerability]
[clj-watson.controller.deps :as controller.deps]
Expand Down Expand Up @@ -38,8 +39,10 @@
(defmethod scan* :default [opts]
(scan* (assoc opts :database-strategy "dependency-check")))

(defn scan [{:keys [fail-on-result output deps-edn-path] :as opts}]
(let [vulnerabilities (scan* opts)
(defn scan [opts]
(let [opts (cli-spec/clean-options opts)
{:keys [fail-on-result output deps-edn-path]} opts
vulnerabilities (scan* opts)
contains-vulnerabilities? (->> vulnerabilities
(map (comp empty? :vulnerabilities))
(some false?))]
Expand Down

0 comments on commit 151ca1d

Please sign in to comment.