Skip to content

Commit

Permalink
Run tests on GitHub Actions
Browse files Browse the repository at this point in the history
Expand testing from ubuntu only to also cover macOS and Windows.

Will follow up to complete clj-commons#392

Closes clj-commons#381
  • Loading branch information
lread committed May 18, 2022
1 parent 90255e7 commit 4d02908
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 0 deletions.
65 changes: 65 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Test

# temporary setup for testing on my forked branches
on:
push:
branches:
- 'lread-*'

jobs:
build:
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ ubuntu, macos, windows ]

name: ${{ matrix.os }}

steps:

- uses: actions/checkout@v3

- name: Clojure deps cache
uses: actions/cache@v3
with:
path: |
~/.m2/repository
key: ${{ runner.os }}-cljdeps-${{ hashFiles('project.clj') }}
restore-keys: ${{ runner.os }}-cljdeps-

- name: "Setup Java"
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'

- name: Install Clojure Tools
uses: DeLaGuardo/[email protected]
with:
bb: 'latest'
lein: 'latest'

- name: Tools versions
run: bb tools-versions

- name: Bring down deps
run: lein deps

- name: Launch Virtual Display (ubuntu)
if: matrix.os == 'ubuntu'
run: Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &

- name: Screen info (temporary mac)
if: matrix.os == 'macos'
run: system_profiler SPDisplaysDataType

- name: Run Tests (unbuntu)
if: matrix.os == 'ubuntu'
run: lein test
env:
DISPLAY: :99.0

- name: Run Tests (macos, windows)
if: matrix.os != 'ubuntu'
run: lein test
3 changes: 3 additions & 0 deletions bb.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{:paths ["script"]
:deps {doric/doric {:mvn/version "0.9.0"}}
:tasks {tools-versions {:task tools-versions/report :doc "report on tools versions"}}}
146 changes: 146 additions & 0 deletions script/tools_versions.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
(ns tools-versions
(:require [babashka.fs :as fs]
[babashka.tasks :as tasks]
[clojure.string :as string]
[doric.core :as doric]
[cheshire.core :as json]))

(def tools
[;; earlier versions of java used -version and spit version info to stderr
{:oses :all :name "Java" :type :bin :app "java" :args "-version" :shell-opts {:out :string :err :string :continue true}}
{:oses :all :name "Leiningen" :type :bin :app "lein"}
{:oses :all :name "Babashka" :type :bin :app "bb"}

{:oses [:unix] :name "Chrome" :type :bin :app "google-chrome"} ;; only handling nix for now
{:oses [:mac] :name "Chrome" :type :mac-app :app "Google Chrome"}
{:oses [:win] :name "Chrome" :type :win-package :app "Google Chrome"}
{:oses :all :name "Chrome Webdriver" :type :bin :app "chromedriver"}

{:oses [:unix] :name "Firefox" :type :bin :app "firefox"} ;; only handling nix for now
{:oses [:mac] :name "Firefox" :type :mac-app :app "Firefox"}
{:oses [:win] :name "Firefox" :type :win-package :app #"Mozilla Firefox .*"}
{:oses :all :name "Firefox Webdriver" :type :bin :app "geckodriver" :version-post-fn #(->> % string/split-lines first)}

{:oses [:mac] :name "Edge" :type :mac-app :app "Microsoft Edge"}
{:oses [:win] :name "Edge" :type :win-package :app "Microsoft Edge"}
{:oses [:win :mac] :name "Edge Webdriver" :type :bin :app "msedgedriver"}

{:oses [:mac] :name "Safari" :type :mac-app :app "Safari"}
{:oses [:mac] :name "Safari Webdriver" :type :bin :app "safaridriver"}])

(def tool-defaults {:shell-opts {:out :string :continue true}
:args "--version"
:version-post-fn identity})

(defn- get-os []
(let [os-name (string/lower-case (System/getProperty "os.name"))]
(condp re-find os-name
#"win" :win
#"mac" :mac
#"(nix|nux|aix)" :unix
:unknown)))

(defn- expected-on-this-os [{:keys [oses]}]
(or (= :all oses)
(some #{(get-os)} oses)))

(defn- version-cmd-result [shell-opts {:keys [out err exit]}]
(if (not (zero? exit))
(format "<exit code %d>" exit)
(cond-> ""
(= :string (:out shell-opts)) (str out)
(= :string (:err shell-opts)) (str err))))

(defn- table-multilines->rows
"Convert a seq of maps from [{:a \"one\n\two\" :b \"a\nb\nc\"}]
to: [{:a \"one\" :b \"a\"}
{:a \"two\" :b \"b\"}
{:a \"\" :b \"c\"}]
in preparation for printing with doric."
[results]
(reduce (fn [acc n]
(let [n (reduce-kv (fn [m k v]
(assoc m k (string/split-lines v)))
{}
n)
max-lines (apply max (map #(count (val %)) n))]
(concat acc
(for [ln (range max-lines)]
(reduce-kv (fn [m k _v]
(assoc m k (get (k n) ln "")))
{}
n)))))
[]
results))

(defn- windows-software-list*
"One way to get a list of installed software on Windows.
Seems like there are many many ways, but this also often gets the install
location which is interesting to report."
[]
(let [reg-keys ["\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*"
"\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*"]]
(->> (mapcat (fn [reg-key]
(-> (tasks/shell {:out :string :continue true}
"powershell"
"-command"
(format "Get-ItemProperty HKLM:%s | Select-Object DisplayName, DisplayVersion, InstallLocation | ConvertTo-Json"
reg-key))
:out
json/parse-string))
reg-keys))))

(def windows-software-list (memoize windows-software-list*))

(defmulti resolve-tool :type)

(defmethod resolve-tool :win-package
[{:keys [app]}]
(if-let [found-package (->> (windows-software-list)
(filter (fn [p]
(when-let [pname (get p "DisplayName")]
(if (string? app)
(= app pname)
(re-matches app pname)))))
first)]
{:app (get found-package "InstallLocation" "?")
:version (get found-package "DisplayVersion" "?")}
{:error (format "<windows package not found: %s>" app)}))

(defmethod resolve-tool :mac-app
[{:keys [app shell-opts version-post-fn]}]
(let [app-dir (format "/Applications/%s.app" app)]
(if (fs/exists? app-dir)
{:app app-dir
:version
(->> (tasks/shell shell-opts (format "defaults read '%s/Contents/Info' CFBundleShortVersionString" app-dir))
(version-cmd-result shell-opts)
version-post-fn)}
{:error (format "<mac app not found: %s>" app)})))

(defmethod resolve-tool :bin
[{:keys [app shell-opts args version-post-fn]}]
(if-let [found-bin (some-> (fs/which app {:win-exts ["com" "exe" "bat" "cmd" "ps1"]})
str)]
{:app found-bin
:version (->> (if (string/ends-with? found-bin ".ps1")
(tasks/shell shell-opts "powershell" "-command" found-bin args)
(tasks/shell shell-opts found-bin args))
(version-cmd-result shell-opts)
version-post-fn)}
{:error (format "<bin not found: %s>" app)}))

(defn report
"Report on tools versions based the the OS the script it is run from.
Currently informational only, should always return 0 unless, of course,
something exceptional happens."
[]
(->> (for [{:keys [name] :as t} (map #(merge tool-defaults %) tools)
:when (expected-on-this-os t)
:let [{:keys [error app version]} (resolve-tool t)]]
(if error
{:name name :version error}
{:name name :app app :version version}))
table-multilines->rows
(doric/table [:name :version :app])
println))

0 comments on commit 4d02908

Please sign in to comment.