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.
Files changed (95) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +6 -11
  3. data/README.md +24 -1
  4. data/Rakefile +13 -9
  5. data/bin/tipsy +4 -2
  6. data/lib/templates/server/htaccess.erb +14 -0
  7. data/lib/templates/site/Gemfile +19 -0
  8. data/lib/templates/site/assets/stylesheets/_config.css.scss +1 -0
  9. data/lib/templates/site/assets/stylesheets/screen.css.scss +1 -0
  10. data/lib/templates/site/config.rb +52 -0
  11. data/lib/templates/site/deploy.yml +27 -0
  12. data/lib/templates/site/layouts/default.html.erb +41 -0
  13. data/lib/templates/site/views/index.html.erb +2 -0
  14. data/lib/tipsy/compressors/{css.rb → css_compressor.rb} +0 -0
  15. data/lib/tipsy/compressors/javascript_compressor.rb +44 -0
  16. data/lib/tipsy/configuration.rb +9 -0
  17. data/lib/tipsy/handler/all.rb +4 -0
  18. data/lib/tipsy/handler/asset.rb +93 -0
  19. data/lib/tipsy/handler/erb.rb +42 -0
  20. data/lib/tipsy/handler/php.rb +36 -0
  21. data/lib/tipsy/{sass/template.rb → handler/sass/importer.rb} +15 -53
  22. data/lib/tipsy/handler/sass/resolver.rb +30 -0
  23. data/lib/tipsy/handler/sass.rb +36 -0
  24. data/lib/tipsy/handler/static.rb +30 -0
  25. data/lib/tipsy/helpers/asset_paths.rb +29 -1
  26. data/lib/tipsy/helpers/asset_tags.rb +1 -1
  27. data/lib/tipsy/helpers/capture.rb +12 -41
  28. data/lib/tipsy/helpers/rendering.rb +46 -0
  29. data/lib/tipsy/helpers/sass.rb +17 -6
  30. data/lib/tipsy/helpers/tag.rb +6 -9
  31. data/lib/tipsy/helpers.rb +13 -16
  32. data/lib/tipsy/runner.rb +82 -0
  33. data/lib/tipsy/runners/compiler.rb +189 -0
  34. data/lib/tipsy/runners/deployer.rb +7 -0
  35. data/lib/tipsy/runners/generator.rb +24 -0
  36. data/lib/tipsy/server.rb +56 -114
  37. data/lib/tipsy/site.rb +88 -0
  38. data/lib/tipsy/utils/logger.rb +47 -0
  39. data/lib/tipsy/utils/system.rb +115 -0
  40. data/lib/tipsy/utils/system_test.rb +103 -0
  41. data/lib/tipsy/version.rb +1 -1
  42. data/lib/tipsy/view/base.rb +55 -0
  43. data/lib/tipsy/view/context.rb +28 -0
  44. data/lib/tipsy/view/path.rb +44 -0
  45. data/lib/tipsy/view.rb +14 -68
  46. data/lib/tipsy.rb +30 -67
  47. data/{lib/tipsy/project/assets/javascripts/site.js → test/fixtures/capture.html.erb} +0 -0
  48. data/test/helpers/tag_test.rb +22 -0
  49. data/{lib/tipsy/project/assets/stylesheets/screen.css.scss → test/root/compiled/fake.txt} +0 -0
  50. data/test/root/{test/assets/javascripts/test.js → compiled/sub-path/fake.txt} +0 -0
  51. data/test/root/{development/assets/javascripts/test.js → compiled/sub-path-with-skip/fake.txt} +0 -0
  52. data/test/root/layouts/default.html.erb +0 -0
  53. data/test/root/views/index.html.erb +0 -0
  54. data/test/root/views/page.html.erb +0 -0
  55. data/test/root/views/sub/page.html.erb +0 -0
  56. data/test/root/views/sub/tertiary/index.html.erb +0 -0
  57. data/test/runner/compiler_test.rb +49 -0
  58. data/test/test_helper.rb +160 -21
  59. data/test/unit/site_test.rb +23 -0
  60. data/test/unit/tipsy_test.rb +13 -0
  61. data/test/unit/utils/system_test.rb +26 -0
  62. data/test/view/base_test.rb +34 -0
  63. data/test/view/path_test.rb +34 -0
  64. data/tipsy.gemspec +10 -7
  65. metadata +113 -84
  66. data/lib/tipsy/application.rb +0 -86
  67. data/lib/tipsy/builder.rb +0 -26
  68. data/lib/tipsy/builders/base.rb +0 -64
  69. data/lib/tipsy/builders/export.rb +0 -16
  70. data/lib/tipsy/builders/project.rb +0 -40
  71. data/lib/tipsy/builders/remote.rb +0 -14
  72. data/lib/tipsy/compressors/javascript.rb +0 -25
  73. data/lib/tipsy/logger.rb +0 -62
  74. data/lib/tipsy/project/Gemfile +0 -8
  75. data/lib/tipsy/project/config.erb +0 -19
  76. data/lib/tipsy/project/helpers/site_helper.rb +0 -4
  77. data/lib/tipsy/project/views/_layout.html.erb +0 -16
  78. data/test/fixtures/about.html +0 -1
  79. data/test/fixtures/contact.html +0 -1
  80. data/test/fixtures/index.html +0 -1
  81. data/test/functional/page_test.rb +0 -33
  82. data/test/root/.gitignore +0 -7
  83. data/test/root/development/assets/stylesheets/screen.css.scss +0 -3
  84. data/test/root/development/config.rb +0 -6
  85. data/test/root/development/views/_layout.html.erb +0 -20
  86. data/test/root/development/views/index.html.erb +0 -3
  87. data/test/root/test/assets/stylesheets/screen.css.scss +0 -3
  88. data/test/root/test/config.rb +0 -6
  89. data/test/root/test/views/_layout.html.erb +0 -1
  90. data/test/root/test/views/about/index.html +0 -1
  91. data/test/root/test/views/contact.html +0 -1
  92. data/test/root/test/views/index.html.erb +0 -1
  93. data/test/unit/helpers/asset_paths_test.rb +0 -14
  94. data/test/unit/helpers_test.rb +0 -22
  95. 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
- "/" << File.join('assets', path)
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
- content_tag('link', '', { 'href' => asset_path(path_with_ext(file, 'css')), 'rel' => "stylesheet" }.merge!(html_attrs))
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 render(options = {})
21
- options.symbolize_keys!
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
- private
34
-
35
- def _render_template(name, options = {}, partial = false)
36
- to_render = ( partial === true ? "_#{name}" : name )
37
- to_render = view_trail.find(to_render)
38
- unless to_render.nil?
39
- local_vars = options.delete(:locals) || {}
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
@@ -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.value, kind.value), true)
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(#{public_path(asset.value, kind.value)})})
12
+ ::Sass::Script::String.new(%Q{url(#{asset_path(asset, kind)})})
13
13
  end
14
14
 
15
- [:image, :font, :video, :audio, :javascript, :stylesheet].each do |asset_class|
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
- options[:custom][:resolver].public_path(asset, kind.pluralize)
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
@@ -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 = {}, &block)
10
+ def content_tag(name, content = nil, html_attrs = {}, &capt)
12
11
  buffer = "<#{name}#{make_attributes(html_attrs)}>"
13
- content = capture(&block) if block_given?
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/sass'
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
- module InstanceMethods
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
@@ -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,7 @@
1
+ module Tipsy
2
+ module Runners
3
+ class Deployer
4
+
5
+ end
6
+ end
7
+ 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