snack 0.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/snack +15 -9
- data/lib/snack.rb +26 -47
- data/test/snack_test.rb +13 -13
- data/test/test_app/index.html.haml +34 -1
- data/test/test_app/pages/_layouts/normal.html.haml +1 -1
- data/test/test_app/pages/_layouts/variable.html.haml +1 -1
- data/test/test_app/pages/variable-normal.html.haml +1 -1
- data/test/test_app/public/application.js.coffee +1 -2
- metadata +11 -36
data/bin/snack
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require File.expand_path('../../lib/snack', __FILE__)
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
cmd = ARGV[0] || 'serve'
|
5
|
+
dir = ARGV[1] || '_source'
|
6
|
+
puts "-: Snack :- App root is: '#{dir}'"
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
case cmd
|
9
|
+
when 'new'
|
10
|
+
require 'fileutils'
|
11
|
+
File.open(File.join(FileUtils.mkpath(dir), 'index.html'), 'w') do |f|
|
12
|
+
f.puts 'Hello from snack!'
|
13
|
+
end
|
14
|
+
when 'build', 'serve'
|
15
|
+
abort "-: Snack :- Unable to locate: '#{dir}'" unless Dir.exists?(dir)
|
16
|
+
@app = Snack::Application.new(:root => dir)
|
17
|
+
@app.send cmd
|
12
18
|
else
|
13
|
-
puts "'#{
|
14
|
-
puts
|
19
|
+
puts "'#{cmd}' is not a valid snack command"
|
20
|
+
puts 'Usage: snack (build,serve,new) <directory>'
|
15
21
|
end
|
data/lib/snack.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
%w[
|
1
|
+
%w[ rack tilt ].each { |s| require s }
|
2
2
|
|
3
3
|
module Snack
|
4
4
|
class Application
|
5
5
|
attr_accessor :settings, :builder
|
6
6
|
|
7
7
|
def initialize(options = {})
|
8
|
-
@settings =
|
9
|
-
@settings
|
8
|
+
@settings = options
|
9
|
+
@settings[:output_dir] ||= '../'
|
10
10
|
|
11
11
|
app = self
|
12
12
|
@builder = Rack::Builder.new do
|
@@ -17,40 +17,27 @@ module Snack
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
def method_missing(sym)
|
21
|
-
settings.send sym
|
22
|
-
end
|
23
|
-
|
24
20
|
def serve
|
25
21
|
Rack::Handler::Thin.run @builder, :Port => 9393
|
26
22
|
end
|
27
23
|
|
28
|
-
def new
|
29
|
-
FileUtils.mkdir root unless File.exists? root
|
30
|
-
FileUtils.cd root do
|
31
|
-
File.open('index.html.haml', 'w') { |f| f.puts 'Hello from snack!' }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
24
|
def build
|
36
|
-
FileUtils.cd root do
|
25
|
+
FileUtils.cd @settings[:root] do
|
37
26
|
# collect all files that don't start with '_'
|
38
|
-
files = Dir[File.join('**', '*')].reject{ |f| f
|
27
|
+
files = Dir[File.join('**', '*')].reject { |f| f =~ /(^_|\/_)/ }
|
39
28
|
|
40
29
|
files.each do |file|
|
41
|
-
|
30
|
+
path = File.join @settings[:output_dir], file
|
42
31
|
|
43
|
-
if
|
44
|
-
FileUtils.mkdir(new_path) unless File.exists?(new_path)
|
45
|
-
elsif Tilt.registered?(File.extname(file).gsub('.', ''))
|
32
|
+
if Tilt[path]
|
46
33
|
body = View.new(file).render
|
47
|
-
|
48
|
-
|
34
|
+
File.open(path.chomp(File.extname(path)), 'w') { |f| f.write body }
|
35
|
+
elsif Dir.exists? file
|
36
|
+
FileUtils.mkpath path
|
49
37
|
else
|
50
|
-
FileUtils.cp
|
38
|
+
FileUtils.cp file, path
|
51
39
|
end
|
52
40
|
end
|
53
|
-
|
54
41
|
end
|
55
42
|
end
|
56
43
|
end
|
@@ -61,46 +48,38 @@ module Snack
|
|
61
48
|
end
|
62
49
|
|
63
50
|
def call(env)
|
64
|
-
body = render File.join(@app.root, env['PATH_INFO'])
|
51
|
+
body = render File.join(@app.settings[:root], env['PATH_INFO'])
|
65
52
|
if body
|
66
|
-
[200, {
|
53
|
+
[200, { 'Content-Type' => Rack::Mime.mime_type(File.extname(env['PATH_INFO']), 'text/html') }, [body]]
|
67
54
|
else
|
68
|
-
[404, {
|
55
|
+
[404, { 'Content-Type' => 'text/plain' }, 'Not Found']
|
69
56
|
end
|
70
57
|
end
|
71
58
|
|
72
|
-
def render(
|
73
|
-
return File.read
|
59
|
+
def render(path)
|
60
|
+
return File.read path if File.file? path
|
74
61
|
|
75
62
|
# default to index if path to directory
|
76
|
-
|
63
|
+
path = File.join(path, 'index') if Dir.exists? path
|
77
64
|
|
78
65
|
# return the first filename that matches file
|
79
|
-
template = Dir[File.join(
|
66
|
+
template = Dir[File.join("#{path}*")].first
|
80
67
|
return View.new(template).render if template
|
81
68
|
end
|
82
|
-
|
83
69
|
end
|
84
70
|
|
85
|
-
# Basically take a template and render a string from it
|
86
71
|
class View
|
87
72
|
def initialize(template)
|
88
73
|
@template = template
|
89
74
|
end
|
90
75
|
|
91
|
-
# return the path to a valid layout file
|
92
|
-
def layout
|
93
|
-
Dir[File.join(File.dirname(@template), @layout) + '*'].first if @layout
|
94
|
-
end
|
95
|
-
|
96
76
|
def partial(path, locals = {})
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
template = Dir[filepath + '*'].first
|
77
|
+
filepath = File.join File.dirname(@template), path.to_s
|
78
|
+
# insert a '_' before the filename before we search
|
79
|
+
_partial = Dir["#{filepath.sub(/\/(?!.*\/)/, '/_')}*"].first
|
101
80
|
|
102
|
-
if
|
103
|
-
Tilt.new(
|
81
|
+
if _partial
|
82
|
+
Tilt.new(_partial).render(self, locals)
|
104
83
|
else
|
105
84
|
raise "-: Snack :- Unable to locate partial at: '#{filepath}'"
|
106
85
|
end
|
@@ -109,10 +88,10 @@ module Snack
|
|
109
88
|
# return a view body or nil if adequate template cannot be found
|
110
89
|
def render
|
111
90
|
template_body = Tilt.new(@template).render(self)
|
112
|
-
if layout
|
91
|
+
if @layout
|
92
|
+
layout = Dir[File.join(File.dirname(@template), @layout) + '*'].first
|
93
|
+
raise "-: Snack :- Unable to locate layout at: '#@layout'" unless layout
|
113
94
|
@body = Tilt.new(layout).render(self) { template_body }
|
114
|
-
elsif @layout # user changed; alert them to fails
|
115
|
-
raise "-: Snack :- Unable to locate layout at: '#{@layout}'"
|
116
95
|
end
|
117
96
|
@body || template_body
|
118
97
|
end
|
data/test/snack_test.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
# use 'turn test/snack_test.rb' for pretty output
|
1
2
|
# TODO: test build and new commands?
|
2
|
-
require 'rubygems'
|
3
3
|
require 'minitest/spec'
|
4
4
|
require 'rack/test'
|
5
5
|
require File.expand_path('../../lib/snack', __FILE__)
|
@@ -13,27 +13,27 @@ describe Snack::Server do
|
|
13
13
|
@app = Snack::Application.new(:root => "#{File.dirname(__FILE__)}/test_app").builder
|
14
14
|
end
|
15
15
|
|
16
|
-
it
|
16
|
+
it 'should respond with 404 on bad requests' do
|
17
17
|
get('/foo')
|
18
18
|
last_response.status.must_equal 404
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it 'should serve static file directly first' do
|
22
22
|
get('/public/style.css')
|
23
23
|
last_response.body.must_equal "body {\n\tbackground: blue;\n}"
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
26
|
+
it 'should compile and serve sass files' do
|
27
27
|
get('/public/sass_style.css')
|
28
28
|
last_response.body.must_equal "body {\n background: blue; }\n"
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
31
|
+
it 'should serve coffeescript files compiled through tilt if request path exists with coffee extension' do
|
32
32
|
get('/public/application.js')
|
33
|
-
last_response.body.must_equal "(function() {\n $(document).ready(function() {\n return alert('hello from snack');\n });\n})();\n"
|
33
|
+
last_response.body.must_equal "(function() {\n\n $(document).ready(function() {\n return alert('hello from snack');\n });\n\n}).call(this);\n"
|
34
34
|
end
|
35
35
|
|
36
|
-
it
|
36
|
+
it 'should default to index.html if directory is requested' do
|
37
37
|
direct = get('/index.html')
|
38
38
|
response = get('/')
|
39
39
|
|
@@ -42,31 +42,31 @@ describe Snack::Server do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
# partials
|
45
|
-
it
|
45
|
+
it 'should render partials if found' do
|
46
46
|
get('/pages/partial-normal.html')
|
47
47
|
last_response.body.must_equal "This is a partial!\n"
|
48
48
|
end
|
49
49
|
|
50
|
-
it
|
50
|
+
it 'should error if partial not found' do
|
51
51
|
get('/pages/partial-failing.html')
|
52
52
|
last_response.status.must_equal 500
|
53
53
|
end
|
54
54
|
|
55
55
|
# layouts
|
56
|
-
it
|
56
|
+
it 'should render a page within a layout if layout exists' do
|
57
57
|
get('/pages/layout-normal.html')
|
58
58
|
last_response.body.must_equal "<div id='content'>\n <h1>Page Content</h1>\n</div>\n"
|
59
59
|
end
|
60
60
|
|
61
|
-
it
|
61
|
+
it 'should error if user set layout and layout not found' do
|
62
62
|
get('/pages/layout-failing.html')
|
63
63
|
last_response.status.must_equal 500
|
64
64
|
end
|
65
65
|
|
66
66
|
# variables
|
67
|
-
it
|
67
|
+
it 'should pass variables defined in the page to the layout' do
|
68
68
|
get('/pages/variable-normal.html')
|
69
69
|
last_response.body.must_equal "happy\nsad\nmad\n"
|
70
70
|
end
|
71
71
|
|
72
|
-
end
|
72
|
+
end
|
@@ -1,2 +1,35 @@
|
|
1
1
|
- @layout = nil
|
2
|
-
%h1
|
2
|
+
%h1 Snack Tests
|
3
|
+
|
4
|
+
%h2 Snack::Server
|
5
|
+
%h3 Basic
|
6
|
+
%ul
|
7
|
+
%li
|
8
|
+
%a{:href => '/foo'} should respond with 404 on bad requests
|
9
|
+
%li
|
10
|
+
%a{:href => '/public/style.css'} should serve static file directly first
|
11
|
+
%li
|
12
|
+
%a{:href => '/public/sass_style.css'} should compile and serve sass files
|
13
|
+
%li
|
14
|
+
%a{:href => '/public/application.js'} should serve coffeescript files compiled through tilt if request path exists with coffee extension
|
15
|
+
%li
|
16
|
+
%a{:href => '/'} should default to index.html if directory is requested
|
17
|
+
|
18
|
+
%h3 Partials
|
19
|
+
%ul
|
20
|
+
%li
|
21
|
+
%a{:href => '/pages/partial-normal.html'} should render partials if found
|
22
|
+
%li
|
23
|
+
%a{:href => '/pages/partial-failing.html'} should error if partial not found
|
24
|
+
|
25
|
+
%h3 Layouts
|
26
|
+
%ul
|
27
|
+
%li
|
28
|
+
%a{:href => '/pages/layout-normal.html'} should render a page within a layout if layout exists
|
29
|
+
%li
|
30
|
+
%a{:href => '/pages/layout-failing.html'} should error if user set layout and layout not found
|
31
|
+
|
32
|
+
%h3 Variables
|
33
|
+
%ul
|
34
|
+
%li
|
35
|
+
%a{:href => '/pages/variable-normal.html'} should pass variables defined in the page to the layout
|
@@ -1,2 +1,2 @@
|
|
1
1
|
#content
|
2
|
-
|
2
|
+
= yield
|
@@ -1,2 +1,2 @@
|
|
1
1
|
- @emotions.each do |emotion|
|
2
|
-
|
2
|
+
= emotion
|
@@ -1,2 +1,2 @@
|
|
1
1
|
- @layout = '_layouts/variable'
|
2
|
-
- @emotions = %w[happy sad mad]
|
2
|
+
- @emotions = %w[ happy sad mad ]
|
@@ -1,2 +1 @@
|
|
1
|
-
$(document).ready () ->
|
2
|
-
alert('hello from snack')
|
1
|
+
$(document).ready () -> alert('hello from snack')
|
metadata
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 1
|
8
|
-
version: "0.1"
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.1
|
9
6
|
platform: ruby
|
10
7
|
authors:
|
11
8
|
- Rob Law
|
@@ -13,8 +10,7 @@ autorequire:
|
|
13
10
|
bindir: bin
|
14
11
|
cert_chain: []
|
15
12
|
|
16
|
-
date:
|
17
|
-
default_executable: snack
|
13
|
+
date: 2012-04-20 00:00:00 Z
|
18
14
|
dependencies:
|
19
15
|
- !ruby/object:Gem::Dependency
|
20
16
|
name: rack
|
@@ -24,10 +20,8 @@ dependencies:
|
|
24
20
|
requirements:
|
25
21
|
- - ">="
|
26
22
|
- !ruby/object:Gem::Version
|
27
|
-
segments:
|
28
|
-
- 0
|
29
23
|
version: "0"
|
30
|
-
type: :
|
24
|
+
type: :runtime
|
31
25
|
version_requirements: *id001
|
32
26
|
- !ruby/object:Gem::Dependency
|
33
27
|
name: tilt
|
@@ -37,23 +31,19 @@ dependencies:
|
|
37
31
|
requirements:
|
38
32
|
- - ">="
|
39
33
|
- !ruby/object:Gem::Version
|
40
|
-
segments:
|
41
|
-
- 0
|
42
34
|
version: "0"
|
43
|
-
type: :
|
35
|
+
type: :runtime
|
44
36
|
version_requirements: *id002
|
45
37
|
- !ruby/object:Gem::Dependency
|
46
|
-
name:
|
38
|
+
name: coffee-script
|
47
39
|
prerelease: false
|
48
40
|
requirement: &id003 !ruby/object:Gem::Requirement
|
49
41
|
none: false
|
50
42
|
requirements:
|
51
43
|
- - ">="
|
52
44
|
- !ruby/object:Gem::Version
|
53
|
-
segments:
|
54
|
-
- 0
|
55
45
|
version: "0"
|
56
|
-
type: :
|
46
|
+
type: :runtime
|
57
47
|
version_requirements: *id003
|
58
48
|
- !ruby/object:Gem::Dependency
|
59
49
|
name: haml
|
@@ -63,28 +53,22 @@ dependencies:
|
|
63
53
|
requirements:
|
64
54
|
- - ">="
|
65
55
|
- !ruby/object:Gem::Version
|
66
|
-
segments:
|
67
|
-
- 2
|
68
|
-
- 2
|
69
|
-
- 11
|
70
56
|
version: 2.2.11
|
71
57
|
type: :development
|
72
58
|
version_requirements: *id004
|
73
59
|
- !ruby/object:Gem::Dependency
|
74
|
-
name:
|
60
|
+
name: minitest
|
75
61
|
prerelease: false
|
76
62
|
requirement: &id005 !ruby/object:Gem::Requirement
|
77
63
|
none: false
|
78
64
|
requirements:
|
79
65
|
- - ">="
|
80
66
|
- !ruby/object:Gem::Version
|
81
|
-
segments:
|
82
|
-
- 0
|
83
67
|
version: "0"
|
84
68
|
type: :development
|
85
69
|
version_requirements: *id005
|
86
70
|
description: Snack is a small framework for building static websites.
|
87
|
-
email: rob@
|
71
|
+
email: rob@robmadethis.com
|
88
72
|
executables:
|
89
73
|
- snack
|
90
74
|
extensions: []
|
@@ -108,8 +92,7 @@ files:
|
|
108
92
|
- test/test_app/public/application.js.coffee
|
109
93
|
- test/test_app/public/sass_style.css.sass
|
110
94
|
- test/test_app/public/style.css
|
111
|
-
|
112
|
-
homepage: http://github.com/robinator/snack/
|
95
|
+
homepage: http://robmadethis.com/snack
|
113
96
|
licenses: []
|
114
97
|
|
115
98
|
post_install_message:
|
@@ -122,25 +105,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
122
105
|
requirements:
|
123
106
|
- - ">="
|
124
107
|
- !ruby/object:Gem::Version
|
125
|
-
segments:
|
126
|
-
- 1
|
127
|
-
- 8
|
128
|
-
- 7
|
129
108
|
version: 1.8.7
|
130
109
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
110
|
none: false
|
132
111
|
requirements:
|
133
112
|
- - ">="
|
134
113
|
- !ruby/object:Gem::Version
|
135
|
-
segments:
|
136
|
-
- 1
|
137
|
-
- 3
|
138
|
-
- 6
|
139
114
|
version: 1.3.6
|
140
115
|
requirements: []
|
141
116
|
|
142
117
|
rubyforge_project:
|
143
|
-
rubygems_version: 1.
|
118
|
+
rubygems_version: 1.8.15
|
144
119
|
signing_key:
|
145
120
|
specification_version: 3
|
146
121
|
summary: A static website framework.
|