ichiban 0.0.2 → 1.0.0
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/lib/ichiban/command.rb +13 -1
- data/lib/ichiban/config.rb +7 -17
- data/lib/ichiban/deleter.rb +24 -0
- data/lib/ichiban/dependencies.rb +33 -0
- data/lib/ichiban/file.rb +115 -0
- data/lib/ichiban/helpers.rb +6 -10
- data/lib/ichiban/html_compiler.rb +61 -0
- data/lib/ichiban/logger.rb +59 -3
- data/lib/ichiban/markdown.rb +34 -0
- data/lib/ichiban/watcher.rb +35 -3
- data/lib/ichiban.rb +44 -17
- metadata +123 -74
- data/.gitignore +0 -5
- data/Gemfile +0 -4
- data/README +0 -56
- data/bin/ichiban.rb +0 -6
- data/ichiban.gemspec +0 -25
- data/klass.rb +0 -7
- data/lib/ichiban/compilation.rb +0 -93
- data/lib/ichiban/erb_page.rb +0 -16
- data/lib/ichiban/files.rb +0 -105
- data/lib/ichiban/layouts.rb +0 -10
- data/lib/ichiban/loading.rb +0 -19
- data/lib/ichiban/mapping.rb +0 -38
- data/lib/ichiban/path.rb +0 -55
- data/lib/ichiban/script_runner.rb +0 -33
- data/lib/ichiban/tasks.rb +0 -23
- data/lib/ichiban/version.rb +0 -3
- data/sample/Rakefile +0 -2
- data/sample/compiled/about.html +0 -13
- data/sample/compiled/bad.html +0 -0
- data/sample/compiled/images/check.png +0 -0
- data/sample/compiled/index.html +0 -13
- data/sample/compiled/javascripts/interaction.js +0 -1
- data/sample/compiled/staff/_employee.html +0 -13
- data/sample/compiled/staff/andre-marques.html +0 -13
- data/sample/compiled/staff/index.html +0 -17
- data/sample/compiled/staff/jarrett-colby.html +0 -13
- data/sample/compiled/stylesheets/reset.css +0 -1
- data/sample/compiled/stylesheets/screen.css +0 -1
- data/sample/config.rb +0 -3
- data/sample/content/about.html +0 -1
- data/sample/content/bad.html +0 -3
- data/sample/content/index.html +0 -1
- data/sample/content/staff/_employee.html +0 -1
- data/sample/content/staff/index.html +0 -6
- data/sample/data/employees.csv +0 -2
- data/sample/errors/404.html +0 -1
- data/sample/helpers/staff_helper.rb +0 -5
- data/sample/images/check.png +0 -0
- data/sample/javascripts/interaction.js +0 -1
- data/sample/layouts/default.html +0 -13
- data/sample/models/employee.rb +0 -16
- data/sample/scripts/bad.rb +0 -1
- data/sample/scripts/staff.rb +0 -8
- data/sample/stylesheets/reset.css +0 -1
- data/sample/stylesheets/screen.scss +0 -5
- data/spec/integration_spec.rb +0 -89
- data/spec/path_spec.rb +0 -15
- data/spec/spec_helper.rb +0 -19
data/lib/ichiban/command.rb
CHANGED
@@ -1,11 +1,23 @@
|
|
1
1
|
module Ichiban
|
2
2
|
class Command
|
3
3
|
def initialize(args)
|
4
|
+
@task = args.shift
|
4
5
|
@args = args
|
5
6
|
end
|
6
7
|
|
8
|
+
def print_usage
|
9
|
+
puts "Usage: ichiban <command>"
|
10
|
+
puts " Available commands: watch"
|
11
|
+
end
|
12
|
+
|
7
13
|
def run
|
8
|
-
|
14
|
+
Ichiban.project_root = Dir.getwd
|
15
|
+
case @task
|
16
|
+
when 'watch'
|
17
|
+
Ichiban::Watcher.new.start
|
18
|
+
else
|
19
|
+
print_usage
|
20
|
+
end
|
9
21
|
end
|
10
22
|
end
|
11
23
|
end
|
data/lib/ichiban/config.rb
CHANGED
@@ -5,27 +5,17 @@ module Ichiban
|
|
5
5
|
@config
|
6
6
|
end
|
7
7
|
|
8
|
-
def self.configure_for_project(project_root)
|
9
|
-
config.project_root = project_root
|
10
|
-
config_file = File.join(project_root, 'config.rb')
|
11
|
-
raise "#{config_file} must exist" unless File.exists?(config_file)
|
12
|
-
load config_file
|
13
|
-
end
|
14
|
-
|
15
|
-
# It's a bit messy to have this class method that's just an alias to a method on the config object.
|
16
|
-
# But so many different bits of code (including client code) need to know the project root, it makes
|
17
|
-
# pragmatic sense to have a really compact way to get it.
|
18
|
-
def self.project_root
|
19
|
-
config.project_root
|
20
|
-
end
|
21
|
-
|
22
8
|
class Config
|
23
|
-
attr_accessor :project_root
|
24
|
-
|
25
9
|
attr_writer :relative_url_root
|
26
10
|
|
11
|
+
def self.load_file
|
12
|
+
config_file = ::File.join(Ichiban.project_root, 'config.rb')
|
13
|
+
raise "#{config_file} must exist" unless ::File.exists?(config_file)
|
14
|
+
load config_file
|
15
|
+
end
|
16
|
+
|
27
17
|
def relative_url_root
|
28
|
-
@relative_url_root || raise(
|
18
|
+
@relative_url_root || raise("Ichiban.config.relative_url_root not set. Set inside block in config.rb like this: cfg.relative_url_root = '/'")
|
29
19
|
end
|
30
20
|
end
|
31
21
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Ichiban
|
2
|
+
class Deleter
|
3
|
+
# Deletes a file's associated destination file, if any.
|
4
|
+
def delete_dest(path)
|
5
|
+
file = Ichiban::File.from_abs(path)
|
6
|
+
# file will be nil if the path doesn't map to a known subclass of Ichiban::File. Furthermore,
|
7
|
+
# even if file is not nil, it may be a kind of Ichiban::File that does not have a destination.
|
8
|
+
if file and file.has_dest?
|
9
|
+
dest = file.dest
|
10
|
+
else
|
11
|
+
dest = nil
|
12
|
+
end
|
13
|
+
if dest and ::File.exists?(dest)
|
14
|
+
puts 'yep'
|
15
|
+
FileUtils.rm(dest)
|
16
|
+
else
|
17
|
+
puts 'nope'
|
18
|
+
end
|
19
|
+
|
20
|
+
# Log the deletion(s)
|
21
|
+
Ichiban.logger.deletion(path, dest)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Ichiban
|
2
|
+
module Dependencies
|
3
|
+
@graphs = {}
|
4
|
+
|
5
|
+
# graph_file_path is an absolute path.
|
6
|
+
def self.graph(graph_file_path)
|
7
|
+
ensure_graph_initialized(graph_file_path)
|
8
|
+
@graphs[graph_file_path]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.ensure_graph_initialized(graph_file_path)
|
12
|
+
unless @graphs[graph_file_path]
|
13
|
+
if ::File.exists?(graph_file_path)
|
14
|
+
@graphs[graph_file_path] = JSON.parse(::File.read(graph_file_path))
|
15
|
+
else
|
16
|
+
@graphs[graph_file_path] = {}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Loads the graph from disk if it's not already in memory. Updates the graph. Writes the new
|
22
|
+
# graph to disk. graph_file_path is an absolute path.
|
23
|
+
def self.update(graph_file_path, ind, dep)
|
24
|
+
ensure_graph_initialized(graph_file_path)
|
25
|
+
graph = @graphs[graph_file_path]
|
26
|
+
graph[ind] ||= []
|
27
|
+
graph[ind] << dep unless graph[ind].include?(dep)
|
28
|
+
::File.open(graph_file_path, 'w') do |f|
|
29
|
+
f << JSON.generate(graph)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/ichiban/file.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
module Ichiban
|
2
|
+
class File
|
3
|
+
attr_reader :abs
|
4
|
+
|
5
|
+
# Returns an absolute path in the compiled directory
|
6
|
+
def dest
|
7
|
+
::File.join(Ichiban.project_root, 'compiled', dest_rel_to_compiled)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns a new instance based on an absolute path. Will automatically pick the right subclass.
|
11
|
+
# Return nil if the file is not recognized.
|
12
|
+
def self.from_abs(abs)
|
13
|
+
rel = abs.slice(Ichiban.project_root.length..-1) # Relative to project root
|
14
|
+
rel.sub!(/^\//, '') # Remove leading slash
|
15
|
+
if rel.start_with?('html') and rel.end_with?('.html')
|
16
|
+
Ichiban::HTMLFile.new(rel)
|
17
|
+
elsif rel.start_with?('layouts') and rel.end_with?('.html')
|
18
|
+
Ichiban::LayoutFIle.new(rel)
|
19
|
+
elsif rel.start_with?('assets/js')
|
20
|
+
Ichiban::JSFile.new(rel)
|
21
|
+
elsif rel.start_with?('assets/css') and rel.end_with?('.css')
|
22
|
+
Ichiban::CSSFile.new(rel)
|
23
|
+
elsif rel.start_with?('assets/css') and rel.end_with?('.scss')
|
24
|
+
Ichiban::SCSSFile.new(rel)
|
25
|
+
elsif rel.start_with?('assets/img')
|
26
|
+
Ichiban::ImageFile.new(rel)
|
27
|
+
elsif rel.start_with?('assets/misc')
|
28
|
+
Ichiban::MiscAssetFile.new(rel)
|
29
|
+
elsif rel.start_with?('models')
|
30
|
+
Ichiban::ModelFile.new(rel)
|
31
|
+
elsif rel.start_with?('data')
|
32
|
+
Ichiban::DataFile.new(rel)
|
33
|
+
elsif rel.start_with?('scripts')
|
34
|
+
Ichiban::ScriptFile.new(rel)
|
35
|
+
elsif rel.start_with?('helpers')
|
36
|
+
Ichiban::HelperFile.new(rel)
|
37
|
+
else
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_dest?
|
43
|
+
respond_to?(:dest_rel_to_compiled)
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(rel)
|
47
|
+
@rel = rel
|
48
|
+
@abs = ::File.join(Ichiban.project_root, rel)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns a new path where the old extension is replaced with new_ext
|
52
|
+
def replace_ext(path, new_ext)
|
53
|
+
path.sub(/\..+$/, '.' + new_ext)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class HTMLFile < File
|
58
|
+
def dest_rel_to_compiled
|
59
|
+
d = @rel.slice('html/'.length..-1)
|
60
|
+
(d.end_with?('.markdown') or d.end_with?('.md')) ? replace_ext(d, 'html') : d
|
61
|
+
end
|
62
|
+
|
63
|
+
def update
|
64
|
+
Ichiban::HTMLCompiler.new(self).compile
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class LayoutFile < File
|
69
|
+
end
|
70
|
+
|
71
|
+
class JSFile < File
|
72
|
+
def dest_rel_to_compiled
|
73
|
+
File.join('js', @rel.slice('assets/js/'.length..-1))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class CSSFile < File
|
78
|
+
def dest_rel_to_compiled
|
79
|
+
File.join('css', @rel.slice('assets/css/'.length..-1))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class SCSSFile < File
|
84
|
+
def dest_rel_to_compiled
|
85
|
+
replace_ext(
|
86
|
+
File.join('css', @rel.slice('assets/css/'.length..-1)),
|
87
|
+
'css'
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class ImageFile < File
|
93
|
+
def dest_rel_to_compiled
|
94
|
+
File.join('img', @rel.slice('assets/img/'.length..-1))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class MiscAssetFile < File
|
99
|
+
def dest_rel_to_compiled
|
100
|
+
@rel.slice('assets/misc/'.length..-1)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class ModelFile < File
|
105
|
+
end
|
106
|
+
|
107
|
+
class DataFile < File
|
108
|
+
end
|
109
|
+
|
110
|
+
class ScriptFile < File
|
111
|
+
end
|
112
|
+
|
113
|
+
class HelperFile < File
|
114
|
+
end
|
115
|
+
end
|
data/lib/ichiban/helpers.rb
CHANGED
@@ -13,10 +13,6 @@ module Ichiban
|
|
13
13
|
@_erb_out << str
|
14
14
|
end
|
15
15
|
|
16
|
-
def content_for(ivar_name, &block)
|
17
|
-
instance_variable_set '@' + ivar_name, capture(&block)
|
18
|
-
end
|
19
|
-
|
20
16
|
def content_tag(*args)
|
21
17
|
options = args.extract_options!
|
22
18
|
name = args.shift
|
@@ -32,7 +28,7 @@ module Ichiban
|
|
32
28
|
|
33
29
|
def javascript_include_tag(js_file)
|
34
30
|
js_file = js_file + '.js' unless js_file.end_with?('.js')
|
35
|
-
path = normalize_path(File.join('/javascripts', js_file))
|
31
|
+
path = normalize_path(::File.join('/javascripts', js_file))
|
36
32
|
content_tag 'script', 'type' => 'text/javascript', 'src' => path
|
37
33
|
end
|
38
34
|
|
@@ -42,7 +38,7 @@ module Ichiban
|
|
42
38
|
|
43
39
|
alias_method :layouts, :layout
|
44
40
|
|
45
|
-
def
|
41
|
+
def _limit_options(hash, keys = [])
|
46
42
|
keys = keys.collect(&:to_s)
|
47
43
|
hash.inject({}) do |result, (key, value)|
|
48
44
|
result[key] = value if (keys.include?(key.to_s) or (block_given? and yield(key, value)))
|
@@ -86,11 +82,11 @@ module Ichiban
|
|
86
82
|
# If you don't specify a section, and your URLs don't have leading slashes,
|
87
83
|
# the hrefs will use relative URLs.
|
88
84
|
def nav(items, options = {})
|
89
|
-
ul_options =
|
85
|
+
ul_options = _limit_options(options, %w(id class)) { |key, value| key.to_s.start_with?('data-') }
|
90
86
|
content_tag('ul', ul_options) do
|
91
87
|
items.inject('') do |lis, (text, path, attrs)|
|
92
88
|
if options[:section]
|
93
|
-
path = File.join(options[:section], path)
|
89
|
+
path = ::File.join(options[:section], path)
|
94
90
|
end
|
95
91
|
path = normalize_path(path)
|
96
92
|
lis + content_tag('li', (attrs or {})) do
|
@@ -108,7 +104,7 @@ module Ichiban
|
|
108
104
|
# Otherwise, it will remain relative.
|
109
105
|
def normalize_path(path)
|
110
106
|
if path.start_with?('/')
|
111
|
-
File.join(relative_url_root, path)
|
107
|
+
::File.join(relative_url_root, path)
|
112
108
|
else
|
113
109
|
path
|
114
110
|
end
|
@@ -131,7 +127,7 @@ module Ichiban
|
|
131
127
|
|
132
128
|
def stylesheet_link_tag(css_file, media = 'screen')
|
133
129
|
css_file = css_file + '.css' unless css_file.end_with?('.css')
|
134
|
-
href = normalize_path(File.join('/stylesheets', css_file))
|
130
|
+
href = normalize_path(::File.join('/stylesheets', css_file))
|
135
131
|
tag 'link', 'href' => href, 'type' => 'text/css', 'rel' => 'stylesheet', 'media' => media
|
136
132
|
end
|
137
133
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Ichiban
|
2
|
+
class HTMLCompiler
|
3
|
+
def compile
|
4
|
+
::File.open(@html_file.dest, 'w') do |f|
|
5
|
+
f << compile_to_str
|
6
|
+
end
|
7
|
+
Ichiban.logger.compilation(@html_file.abs, @html_file.dest)
|
8
|
+
end
|
9
|
+
|
10
|
+
def compile_to_str
|
11
|
+
# Compile the HTML of the content page, but not the layouts (yet)
|
12
|
+
ctx = Ichiban::HTMLCompiler::Context.new(:_current_path => @html_file.dest_rel_to_compiled)
|
13
|
+
inner_html = Eruby.new(::File.read(@html_file.abs)).evaluate(ctx)
|
14
|
+
|
15
|
+
# Compile Markdown if necessary
|
16
|
+
if (@html_file.abs.end_with?('.markdown') or @html_file.abs.end_with?('.md'))
|
17
|
+
inner_html = Ichiban::Markdown.compile(inner_html) # Will look for installed Markdown gems
|
18
|
+
end
|
19
|
+
|
20
|
+
# Layouts
|
21
|
+
wrap_in_layouts(ctx, inner_html)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Takes an instance of Ichiban::HTMLFile
|
25
|
+
def initialize(html_file)
|
26
|
+
@html_file = html_file
|
27
|
+
end
|
28
|
+
|
29
|
+
def wrap_in_layouts(ctx, inner_rhtml)
|
30
|
+
ctx.layout_stack.reverse.inject(inner_rhtml) do |html, layout_name|
|
31
|
+
layout_path = ::File.join(Ichiban.project_root, 'layouts', layout_name + '.html')
|
32
|
+
unless ::File.exists?(layout_path)
|
33
|
+
raise "Layout does not exist: #{layout_path}"
|
34
|
+
end
|
35
|
+
eruby = Eruby.new(
|
36
|
+
::File.read(layout_path),
|
37
|
+
:filename => layout_path
|
38
|
+
)
|
39
|
+
html = eruby.evaluate(ctx) { html }
|
40
|
+
Ichiban::Dependencies.update('.layout_dependencies.json', layout_name, @html_file.abs)
|
41
|
+
html
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Eruby < Erubis::Eruby
|
46
|
+
def add_preamble(src)
|
47
|
+
src << "@_erb_out = _buf = '';"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Context < Erubis::Context
|
52
|
+
include Ichiban::Helpers
|
53
|
+
include Erubis::XmlHelper
|
54
|
+
include ERB::Util # Give us #h
|
55
|
+
|
56
|
+
def layout_stack
|
57
|
+
@_layout_stack or ['default']
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/ichiban/logger.rb
CHANGED
@@ -4,16 +4,72 @@ module Ichiban
|
|
4
4
|
end
|
5
5
|
|
6
6
|
class Logger
|
7
|
+
def self.ansi?
|
8
|
+
@ansi
|
9
|
+
end
|
10
|
+
|
11
|
+
def ansi?
|
12
|
+
self.class.ansi?
|
13
|
+
end
|
14
|
+
|
7
15
|
def compilation(src, dst)
|
8
|
-
|
16
|
+
src = src.slice(Ichiban.project_root.length + 1..-1)
|
17
|
+
dst = dst.slice(Ichiban.project_root.length + 1..-1)
|
18
|
+
msg = "#{src} -> #{dst}"
|
19
|
+
if ansi?
|
20
|
+
msg = ANSI.color(msg, :green)
|
21
|
+
end
|
22
|
+
out msg
|
23
|
+
end
|
24
|
+
|
25
|
+
def deletion(src, dst = nil)
|
26
|
+
src = src.slice(Ichiban.project_root.length + 1..-1)
|
27
|
+
if dst
|
28
|
+
dst = dst.slice(Ichiban.project_root.length + 1..-1)
|
29
|
+
end
|
30
|
+
if dst
|
31
|
+
msg = "Deleted: #{src} -> #{dst}"
|
32
|
+
else
|
33
|
+
msg = "Deleted: #{src}"
|
34
|
+
end
|
35
|
+
if ansi?
|
36
|
+
msg = ANSI.color(msg, :cyan)
|
37
|
+
end
|
38
|
+
out msg
|
9
39
|
end
|
10
40
|
|
11
41
|
def exception(exc)
|
12
|
-
|
42
|
+
msg = "#{exc.class.to_s}: #{exc.message}\n" + exc.backtrace.collect { |line| ' ' + line }.join("\n")
|
43
|
+
if ansi?
|
44
|
+
msg = ANSI.color(msg, :red)
|
45
|
+
end
|
46
|
+
out msg
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize
|
50
|
+
@out = STDOUT
|
51
|
+
end
|
52
|
+
|
53
|
+
def out=(io)
|
54
|
+
@out = io
|
13
55
|
end
|
14
56
|
|
15
57
|
def out(msg)
|
16
|
-
puts msg
|
58
|
+
@out.puts msg
|
59
|
+
end
|
60
|
+
|
61
|
+
def warn(msg)
|
62
|
+
if ansi?
|
63
|
+
msg = ANSI.color(msg, :red)
|
64
|
+
end
|
65
|
+
out msg
|
66
|
+
end
|
67
|
+
|
68
|
+
begin
|
69
|
+
require 'ansi'
|
70
|
+
@ansi = true
|
71
|
+
rescue LoadError
|
72
|
+
Ichiban.logger.out("Try `gem install ansi` for colorized output")
|
17
73
|
end
|
18
74
|
end
|
19
75
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Ichiban
|
2
|
+
module Markdown
|
3
|
+
def self.compile(src)
|
4
|
+
require_markdown
|
5
|
+
case @strategy
|
6
|
+
when :redcarpet
|
7
|
+
@redcarpet.render(src)
|
8
|
+
when :maruku
|
9
|
+
Maruku.new(src).to_html
|
10
|
+
when :rdiscount
|
11
|
+
RDiscount.new(src).to_html
|
12
|
+
else
|
13
|
+
raise "unrecognized @strategy: #{@strategy}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.require_markdown
|
18
|
+
unless @markdown_loaded
|
19
|
+
case Ichiban.try_require('redcarpet', 'maruku', 'rdiscount')
|
20
|
+
when 'redcarpet'
|
21
|
+
@redcarpet = Redcarpet::Markdown.new(Redcarpet::Render::XHTML.new)
|
22
|
+
@strategy = :redcarpet
|
23
|
+
when 'maruku'
|
24
|
+
@strategy = :maruku
|
25
|
+
when 'rdiscount'
|
26
|
+
@strategy = :rdiscount
|
27
|
+
else
|
28
|
+
raise "Your Ichiban project contains at least one Markdown file. To process it, you need to install either the redcarpet or maruku gem."
|
29
|
+
end
|
30
|
+
@markdown_loaded = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/ichiban/watcher.rb
CHANGED
@@ -1,7 +1,39 @@
|
|
1
1
|
module Ichiban
|
2
|
-
class Watcher
|
3
|
-
def
|
4
|
-
|
2
|
+
class Watcher
|
3
|
+
def initialize(options = {})
|
4
|
+
@options = {
|
5
|
+
:latency => 0.5
|
6
|
+
}.merge(options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def start
|
10
|
+
@listener = Listen.to(
|
11
|
+
::File.join(Ichiban.project_root, 'html')#,
|
12
|
+
#::File.join(Ichiban.project_root, 'assets')
|
13
|
+
)
|
14
|
+
.ignore(/.listen_test$/)
|
15
|
+
.latency(@options[:latency])
|
16
|
+
.change do |modified, added, deleted|
|
17
|
+
begin
|
18
|
+
(modified + added).each do |path|
|
19
|
+
if file = Ichiban::File.from_abs(path)
|
20
|
+
file.update
|
21
|
+
end
|
22
|
+
end
|
23
|
+
rescue => exc
|
24
|
+
Ichiban.logger.exception(exc)
|
25
|
+
end
|
26
|
+
deleted.each do |path|
|
27
|
+
Ichiban::Deleter.new.delete(path)
|
28
|
+
end
|
29
|
+
end.start(false) # nonblocking
|
30
|
+
end
|
31
|
+
|
32
|
+
def stop
|
33
|
+
if @listener
|
34
|
+
@listener.stop
|
35
|
+
@listener = nil
|
36
|
+
end
|
5
37
|
end
|
6
38
|
end
|
7
39
|
end
|
data/lib/ichiban.rb
CHANGED
@@ -1,25 +1,52 @@
|
|
1
|
-
|
1
|
+
# Standard lib
|
2
2
|
require 'fileutils'
|
3
|
+
require 'json'
|
4
|
+
require 'erb' # Just for the helpers
|
5
|
+
|
6
|
+
# Gems
|
3
7
|
require 'active_support/core_ext/class/attribute'
|
4
8
|
require 'active_support/core_ext/object/blank'
|
5
9
|
require 'active_support/inflector'
|
6
|
-
require 'erubis'
|
7
|
-
require 'maruku'
|
8
10
|
require 'sass'
|
11
|
+
require 'listen'
|
12
|
+
require 'erubis'
|
13
|
+
require 'rake'
|
9
14
|
|
10
|
-
# Order matters!
|
11
|
-
require 'ichiban/command'
|
12
|
-
require 'ichiban/layouts'
|
13
|
-
require 'ichiban/helpers'
|
14
|
-
require 'ichiban/compilation'
|
15
|
+
# Ichiban files. Order matters!
|
15
16
|
require 'ichiban/config'
|
16
|
-
require 'ichiban/erb_page'
|
17
|
-
require 'ichiban/files'
|
18
17
|
require 'ichiban/logger'
|
19
|
-
require 'ichiban/
|
20
|
-
require 'ichiban/
|
21
|
-
require 'ichiban/
|
22
|
-
require 'ichiban/
|
23
|
-
require 'ichiban/
|
24
|
-
require 'ichiban/
|
25
|
-
require 'ichiban/
|
18
|
+
require 'ichiban/command'
|
19
|
+
require 'ichiban/watcher'
|
20
|
+
require 'ichiban/deleter'
|
21
|
+
require 'ichiban/file'
|
22
|
+
require 'ichiban/helpers'
|
23
|
+
require 'ichiban/html_compiler'
|
24
|
+
require 'ichiban/markdown'
|
25
|
+
require 'ichiban/dependencies'
|
26
|
+
require 'ichiban/helpers'
|
27
|
+
|
28
|
+
module Ichiban
|
29
|
+
# In addition to setting the variable, this loads the config file
|
30
|
+
def self.project_root=(path)
|
31
|
+
@project_root = path
|
32
|
+
if path # It's valid to set project_root to nil, though this would likely only happen in tests
|
33
|
+
Ichiban::Config.load_file
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.project_root
|
38
|
+
@project_root
|
39
|
+
end
|
40
|
+
|
41
|
+
# Try to load the libraries
|
42
|
+
def self.try_require(*gems)
|
43
|
+
gems.each do |gem|
|
44
|
+
begin
|
45
|
+
require gem
|
46
|
+
return gem
|
47
|
+
rescue LoadError
|
48
|
+
end
|
49
|
+
end
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|