rackstatic 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +50 -3
- data/bin/rackstatic +12 -4
- data/lib/rack/static-builder.rb +15 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc1751213160fd605d7884ac94edf263ba7c2050
|
4
|
+
data.tar.gz: e783ebc5fe72cd0a64b5ba01641690fd9d6fb8f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19284839fe275f71d4e42f23d511a197af1a0ff5d7f5a866ea5ea30f98a90d63093e31dda37a3e442103e82d8dffc2e097a4716552b498d28e956a942a6c89ac
|
7
|
+
data.tar.gz: 72dc00451eee38e4afb170e3ba76e7e09c7163d9b7391d5c3f5dcd2b16fc14aef9ebc5f59d8580047a28eb5ecbd795c4c566251b525db5c35e911061847e931b
|
data/README.md
CHANGED
@@ -1,7 +1,54 @@
|
|
1
|
-
#
|
1
|
+
# Introduction
|
2
|
+
|
3
|
+
There's this category of web framework called "static-site generators", or "SSGs" for short. We, as developers, use them because it's easier than the alternative: writing a regular server, then launching it, mirroring the contents using some arcane `wget` incantation, and shutting it back down afterward.
|
4
|
+
|
5
|
+
But while SSGs eliminate *this* particular hassle, they come with their own: they require you to organize everything their own persnickety way; they don't follow common web-development practices; you have to write special plugins for them if you want to use any templating library or database adapter or whatever else that would "just work" anywhere else. It's almost less work to use `wget`.
|
6
|
+
|
7
|
+
`rackstatic` cuts this Gordian knot. Using `rackstatic`, you can develop your static website in, say, [Sinatra](https://github.com/sinatra/sinatra). Or any Rack-compatible web framework (yes, even Rails, if you really really want.) And it's just as easy as using an SSG.
|
8
|
+
|
9
|
+
## Here's the deal:
|
2
10
|
|
3
11
|
$ gem install rackstatic
|
4
12
|
$ cd your_rack_app/
|
5
|
-
$ rackstatic
|
13
|
+
$ rackstatic dist/
|
14
|
+
|
15
|
+
A static mirror-copy of your website will now exist under `your_rack_app/dist/`.
|
16
|
+
|
17
|
+
If your repo is layed out such that your application files (`config.ru` et al) exist under `your_repo/app/`, you can build from above it to keep things clean and separate:
|
18
|
+
|
19
|
+
$ gem install rackstatic
|
20
|
+
$ cd your_repo/
|
21
|
+
$ rackstatic dist/
|
22
|
+
|
23
|
+
This will use the app in `your_repo/app/` to build `your_repo/dist/`.
|
24
|
+
|
25
|
+
## How does it work?
|
26
|
+
|
27
|
+
`rackstatic` uses the mock Rack session functionality of [rack-test](https://github.com/brynary/rack-test). Except, not so much for testing :grinning:. Instead, the values returned in each request are written to disk, then spidered (using [nokogiri](https://github.com/sparklemotion/nokogiri) to find more URLs to request.
|
28
|
+
|
29
|
+
## What about static files?
|
30
|
+
|
31
|
+
Some files aren't linked anywhere: `robots.txt`, `crossdomain.xml`, `favicon.ico`, and so forth. A regular spidering-based mirroring process would miss these.
|
32
|
+
|
33
|
+
To prevent this, `rackstatic` will attempt to request anything it sees under `your_rack_app/public/` (e.g. `your_rack_app/public/robots.txt` -> `GET /robots.txt`), as if they had been linked to. You can change what subdirectory of your app is looked under using the `-s` switch:
|
34
|
+
|
35
|
+
$ rackstatic -s static/ dist/
|
36
|
+
|
37
|
+
## It's probably better to...
|
38
|
+
|
39
|
+
add `rackstatic` to your Gemfile. Then, when you pull down your app from its repo, it's as simple as:
|
40
|
+
|
41
|
+
$ bundle install
|
42
|
+
$ bundle exec rackstatic dist/
|
43
|
+
|
44
|
+
## Programmatic usage
|
45
|
+
|
46
|
+
You can add a deploy task to your Rakefile that calls `rackstatic`. Rather than messing with shell commands, try this:
|
47
|
+
|
48
|
+
task :deploy do
|
49
|
+
require 'rack/static-builder'
|
50
|
+
Rack::StaticBuilder.new(:app_dir => 'app/', :dest_dir => 'dist/').build!
|
51
|
+
|
52
|
+
# now push dist/ to S3 or Github or where-ever you like
|
53
|
+
end
|
6
54
|
|
7
|
-
A static mirror-copy of your website will now be exist under `your_rack_app/build/`.
|
data/bin/rackstatic
CHANGED
@@ -8,11 +8,11 @@ require 'rack/static-builder'
|
|
8
8
|
opts = {}
|
9
9
|
opts[:app_dir] = 'app'
|
10
10
|
opts[:app_static_dir] = 'public'
|
11
|
-
opts[:dest_dir] = '
|
11
|
+
opts[:dest_dir] = 'dist'
|
12
12
|
opts[:noisy] = true
|
13
13
|
|
14
14
|
OptionParser.new do |op|
|
15
|
-
op.banner = "Usage: rackstatic [opts]"
|
15
|
+
op.banner = "Usage: rackstatic [opts] [destination]"
|
16
16
|
|
17
17
|
op.on("-a", "--app DIRECTORY", "Application directory (where config.ru is)"){ |v| opts[:app_dir] = v }
|
18
18
|
op.on("-s", "--static SUBDIRECTORY", "Directory within the app dir where static files are kept"){ |v| opts[:app_static_dir] = v }
|
@@ -20,11 +20,19 @@ OptionParser.new do |op|
|
|
20
20
|
op.on("-d", "--dest DIRECTORY", "Build output directory"){ |v| opts[:dest_dir] = v }
|
21
21
|
|
22
22
|
op.on("-q", "--quiet", "Build quietly"){ opts[:noisy] = false }
|
23
|
+
|
24
|
+
op.on_tail("-h", "--help", "Show this message") { puts opts; exit }
|
25
|
+
op.on_tail("--version", "Show version") { puts Rack::StaticBuilder::VERSION }
|
23
26
|
end.parse!
|
24
27
|
|
28
|
+
if ARGV.length == 1
|
29
|
+
opts[:dest_dir] = ARGV.shift
|
30
|
+
end
|
31
|
+
|
25
32
|
begin
|
26
|
-
Rack::StaticBuilder.new(opts).build!
|
33
|
+
status = Rack::StaticBuilder.new(opts).build!
|
34
|
+
Kernel.exit( status ? 0 : 1 )
|
27
35
|
rescue ArgumentError
|
28
|
-
$stderr.puts "rackstatic: must be run within a rack-compatible application directory"
|
36
|
+
$stderr.puts "rackstatic: must be run within or above a rack-compatible application directory"
|
29
37
|
Kernel.exit 1
|
30
38
|
end
|
data/lib/rack/static-builder.rb
CHANGED
@@ -6,7 +6,7 @@ require 'rack/test'
|
|
6
6
|
require 'nokogiri'
|
7
7
|
|
8
8
|
class Rack::StaticBuilder
|
9
|
-
VERSION = '0.1.
|
9
|
+
VERSION = '0.1.1'
|
10
10
|
|
11
11
|
|
12
12
|
class RequestPathQueue
|
@@ -19,8 +19,11 @@ class Rack::StaticBuilder
|
|
19
19
|
def enqueue(url)
|
20
20
|
path = URI.parse(url).path
|
21
21
|
|
22
|
+
# discard URNs like data: and magnet:
|
23
|
+
return false unless path
|
24
|
+
|
22
25
|
if path[0] != '/'
|
23
|
-
path = (@active || '/').sub(/\/[^\/]*$/, '') + '/' + path
|
26
|
+
path = URI.parse( (@active || '/').sub(/\/[^\/]*$/, '') + '/' + path ).path
|
24
27
|
end
|
25
28
|
|
26
29
|
@queue << path
|
@@ -40,7 +43,7 @@ class Rack::StaticBuilder
|
|
40
43
|
raise ArgumentError unless @app_dir
|
41
44
|
|
42
45
|
@app_dir = Pathname.new(@app_dir).expand_path.cleanpath
|
43
|
-
@dest_dir = Pathname.new(opts.delete(:dest_dir) || '
|
46
|
+
@dest_dir = Pathname.new(opts.delete(:dest_dir) || 'dist').expand_path.cleanpath
|
44
47
|
@app_static_dir = (@app_dir + (opts.delete(:static_dir) || 'public')).expand_path.cleanpath
|
45
48
|
|
46
49
|
@noisy = opts.delete(:noisy)
|
@@ -53,6 +56,8 @@ class Rack::StaticBuilder
|
|
53
56
|
|
54
57
|
enqueue_static_assets(queue)
|
55
58
|
|
59
|
+
counts = {true => 0, false => 0}
|
60
|
+
|
56
61
|
with_rack_client do |client|
|
57
62
|
|
58
63
|
queue.drain do |req_path|
|
@@ -61,6 +66,7 @@ class Rack::StaticBuilder
|
|
61
66
|
if @noisy
|
62
67
|
channel = (resp.status == 200) ? $stdout : $stderr
|
63
68
|
channel.puts("#{resp.status} #{req_path}")
|
69
|
+
counts[(resp.status == 200)] += 1
|
64
70
|
end
|
65
71
|
|
66
72
|
next unless resp.status == 200
|
@@ -72,6 +78,12 @@ class Rack::StaticBuilder
|
|
72
78
|
end
|
73
79
|
|
74
80
|
end
|
81
|
+
|
82
|
+
if @noisy and counts[false] > 0
|
83
|
+
$stderr.puts "\nFAILED: #{ counts[false] } requests returned non-200 and were discarded"
|
84
|
+
end
|
85
|
+
|
86
|
+
(counts[false] > 0)
|
75
87
|
end
|
76
88
|
|
77
89
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rackstatic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Keith McAuley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-03-
|
11
|
+
date: 2013-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|