flutterby 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/flutterby.gemspec +3 -0
- data/lib/flutterby/cli.rb +16 -0
- data/lib/flutterby/entity.rb +26 -8
- data/lib/flutterby/file.rb +45 -21
- data/lib/flutterby/folder.rb +14 -0
- data/lib/flutterby/server.rb +23 -1
- data/lib/flutterby/version.rb +1 -1
- metadata +43 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e74e653d62257035937eb6cec35fafae4ae6272
|
4
|
+
data.tar.gz: b0b8918a534bad69247b60e209e5431d31f08731
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3a8ac8a2eb8e1c53bdbec7b07742cd82461d8255ffe612ef630eaa7b925c6f657e18769854c559463bbc80f08497e5268d31a29d05adaf0ec4c3c910c1a5054
|
7
|
+
data.tar.gz: 1189422cf9ed293b66e6295ff3c0eb0a8b7eeba09d7efe1ffda75ab0de592197e5c97f75a86211f3dd5d6d6cf1503ecdb3577190a0f6941184fa2b22cfd9bb9c
|
data/flutterby.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
26
|
spec.add_development_dependency "rspec", "~> 3.0"
|
27
27
|
spec.add_development_dependency 'awesome_print'
|
28
|
+
spec.add_development_dependency 'gem-release'
|
28
29
|
|
29
30
|
spec.add_dependency 'commander'
|
30
31
|
spec.add_dependency 'slodown'
|
@@ -33,4 +34,6 @@ Gem::Specification.new do |spec|
|
|
33
34
|
spec.add_dependency 'slim'
|
34
35
|
spec.add_dependency 'toml-rb'
|
35
36
|
spec.add_dependency 'rack'
|
37
|
+
spec.add_dependency 'listen'
|
38
|
+
spec.add_dependency 'mime-types'
|
36
39
|
end
|
data/lib/flutterby/cli.rb
CHANGED
@@ -21,6 +21,22 @@ Commander.configure do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
command :serve do |c|
|
25
|
+
c.syntax = 'flutterby serve [options]'
|
26
|
+
c.description = "Serve your website for development."
|
27
|
+
|
28
|
+
c.option '--in DIR', String, "Directory containing your source files"
|
29
|
+
|
30
|
+
c.action do |args, options|
|
31
|
+
options.default in: "./site/"
|
32
|
+
|
33
|
+
root = Flutterby.from(options.in, name: "/")
|
34
|
+
server = Flutterby::Server.new(root)
|
35
|
+
server.run!
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
24
40
|
command :test do |c|
|
25
41
|
c.syntax = 'flutterby test'
|
26
42
|
c.description = 'TEST. Yo.'
|
data/lib/flutterby/entity.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
module Flutterby
|
2
2
|
class Entity
|
3
|
-
attr_reader :name, :ext, :filters, :parent, :fs_path, :path
|
3
|
+
attr_reader :name, :ext, :filters, :parent, :fs_path, :path, :data
|
4
4
|
|
5
5
|
def initialize(name, parent: nil, fs_path: nil)
|
6
6
|
@parent = parent
|
7
|
+
@data = {}
|
7
8
|
|
8
9
|
# Extract name, extension, and filters from given name
|
9
10
|
parts = name.split(".")
|
10
11
|
@name = parts.shift
|
11
12
|
@ext = parts.shift
|
12
|
-
@filters = parts
|
13
|
+
@filters = parts.reverse
|
13
14
|
|
14
15
|
# Calculate full path
|
15
16
|
@path = parent ? ::File.join(parent.path, full_name) : full_name
|
@@ -21,6 +22,10 @@ module Flutterby
|
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
25
|
+
def reload!
|
26
|
+
read
|
27
|
+
end
|
28
|
+
|
24
29
|
def list(indent: 0)
|
25
30
|
puts "#{" " * indent}[#{self.class}] #{path}"
|
26
31
|
end
|
@@ -33,7 +38,8 @@ module Flutterby
|
|
33
38
|
end
|
34
39
|
end
|
35
40
|
|
36
|
-
def
|
41
|
+
def process_filters(input)
|
42
|
+
input
|
37
43
|
end
|
38
44
|
|
39
45
|
def url
|
@@ -44,15 +50,27 @@ module Flutterby
|
|
44
50
|
::File.expand_path(::File.join(base, full_name))
|
45
51
|
end
|
46
52
|
|
47
|
-
def call(env)
|
48
|
-
['200', {"Content-Type" => "text/html"}, [name]]
|
49
|
-
end
|
50
|
-
|
51
53
|
def root
|
52
54
|
parent ? parent.root : self
|
53
55
|
end
|
54
56
|
|
55
|
-
|
57
|
+
|
58
|
+
#
|
59
|
+
# Serving
|
60
|
+
#
|
61
|
+
|
62
|
+
def call(env)
|
63
|
+
env['rack.request'] ||= Rack::Request.new(env)
|
64
|
+
env['rack.response'] ||= Rack::Response.new([], 200, {})
|
65
|
+
parts = env['rack.request'].path.split("/").reject(&:empty?)
|
66
|
+
|
67
|
+
serve(parts, env['rack.request'], env['rack.response'])
|
68
|
+
|
69
|
+
env['rack.response']
|
70
|
+
end
|
71
|
+
|
72
|
+
def serve(parts, req, res)
|
73
|
+
end
|
56
74
|
|
57
75
|
def sibling(name)
|
58
76
|
parent && parent.find(name)
|
data/lib/flutterby/file.rb
CHANGED
@@ -3,14 +3,23 @@ require 'sass'
|
|
3
3
|
require 'tilt'
|
4
4
|
require 'slim'
|
5
5
|
require 'toml'
|
6
|
+
require 'mime-types'
|
6
7
|
|
7
8
|
module Flutterby
|
8
9
|
class File < Entity
|
9
|
-
attr_reader :contents
|
10
|
+
attr_reader :contents
|
10
11
|
|
11
12
|
def read
|
12
13
|
@contents = ::File.read(fs_path)
|
13
|
-
|
14
|
+
|
15
|
+
# Extract date from name
|
16
|
+
if name =~ %r{^(\d\d\d\d\-\d\d?\-\d\d?)\-}
|
17
|
+
@data['date'] = Time.parse($1)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Read remaining data from frontmatter. Data in frontmatter
|
21
|
+
# will always have precedence!
|
22
|
+
@data.merge! parse_frontmatter
|
14
23
|
end
|
15
24
|
|
16
25
|
def parse_frontmatter
|
@@ -28,16 +37,18 @@ module Flutterby
|
|
28
37
|
data
|
29
38
|
end
|
30
39
|
|
31
|
-
def
|
32
|
-
# Apply
|
33
|
-
|
40
|
+
def process_filters(input)
|
41
|
+
# Apply all filters
|
42
|
+
filters.each do |filter|
|
34
43
|
meth = "process_#{filter}"
|
35
44
|
if respond_to?(meth)
|
36
|
-
send(meth)
|
45
|
+
input = send(meth, input)
|
37
46
|
else
|
38
47
|
puts "Woops, no #{meth} available :("
|
39
48
|
end
|
40
49
|
end
|
50
|
+
|
51
|
+
input
|
41
52
|
end
|
42
53
|
|
43
54
|
def page?
|
@@ -48,27 +59,27 @@ module Flutterby
|
|
48
59
|
@view ||= View.new(self)
|
49
60
|
end
|
50
61
|
|
51
|
-
def process_erb
|
52
|
-
tilt = Tilt["erb"].new {
|
53
|
-
|
62
|
+
def process_erb(input)
|
63
|
+
tilt = Tilt["erb"].new { input }
|
64
|
+
tilt.render(view)
|
54
65
|
end
|
55
66
|
|
56
|
-
def process_slim
|
57
|
-
tilt = Tilt["slim"].new {
|
58
|
-
|
67
|
+
def process_slim(input)
|
68
|
+
tilt = Tilt["slim"].new { input }
|
69
|
+
tilt.render(view)
|
59
70
|
end
|
60
71
|
|
61
|
-
def process_md
|
62
|
-
|
72
|
+
def process_md(input)
|
73
|
+
Slodown::Formatter.new(input).complete.to_s
|
63
74
|
end
|
64
75
|
|
65
|
-
def process_scss
|
66
|
-
engine = Sass::Engine.new(
|
67
|
-
|
76
|
+
def process_scss(input)
|
77
|
+
engine = Sass::Engine.new(input, syntax: :scss)
|
78
|
+
engine.render
|
68
79
|
end
|
69
80
|
|
70
|
-
def apply_layout
|
71
|
-
output =
|
81
|
+
def apply_layout(input)
|
82
|
+
output = input
|
72
83
|
|
73
84
|
# collect layouts to apply
|
74
85
|
layouts = []
|
@@ -93,10 +104,23 @@ module Flutterby
|
|
93
104
|
end
|
94
105
|
|
95
106
|
def write_static(path)
|
96
|
-
|
97
|
-
output = apply_layout? ? apply_layout :
|
107
|
+
rendered = process_filters(@contents)
|
108
|
+
output = apply_layout? ? apply_layout(rendered) : rendered
|
98
109
|
|
99
110
|
::File.write(path, output)
|
100
111
|
end
|
112
|
+
|
113
|
+
def serve(parts, req, res)
|
114
|
+
# TODO: DRY this up
|
115
|
+
rendered = process_filters(@contents)
|
116
|
+
output = apply_layout? ? apply_layout(rendered) : rendered
|
117
|
+
|
118
|
+
# Determine MIME type
|
119
|
+
mime_type = MIME::Types.type_for(ext) || "text/plain"
|
120
|
+
|
121
|
+
# Build response
|
122
|
+
res.headers["Content-Type"] = mime_type
|
123
|
+
res.body = [output]
|
124
|
+
end
|
101
125
|
end
|
102
126
|
end
|
data/lib/flutterby/folder.rb
CHANGED
@@ -22,6 +22,7 @@ module Flutterby
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def find(name)
|
25
|
+
name = name.split('.').first
|
25
26
|
@children.find { |c| c.name == name }
|
26
27
|
end
|
27
28
|
|
@@ -30,5 +31,18 @@ module Flutterby
|
|
30
31
|
def pages
|
31
32
|
children.select { |c| c.ext == "html" }
|
32
33
|
end
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
def serve(parts, req, res)
|
38
|
+
# If no further parts are requested, let's look for an index
|
39
|
+
# document and serve that instead.
|
40
|
+
if child = find(parts.empty? ? "index" : parts.shift)
|
41
|
+
child.serve(parts, req, res)
|
42
|
+
else
|
43
|
+
res.headers["Content-Type"] = "text/html"
|
44
|
+
res.body = ["404"]
|
45
|
+
end
|
46
|
+
end
|
33
47
|
end
|
34
48
|
end
|
data/lib/flutterby/server.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rack'
|
2
|
+
require 'listen'
|
2
3
|
|
3
4
|
module Flutterby
|
4
5
|
class Server
|
@@ -7,7 +8,28 @@ module Flutterby
|
|
7
8
|
end
|
8
9
|
|
9
10
|
def run!
|
10
|
-
|
11
|
+
# Set up listener
|
12
|
+
listener = Listen.to(@root.fs_path) do |modified, added, removed|
|
13
|
+
# puts "modified absolute path: #{modified}"
|
14
|
+
# puts "added absolute path: #{added}"
|
15
|
+
# puts "removed absolute path: #{removed}"
|
16
|
+
|
17
|
+
puts "Change detected, reloading everything!"
|
18
|
+
@root.reload!
|
19
|
+
end
|
20
|
+
|
21
|
+
# Set up server
|
22
|
+
server = Rack::Handler::WEBrick
|
23
|
+
|
24
|
+
# Make sure we handle interrupts correctly
|
25
|
+
trap('INT') do
|
26
|
+
listener.stop
|
27
|
+
server.shutdown
|
28
|
+
end
|
29
|
+
|
30
|
+
# Go!
|
31
|
+
listener.start
|
32
|
+
server.run @root
|
11
33
|
end
|
12
34
|
end
|
13
35
|
end
|
data/lib/flutterby/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flutterby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hendrik Mans
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: gem-release
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: commander
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +178,34 @@ dependencies:
|
|
164
178
|
- - ">="
|
165
179
|
- !ruby/object:Gem::Version
|
166
180
|
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: listen
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: mime-types
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :runtime
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
167
209
|
description: There are many static site generators. This is mine.
|
168
210
|
email:
|
169
211
|
- hendrik@mans.de
|