lein new duct

next
Marcin Kulik 8 years ago
parent 75143edddf
commit af35483f2d

16
.gitignore vendored

@ -23,10 +23,16 @@ public/uploads/*
.rbx
.env
/.dir-locals.el
/.lein-env
/.lein-repl-history
/target
/classes
/checkouts
pom.xml
pom.xml.asc
*.jar
*.class
/.lein-*
/.nrepl-port
/dev/
/.dir-locals.el
/profiles.clj
/target/
/dev/resources/local.edn
/dev/src/local.clj

@ -1,116 +1,140 @@
# asciinema.org
# asciinema
[![Build Status](https://travis-ci.org/asciinema/asciinema.org.svg?branch=master)](https://travis-ci.org/asciinema/asciinema.org)
[![Code Climate](https://codeclimate.com/github/asciinema/asciinema.org/badges/gpa.svg)](https://codeclimate.com/github/asciinema/asciinema.org)
[![Coverage Status](https://coveralls.io/repos/asciinema/asciinema.org/badge.svg)](https://coveralls.io/r/asciinema/asciinema.org)
FIXME: description
Record and share your terminal sessions, the right way.
## Developing
asciinema is a free and open source solution for recording terminal sessions
and sharing them on the web.
### Setup
This is the source code of asciinema.org website. You can find asciinema's
terminal recorder at
[asciinema/asciinema](https://github.com/asciinema/asciinema) and asciinema
player at
[asciinema/asciinema-player](https://github.com/asciinema/asciinema-player).
When you first clone this repository, run:
## Setup instructions
```sh
lein setup
```
Below you'll find setup instructions in case you want to contribute, play with
it on your local machine, or setup your own instance for private use or for
your organization.
This will create files for local configuration, and prep your system
for the project.
### Quickstart Using Docker Compose
### Environment
Required:
- [Docker](https://docs.docker.com/engine/getstarted/step_one/#step-1-get-docker)
- [docker-compose 1.5+](https://docs.docker.com/compose/install/)
```bash
$ wget https://raw.githubusercontent.com/asciinema/asciinema.org/master/docker-compose.yml
$ docker-compose up -d asciinema
$ docker-compose run --rm db_init
To begin developing, start with a REPL.
```sh
lein repl
```
You can override the address/port that is sent in email with login token by passing HOST="host:port" environment variable when starting the web server.
Assuming you are running Docker Toolbox and VirtualBox: go to http://192.168.99.100:3000/ and enjoy.
Then load the development environment.
### Manual setup
```clojure
user=> (dev)
:loaded
```
#### 1. Install dependencies
Run `go` to initiate and start the system.
asciinema.org site is a Ruby on Rails application. You need to have following
dependencies installed:
```clojure
dev=> (go)
:started
```
* Ruby 2.0+ (Ruby 2.1 is recommended)
By default this creates a web server at <http://localhost:3000>.
* bundler gem
`gem install bundler`
When you make changes to your source files, use `reset` to reload any
modified files and reset the server.
* PostgreSQL 8+ with libpq development headers
`sudo apt-get install postgresql libpq-dev` on Debian/Ubuntu
```clojure
dev=> (reset)
:reloading (...)
:resumed
```
* asciinema's libtsm fork (`asciinema` branch)
See [here](https://github.com/asciinema/libtsm/blob/asciinema/README) for installation instructions.
If you don't install it now the setup script (point 4 below) will try to
install it for you anyway.
### Testing
* phantomjs 2.0+
`sudo add-apt-repository ppa:tanguy-patte/phantomjs && sudo apt-get update && sudo apt-get install phantomjs`
Testing is fastest through the REPL, as you avoid environment startup
time.
#### 2. Get the source code
```clojure
dev=> (test)
...
```
Clone git repository:
But you can also run tests through Leiningen.
```bash
$ git clone git://github.com/asciinema/asciinema.org.git
$ cd asciinema.org
```sh
lein test
```
#### 3. Prepare database config file
### Migrations
Copy *config/database.yml.example* to *config/database.yml*. Then set
database/user/password to whatever you prefer.
Migrations are handled by [ragtime][]. Migration files are stored in
the `resources/migrations` directory, and are applied in alphanumeric
order.
If database specified in database.yml doesn't exist then the following setup
task will create it (make sure database user is allowed to create new
databases).
To update the database to the latest migration, open the REPL and run:
#### 4. Setup the app
```clojure
dev=> (migrate)
Applying 20150815144312-create-users
Applying 20150815145033-create-posts
```
Following script will install gem dependencies and setup database:
To rollback the last migration, run:
```bash
$ ./script/setup
```clojure
dev=> (rollback)
Rolling back 20150815145033-create-posts
```
#### 5. Run Rails server
Note that the system needs to be setup with `(init)` or `(go)` before
migrations can be applied.
```bash
$ bundle exec rails server
[ragtime]: https://github.com/weavejester/ragtime
### Generators
This project has several generator functions to help you create files.
To create a new endpoint:
```clojure
dev=> (gen/endpoint "bar")
Creating file src/foo/endpoint/bar.clj
Creating file test/foo/endpoint/bar_test.clj
Creating directory resources/foo/endpoint/bar
nil
```
#### 6. Run the background job processor
To create a new component:
The background job processor is needed for asciicast pre-processing and
thumbnail generation.
```clojure
dev=> (gen/component "baz")
Creating file src/foo/component/baz.clj
Creating file test/foo/component/baz_test.clj
nil
```
To create a new boundary:
```bash
$ bundle exec sidekiq
```clojure
dev=> (gen/boundary "quz" foo.component.baz.Baz)
Creating file src/foo/boundary/quz.clj
Creating file test/foo/boundary/quz_test.clj
nil
```
## Contributing
To create a new SQL migration:
If you want to contribute to this project check out
[Contributing](http://asciinema.org/contributing) page.
```clojure
dev=> (gen/sql-migration "create-users")
Creating file resources/foo/migrations/20160519143643-create-users.up.sql
Creating file resources/foo/migrations/20160519143643-create-users.down.sql
nil
```
## Authors
## Deploying
Developed with passion by [Marcin Kulik](http://ku1ik.com) and great open
source [contributors](https://github.com/asciinema/asciinema.org/contributors)
FIXME: steps to deploy
## Copyright
## Legal
Copyright &copy; 2011-2016 Marcin Kulik. See LICENSE.txt for details.
Copyright © 2017 FIXME

@ -0,0 +1,9 @@
{:config
{:app
{:middleware
{:functions {:stacktrace #var ring.middleware.stacktrace/wrap-stacktrace}
:applied ^:replace [:not-found :webjars :ring-defaults :route-aliases :stacktrace]}}
:http
{:port 4000}
:db
{:uri "jdbc:postgresql://localhost/postgres"}}}

@ -0,0 +1,21 @@
(ns dev
(:refer-clojure :exclude [test])
(:require [clojure.repl :refer :all]
[clojure.pprint :refer [pprint]]
[clojure.tools.namespace.repl :refer [refresh]]
[clojure.java.io :as io]
[com.stuartsierra.component :as component]
[duct.generate :as gen]
[duct.util.repl :refer [setup test cljs-repl migrate rollback]]
[duct.util.system :refer [load-system]]
[reloaded.repl :refer [system init start stop go reset]]))
(defn new-system []
(load-system (keep io/resource ["asciinema/system.edn" "dev.edn" "local.edn"])))
(when (io/resource "local.clj")
(load "local"))
(gen/set-ns-prefix 'asciinema)
(reloaded.repl/set-init! new-system)

@ -0,0 +1,8 @@
(ns user)
(defn dev
"Load and switch to the 'dev' namespace."
[]
(require 'dev)
(in-ns 'dev)
:loaded)

@ -0,0 +1,40 @@
(defproject asciinema "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:min-lein-version "2.0.0"
:dependencies [[org.clojure/clojure "1.8.0"]
[com.stuartsierra/component "0.3.1"]
[compojure "1.5.1"]
[duct "0.8.2"]
[environ "1.1.0"]
[ring "1.5.0"]
[ring/ring-defaults "0.2.1"]
[ring-jetty-component "0.3.1"]
[ring-webjars "0.1.1"]
[org.slf4j/slf4j-nop "1.7.21"]
[org.webjars/normalize.css "3.0.2"]
[duct/hikaricp-component "0.1.0"]
[org.postgresql/postgresql "9.4.1211"]
[duct/ragtime-component "0.1.4"]]
:plugins [[lein-environ "1.0.3"]]
:main ^:skip-aot asciinema.main
:target-path "target/%s/"
:aliases {"setup" ["run" "-m" "duct.util.repl/setup"]}
:profiles
{:dev [:project/dev :profiles/dev]
:test [:project/test :profiles/test]
:uberjar {:aot :all}
:profiles/dev {}
:profiles/test {}
:project/dev {:dependencies [[duct/generate "0.8.2"]
[reloaded.repl "0.2.3"]
[org.clojure/tools.namespace "0.2.11"]
[org.clojure/tools.nrepl "0.2.12"]
[eftest "0.1.1"]
[com.gearswithingears/shrubbery "0.4.1"]
[kerodon "0.8.0"]]
:source-paths ["dev/src"]
:resource-paths ["dev/resources"]
:repl-options {:init-ns user}
:env {:port "3000"}}
:project/test {}})

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en" class="example">
<head>
<title>Example Endpoint</title>
<link rel="stylesheet" href="/assets/normalize.css/normalize.css">
<link rel="stylesheet" href="/css/site.css">
</head>
<body>
<h1>This is an example endpoint</h1>
</body>
</html>

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en" class="error-page">
<head>
<title>Server Error</title>
<link rel="stylesheet" href="/assets/normalize.css/normalize.css">
<link rel="stylesheet" href="/css/site.css">
</head>
<body>
<h1>Resource Not Found</h1>
<h2>The requested page does not exist.</h2>
</body>
</html>

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en" class="error-page">
<head>
<title>Server Error</title>
<link rel="stylesheet" href="/assets/normalize.css/normalize.css">
<link rel="stylesheet" href="/css/site.css">
</head>
<body>
<h1>Internal Server Error</h1>
<h2>Sorry, something went wrong.</h2>
</body>
</html>

@ -0,0 +1,103 @@
.error-page body {
background: #eee;
}
.error-page h1 {
margin: 15% 0 0 0;
text-align: center;
font-size: 42px;
color: #900;
}
.error-page h2 {
text-align: center;
font-size: 32px;
font-weight: normal;
color: #333;
}
.welcome body {
background: #eee;
color: #333;
font-family: Helvetica, Arial, sans-serif;
max-width: 700px;
padding: 15px;
margin: auto;
}
.welcome p {
line-height: 1.4em;
}
.welcome code {
font-family: Menlo, DejaVu Sans Mono, Lucida Console, monospace;
font-size: 12px;
background: #ddd;
color: #111;
}
.welcome h1 {
text-align: center;
font-size: 36px;
font-weight: lighter;
margin: 40px 0 30px 0;
}
.welcome h1 .outer {
border: solid 4px #555;
padding: 3px;
display: inline-block;
}
.welcome h1 .inner {
border: solid 2px #555;
padding: 0 3px;
display: inline-block;
font-weight: normal;
color: #444;
}
.welcome .project-name {
font-weight: bold;
}
.welcome .profiles {
margin-top: 30px;
}
.welcome .profiles code {
font-size: 11px;
}
.welcome .profiles h2 {
font-weight: normal;
font-size: 23px;
margin-bottom: 0;
color: #333;
}
.welcome .profiles dl {
margin: 0 10px;
}
.welcome .profiles dt {
font-weight: normal;
font-size: 19px;
margin: 18px 0 5px 0;
}
.welcome .profiles dd {
font-size: 14px;
margin: 8px 0 8px 0;
}
.example body {
background: #eee;
}
.example h1 {
margin: 15% 0 0 0;
text-align: center;
font-size: 36px;
font-weight: normal;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en" class="welcome">
<head>
<title>Welcome to Duct</title>
<link rel="stylesheet" href="/assets/normalize.css/normalize.css">
<link rel="stylesheet" href="/css/site.css">
</head>
<body>
<h1>Welcome to <span class="outer"><span class="inner">Duct</span></span></h1>
<div class="intro">
<p>Congratulations! Your project <span class="project-name">asciinema</span> is
ready and running.</p>
<p>This is a static welcome page located at <code>resources/asciinema/public/index.html</code>
in the project directory. Remove or replace it when you start developing.
If you remove the index page entirely, be sure to change the
<code>:route-aliases</code> map in <code>resources/asciinema/system.edn</code>.
</div>
<div class="profiles">
<h2>Template profiles used:</h2>
<dl>
<dt>+example</dt>
<dd>Adds an example endpoint at <a href="/example">/example</a>.</dd>
<dt>+postgres</dt>
<dd>Adds a PostgreSQL dependency and database component. The database used for
development defaults to <code>postgres</code> on <code>localhost</code>.</dd>
<dt>+ragtime</dt>
<dd>Adds Ragtime migrations. Use <code>(migrate)</code> and <code>(rollback)</code>
in the REPL. Migrations are stored in <code>resources/asciinema/migrations</code>.
</dd>
<dt>+site</dt>
<dd>Adds middleware and configuration suited for a user-facing website.</dd>
</dl>
</div>
</body>
</html>

@ -0,0 +1,2 @@
User-agent: *
Disallow:

@ -0,0 +1,50 @@
{:components
{:app #var duct.component.handler/handler-component
:http #var ring.component.jetty/jetty-server
:db #var duct.component.hikaricp/hikaricp
:ragtime #var duct.component.ragtime/ragtime}
:endpoints
{:example #var asciinema.endpoint.example/example-endpoint}
:dependencies
{:http [:app]
:app [:example]
:ragtime [:db]
:example [:db]}
:config
{:app
{:middleware
{:functions
{:hide-errors #var duct.middleware.errors/wrap-hide-errors
:not-found #var duct.middleware.not-found/wrap-not-found
:ring-defaults #var ring.middleware.defaults/wrap-defaults
:route-aliases #var duct.middleware.route-aliases/wrap-route-aliases
:webjars #var ring.middleware.webjars/wrap-webjars}
:applied
[:not-found :webjars :ring-defaults :route-aliases :hide-errors]
:arguments
{:not-found #resource "asciinema/errors/404.html"
:hide-errors #resource "asciinema/errors/500.html"
:route-aliases {"/" "/index.html"}
:ring-defaults
{:params {:urlencoded true
:keywordize true
:multipart true
:nested true}
:cookies true
:session {:flash true
:cookie-attrs {:http-only true}}
:security {:anti-forgery true
:xss-protection {:enable? true, :mode :block}
:frame-options :sameorigin
:content-type-options :nosniff}
:static {:resources "asciinema/public"}
:responses {:not-modified-responses true
:absolute-redirects true
:content-types true
:default-charset "utf-8"}}}}}
:http
{:port http-port}
:db
{:uri db-uri}
:ragtime
{:resource-path "asciinema/migrations"}}}

@ -0,0 +1,8 @@
(ns asciinema.endpoint.example
(:require [compojure.core :refer :all]
[clojure.java.io :as io]))
(defn example-endpoint [{{db :spec} :db}]
(context "/example" []
(GET "/" []
(io/resource "asciinema/endpoint/example/example.html"))))

@ -0,0 +1,15 @@
(ns asciinema.main
(:gen-class)
(:require [com.stuartsierra.component :as component]
[duct.util.runtime :refer [add-shutdown-hook]]
[duct.util.system :refer [load-system]]
[environ.core :refer [env]]
[clojure.java.io :as io]))
(defn -main [& args]
(let [bindings {'http-port (Integer/parseInt (:port env "3000"))
'db-uri (:database-url env)}
system (->> (load-system [(io/resource "asciinema/system.edn")] bindings)
(component/start))]
(add-shutdown-hook ::stop-system #(component/stop system))
(println "Started HTTP server on port" (-> system :http :port))))

@ -0,0 +1,16 @@
(ns asciinema.endpoint.example-test
(:require [com.stuartsierra.component :as component]
[clojure.test :refer :all]
[kerodon.core :refer :all]
[kerodon.test :refer :all]
[shrubbery.core :as shrub]
[asciinema.endpoint.example :as example]))
(def handler
(example/example-endpoint {}))
(deftest smoke-test
(testing "example page exists"
(-> (session handler)
(visit "/example")
(has (status? 200) "page exists"))))
Loading…
Cancel
Save