tipsy 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +6 -11
- data/README.md +24 -1
- data/Rakefile +13 -9
- data/bin/tipsy +4 -2
- data/lib/templates/server/htaccess.erb +14 -0
- data/lib/templates/site/Gemfile +19 -0
- data/lib/templates/site/assets/stylesheets/_config.css.scss +1 -0
- data/lib/templates/site/assets/stylesheets/screen.css.scss +1 -0
- data/lib/templates/site/config.rb +52 -0
- data/lib/templates/site/deploy.yml +27 -0
- data/lib/templates/site/layouts/default.html.erb +41 -0
- data/lib/templates/site/views/index.html.erb +2 -0
- data/lib/tipsy/compressors/{css.rb → css_compressor.rb} +0 -0
- data/lib/tipsy/compressors/javascript_compressor.rb +44 -0
- data/lib/tipsy/configuration.rb +9 -0
- data/lib/tipsy/handler/all.rb +4 -0
- data/lib/tipsy/handler/asset.rb +93 -0
- data/lib/tipsy/handler/erb.rb +42 -0
- data/lib/tipsy/handler/php.rb +36 -0
- data/lib/tipsy/{sass/template.rb → handler/sass/importer.rb} +15 -53
- data/lib/tipsy/handler/sass/resolver.rb +30 -0
- data/lib/tipsy/handler/sass.rb +36 -0
- data/lib/tipsy/handler/static.rb +30 -0
- data/lib/tipsy/helpers/asset_paths.rb +29 -1
- data/lib/tipsy/helpers/asset_tags.rb +1 -1
- data/lib/tipsy/helpers/capture.rb +12 -41
- data/lib/tipsy/helpers/rendering.rb +46 -0
- data/lib/tipsy/helpers/sass.rb +17 -6
- data/lib/tipsy/helpers/tag.rb +6 -9
- data/lib/tipsy/helpers.rb +13 -16
- data/lib/tipsy/runner.rb +82 -0
- data/lib/tipsy/runners/compiler.rb +189 -0
- data/lib/tipsy/runners/deployer.rb +7 -0
- data/lib/tipsy/runners/generator.rb +24 -0
- data/lib/tipsy/server.rb +56 -114
- data/lib/tipsy/site.rb +88 -0
- data/lib/tipsy/utils/logger.rb +47 -0
- data/lib/tipsy/utils/system.rb +115 -0
- data/lib/tipsy/utils/system_test.rb +103 -0
- data/lib/tipsy/version.rb +1 -1
- data/lib/tipsy/view/base.rb +55 -0
- data/lib/tipsy/view/context.rb +28 -0
- data/lib/tipsy/view/path.rb +44 -0
- data/lib/tipsy/view.rb +14 -68
- data/lib/tipsy.rb +30 -67
- data/{lib/tipsy/project/assets/javascripts/site.js → test/fixtures/capture.html.erb} +0 -0
- data/test/helpers/tag_test.rb +22 -0
- data/{lib/tipsy/project/assets/stylesheets/screen.css.scss → test/root/compiled/fake.txt} +0 -0
- data/test/root/{test/assets/javascripts/test.js → compiled/sub-path/fake.txt} +0 -0
- data/test/root/{development/assets/javascripts/test.js → compiled/sub-path-with-skip/fake.txt} +0 -0
- data/test/root/layouts/default.html.erb +0 -0
- data/test/root/views/index.html.erb +0 -0
- data/test/root/views/page.html.erb +0 -0
- data/test/root/views/sub/page.html.erb +0 -0
- data/test/root/views/sub/tertiary/index.html.erb +0 -0
- data/test/runner/compiler_test.rb +49 -0
- data/test/test_helper.rb +160 -21
- data/test/unit/site_test.rb +23 -0
- data/test/unit/tipsy_test.rb +13 -0
- data/test/unit/utils/system_test.rb +26 -0
- data/test/view/base_test.rb +34 -0
- data/test/view/path_test.rb +34 -0
- data/tipsy.gemspec +10 -7
- metadata +113 -84
- data/lib/tipsy/application.rb +0 -86
- data/lib/tipsy/builder.rb +0 -26
- data/lib/tipsy/builders/base.rb +0 -64
- data/lib/tipsy/builders/export.rb +0 -16
- data/lib/tipsy/builders/project.rb +0 -40
- data/lib/tipsy/builders/remote.rb +0 -14
- data/lib/tipsy/compressors/javascript.rb +0 -25
- data/lib/tipsy/logger.rb +0 -62
- data/lib/tipsy/project/Gemfile +0 -8
- data/lib/tipsy/project/config.erb +0 -19
- data/lib/tipsy/project/helpers/site_helper.rb +0 -4
- data/lib/tipsy/project/views/_layout.html.erb +0 -16
- data/test/fixtures/about.html +0 -1
- data/test/fixtures/contact.html +0 -1
- data/test/fixtures/index.html +0 -1
- data/test/functional/page_test.rb +0 -33
- data/test/root/.gitignore +0 -7
- data/test/root/development/assets/stylesheets/screen.css.scss +0 -3
- data/test/root/development/config.rb +0 -6
- data/test/root/development/views/_layout.html.erb +0 -20
- data/test/root/development/views/index.html.erb +0 -3
- data/test/root/test/assets/stylesheets/screen.css.scss +0 -3
- data/test/root/test/config.rb +0 -6
- data/test/root/test/views/_layout.html.erb +0 -1
- data/test/root/test/views/about/index.html +0 -1
- data/test/root/test/views/contact.html +0 -1
- data/test/root/test/views/index.html.erb +0 -1
- data/test/unit/helpers/asset_paths_test.rb +0 -14
- data/test/unit/helpers_test.rb +0 -22
- data/test/unit/server_test.rb +0 -1
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
require 'sass/engine'
|
3
|
+
require 'tipsy/handler/sass/resolver'
|
4
|
+
require 'tipsy/handler/sass/importer'
|
5
|
+
|
6
|
+
module Tipsy
|
7
|
+
module Handler
|
8
|
+
class SassHandler < ::Tilt::ScssTemplate
|
9
|
+
self.default_mime_type = 'text/css'
|
10
|
+
|
11
|
+
def prepare; end;
|
12
|
+
|
13
|
+
def evaluate(scope, locals, &block)
|
14
|
+
::Sass::Engine.new(data, sass_engine_options(scope)).render
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def sass_engine_options(scope)
|
20
|
+
options = {
|
21
|
+
:filename => eval_file,
|
22
|
+
:line => line,
|
23
|
+
:syntax => :scss,
|
24
|
+
:importer => Importer.new(scope)
|
25
|
+
}
|
26
|
+
begin
|
27
|
+
require 'compass'
|
28
|
+
options.reverse_merge!(::Compass.sass_engine_options)
|
29
|
+
rescue LoadError
|
30
|
+
end
|
31
|
+
ensure options
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module Tipsy
|
4
|
+
module Handler
|
5
|
+
##
|
6
|
+
# Handles serving/delivering static files from the
|
7
|
+
# /public directory.
|
8
|
+
#
|
9
|
+
class StaticHandler
|
10
|
+
attr_reader :app, :try_files, :static
|
11
|
+
|
12
|
+
def initialize(app, options)
|
13
|
+
@app = app
|
14
|
+
@try_files = ['', *options.delete(:try)]
|
15
|
+
@static = ::Rack::Static.new(lambda { [404, {}, []] }, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(env)
|
19
|
+
pathinfo = env['PATH_INFO']
|
20
|
+
found = nil
|
21
|
+
try_files.each do |path|
|
22
|
+
response = static.call(env.merge!({ 'PATH_INFO' => pathinfo + path }))
|
23
|
+
break if 404 != response[0] && found = response
|
24
|
+
end
|
25
|
+
found or app.call(env.merge!('PATH_INFO' => pathinfo))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -6,13 +6,41 @@ module Tipsy
|
|
6
6
|
|
7
7
|
def asset_path(path)
|
8
8
|
return path if path.match(/^https?:/) || Pathname.new(path).absolute?
|
9
|
-
"/" <<
|
9
|
+
"/" << path_for_asset_type(path)
|
10
10
|
end
|
11
11
|
|
12
12
|
def path_with_ext(path, ext)
|
13
13
|
return path if path.match(/^https?:/) || path.ends_with?(".#{ext}")
|
14
14
|
[path, ext].join('.')
|
15
15
|
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def path_for_asset_type(path)
|
20
|
+
result = if is_javascript?(path)
|
21
|
+
File.join(Tipsy::Site.javascripts_path, path)
|
22
|
+
elsif is_css?(path)
|
23
|
+
File.join(Tipsy::Site.css_path, path)
|
24
|
+
elsif is_image?(path)
|
25
|
+
File.join(Tipsy::Site.images_path, path)
|
26
|
+
else
|
27
|
+
File.join(Tipsy::Site.asset_path, path)
|
28
|
+
end
|
29
|
+
result = (Pathname.new(result).absolute? ? result.sub("/",'') : result)
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
def is_image?(path)
|
34
|
+
!!(['.png', '.jpg', '.jpeg', '.gif', '.svg', '.bmp'].detect{ |p| path.ends_with?(p) })
|
35
|
+
end
|
36
|
+
|
37
|
+
def is_css?(path)
|
38
|
+
path.ends_with?('.css')
|
39
|
+
end
|
40
|
+
|
41
|
+
def is_javascript?(path)
|
42
|
+
path.ends_with?(".js")
|
43
|
+
end
|
16
44
|
|
17
45
|
end
|
18
46
|
end
|
@@ -23,7 +23,7 @@ module Tipsy
|
|
23
23
|
}).stringify_keys!
|
24
24
|
|
25
25
|
files.map{ |file|
|
26
|
-
|
26
|
+
tag('link', { 'href' => asset_path(path_with_ext(file, 'css')), 'rel' => "stylesheet" }.merge!(html_attrs))
|
27
27
|
}.join("\n")
|
28
28
|
end
|
29
29
|
|
@@ -5,51 +5,22 @@ module Tipsy
|
|
5
5
|
def content_for(name, content = nil, &block)
|
6
6
|
content ||= capture(&block) if block_given?
|
7
7
|
instance_variable_set("@_#{name}", content) if content
|
8
|
-
instance_variable_get("@_#{name}") unless content
|
9
|
-
end
|
10
|
-
|
11
|
-
def capture(&block)
|
12
|
-
buffer = ""
|
13
|
-
orig_buffer, @_output_buffer = @_output_buffer, buffer
|
14
|
-
yield
|
15
|
-
buffer
|
16
|
-
ensure
|
17
|
-
@_output_buffer = orig_buffer
|
8
|
+
instance_variable_get("@_#{name}").to_s unless content
|
18
9
|
end
|
19
10
|
|
20
|
-
def
|
21
|
-
|
22
|
-
assert_valid_keys!(options, :template, :partial, :collection, :locals)
|
23
|
-
|
24
|
-
if template = options.delete(:template)
|
25
|
-
_render_template(template, options)
|
26
|
-
elsif template = options.delete(:partial)
|
27
|
-
_render_template(template, options, true)
|
28
|
-
else
|
29
|
-
raise 'Render requires a :template or :partial option.'
|
30
|
-
end
|
11
|
+
def content_for?(name)
|
12
|
+
!instance_variable_get("@_#{name}").nil?
|
31
13
|
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
results = Tilt[to_render].new(to_render, nil)
|
41
|
-
return results.render(self, local_vars)
|
42
|
-
end
|
43
|
-
raise "Missing #{ partial ? 'partial' : 'template' } #{name}."
|
44
|
-
end
|
45
|
-
|
46
|
-
def assert_valid_keys!(hash, *keys)
|
47
|
-
left = hash.keys.reject{ |k| keys.include?(k) }
|
48
|
-
unless left.empty?
|
49
|
-
raise 'Invalid keys for hash: #{left.join(", ")}'
|
50
|
-
end
|
14
|
+
|
15
|
+
def capture(*args)
|
16
|
+
buffer ||= ""
|
17
|
+
@output_buffer, old_buffer = buffer, @output_buffer
|
18
|
+
yield
|
19
|
+
@output_buffer
|
20
|
+
ensure
|
21
|
+
@output_buffer = old_buffer
|
51
22
|
end
|
52
23
|
|
53
|
-
end
|
24
|
+
end
|
54
25
|
end
|
55
26
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Tipsy
|
2
|
+
module Helpers
|
3
|
+
module Rendering
|
4
|
+
|
5
|
+
def render(options = {})
|
6
|
+
options.symbolize_keys!
|
7
|
+
assert_valid_keys!(options, :template, :partial, :collection, :locals)
|
8
|
+
|
9
|
+
if template = options.delete(:template)
|
10
|
+
render_inline_template(template, options)
|
11
|
+
elsif template = options.delete(:partial)
|
12
|
+
render_inline_template(template, options, true)
|
13
|
+
else
|
14
|
+
raise 'Render requires a :template or :partial option.'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def render_inline_template(path, options = {}, partial = false)
|
21
|
+
|
22
|
+
to_render = File.basename(path)
|
23
|
+
to_render = "_#{to_render}" if partial
|
24
|
+
render_path = Pathname.new(path)
|
25
|
+
render_path = render_path.absolute? ? render_path : lookup_context.locate_relative(render_path.dirname, to_render)
|
26
|
+
|
27
|
+
unless render_path.nil?
|
28
|
+
local_vars = options.delete(:locals) || {}
|
29
|
+
results = Tilt[render_path].new(render_path, nil)
|
30
|
+
return results.render(self, local_vars)
|
31
|
+
end
|
32
|
+
|
33
|
+
raise "Missing #{ partial ? 'partial' : 'template' } #{to_render}."
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_valid_keys!(hash, *keys)
|
38
|
+
left = hash.keys.reject{ |k| keys.include?(k) }
|
39
|
+
unless left.empty?
|
40
|
+
raise 'Invalid keys for hash: #{left.join(", ")}'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/tipsy/helpers/sass.rb
CHANGED
@@ -5,27 +5,38 @@ module Tipsy
|
|
5
5
|
module Sass
|
6
6
|
|
7
7
|
def asset_path(asset, kind)
|
8
|
-
::Sass::Script::String.new(public_path(asset
|
8
|
+
::Sass::Script::String.new(public_path(asset, kind), true)
|
9
9
|
end
|
10
10
|
|
11
11
|
def asset_url(asset, kind)
|
12
|
-
::Sass::Script::String.new(%Q{url(#{
|
12
|
+
::Sass::Script::String.new(%Q{url(#{asset_path(asset, kind)})})
|
13
13
|
end
|
14
14
|
|
15
|
-
[:image, :font, :
|
15
|
+
[:image, :font, :stylesheet].each do |asset_class|
|
16
16
|
class_eval %Q{
|
17
17
|
def #{asset_class}_path(asset)
|
18
|
-
asset_path(asset, Sass::Script::String.new("#{asset_class}"))
|
18
|
+
asset_path(asset, ::Sass::Script::String.new("#{asset_class}"))
|
19
19
|
end
|
20
20
|
def #{asset_class}_url(asset)
|
21
|
-
asset_url(asset, Sass::Script::String.new("#{asset_class}"))
|
21
|
+
asset_url(asset, ::Sass::Script::String.new("#{asset_class}"))
|
22
22
|
end
|
23
23
|
}, __FILE__, __LINE__ - 6
|
24
24
|
end
|
25
25
|
|
26
26
|
protected
|
27
27
|
def public_path(asset, kind)
|
28
|
-
|
28
|
+
|
29
|
+
check = ::Pathname.new(asset.to_s)
|
30
|
+
return asset.to_s if check.absolute?
|
31
|
+
|
32
|
+
path = case kind.to_s
|
33
|
+
when 'stylesheet' || 'css' then Tipsy::Site.css_path
|
34
|
+
when 'javascript' || 'js' then Tipsy::Site.javascripts_path
|
35
|
+
when 'image' || 'images' then Tipsy::Site.images_path
|
36
|
+
when 'font' || 'fonts' then Tipsy::Site.fonts_path
|
37
|
+
else "/"
|
38
|
+
end
|
39
|
+
path.to_s
|
29
40
|
end
|
30
41
|
end
|
31
42
|
end
|
data/lib/tipsy/helpers/tag.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
module Tipsy
|
2
|
-
module Helpers
|
3
|
-
|
2
|
+
module Helpers
|
4
3
|
module Tag
|
5
|
-
include Capture
|
4
|
+
include Tipsy::Helpers::Capture
|
6
5
|
|
7
6
|
def tag(name, html_attrs = {}, open = false)
|
8
7
|
"<#{name}#{make_attributes(html_attrs)}#{open ? ">" : " />"}"
|
9
8
|
end
|
10
9
|
|
11
|
-
def content_tag(name, content = nil, html_attrs = {}, &
|
10
|
+
def content_tag(name, content = nil, html_attrs = {}, &capt)
|
12
11
|
buffer = "<#{name}#{make_attributes(html_attrs)}>"
|
13
|
-
content = capture(&
|
12
|
+
content = capture(&capt) if block_given?
|
14
13
|
"<#{name}#{make_attributes(html_attrs)}>#{content}</#{name}>"
|
15
14
|
end
|
16
15
|
|
@@ -34,9 +33,7 @@ module Tipsy
|
|
34
33
|
attrs << "#{key}=#{value.inspect}"
|
35
34
|
end
|
36
35
|
(attrs.empty? ? "" : " #{attrs.join(" ")}")
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
36
|
+
end
|
37
|
+
end
|
41
38
|
end
|
42
39
|
end
|
data/lib/tipsy/helpers.rb
CHANGED
@@ -1,32 +1,29 @@
|
|
1
1
|
require 'active_support/core_ext/array'
|
2
|
-
|
3
2
|
require 'tipsy/helpers/asset_paths'
|
4
3
|
require 'tipsy/helpers/capture'
|
5
4
|
require 'tipsy/helpers/tag'
|
6
5
|
require 'tipsy/helpers/asset_tags'
|
7
|
-
require 'tipsy/helpers/
|
6
|
+
require 'tipsy/helpers/rendering'
|
8
7
|
|
9
8
|
module Tipsy
|
10
9
|
module Helpers
|
11
|
-
extend ActiveSupport::Concern
|
12
10
|
include Capture
|
13
11
|
include Tag
|
14
12
|
include AssetPaths
|
15
13
|
include AssetTags
|
14
|
+
include Rendering
|
16
15
|
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def __initialize_helpers
|
21
|
-
module_names = []
|
22
|
-
includes = Dir.glob(File.expand_path(Tipsy.root) << "/helpers/*.rb").inject([]) do |arr, helper|
|
23
|
-
module_names << File.basename(helper, '.rb').classify
|
24
|
-
arr.concat File.open(helper).readlines
|
25
|
-
end
|
26
|
-
module_names.each{ |mod| includes.concat(["\n include #{mod}"]) }
|
27
|
-
self.class_eval(includes.join("\n"))
|
28
|
-
end
|
29
|
-
end
|
16
|
+
extend ActiveSupport::Concern
|
30
17
|
|
18
|
+
included do
|
19
|
+
module_names = []
|
20
|
+
includes = Dir.glob(File.expand_path(Tipsy.root) << "/helpers/*.rb").inject([]) do |arr, helper|
|
21
|
+
module_names << File.basename(helper, '.rb').classify
|
22
|
+
arr.concat File.open(helper).readlines
|
23
|
+
end
|
24
|
+
module_names.each{ |mod| includes.concat(["\n include #{mod}"]) }
|
25
|
+
eval(includes.join("\n"), binding)
|
26
|
+
end
|
31
27
|
end
|
28
|
+
|
32
29
|
end
|
data/lib/tipsy/runner.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'tipsy/site'
|
3
|
+
|
4
|
+
module Tipsy
|
5
|
+
class Runner
|
6
|
+
attr_reader :args, :site
|
7
|
+
|
8
|
+
def initialize(ar, stdin)
|
9
|
+
@args = [ar].flatten
|
10
|
+
cmd = args.first || "serve"
|
11
|
+
cmd = "serve" if ['', 'run', 's', 'serve'].include?(cmd)
|
12
|
+
cmd = "create" if cmd == 'new'
|
13
|
+
args.shift
|
14
|
+
Tipsy::Site.configure!
|
15
|
+
@site = Tipsy::Site.new
|
16
|
+
send(:"#{cmd}")
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Create an instance of Rack::Builder to serve the "static" site.
|
21
|
+
# @usage From the command line,
|
22
|
+
# run `tipsy`, `tipsy serve` or simply `tipsy s`
|
23
|
+
#
|
24
|
+
def serve
|
25
|
+
require 'tipsy/server'
|
26
|
+
require 'tipsy/view'
|
27
|
+
require 'rack'
|
28
|
+
|
29
|
+
app = Rack::Builder.new {
|
30
|
+
use Rack::Reloader
|
31
|
+
use Rack::ShowStatus
|
32
|
+
use Rack::ShowExceptions
|
33
|
+
use Tipsy::Handler::StaticHandler, :root => Tipsy::Site.config.public_path, :urls => %w[/]
|
34
|
+
run Rack::Cascade.new([
|
35
|
+
Rack::URLMap.new(Tipsy::Handler::AssetHandler.map!),
|
36
|
+
Tipsy::Server.new
|
37
|
+
])
|
38
|
+
}.to_app
|
39
|
+
|
40
|
+
conf = Tipsy::Site.config
|
41
|
+
options = {
|
42
|
+
:Host => conf.address,
|
43
|
+
:Port => conf.port
|
44
|
+
}
|
45
|
+
|
46
|
+
Tipsy::Server.run!(app, options)
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Generates a new site in the specified path.
|
51
|
+
# @usage From the command line, run `tipsy new name_of_site_to_create`
|
52
|
+
#
|
53
|
+
def create
|
54
|
+
Tipsy::Runners::Generator.new(args, @site)
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Responsible for compiling the final site for deployment. This process will
|
59
|
+
# take the following steps:
|
60
|
+
#
|
61
|
+
# 1. Copy files recursively from /public
|
62
|
+
# 2. Compile javascripts, sprites, and css files into their respective directories within the compile folder
|
63
|
+
# 3. Render all templates and place in their proper directories within the compile folder.
|
64
|
+
#
|
65
|
+
# @usage From the command line, run `tipsy compile`
|
66
|
+
#
|
67
|
+
def compile
|
68
|
+
Tipsy::Runners::Compiler.new
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
##
|
73
|
+
# Responsible for deploying a compiled site to a production server.
|
74
|
+
# @usage From the command line, run `tipsy deploy`
|
75
|
+
#
|
76
|
+
def deploy
|
77
|
+
Tipsy::Runners::Deployer.new
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
module Tipsy
|
4
|
+
module Runners
|
5
|
+
class Compiler
|
6
|
+
include Tipsy::Utils::System
|
7
|
+
|
8
|
+
attr_reader :source_path, :dest_path, :scope
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@source_path = config.public_path
|
12
|
+
@dest_path = config.compile_to
|
13
|
+
excluded = [excludes, config.compile.preserve].flatten.uniq
|
14
|
+
@_excludes = excluded
|
15
|
+
clean_existing!
|
16
|
+
|
17
|
+
[:public, :images, :assets, :templates].each do |m|
|
18
|
+
send(:"compile_#{m}!")
|
19
|
+
end
|
20
|
+
|
21
|
+
cleanup!
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def config
|
26
|
+
Tipsy::Site.config
|
27
|
+
end
|
28
|
+
|
29
|
+
def skip_file?(src)
|
30
|
+
return false unless scope == :clean || scope == :public
|
31
|
+
check = case scope
|
32
|
+
when :clean then config.compile.preserve
|
33
|
+
when :public then config.compile.skip
|
34
|
+
else []
|
35
|
+
end
|
36
|
+
check.detect{ |path| File.basename(src) == path }
|
37
|
+
end
|
38
|
+
|
39
|
+
alias :skip_path? :skip_file?
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def clean_existing!
|
44
|
+
@scope = :clean
|
45
|
+
return true unless ::File.directory?(dest_path)
|
46
|
+
::Find.find(dest_path) do |path|
|
47
|
+
next if path == config.compile_to
|
48
|
+
if ::File.directory?(path)
|
49
|
+
if skip_path?(path)
|
50
|
+
::Find.prune
|
51
|
+
elsif empty_dir?(path)
|
52
|
+
rm_rf(path)
|
53
|
+
::Find.prune
|
54
|
+
else
|
55
|
+
next
|
56
|
+
end
|
57
|
+
elsif ::File.exists?(path)
|
58
|
+
unlink(path) unless skip_file?(path)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
Dir["#{dest_path}/**/**"].select{ |path| File.directory?(path) }.each do |dir|
|
63
|
+
next if config.compile_to == dir
|
64
|
+
rm_rf(dir) if empty_dir?(dir)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
def compile_public!
|
70
|
+
@scope = :public
|
71
|
+
log_action("copy", "public files")
|
72
|
+
copy_tree(source_path, dest_path)
|
73
|
+
end
|
74
|
+
|
75
|
+
def compile_images!
|
76
|
+
@scope = :images
|
77
|
+
log_action("compile", "images")
|
78
|
+
image_path = File.join(dest_path, config.images_path)
|
79
|
+
mkdir_p image_path
|
80
|
+
copy_tree(File.join(Tipsy.root, 'assets', 'images'), image_path)
|
81
|
+
end
|
82
|
+
|
83
|
+
def compile_assets!
|
84
|
+
@scope = :assets
|
85
|
+
log_action('compile', 'assets')
|
86
|
+
handler = Tipsy::Handler::AssetHandler.new
|
87
|
+
handler.prepare_compiler
|
88
|
+
|
89
|
+
config.compile.assets.each do |file|
|
90
|
+
handler.each_logical_path do |path|
|
91
|
+
should_compile = path.is_a?(Regexp) ? file.match(path) : File.fnmatch(file.to_s, path)
|
92
|
+
next unless should_compile?
|
93
|
+
|
94
|
+
if asset = handler.find_asset(path)
|
95
|
+
log_action("compile", asset.logical_path)
|
96
|
+
writepath = build_asset_path(asset, file)
|
97
|
+
asset.write_to(writepath)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def compile_templates!
|
105
|
+
dirs = ::Dir[::File.join(Tipsy.root, "views") << "/**/**"].reject do |dir|
|
106
|
+
dir == '.' || dir == ".." || dir[0] == "." || !::File.directory?(dir)
|
107
|
+
end
|
108
|
+
dirs = dirs.reject do |dir|
|
109
|
+
# Skip folders that only have partials or all files/dirs excluded
|
110
|
+
::Dir.entries(dir).reject{ |f| f.to_s[0] == "_" || excluded?(f) }.empty?
|
111
|
+
end.push(File.join(Tipsy.root, "views"))
|
112
|
+
|
113
|
+
view_path = ::File.join(Tipsy.root, "views")
|
114
|
+
|
115
|
+
dirs.each do |path|
|
116
|
+
templates_in_path(path).each do |tpl|
|
117
|
+
next if ::File.directory?(File.join(path, tpl))
|
118
|
+
|
119
|
+
route = ::Pathname.new(path.gsub("#{Tipsy.root}/views", ""))
|
120
|
+
route = "/" if route.blank?
|
121
|
+
route = "/#{route.to_s}" unless route.absolute?
|
122
|
+
route = File.join(route.to_s, tpl.split(".").first) unless tpl.to_s.match(/^index/i)
|
123
|
+
request = MockRequest.new(route.to_s)
|
124
|
+
view = Tipsy::View::Base.new(request, MockResponse.new)
|
125
|
+
|
126
|
+
compiled = view.render
|
127
|
+
next if view.template.nil?
|
128
|
+
proper_name = proper_template_name(view.template)
|
129
|
+
|
130
|
+
if ::File.directory?(File.join(view_path, request.path))
|
131
|
+
write_to = ::File.join(request.path, proper_name)
|
132
|
+
else
|
133
|
+
write_to = "#{request.path}#{::File.extname(proper_template_name(view.template))}"
|
134
|
+
end
|
135
|
+
|
136
|
+
log_action("render", request.path)
|
137
|
+
mkdir_p ::File.join(config.compile_to, write_to)
|
138
|
+
make_file(::File.join(config.compile_to, write_to), compiled)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def cleanup!
|
144
|
+
wipe = { :files => [".DS_Store"], :dirs => [".sass-cache"] }
|
145
|
+
enumerate_tree(dest_path) do |path|
|
146
|
+
wipe[:files].each do|file|
|
147
|
+
::File.unlink(path) if ::File.basename(path) == file
|
148
|
+
end
|
149
|
+
wipe[:dirs].each do |dir|
|
150
|
+
::FileUtils.rm_rf(path) if ::File.basename(path) == dir
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class MockRequest
|
156
|
+
attr_reader :path_info, :path
|
157
|
+
def initialize(p)
|
158
|
+
@path_info, @path = p, p
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class MockResponse
|
163
|
+
attr_accessor :status, :body, :headers
|
164
|
+
def initialize
|
165
|
+
@headers = {}
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
|
171
|
+
def templates_in_path(path)
|
172
|
+
::Dir.entries(path).reject{ |file| file[0] == "_" || ::File.directory?(file) }
|
173
|
+
end
|
174
|
+
|
175
|
+
def proper_template_name(tpl)
|
176
|
+
::File.basename(tpl).gsub(/(md|haml|erb|rb|slim)/i, "").gsub(/\.$/, '')
|
177
|
+
end
|
178
|
+
|
179
|
+
def build_asset_path(asset, file)
|
180
|
+
base = (file.to_s.match(/\.js$/i) ? :javascripts_path : (file.to_s.match(/\.css$/i) ? :css_path : :images_path))
|
181
|
+
base = config.send(base)
|
182
|
+
path = File.expand_path(File.join(config.compile_to, base))
|
183
|
+
mkdir_p(path) unless File.directory?(path)
|
184
|
+
File.join(path, asset.logical_path)
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Tipsy
|
2
|
+
module Runners
|
3
|
+
class Generator
|
4
|
+
attr_reader :site_name, :site, :source_path, :dest_path
|
5
|
+
|
6
|
+
include Tipsy::Utils::System
|
7
|
+
|
8
|
+
def initialize(args, site)
|
9
|
+
@site_name, @site = args.first, site
|
10
|
+
@source_path = File.expand_path("../../../templates/site", __FILE__)
|
11
|
+
@dest_path = File.join(Tipsy.root, site_name)
|
12
|
+
ensure_destination
|
13
|
+
copy_tree(source_path, dest_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def ensure_destination
|
19
|
+
::FileUtils.mkdir(dest_path) unless ::File.exists?(dest_path) && ::File.directory?(dest_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|