Skip to content

Instantly share code, notes, and snippets.

@practicalli-johnny
Created October 17, 2022 11:48
Show Gist options
  • Save practicalli-johnny/904b5d9ae398aaec2649b50b98a709eb to your computer and use it in GitHub Desktop.
Save practicalli-johnny/904b5d9ae398aaec2649b50b98a709eb to your computer and use it in GitHub Desktop.
Custom Clojure user namespace to be loaded during development to provide tools for a REPL driven workflow
;; --------------------------------------------------
;; REPL Driven Development namespace
;; - start REPL with `:env/dev` alias to include this namespace
;;
;; - Commands to start, restart, fraud system with Integrant REPL
;; & view system configuration
;; - Test API endpoints
;; - Hotload libraries into a running REPL process
;; - Inspect evaluation results with Portal
;; --------------------------------------------------
(ns user
(:require
[system :refer [config go halt
reset reset-all system]] ; System component commands
[com.brunobonacci.mulog :as mulog] ; Event Logging
[portal.api :as inspector] ; Data inspector
[clojure.pprint :as pprint] ; Human readable data structures
[clojure.tools.deps.alpha.repl :refer [add-libs]] ; hotload libraries
;; Testing Routes and Handlers in the REPL
[muuntaja.core :as transformer]
[org.httpkit.fake :as http-fake]))
;; User feedback on REPL startup
(println "--------- system ---------")
(println "Using Java vendor version" (System/getProperty "java.vendor.version") "from" (System/getProperty "java.vendor"))
(println "Loading dev namespace for Integrant REPL")
(println "---------- Help ----------")
(println "(go) to start the Fraud service")
(println "(reset) to reload code changes (try evaluating code first)")
(println "(require 'user :reload) if reset fails, or quit the repl")
(println "(config) to view the application configuration")
(println "(system) to view the configuration currently being used by the system")
(println "(halt) to stop the Fraud service")
(println ":repl/quit to quit the REPL session")
;; set event global context - information added to every event for REPL workflow
(mulog/set-global-context! {:app-name "Billie Fraud API Service",
:version "0.1.0", :env "dev"})
(comment
;;--------------------------------------------------
;; Manage system components
;; Prepare and start the system using the :dev profile or specify the environment
(go)
(go :test)
;; Reload changed and new source code files and restart the system
;; (require 'user :reload) if code fails to compile to load custom user namespace
(reset)
(reset :dev)
;; Reload all source code files on the Classpath and restart the system
(reset-all)
(reset-all :dev)
;; Return the current Integrant configuration (already parsed by environment)
(config)
;; Show the running system configuration, returns nil when system not running
(system)
;; Shutdown the system using the app-server object reference in the Integrant state
(halt)
;; Pretty print the system state in the REPL
(pprint/pprint system)
;;--------------------------------------------------
;;--------------------------------------------------
;; Testing API routes
;; A reference to the running handler, so a request map can be sent and get a result
(def app (-> (system) :billie.fraud.service/router))
;; Fraud API service status string
;; Raw response from request
(app {:request-method :get :uri "/system-admin/status"})
;; Decoded response
(let [response (app {:request-method :get :uri "/system-admin/status"})]
{:status (response :status)
:body (transformer/decode-response-body response)
:headers (response :headers)})
;; Print namespaced maps as fully qualified keys within a hash-map
;; {:fraud/status ""} rather than #:fraud{:status ""}
(set! *print-namespace-maps* false)
;;--------------------------------------------------
;;--------------------------------------------------
;; Hotload libraries as dependencies without restarting the REPl
;; Example - hotload the hiccup library
(add-libs '{hiccup/hiccup {:mvn/version "2.0.0-alpha2"}
ring/ring-devel {:mvn/version "1.9.5"}})
(add-libs '{http-kit.fake/http-kit.fake {:mvn/version "0.2.2"}})
(add-libs '{metosin/reitit-dev {:mvn/version "0.5.18"}})
;;--------------------------------------------------
;;--------------------------------------------------
;; Data Inspectors
;; Open a portal inspector window
(inspector/open)
;; Add portal as a tap> target
(inspector/tap)
;; Example tap> call - results sent to portal window
;; select porta.vierw/tree to see resulting hash-map
(tap> (for [value (range 10)] {(random-uuid) value}))
;; Inspect response in tap> source, i.e. portal
;; Echo request details - supports request debugging
(tap>
(app {:request-method :get :uri "/system-admin/echo-request"}))
;; Clear all values in the portal inspector window
(inspector/clear)
;; Close the inspector
(inspector/close)
;;--------------------------------------------------
;;--------------------------------------------------
;; JVM Host Environment Check
(System/getProperty "java.version")
(System/getProperty "java.vendor.version")
(System/getProperty "java.vendor")
(System/getProperty "java.vendor.url")
;; Get system path as a vector of individual paths (eval using pprint)
#_(clojure.string/split (System/getProperty "java.class.path") #":")
;; Get all available properties
(System/getProperties)
;;--------------------------------------------------
#_()) ; End of rich comment block
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment