massimo 0.4.6 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/VERSION +1 -1
  2. data/bin/massimo +5 -3
  3. data/lib/massimo/cli.rb +101 -0
  4. data/lib/massimo/config.rb +56 -0
  5. data/lib/massimo/helpers.rb +12 -19
  6. data/lib/massimo/javascript.rb +18 -19
  7. data/lib/massimo/page.rb +63 -70
  8. data/lib/massimo/resource.rb +92 -0
  9. data/lib/massimo/server.rb +27 -0
  10. data/lib/massimo/site.rb +64 -101
  11. data/lib/massimo/stylesheet.rb +13 -35
  12. data/lib/massimo/view.rb +5 -32
  13. data/lib/massimo/watcher.rb +52 -0
  14. data/lib/massimo.rb +22 -31
  15. metadata +172 -117
  16. data/.document +0 -5
  17. data/.gitignore +0 -25
  18. data/Gemfile +0 -13
  19. data/Rakefile +0 -62
  20. data/lib/massimo/command.rb +0 -243
  21. data/lib/massimo/resource/base.rb +0 -74
  22. data/lib/massimo/resource/collection.rb +0 -56
  23. data/lib/massimo/resource/processing.rb +0 -67
  24. data/lib/massimo/templates.rb +0 -22
  25. data/massimo.gemspec +0 -135
  26. data/test/assertions.rb +0 -8
  27. data/test/helper.rb +0 -64
  28. data/test/source/config.yml +0 -4
  29. data/test/source/helpers/test_helper.rb +0 -5
  30. data/test/source/javascripts/_plugin.js +0 -1
  31. data/test/source/javascripts/application.js +0 -3
  32. data/test/source/javascripts/lib.js +0 -1
  33. data/test/source/lib/site.rb +0 -5
  34. data/test/source/pages/_skipped_page.haml +0 -0
  35. data/test/source/pages/about_us.erb +0 -5
  36. data/test/source/pages/erb.erb +0 -5
  37. data/test/source/pages/erb_with_layout.erb +0 -4
  38. data/test/source/pages/feed.haml +0 -6
  39. data/test/source/pages/haml.haml +0 -5
  40. data/test/source/pages/html.html +0 -4
  41. data/test/source/pages/index.erb +0 -4
  42. data/test/source/pages/markdown.markdown +0 -5
  43. data/test/source/pages/posts/first-post.haml +0 -1
  44. data/test/source/pages/with_extension.haml +0 -4
  45. data/test/source/pages/with_meta_data.haml +0 -7
  46. data/test/source/pages/with_title.haml +0 -4
  47. data/test/source/pages/with_url.haml +0 -4
  48. data/test/source/pages/without_extension.haml +0 -0
  49. data/test/source/pages/without_meta_data.haml +0 -1
  50. data/test/source/pages/without_title.haml +0 -1
  51. data/test/source/pages/without_url.haml +0 -1
  52. data/test/source/stylesheets/_base.sass +0 -2
  53. data/test/source/stylesheets/application.sass +0 -4
  54. data/test/source/stylesheets/basic.css +0 -3
  55. data/test/source/stylesheets/less_file.less +0 -5
  56. data/test/source/views/layouts/application.haml +0 -2
  57. data/test/source/views/with_helper.haml +0 -1
  58. data/test/source/views/with_locals.haml +0 -1
  59. data/test/source/views/without_locals.haml +0 -1
  60. data/test/test_helpers.rb +0 -25
  61. data/test/test_javascript.rb +0 -30
  62. data/test/test_page.rb +0 -142
  63. data/test/test_resource.rb +0 -70
  64. data/test/test_site.rb +0 -125
  65. data/test/test_stylesheet.rb +0 -40
  66. data/test/test_view.rb +0 -50
data/lib/massimo/site.rb CHANGED
@@ -1,132 +1,95 @@
1
- require "active_support/inflector"
2
- require "active_support/core_ext/hash/keys"
3
- require "singleton"
4
- # require "massimo/helpers"
5
- # require "massimo/view"
1
+ require 'active_support/inflector'
2
+ require 'tilt'
6
3
 
7
4
  module Massimo
8
5
  class Site
9
- include Singleton
6
+ attr_accessor :config
10
7
 
