All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.jlangch.venice.venice.venice Maven / Gradle / Ivy

;; -----------------------------------------------------------------------------
;; Venice shell
;; -----------------------------------------------------------------------------
;; This Venice shell is started by a launcher script:
;;   venice.sh     MacOSX & Linux
;;   venice.bat    Windows
;;
;; On MacOSX / Linux the launcher script looks like:
;;
;; cd /Users/juerg/Desktop/scripts/
;; 
;; ${JAVA_8_HOME}/bin/java \
;;   -server \
;;   -cp "lib:libs/*" com.github.jlangch.venice.Launcher \
;;   -Xmx2G \
;;   -XX:-OmitStackTraceInFastThrow \
;;   -Dvenice.repl.home=${VENICE_REPL_HOME} \
;;   -colors \
;;   -macroexpand \
;;   -app-repl venice.venice
;; -----------------------------------------------------------------------------

(load-module :gradlew)
(load-module :ansi)
(load-module :java)

(import :com.github.jlangch.venice.EofException)


;; see https://www.ascii-art-generator.org/ with font "standard"
(defonce logo 
          """
          __    __         _
          \\ \\  / /__ _ __ (_) ___ ___
           \\ \\/ / _ \\ '_ \\| |/ __/ _ \\ 
            \\  /  __/ | | | | (_|  __/
             \\/ \\___|_| |_|_|\\___\\___|
                
          """ )

(defonce COLOR_THEMES {
  :light { :logo     "[38;5;33m"
           :status   "[38;5;64m"
           :result   "[38;5;20m"
           :stdout   "[38;5;243m"
           :stderr   "[38;5;208m"
           :debug    "[38;5;29m"
           :warning  "[38;5;208m"
           :error    "[38;5;196m" }

  :dark  { :logo     "[38;5;33m"
           :status   "[38;5;64m"
           :result   "[38;5;20m"
           :stdout   "[38;5;243m"
           :stderr   "[38;5;208m"
           :debug    "[38;5;29m"
           :warning  "[38;5;208m"
           :error    "[38;5;196m" } } )



;; -----------------------------------------------------------------------------
;; Configuration                                                               -
;; -----------------------------------------------------------------------------

(defonce proj-name "venice")  ;; Venice Git/Eclipse project name

(defonce proj-home (str/strip-end (system-env :VENICE_PROJECT_HOME) "/"))
(defonce repl-home (str/strip-end (system-env :VENICE_REPL_HOME) "/"))

;; Java 8 is mandatory for "./gradlew eclipse", the Eclipse Venice project must
;; be based on Java 8!
(defonce java-8-home (str/strip-end (system-env :JAVA_8_HOME) "/"))
(defonce java-home java-8-home)

(defonce sonatype-user "xxxxxx")

(defonce cmd-line-prompt (str "vshell> "))

(defonce gradle-std-options ["--warning-mode=all" 
                             "--console=plain" 
                             "--stacktrace"
                             ;; "--info"
                             ;; "--debug"
                             "-Dorg.gradle.java.home=\"~{java-home}\""])

(defonce display-status-bar? false)



;; -----------------------------------------------------------------------------
;; Commands                                                                    -
;; -----------------------------------------------------------------------------

(defn exit []
  (printlnc :error "Terminating shell...")
  (sleep 600)
  (throw (ex :EofException "exit")))

(defn deploy []
  ;; deploy the Venice jar to REPL
  (let [repl-libs-dir (io/file repl-home "libs")
        proj-libs-dir (io/file proj-home "build/libs")]
    (io/delete-files-glob  repl-libs-dir "venice-*.jar")
    (io/copy-files-glob proj-libs-dir repl-libs-dir "venice-*.jar")))
 
(defn publish [pgp-key sonatype-pwd]
  (assert (some? pgp-key) "Please provide the PGP key ID (e.g. 0000AAAA)!")
  (assert (some? sonatype-pwd) "Please provide the Sonatype password!")
  (assert (not-match? sonatype-user "[x?]*") "Please configure the Sonatype user!")
  (gradle-tasks "clean" 
                "shadowJar" 
                "publish"
                "-Dorg.gradle.internal.publish.checksums.insecure=true"
                "-Dorg.gradle.internal.http.socketTimeout=60000"
                "-Dorg.gradle.internal.http.connectionTimeout=60000"
                "-Psigning.gnupg.keyName=\"~{pgp-key}\""
                "-PsonatypeUsername=\"~{sonatype-user}\""
                "-PsonatypePassword=\"~{sonatype-pwd}\""))

(defn gradle-tasks [& args]
  (apply gradlew/run* proj-home 
                      (partial printlnc :stdout)  
                      (partial printlnc :stderr)
                      (concat gradle-std-options args)))


;; -----------------------------------------------------------------------------
;; REPL launcher utils                                                         -
;; -----------------------------------------------------------------------------

(defn- start-repl [java-major]
  (println  "Starting new REPL: (~{repl-home})")
  (println)
  (sh/open (repl-script-path java-major)))

(defn- repl-script-path [java-major]
  (let [base-name (case (to-long java-major)
                     8  "repl"
                    11  "replJava11"
                    17  "replJava17"
                    21  "replJava21"
                        "repl")]
    (case (os-type)
      :mac-osx (str repl-home "/" base-name ".sh")
      :linux   (str repl-home "/" base-name ".sh")
      :windows (str repl-home "/" base-name ".bat"))))

(defn- to-long [s]
  (if (and (string? s) (match? s "[1-9][0-9]*")) (long s) nil)) 


;; -----------------------------------------------------------------------------
;; Util                                                                        -
;; -----------------------------------------------------------------------------

(defn fatal-error-and-exit [msg]
  (println)
  (printlnc :error msg)
  (println)
  (printlnc :error "")
  (println)
  (repl/wait-any-key-pressed)
  (throw (ex :EofException "exit")))

(defn invalid-cmd [msg]
  (printlnc :warning msg))

(defn display-welcome-msg []
  (docoll #(printlnc-bold :logo %) (str/split-lines logo)))

(defn show-color-theme []
  (doseq [code [:logo :status :result :stdout :stderr :warning :error]]
         (printlnc code (name code))))

(defn printlnc [color-code text]
  (println (ansi/style (str text) (ansi-color color-code))))

(defn printlnc-bold [color-code text]
  (println (ansi/style (str text) :bold (ansi-color color-code))))

(defn ansi-color [code]
  (code ((repl/color-theme) COLOR_THEMES (:light COLOR_THEMES)) :stdout))

(defn help []
  (println
    """
    ----------------------------------------------------------------------------
    Help
    ----------------------------------------------------------------------------
    b|build        build the Venice project
    r|rebuild      build, deploy, and start a Venice console
    s|start        start the Venice console
    T|tests        run the Venice unit tests
    t|task t1 tN   run one or more Venice project Gradle tasks
    c|cheatsheet   generate the Venice cheatsheet
    P|pdfdoc       show the cheat sheet PDF
    d|dependencies list the Venice dependencies
    e|eclipse      update the Eclipse project classpath
    p|publish k p  publish Venice artefacts, requires pgp-key & password
    C|colors       print the color theme
    i|info         display the configuration
    h|!|help       display the help
    q|quit         quit the shell
    x|exit         quit the shell

    """))

(defn display-info []
  (println
    """
    Configuration:
       Gradle:           ~(gradlew/version proj-home)
       Java version:     ~(java-version)
       User home:        ~(io/user-home-dir)
       Working dir:      ~(io/user-dir)
       Project home:     ~{proj-home}
       Build Java 8:     ~{java-8-home}
       Build Java 11:    ~{java-11-home}
       Color theme:      ~(repl/color-theme)
       Terminal:         [~(repl/term-cols) x ~(repl/term-rows)]

    """))

(defn display-status-bar []
  (when display-status-bar?
    (let [cols  (repl/term-cols)
          left  (str/format "%s" (version))
          right ""
          delim (str/repeat "-" (- cols 8 (count left) (count right)))]
      (printlnc :status "-- ~{left} ~{delim} ~{right} --"))))

(defn run-command [cmd & args]
  (cond
    (nil? cmd)                    nil
    (match? cmd "b|build")        (gradle-tasks "clean" "shadowJar")
    (match? cmd "r|rebuild")      (do (gradle-tasks "clean" "shadowJar")
                                      (deploy)
                                      (start-repl (first args)))
    (match? cmd "s|start")        (start-repl (first args))
    (match? cmd "c|cheatsheet")   (gradle-tasks "cheatsheet")
    (match? cmd "cp")             (do (gradle-tasks "cheatsheet")
                                      (sh/open (io/file proj-home "cheatsheet.pdf")))
    (match? cmd "P|pdfdoc")       (sh/open (io/file proj-home "cheatsheet.pdf"))
    (match? cmd "d|dependencies") (gradle-tasks "dependencies")
    (match? cmd "e|eclipse")      (gradle-tasks "eclipse")
    (match? cmd "T|tests")        (gradle-tasks "clean" "test")
    (match? cmd "p|publish")      (publish (first args) (second args))
    (match? cmd "t|task")         (apply gradle-tasks args)
    (match? cmd "C|colors")       (show-color-theme)
    (match? cmd "i|info")         (display-info)
    (match? cmd "h|!|help")       (help)
    (match? cmd "x|exit")         (exit)
    (match? cmd "q|quit")         (exit)
    :else                         (printlnc :warning "Invalid command: ~{cmd}")))

(defn split-command [cmd]
  (let [c (str/trim-to-nil cmd)]
    (if (some? c)
      (->> (regex/matcher "([^\"]\\S*|\".+?\")\\s*" c)
           (regex/find-all)
           (map str/trim-to-nil)
           (filter some?)
           (map str/double-unquote))
      [nil])))

(defn handle-command [cmd]
  (try
    (apply run-command (split-command cmd))
    (display-status-bar)
    (catch :EofException ex 
      (throw ex))
    (catch :VncException ex 
      (printlnc :error (ex-venice-stacktrace ex)))
    (catch :java.lang.Exception ex 
      (printlnc :error (str "Error: " (:message ex))))))


;; -----------------------------------------------------------------------------
;; MAIN                                                                        -
;; -----------------------------------------------------------------------------

(when-not (io/exists-dir? proj-home)
  (fatal-error-and-exit "The Venice project dir '~{proj-home}' does not exist!"))

(when-not (io/exists-dir? repl-home)
  (fatal-error-and-exit "The REPL dir '~{repl-home}' does not exist!"))

(when-not (io/exists-dir? java-home)
  (fatal-error-and-exit "The JAVA home '~{java-home}' does not exist!"))

;; configure the REPL
(repl/prompt! cmd-line-prompt)
(repl/handler! handle-command)

(display-welcome-msg)
(display-status-bar)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy