diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..d9543aa --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: java $JVM_OPTS -cp target/grub-standalone.jar clojure.main -m grub.core --port $PORT production diff --git a/project.clj b/project.clj index b29102f..a57732a 100644 --- a/project.clj +++ b/project.clj @@ -12,9 +12,11 @@ [ring/ring-core "1.2.0"] [hiccup "1.0.4"] [prismatic/dommy "0.1.1"] - [com.novemberain/monger "1.5.0"]] + [com.novemberain/monger "1.5.0"] + [org.clojure/tools.cli "0.3.1"]] :profiles {:dev {:dependencies [[speclj "2.5.0"] [clj-webdriver "0.6.0"]]}} + :min-lein-version "2.0.0" :plugins [[lein-cljsbuild "0.3.2"] [lein-ring "0.8.6"] [speclj "2.5.0"]] @@ -30,4 +32,5 @@ :source-paths ["src/clj" "integration"] :test-paths ["spec/clj"] :ring {:handler grub.core/app} + :uberjar-name "grub-standalone.jar" :main grub.core) diff --git a/src/clj/grub/core.clj b/src/clj/grub/core.clj index f133b5c..0f47c8e 100644 --- a/src/clj/grub/core.clj +++ b/src/clj/grub/core.clj @@ -11,7 +11,8 @@ [org.httpkit.server :as httpkit] [hiccup [page :refer [html5]] - [page :refer [include-js include-css]]])) + [page :refer [include-js include-css]]] + [clojure.tools.cli :refer [parse-opts]])) (def js-file (atom "/js/grub_dev.js")) @@ -45,7 +46,6 @@ (def integration-test-port 3456) (defn start-server [port] - (println (str "Starting server on localhost:" port)) (httpkit/run-server app {:port port})) (defn run-integration-test [] @@ -53,19 +53,60 @@ (integration-test/run integration-test-port) (stop-server))) -(defn start-production-server [] +(defn start-production-server [port] (reset! js-file "/js/grub.js") (let [db-chan (db/connect-production-database)] (ws/pass-received-events-to-clients-and-db db-chan) - (start-server default-port))) + (println (str "Starting production server on localhost:" port)) + (start-server port))) -(defn start-development-server [] +(defn start-development-server [port] (let [db-chan (db/connect-development-database)] (ws/pass-received-events-to-clients-and-db db-chan) - (start-server default-port))) + (println (str "Starting development server on localhost:" port)) + (start-server port))) + +(defn usage [options-summary] + (->> ["Usage: grub [options] action" + "" + "Options:" + options-summary + "" + "Actions:" + " dev[elopment] Start development server" + " prod[uction] Start production server" + " integration Run integration tests"] + (clojure.string/join \newline))) + +(def cli-options + ;; An option with a required argument + [["-p" "--port PORT" "Port number" + :default default-port + :parse-fn #(Integer/parseInt %) + :validate [#(< 0 % 0x10000) "Must be a number between 0 and 65536"]] + ;; A boolean option defaulting to nil + ["-h" "--help"]]) + +(defn error-msg [errors] + (str "The following errors occurred while parsing your command:\n\n" + (clojure.string/join \newline errors))) + +(defn exit [status msg] + (println msg) + (System/exit status)) (defn -main [& args] - (cond - (some #(= % "integration") args) (run-integration-test) - (some #(= % "production") args) (start-production-server) - :else (start-development-server))) + (let [{:keys [options arguments errors summary]} (parse-opts args cli-options)] + ;; Handle help and error conditions + (cond + (:help options) (exit 0 (usage summary)) + (not= (count arguments) 1) (exit 1 (usage summary)) + errors (exit 1 (error-msg errors))) + ;; Execute program with options + (case (first arguments) + "development" (start-development-server (:port options)) + "dev" (start-development-server (:port options)) + "production" (start-production-server (:port options)) + "prod" (start-production-server (:port options)) + "integration" (run-integration-test) + (exit 1 (usage summary)))))