Browse files

Heroku template instantiated

  • Loading branch information...
0 parents commit 21f7beaa80166bc6fde1c21073aaf326116cb47d @skuro committed Nov 17, 2012
Showing with 208 additions and 0 deletions.
  1. +9 −0 .gitignore
  2. +1 −0 Procfile
  3. +81 −0 README.md
  4. +16 −0 project.clj
  5. +21 −0 resources/404.html
  6. +20 −0 resources/500.html
  7. +54 −0 src/chai/web.clj
  8. +6 −0 test/chai/web_test.clj
9 .gitignore
@@ -0,0 +1,9 @@
+pom.xml
+*jar
+/classes/
+/.lein-deps-sum
+/.lein-failures
+/.lein-env
+/checkouts
+/.env
+/target
1 Procfile
@@ -0,0 +1 @@
+web: lein with-profile production trampoline run -m chai.web
81 README.md
@@ -0,0 +1,81 @@
+# chai
+
+A [Heroku](http://www.heroku.com) web app using Compojure.
+
+This generated project has a few basics set up beyond the bare Compojure defaults:
+
+* Cookie-backed session store
+* Stack traces when in development
+* Environment-based config via [enviorn](https://github.com/weavejester/environ)
+* [HTTP-based REPL debugging](https://devcenter.heroku.com/articles/debugging-clojure) via [drawbridge](https://github.com/cemerick/drawbridge)
+
+## Usage
+
+To start a local web server for development you can either eval the
+commented out forms at the bottom of `web.clj` from your editor or
+launch from the command line:
+
+ $ lein run -m chai.web
+
+Initialize a git repository for your project.
+
+ $ git init
+ $ git add .
+ $ git commit -m "Initial commit."
+
+You'll need the [heroku toolbelt](https://toolbelt.herokuapp.com)
+installed to manage the heroku side of your app. Once it's installed,
+get the app created:
+
+ $ heroku apps:create chai
+ Creating chai... done, stack is cedar
+ http://chai.herokuapp.com/ | git@heroku.com:chai.git
+ Git remote heroku added
+
+You can deploy the skeleton project immediately:
+
+ $ git push heroku master
+ Writing objects: 100% (13/13), 2.87 KiB, done.
+ Total 13 (delta 0), reused 0 (delta 0)
+
+ -----> Heroku receiving push
+ -----> Clojure app detected
+ -----> Installing Leiningen
+ Downloading: leiningen-2.0.0-preview7-standalone.jar
+ [...]
+ -----> Launching... done, v3
+ http://chai.herokuapp.com deployed to Heroku
+
+ To git@heroku.com:chai.git
+ * [new branch] master -> master
+
+It's live! Hit it with `curl`:
+
+ $ curl http://chai.herokuap.com
+ ["Hello" :from Heroku]
+
+The cookie-backed session store needs a session secret configured for encryption:
+
+ $ heroku config:add SESSION_SECRET=$RANDOM_16_CHARS
+
+## Remote REPL
+
+The [devcenter article](https://devcenter.heroku.com/articles/debugging-clojure)
+has a detailed explanation, but using the `repl` task from Leiningen
+2.x lets you connect a REPL to a remote process over HTTP. The first
+step is setting up credentials:
+
+ $ heroku config:add REPL_USER=[...] REPL_PASSWORD=[...]
+
+Then you can launch the REPL:
+
+ $ lein repl :connect http://$REPL_USER:$REPL_PASSWORD@myapp.herokuapp.com/repl
+
+Everything you enter will be evaluated remotely in the running dyno,
+which can be very useful for debugging or inspecting live data.
+
+## License
+
+Copyright © 2012 FIXME
+
+Distributed under the Eclipse Public License, the same as Clojure.
16 project.clj
@@ -0,0 +1,16 @@
+(defproject chai "1.0.0-SNAPSHOT"
+ :description "FIXME: write description"
+ :url "http://chai.herokuapp.com"
+ :license {:name "FIXME: choose"
+ :url "http://example.com/FIXME"}
+ :dependencies [[org.clojure/clojure "1.4.0"]
+ [compojure "1.1.1"]
+ [ring/ring-jetty-adapter "1.1.0"]
+ [ring/ring-devel "1.1.0"]
+ [ring-basic-authentication "1.0.1"]
+ [environ "0.2.1"]
+ [com.cemerick/drawbridge "0.0.6"]]
+ :min-lein-version "2.0.0"
+ :plugins [[environ/environ.lein "0.2.1"]]
+ :hooks [environ.leiningen.hooks]
+ :profiles {:production {:env {:production true}}})
21 resources/404.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Page Not Found</title>
+ <style type="text/css">
+ body {
+ font-family: "Ubuntu Light", helvetica, sans-serif;
+ width: 960px;
+ margin: 3em auto;
+ }
+ </style>
+</head>
+<body>
+ <!-- TODO: replace this with something that matches your app style -->
+ <h1>Page Not Found</h1>
+ <p>There's no page at the address you requested. If you entered it
+ by hand, check for typos. If you followed a link or a bookmark,
+ it may need to be updated.</p>
+</body>
+</html>
20 resources/500.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Error</title>
+ <style type="text/css">
+ body {
+ font-family: "Ubuntu Light", helvetica, sans-serif;
+ width: 960px;
+ margin: 3em auto;
+ }
+ </style>
+</head>
+<body>
+ <!-- TODO: replace this with something that matches your app style -->
+ <h1>Error</h1>
+ <p>Something went wrong. Try again, and if the problem persists
+ please contact support.</p>
+</body>
+</html>
54 src/chai/web.clj
@@ -0,0 +1,54 @@
+(ns chai.web
+ (:require [compojure.core :refer [defroutes GET PUT POST DELETE ANY]]
+ [compojure.handler :refer [site]]
+ [compojure.route :as route]
+ [clojure.java.io :as io]
+ [ring.middleware.stacktrace :as trace]
+ [ring.middleware.session :as session]
+ [ring.middleware.session.cookie :as cookie]
+ [ring.adapter.jetty :as jetty]
+ [ring.middleware.basic-authentication :as basic]
+ [cemerick.drawbridge :as drawbridge]
+ [environ.core :refer [env]]))
+
+(defn- authenticated? [user pass]
+ ;; TODO: heroku config:add REPL_USER=[...] REPL_PASSWORD=[...]
+ (= [user pass] [(env :repl-user false) (env :repl-password false)]))
+
+(def ^:private drawbridge
+ (-> (drawbridge/ring-handler)
+ (session/wrap-session)
+ (basic/wrap-basic-authentication authenticated?)))
+
+(defroutes app
+ (ANY "/repl" {:as req}
+ (drawbridge req))
+ (GET "/" []
+ {:status 200
+ :headers {"Content-Type" "text/plain"}
+ :body (pr-str ["Hello" :from 'Heroku])})
+ (ANY "*" []
+ (route/not-found (slurp (io/resource "404.html")))))
+
+(defn wrap-error-page [handler]
+ (fn [req]
+ (try (handler req)
+ (catch Exception e
+ {:status 500
+ :headers {"Content-Type" "text/html"}
+ :body (slurp (io/resource "500.html"))}))))
+
+(defn -main [& [port]]
+ (let [port (Integer. (or port (env :port) 5000))
+ ;; TODO: heroku config:add SESSION_SECRET=$RANDOM_16_CHARS
+ store (cookie/cookie-store {:key (env :session-secret)})]
+ (jetty/run-jetty (-> #'app
+ ((if (env :production)
+ wrap-error-page
+ trace/wrap-stacktrace))
+ (site {:session {:store store}}))
+ {:port port :join? false})))
+
+;; For interactive development:
+;; (.stop server)
+;; (def server (-main))
6 test/chai/web_test.clj
@@ -0,0 +1,6 @@
+(ns chai.web-test
+ (:require [clojure.test :refer :all]
+ [chai.web :refer :all]))
+
+(deftest first-test
+ (is false "Tests should be written"))

0 comments on commit 21f7bea

Please sign in to comment.