massimo 0.4.6 → 0.5.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.
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"