11
- # Default options. Overriden by values given when creating a Site.
12
- DEFAULT_OPTIONS = {
13
- :source => ".",
14
- :output => File.join(".", "public"),
15
- :server_port => "1984"
16
- }.freeze
17
-
18
- attr_accessor :options, :helpers
19
-
20
- # Setup the Site with the given options. These options may be overridden by the config file.
21
- def setup(options = {})
22
- @options = DEFAULT_OPTIONS.dup.merge(options.symbolize_keys)
23
- reload
24
- self
25
- end
26
-
27
- # Reload helpers and libs.
28
- def reload
29
- reload_helpers
30
- reload_libs
31
- reload_resources
32
- end
33
-
34
- # Processes all the Pages, Stylesheets, and Javascripts and outputs
35
- # them to the output dir.
36
- def process!
37
- reload
38
- Massimo.processable_resources.each(&:process!)
39
- end
40
-
41
- # Finds a view by the given name
42
- def find_view(name, meta_data = {})
43
- view_path = Dir.glob(dir_for(:views, "#{name}.*")).first
44
- view_path && Massimo::View.new(view_path, meta_data)
45
- end
46
-
47
- # Finds a view then renders it with the given locals
48
- def render_view(name, locals = {}, &block)
49
- view = find_view(name)
50
- view && view.render(locals, &block)
51
- end
52
-
53
- # Determines if the Site is in development mode.
54
- def development?
55
- @options[:environment].nil? || @options[:environment].to_sym == :development || @options[:development]
8
+ def initialize(options = nil, &block)
9
+ @config = Config.new(options)
10
+ @template_scope_blocks = []
11
+ @template_scope_extensions = []
12
+ Massimo.site = self
13
+
14
+ instance_eval(&block) if block_given?
56
15
  end
57
16
 
58
- # Determines if the Site is in production mode.
59
- def production?
60
- (@options[:environment] && @options[:environment].to_sym == :production) || @options[:production]
17
+ def resources
18
+ @resources ||= [ Massimo::Page, Massimo::Javascript, Massimo::Stylesheet, Massimo::View ]
61
19
  end
62
20
 
63
- #------------------------------------
64
- # Directory Path Methods
65
- #------------------------------------
66
-
67
- # The path to the source dir
68
- def source_dir(*path)
69
- File.join(@options[:source], *path)
21
+ def resource(name_or_class, &block)
22
+ resource = case name_or_class
23
+ when Class
24
+ name_or_class
25
+ else
26
+ Object.const_set name_or_class.to_s.classify, Class.new(Massimo::Page, &block)
27
+ end
28
+ resources << resource
70
29
  end
71
30
 
72
- # Get the directory to the given resource type (pages, views, etc.).
73
- # If the path has been manually set in the options, you will get that
74
- # path. Otherwise you will get the path relative to the source directory.
75
- def dir_for(type, *path)
76
- if type_path = @options["#{type}_path".to_sym]
77
- File.join(type_path, *path)
78
- else
79
- source_dir(type.to_s, *path)
31
+ def template_scope
32
+ @template_scope ||= begin
33
+ scope = Object.new.extend(Massimo::Helpers, Tilt::CompileSite)
34
+ add_template_scope_blocks(scope)
35
+ add_template_scope_extensions(scope)
36
+ add_template_scope_helpers(scope)
37
+ scope
80
38
  end
81
39
  end
82
40
 
83
- # Get all the source directories as an array.
84
- def all_source_dirs
85
- Massimo.resources.collect(&:dir) + [ dir_for(:helpers), dir_for(:lib) ]
41
+ def helpers(*extensions, &block)
42
+ @template_scope_blocks << block if block_given?
43
+ @template_scope_extensions += extensions
86
44
  end
87
45
 
88
- # The path to the output dir
89
- def output_dir(*path)
90
- File.join(@options[:output], *path)
46
+ def process
47
+ @template_scope = nil
48
+ reload_libs
49
+ resources.select(&:processable?).each do |resource|
50
+ resource.all.each(&:process)
51
+ end
91
52
  end
92
53
 
93
54
  protected
55
+
56
+ def add_template_scope_blocks(scope)
57
+ @template_scope_blocks.each do |block|
58
+ scope.instance_eval(&block)
59
+ end
60
+ end
94
61
 
95
- # Reload the Helpers instance with the helper modules
96
- def reload_helpers
97
- @helpers = Helpers.new(helper_modules.compact)
62
+ def add_template_scope_extensions(scope)
63
+ @template_scope_extensions.each do |extension|
64
+ scope.extend(extension)
65
+ end
98
66
  end
99
67
 
100
- # Reload all the files in the source lib dir.
101
- def reload_libs
102
- reload_files Dir.glob(dir_for(:lib, "**/*.rb"))
68
+ def add_template_scope_helpers(scope)
69
+ config.files_in(:helpers, :rb).each do |file|
70
+ load(file)
71
+ if helper = (class_name_of_file(file).constantize rescue nil)
72
+ scope.extend(helper)
73
+ end
74
+ end
103
75
  end
104
76
 
105
- # Load methods for listing all available files for each Resource type.
106
- def reload_resources
107
- class_eval do
108
- # Define methods for getting all of the files for each Resource Type
109
- Massimo.processable_resources.each do |type|
110
- define_method(type.name.to_s.pluralize) do |*args|
111
- type.all(*args)
77
+ def reload_libs
78
+ if defined? @previous_libs
79
+ @previous_libs.each do |lib|
80
+ class_name = class_name_of_file(lib)
81
+ Object.class_eval do
82
+ remove_const(class_name) if const_defined?(class_name)
112
83
  end
113
84
  end
114
85
  end
115
- end
116
-
117
- # Find all the helper modules
118
- def helper_modules
119
- reload_files Dir.glob(dir_for(:helpers, "*.rb"))
120
- end
121
-
122
- # Reload the given files and an Array of the reloaded Constants.
123
- def reload_files(files)
124
- files.collect do |file|
125
- class_name = File.basename(file).gsub(File.extname(file), "").classify
126
- Object.class_eval { remove_const(class_name) if const_defined?(class_name) }
86
+ @previous_libs = config.files_in(:lib, :rb).each do |file|
127
87
  load(file)
128
- class_name.constantize rescue nil
129
88
  end
130
89
  end
90
+
91
+ def class_name_of_file(file)
92
+ File.basename(file).sub(/\.[^\.]+$/, '').classify
93
+ end
131
94
  end
132
95
  end
@@ -1,42 +1,20 @@
1
- require "pathname"
2
- require "massimo/resource/base"
3
-
4
1
  module Massimo
5
- class Stylesheet < Massimo::Resource::Base
6
- processable!
7
-
8
- # Render the css based on the type of resource
2
+ class Stylesheet < Massimo::Resource
9
3
  def render
10
- case resource_type.to_sym
11
- when :sass
12
- require "sass" unless defined?(Sass)
13
- Sass::Files.tree_for(@source_path, sass_options).render
14
- when :less
15
- require "less" unless defined?(Less)
16
- Less.parse(@body)
4
+ case source_path.extname.to_s
5
+ when '.sass'
6
+ require 'sass' unless defined?(Sass)
7
+ Sass::Files.tree_for(source_path.to_s, :css_filename => output_path).render
8
+ when '.less'
9
+ require 'less' unless defined?(Less)
10
+ Less::Engine.new(content).to_css
17
11
  else
18
- @body.to_s
12
+ super
19
13
  end
20
14
  end
21
15
 
22
- protected
23
-
24
- # Determine the output file path
25
- def output_path
26
- @output_path ||= Pathname.new(@source_path.to_s.
27
- sub(site.source_dir, site.output_dir). # move to output dir
28
- sub(/#{@source_path.extname}$/, ".css") # replace extension with .css
29
- )
30
- end
31
-
32
- # Gets the Sass options, with Site options merged in.
33
- def sass_options
34
- options = {
35
- :style => site.production? ? :compressed : :nested
36
- }
37
- options.merge!(site.options[:sass]) if site.options[:sass].is_a?(Hash)
38
- options.merge(:css_filename => output_path)
39
- end
40
-
16
+ def extension
17
+ @extension ||= '.css'
18
+ end
41
19
  end
42
- end
20
+ end
data/lib/massimo/view.rb CHANGED
@@ -1,39 +1,12 @@
1
- require "tilt"
2
- require "massimo/resource/base"
1
+ require 'tilt'
3
2
 
4
3
  module Massimo
5
- class View < Massimo::Resource::Base
6
- attr_reader :meta_data
4
+ class View < Resource
5
+ unprocessable
7
6
 
8
- # Creates a new page associated with the given file path.
9
- def initialize(source_path, meta_data = {})
10
- @meta_data = meta_data
11
- super(source_path)
12
- end
13
-
14
- # Renders the page using the appropriate Tilt Template
15
7
  def render(locals = {}, &block)
16
- template = Tilt.new(file_name, @line || 1, options_for_resource_type) { @body }
17
- template.render(site.helpers, @meta_data.merge(locals), &block)
8
+ template = Tilt.new(source_path.basename.to_s) { content }
9
+ template.render(Massimo.site.template_scope, locals, &block)
18
10
  end
19
-
20
- protected
21
-
22
- # All undefined methods are sent to the `@meta_data` hash.
23
- def method_missing(method, *args, &block)
24
- case args.length
25
- when 1
26
- method_name = method.to_s
27
- if method_name.chomp!('=')
28
- @meta_data[method_name.to_sym] = args.first
29
- else
30
- super
31
- end
32
- when 0
33
- @meta_data[method]
34
- else
35
- super
36
- end
37
- end
38
11
  end
39
12
  end
@@ -0,0 +1,52 @@
1
+ module Massimo
2
+ class Watcher
3
+ class << self
4
+ def start(site)
5
+ self.new(site).run
6
+ end
7
+ end
8
+
9
+ def initialize(site)
10
+ @site = site
11
+ @files = []
12
+ end
13
+
14
+ def run
15
+ loop do
16
+ process
17
+ sleep 0.5
18
+ end
19
+ end
20
+
21
+ def process
22
+ if changed?
23
+ begin
24
+ puts 'massimo has noticed a change'
25
+ @site.process
26
+ puts 'massimo has built your site'
27
+ rescue Exception => e
28
+ puts e.message
29
+ puts e.backtrace
30
+ end
31
+ end
32
+ end
33
+
34
+ def changed?
35
+ @files != files
36
+ end
37
+
38
+ protected
39
+
40
+ def files
41
+ @files = Dir[*glob].map { |file| File.mtime(file) }
42
+ end
43
+
44
+ def glob
45
+ glob = @site.resources.map(&:path)
46
+ glob << @site.config.path_for(:lib)
47
+ glob << @site.config.path_for(:helpers)
48
+ glob.map! { |path| File.join(path, '**/*.*') }
49
+ glob
50
+ end
51
+ end
52
+ end
data/lib/massimo.rb CHANGED
@@ -1,37 +1,28 @@
1
- libdir = File.dirname(__FILE__)
2
- $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
-
4
- require "massimo/helpers"
5
- require "massimo/templates"
6
- require "massimo/site"
7
-
8
1
  module Massimo
9
- VERSION = File.read(File.expand_path("../../VERSION", __FILE__)) # :nodoc:
2
+ autoload :Config, 'massimo/config'
3
+ autoload :Helpers, 'massimo/helpers'
4
+ autoload :Javascript, 'massimo/javascript'
5
+ autoload :Page, 'massimo/page'
6
+ autoload :Resource, 'massimo/resource'
7
+ autoload :Server, 'massimo/server'
8
+ autoload :Site, 'massimo/site'
9
+ autoload :Stylesheet, 'massimo/stylesheet'
10
+ autoload :View, 'massimo/view'
11
+ autoload :Watcher, 'massimo/watcher'
10
12
 
11
- MissingResource = Class.new(StandardError) # :nodoc:
12
- InvalidResource = Class.new(StandardError) # :nodoc:
13
+ VERSION = File.read File.expand_path('../../VERSION', __FILE__)
13
14
 
14
- # This will create an instance of Massimo::Site the first time it is called.
15
- # Everytime it's called afterwords, without options, it returns the same
16
- # instance.
17
- def self.Site(options = {})
18
- return @site if defined?(@site) && options.empty?
19
- @site = Site.instance.setup(options)
20
- end
21
-
22
- # All the avaiable Resource types
23
- def self.resources
24
- @resources ||= []
25
- end
15
+ class << self
16
+ def site
17
+ @site ||= Site.new
18
+ end
26
19
 
27
- # All the Resource types that are processable.
28
- def self.processable_resources
29
- resources.select { |resource| resource.processable? }
20
+ def site=(site)
21
+ @site = site
22
+ end
23
+
24
+ def config
25
+ site.config
26
+ end
30
27
  end
31
28
  end
32
-
33
- require "massimo/resource/base"
34
- require "massimo/view"
35
- require "massimo/page"
36
- require "massimo/stylesheet"
37
- require "massimo/javascript"