tipsy 0.0.2 → 0.0.3
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/.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
|