diff --git a/.gitignore b/.gitignore
index 9f6bba4c..06a67829 100755
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ fixtures/generator-test
build
doc
.yardoc
+tmp
diff --git a/.yardopts b/.yardopts
index 59b574b0..5f7ae80d 100644
--- a/.yardopts
+++ b/.yardopts
@@ -1,7 +1,11 @@
lib/**/*.rb
---exclude lib/middleman/vendor
+--exclude lib/middleman/vendor/
--exclude lib/middleman/extensions/automatic_image_sizes/fastimage.rb
--exclude lib/middleman/extensions/minify_css/cssmin.rb
--exclude lib/middleman/step_definitions
---exclude lib/middleman/step_definitions.rb
---no-private
\ No newline at end of file
+--exclude lib/middleman/templates/default/
+--exclude lib/middleman/templates/html5/
+--exclude lib/middleman/templates/mobile/
+--exclude lib/middleman/templates/shared/
+--no-private
+--hide-void-return
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9c064fd7..8cdf4b7e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,9 +10,13 @@
* Sitemap object representing the known world
* FileWatcher proxies file change events
* Unified callback solution
-* Removed Slim and Maruku from base install. Will need to be installed and required by the user (in - config.rb)
+* Removed Slim from base install. Will need to be installed and required by the user (in - config.rb)
* Activate mobile html5boilerplate template
* Update to Redcarpet for Markdown (breaks Haml :markdown filter)
+* Return correct exit codes (0 for success, 1 for failure) from CLI
+* Yard code docs: http://rubydoc.info/github/tdreyno/middleman
+* config.rb and extensions can add command-line commands
+* Nested layouts using `wrap_layout` helper
2.0.14
====
diff --git a/bin/middleman b/bin/middleman
index b6b64011..e055fbe3 100755
--- a/bin/middleman
+++ b/bin/middleman
@@ -9,7 +9,7 @@ require 'rubygems'
module Middleman
module ProjectLocator
class << self
- def locate_middleman_root!(args)
+ def locate_middleman_root!
cwd = Dir.pwd
if !in_middleman_project? && !in_middleman_project_subdirectory?
@@ -18,14 +18,14 @@ module Middleman
end
if in_middleman_project?
- did_locate_middleman_project(cwd, args)
+ did_locate_middleman_project(cwd)
return
end
Dir.chdir("..") do
# Recurse in a chdir block: if the search fails we want to be sure
# the application is generated in the original working directory.
- locate_middleman_root!(args) unless cwd == Dir.pwd
+ locate_middleman_root! unless cwd == Dir.pwd
end
rescue SystemCallError
# could not chdir, no problem just return
@@ -39,39 +39,27 @@ module Middleman
File.exists?(File.join(path, 'config.rb')) || !path.root? && in_middleman_project_subdirectory?(path.parent)
end
- def did_locate_middleman_project(path, args)
+ def did_locate_middleman_project(path)
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('Gemfile', path)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
- start_cli!(args)
+ start_cli!
end
- def start_cli!(args)
+ def start_cli!
require 'middleman'
- Middleman::CLI.start(args)
+ Middleman::Cli::Base.start
end
end
end
end
-args = ARGV.dup
+ARGV << "server" if ARGV.length < 1
-ARG_ALIASES = {
- "s" => "server",
- "b" => "build",
- "i" => "init",
- "new" => "init",
- "n" => "init"
-}
-
-if ARG_ALIASES.has_key?(args[0])
- args[0] = ARG_ALIASES[args[0]]
-end
-
-if args.length < 1 || %w(server build migrate).include?(args.first)
- Middleman::ProjectLocator.locate_middleman_root!(args)
+if %w(server build migrate).include?(ARGV)
+ Middleman::ProjectLocator.locate_middleman_root!
else
- Middleman::ProjectLocator.start_cli!(args)
+ Middleman::ProjectLocator.start_cli!
end
\ No newline at end of file
diff --git a/features/3rd_party_cli.feature b/features/3rd_party_cli.feature
new file mode 100644
index 00000000..297040b5
--- /dev/null
+++ b/features/3rd_party_cli.feature
@@ -0,0 +1,5 @@
+Feature: Allow config.rb and extensions to add CLI commands
+ Scenario: Test 3rd Party Command
+ Given a fixture app "3rd-party-command"
+ When I run `middleman hello`
+ Then the output should contain "Hello World"
\ No newline at end of file
diff --git a/features/builder.feature b/features/builder.feature
index e779302c..c5b23f20 100644
--- a/features/builder.feature
+++ b/features/builder.feature
@@ -2,33 +2,51 @@ Feature: Builder
In order to output static html and css for delivery
Scenario: Checking built folder for content
- Given a built app at "test-app"
- Then "index.html" should exist at "test-app" and include "Comment in layout"
- Then "javascripts/coffee_test.js" should exist at "test-app" and include "Array.prototype.slice"
- Then "index.html" should exist at "test-app" and include "
Welcome
"
- Then "static.html" should exist at "test-app" and include "Static, no code!"
- Then "services/index.html" should exist at "test-app" and include "Services"
- Then "stylesheets/site.css" should exist at "test-app" and include "html, body, div, span"
- Then "stylesheets/site_scss.css" should exist at "test-app" and include "html, body, div, span"
- Then "stylesheets/static.css" should exist at "test-app" and include "body"
- Then "_partial.html" should not exist at "test-app"
- Then "spaces in file.html" should exist at "test-app" and include "spaces"
- Then "images/blank.gif" should exist at "test-app"
- Then "images/Read me (example).txt" should exist at "test-app"
- Then "images/Child folder/regular_file(example).txt" should exist at "test-app"
- Then ".htaccess" should exist at "test-app"
- Then the last exit code should be "0"
+ Given a successfully built app at "test-app"
+ When I cd to "build"
+ Then the following files should exist:
+ | index.html |
+ | javascripts/coffee_test.js |
+ | static.html |
+ | services/index.html |
+ | stylesheets/site.css |
+ | stylesheets/site_scss.css |
+ | stylesheets/static.css |
+ | spaces in file.html |
+ | images/blank.gif |
+ | images/Read me (example).txt |
+ | images/Child folder/regular_file(example).txt |
+ | .htaccess |
+ Then the following files should not exist:
+ | _partial |
+ | _liquid_partial |
+ | layout |
+ | layouts/custom |
+ | layouts/content_for |
+
+ And the file "index.html" should contain "Comment in layout"
+ And the file "index.html" should contain "Welcome
"
+ And the file "javascripts/coffee_test.js" should contain "Array.prototype.slice"
+ And the file "static.html" should contain "Static, no code!"
+ And the file "services/index.html" should contain "Services"
+ And the file "stylesheets/site.css" should contain "html, body, div, span"
+ And the file "stylesheets/site_scss.css" should contain "html, body, div, span"
+ And the file "stylesheets/static.css" should contain "body"
+ And the file "spaces in file.html" should contain "spaces"
Scenario: Build glob
- Given a built app at "glob-app" with flags "--glob '*.css'"
- Then "stylesheets/site.css" should exist at "glob-app" and include "html"
- Then "index.html" should not exist at "glob-app"
- Then the last exit code should be "0"
+ Given a successfully built app at "glob-app" with flags "--glob '*.css'"
+ When I cd to "build"
+ Then the following files should not exist:
+ | index.html |
+ Then the following files should exist:
+ | stylesheets/site.css |
Scenario: Build with errors
Given a built app at "build-with-errors-app"
- Then the last exit code should be "1"
-
- # Scenario: Force relative assets
- # Given a built app at "relative-app" with flags "--relative"
- # Then "stylesheets/relative_assets.css" should exist at "relative-app" and include "../"
+ Then the exit status should be 1
+
+ Scenario: Build alias (b)
+ Given a fixture app "test-app"
+ When I run `middleman b`
+ Then was successfully built
\ No newline at end of file
diff --git a/features/chained_templates.feature b/features/chained_templates.feature
index e9c968e4..b7d4e83e 100644
--- a/features/chained_templates.feature
+++ b/features/chained_templates.feature
@@ -9,7 +9,11 @@ Feature: Templates should be chainable
And I should see "Sup"
Scenario: Build chained template
- Given a built app at "chained-app"
- Then "index.html" should exist at "chained-app" and include "Title"
- Then "index.html" should exist at "chained-app" and include "Subtitle"
- Then "index.html" should exist at "chained-app" and include "Sup"
\ No newline at end of file
+ Given a successfully built app at "chained-app"
+ When I cd to "build"
+ Then the following files should exist:
+ | index.html |
+
+ And the file "index.html" should contain "Title"
+ And the file "index.html" should contain "Subtitle"
+ And the file "index.html" should contain "Sup"
\ No newline at end of file
diff --git a/features/clean_build.feature b/features/clean_build.feature
index 268d65db..e70d5d3e 100644
--- a/features/clean_build.feature
+++ b/features/clean_build.feature
@@ -1,20 +1,31 @@
Feature: Build Clean
Scenario: Build and Clean an app
- Given app "clean-app" is using config "empty"
- And a built app at "clean-app"
+ Given a fixture app "clean-app"
+ And app "clean-app" is using config "empty"
+ And a successfully built app at "clean-app"
And app "clean-app" is using config "complications"
- And a built app at "clean-app" with flags "--clean"
- Then "should_be_ignored.html" should not exist at "clean-app"
- And "should_be_ignored2.html" should not exist at "clean-app"
- And "should_be_ignored3.html" should not exist at "clean-app"
+
+ Given a successfully built app at "clean-app" with flags "--clean"
+ When I cd to "build"
+ Then the following files should not exist:
+ | should_be_ignored.html |
+ | should_be_ignored2.html |
+ | should_be_ignored3.html |
+ And the file "index.html" should contain "Comment in layout"
Scenario: Clean an app with directory indexes
- Given a built app at "clean-dir-app"
- Then "about/index.html" should exist at "clean-dir-app"
- Given a built app at "clean-dir-app" with flags "--clean"
- Then "about/index.html" should exist at "clean-dir-app"
- Then cleanup built app at "clean-dir-app"
+ Given a successfully built app at "clean-dir-app"
+ When I cd to "build"
+ Then the following files should exist:
+ | about/index.html |
+
+ Given a successfully built app at "clean-dir-app" with flags "--clean"
+ When I cd to "build"
+ Then the following files should exist:
+ | about/index.html |
Scenario: Clean build an app that's never been built
- Given a built app at "clean-dir-app" with flags "--clean"
- Then "about/index.html" should exist at "clean-dir-app"
+ Given a successfully built app at "clean-dir-app" with flags "--clean"
+ When I cd to "build"
+ Then the following files should exist:
+ | about/index.html |
diff --git a/features/cli.feature b/features/cli.feature
new file mode 100644
index 00000000..dcb6e6a4
--- /dev/null
+++ b/features/cli.feature
@@ -0,0 +1,121 @@
+Feature: Middleman CLI
+
+ Scenario: Create a new project
+ When I run `middleman init MY_PROJECT`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ Then the following files should not exist:
+ | config.ru |
+ | Gemfile |
+ Then a directory named "source" should exist
+ When I cd to "source"
+ Then the following files should exist:
+ | index.html.erb |
+ | layout.erb |
+ | stylesheets/site.css.scss |
+
+ Scenario: Create a new project (alias i)
+ When I run `middleman i MY_PROJECT`
+ Then a directory named "MY_PROJECT" should exist
+
+ Scenario: Create a new project (alias i)
+ When I run `middleman new MY_PROJECT`
+ Then a directory named "MY_PROJECT" should exist
+
+ Scenario: Create a new project (alias i)
+ When I run `middleman n MY_PROJECT`
+ Then a directory named "MY_PROJECT" should exist
+
+ Scenario: Create a new project with Rack
+ When I run `middleman init MY_PROJECT --rack`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ | config.ru |
+ Then the following files should not exist:
+ | Gemfile |
+
+ Scenario: Create a new project with Bundler
+ When I run `middleman init MY_PROJECT --bundler`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ | Gemfile |
+ Then the following files should not exist:
+ | config.ru |
+
+ Scenario: Create a new HTML5 project
+ When I run `middleman init MY_PROJECT --template=html5`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ Then the following files should not exist:
+ | config.ru |
+ | Gemfile |
+ Then a directory named "source" should exist
+ When I cd to "source"
+ Then the following files should exist:
+ | index.html |
+ | humans.txt |
+ | js/script.js |
+
+ Scenario: Create a new HTML5 project with Rack
+ When I run `middleman init MY_PROJECT --rack --template=html5`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ | config.ru |
+ Then the following files should not exist:
+ | Gemfile |
+
+ Scenario: Create a new HTML5 project with Bundler
+ When I run `middleman init MY_PROJECT --bundler --template=html5`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ | Gemfile |
+ Then the following files should not exist:
+ | config.ru |
+
+ Scenario: Create a new Mobile HTML5 project
+ When I run `middleman init MY_PROJECT --template=mobile`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ Then the following files should not exist:
+ | config.ru |
+ | Gemfile |
+ Then a directory named "source" should exist
+ When I cd to "source"
+ Then the following files should exist:
+ | index.html |
+ | humans.txt |
+ | js/libs/respond.min.js |
+
+ Scenario: Create a new Mobile HTML5 project with Rack
+ When I run `middleman init MY_PROJECT --rack --template=mobile`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ | config.ru |
+ Then the following files should not exist:
+ | Gemfile |
+
+ Scenario: Create a new Mobile HTML5 project with Bundler
+ When I run `middleman init MY_PROJECT --bundler --template=mobile`
+ Then a directory named "MY_PROJECT" should exist
+ When I cd to "MY_PROJECT"
+ Then the following files should exist:
+ | config.rb |
+ | Gemfile |
+ Then the following files should not exist:
+ | config.ru |
\ No newline at end of file
diff --git a/features/coffee-script.feature b/features/coffee-script.feature
index 08496916..ed2c6a1b 100644
--- a/features/coffee-script.feature
+++ b/features/coffee-script.feature
@@ -14,4 +14,4 @@ Feature: Support coffee-script
Scenario: Rendering broken coffee
Given the Server is running at "test-app"
When I go to "/javascripts/broken-coffee.js"
- Then I should see "ProgramError"
\ No newline at end of file
+ Then I should see "Error"
\ No newline at end of file
diff --git a/features/custom_layout_engines.feature b/features/custom_layout_engines.feature
index 5963efd1..4d0a5618 100644
--- a/features/custom_layout_engines.feature
+++ b/features/custom_layout_engines.feature
@@ -1,8 +1,11 @@
Feature: Custom Layout Engine
Scenario: Checking built folder for content
- Given a built app at "custom-layout-app"
- Then "index.html" should exist at "custom-layout-app" and include "Comment in layout"
+ Given a successfully built app at "custom-layout-app"
+ When I cd to "build"
+ Then the following files should exist:
+ | index.html |
+ And the file "index.html" should contain "Comment in layout"
Scenario: Checking server for content
Given the Server is running at "test-app"
diff --git a/features/directory_index.feature b/features/directory_index.feature
index 72e76921..9f74daac 100644
--- a/features/directory_index.feature
+++ b/features/directory_index.feature
@@ -2,16 +2,23 @@ Feature: Directory Index
In order output Apache-friendly directories and indexes
Scenario: Checking built folder for content
- Given a built app at "indexable-app"
- Then "needs_index/index.html" should exist at "indexable-app" and include "Indexable"
- Then "a_folder/needs_index/index.html" should exist at "indexable-app" and include "Indexable"
- Then "leave_me_alone.html" should exist at "indexable-app" and include "Stay away"
- Then "regular/index.html" should exist at "indexable-app" and include "Regular"
- Then "regular/index/index.html" should not exist at "indexable-app"
- Then "needs_index.html" should not exist at "indexable-app"
- Then "a_folder/needs_index.html" should not exist at "indexable-app"
- Then "leave_me_alone/index.html" should not exist at "indexable-app"
- Then ".htaccess" should exist at "indexable-app"
+ Given a successfully built app at "indexable-app"
+ When I cd to "build"
+ Then the following files should exist:
+ | needs_index/index.html |
+ | a_folder/needs_index/index.html |
+ | leave_me_alone.html |
+ | regular/index.html |
+ | .htaccess |
+ Then the following files should not exist:
+ | egular/index/index.html |
+ | needs_index.html |
+ | a_folder/needs_index.html |
+ | leave_me_alone/index.html |
+ And the file "needs_index/index.html" should contain "Indexable"
+ And the file "a_folder/needs_index/index.html" should contain "Indexable"
+ And the file "leave_me_alone.html" should contain "Stay away"
+ And the file "regular/index.html" should contain "Regular"
Scenario: Preview normal file
Given the Server is running at "indexable-app"
diff --git a/features/dynamic_pages.feature b/features/dynamic_pages.feature
index 47d0c6a1..c55e963a 100644
--- a/features/dynamic_pages.feature
+++ b/features/dynamic_pages.feature
@@ -2,14 +2,17 @@ Feature: Dynamic Pages
In order to use a single view to generate multiple output files
Scenario: Checking built folder for content
- Given a built app at "test-app"
- Then "fake.html" should exist at "test-app" and include "I am real"
- Then "fake/one.html" should exist at "test-app" and include "I am real: one"
- Then "fake/two.html" should exist at "test-app" and include "I am real: two"
- Then "target_ignore.html" should exist at "test-app" and include "Ignore me"
- Then "should_be_ignored.html" should not exist at "test-app"
- Then "should_be_ignored2.html" should not exist at "test-app"
- Then "should_be_ignored3.html" should not exist at "test-app"
+ Given a successfully built app at "test-app"
+ When I cd to "build"
+ Then the following files should exist:
+ | fake.html |
+ | fake/one.html |
+ | fake/two.html |
+ | target_ignore.html |
+ Then the following files should not exist:
+ | should_be_ignored.html |
+ | should_be_ignored2.html |
+ | should_be_ignored3.html |
Scenario: Preview basic proxy
Given the Server is running at "test-app"
diff --git a/features/fonts.feature b/features/fonts.feature
index 1c673b28..b839a346 100644
--- a/features/fonts.feature
+++ b/features/fonts.feature
@@ -1,8 +1,11 @@
Feature: Web Fonts
Scenario: Checking built folder for content
- Given a built app at "fonts-app"
- Then "stylesheets/fonts.css" should exist at "fonts-app" and include "/fonts/StMarie-Thin.otf"
+ Given a successfully built app at "fonts-app"
+ When I cd to "build"
+ Then the following files should exist:
+ | stylesheets/fonts.css |
+ And the file "stylesheets/fonts.css" should contain "/fonts/StMarie-Thin.otf"
Scenario: Rendering scss
Given the Server is running at "fonts-app"
diff --git a/features/nested_layouts.feature b/features/nested_layouts.feature
new file mode 100644
index 00000000..146443c5
--- /dev/null
+++ b/features/nested_layouts.feature
@@ -0,0 +1,9 @@
+Feature: Allow nesting of layouts
+
+ Scenario: A page uses an inner layout when uses an outer layout
+ Given the Server is running at "nested-layout-app"
+ When I go to "/index.html"
+ Then I should see "Template"
+ And I should see "Inner"
+ And I should see "Outer"
+ And I should see "Master"
\ No newline at end of file
diff --git a/features/sprockets.feature b/features/sprockets.feature
index 1d01b85d..debd034f 100644
--- a/features/sprockets.feature
+++ b/features/sprockets.feature
@@ -21,8 +21,10 @@ Feature: Sprockets
Then I should see "Hello One"
Scenario: Multiple engine files should build correctly
- Given a built app at "test-app"
- Then "javascripts/multiple_engines.js" should exist at "test-app" and include "Hello One"
+ Given a successfully built app at "test-app"
+ When I cd to "build"
+ Then a file named "javascripts/multiple_engines.js" should exist
+ And the file "javascripts/multiple_engines.js" should contain "Hello One"
Scenario: Sprockets CSS require //require
Given the Server is running at "test-app"
diff --git a/fixtures/3rd-party-command/config.rb b/fixtures/3rd-party-command/config.rb
new file mode 100644
index 00000000..f7bded87
--- /dev/null
+++ b/fixtures/3rd-party-command/config.rb
@@ -0,0 +1,10 @@
+class HelloWorld < Thor
+ default_task :say_hi
+
+ desc "hello", "Say hello"
+ def say_hi
+ puts "Hello World"
+ end
+end
+
+Middleman::Cli::Base.register(HelloWorld, :hello, "hello", "Say hello")
\ No newline at end of file
diff --git a/fixtures/nested-layout-app/config.rb b/fixtures/nested-layout-app/config.rb
new file mode 100644
index 00000000..fe617582
--- /dev/null
+++ b/fixtures/nested-layout-app/config.rb
@@ -0,0 +1 @@
+set :layout, :inner
\ No newline at end of file
diff --git a/fixtures/nested-layout-app/source/index.html.erb b/fixtures/nested-layout-app/source/index.html.erb
new file mode 100644
index 00000000..a1ab916e
--- /dev/null
+++ b/fixtures/nested-layout-app/source/index.html.erb
@@ -0,0 +1 @@
+Template
\ No newline at end of file
diff --git a/fixtures/nested-layout-app/source/layouts/inner.erb b/fixtures/nested-layout-app/source/layouts/inner.erb
new file mode 100644
index 00000000..62dfc12b
--- /dev/null
+++ b/fixtures/nested-layout-app/source/layouts/inner.erb
@@ -0,0 +1,4 @@
+<% wrap_layout :outer do %>
+ Inner
+ <%= yield %>
+<% end %>
\ No newline at end of file
diff --git a/fixtures/nested-layout-app/source/layouts/master.erb b/fixtures/nested-layout-app/source/layouts/master.erb
new file mode 100644
index 00000000..18dcdbb7
--- /dev/null
+++ b/fixtures/nested-layout-app/source/layouts/master.erb
@@ -0,0 +1,2 @@
+Master
+<%= yield %>
\ No newline at end of file
diff --git a/fixtures/nested-layout-app/source/layouts/outer.erb b/fixtures/nested-layout-app/source/layouts/outer.erb
new file mode 100644
index 00000000..643d8efc
--- /dev/null
+++ b/fixtures/nested-layout-app/source/layouts/outer.erb
@@ -0,0 +1,4 @@
+<% wrap_layout :master do %>
+ Outer
+ <%= yield %>
+<% end %>
\ No newline at end of file
diff --git a/lib/middleman.rb b/lib/middleman.rb
index 8944a11e..1cf7785b 100755
--- a/lib/middleman.rb
+++ b/lib/middleman.rb
@@ -1,17 +1,27 @@
+require "rbconfig"
+
# Setup our load paths
libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
# Top-level Middleman object
module Middleman
+ WINDOWS = !!(RUBY_PLATFORM =~ /(mingw|bccwin|wince|mswin32)/i)
+ JRUBY = !!(RbConfig::CONFIG["RUBY_INSTALL_NAME"] =~ /^jruby/i)
+
# Auto-load modules on-demand
autoload :Base, "middleman/base"
autoload :Cache, "middleman/cache"
- autoload :Builder, "middleman/builder"
- autoload :CLI, "middleman/cli"
autoload :Templates, "middleman/templates"
autoload :Guard, "middleman/guard"
+ module Cli
+ autoload :Base, "middleman/cli"
+ autoload :Build, "middleman/cli/build"
+ autoload :Init, "middleman/cli/init"
+ autoload :Server, "middleman/cli/server"
+ end
+
# Custom Renderers
module Renderers
autoload :Haml, "middleman/renderers/haml"
@@ -156,12 +166,6 @@ module Middleman
class << self
- # Where to look for custom templates
- # @returns [String]
- def templates_path
- File.join(File.expand_path("~/"), ".middleman")
- end
-
# Automatically load extensions from available RubyGems
# which contain the EXTENSION_FILE
#
@@ -225,10 +229,13 @@ module Middleman
app_class = options[:app] ||= ::Middleman.server.inst
opts[:app] = app_class
- opts[:server] = 'thin'
-
- # require "thin"
- # ::Thin::Logging.silent = true if options[:debug] != "true"
+ opts[:server] = if ::Middleman::JRUBY
+ 'webrick' # Maybe Kirk?
+ else
+ require "thin"
+ ::Thin::Logging.silent = !options[:is_logging]
+ 'thin'
+ end
server = ::Rack::Server.new(opts)
server.start
diff --git a/lib/middleman/base.rb b/lib/middleman/base.rb
index 27ca2c88..1b68f182 100644
--- a/lib/middleman/base.rb
+++ b/lib/middleman/base.rb
@@ -91,6 +91,7 @@ class Middleman::Base
# Use Rack middleware
#
# @param [Class] Middleware
+ # @return [void]
def use(middleware, *args, &block)
@middleware ||= []
@middleware << [middleware, args, block]
@@ -99,6 +100,7 @@ class Middleman::Base
# Add Rack App mapped to specific path
#
# @param [String] Path to map
+ # @return [void]
def map(map, &block)
@mappings ||= []
@mappings << [map, block]
@@ -106,6 +108,7 @@ class Middleman::Base
# Mix-in helper methods. Accepts either a list of Modules
# and/or a block to be evaluated
+ # @return [void]
def helpers(*extensions, &block)
class_eval(&block) if block_given?
include(*extensions) if extensions.any?
@@ -123,6 +126,7 @@ class Middleman::Base
#
# @param [Symbol] Unique key name
# @param Default value
+ # @return [void]
def set(key, value)
@defaults ||= {}
@defaults[key] = value
@@ -133,6 +137,7 @@ class Middleman::Base
#
# @param [Symbol] Name of the attribue
# @param Attribute value
+ # @return [void]
def set(key, value=nil, &block)
setter = "#{key}=".to_sym
self.class.send(:attr_accessor, key) if !respond_to?(setter)
@@ -263,6 +268,10 @@ class Middleman::Base
@_current_path
end
+ # Set the current path
+ #
+ # @param [String] path The new current path
+ # @return [void]
def current_path=(path)
@_current_path = path
@request = Thor::CoreExt::HashWithIndifferentAccess.new({ :path => path })
@@ -295,14 +304,7 @@ class Middleman::Base
def self.cache
@_cache ||= ::Middleman::Cache.new
end
-
- # Cache accessor for instance, simply forwards to class
- #
- # @private
- # @return [Middleman::Cache] The cache
- def cache
- self.class.cache
- end
+ delegate :cache, :to => :"self.class"
# Rack env
attr :env
@@ -423,7 +425,7 @@ class Middleman::Base
# Expand a path to include the index file if it's a directory
#
# @private
- # @param [String] Request path
+ # @param [String] path Request path
# @return [String] Path with index file if necessary
def full_path(path)
cache.fetch(:full_path, path) do
@@ -437,8 +439,9 @@ class Middleman::Base
# Add a new mime-type for a specific extension
#
- # @param [Symbol] File extension
- # @param [String] Mime type
+ # @param [Symbol] type File extension
+ # @param [String] value Mime type
+ # @return [void]
def mime_type(type, value=nil)
return type if type.nil? || type.to_s.include?('/')
type = ".#{type}" unless type.to_s[0] == ?.
@@ -455,24 +458,11 @@ protected
@res.finish
end
- # Set helpers at the class level
- def helpers(*extensions, &block)
- self.class.helpers(*extensions, &block)
- end
-
- # Set middleware at the class level
- def use(middleware, *args, &block)
- self.class.use(middleware, *args, &block)
- end
-
- # Set mapped rack app at the class level
- def map(map, &block)
- self.class.map(map, &block)
- end
+ delegate :helpers, :use, :map, :to => :"self.class"
# Immediately send static file
#
- # @param [String] File to send
+ # @param [String] path File to send
def send_file(path)
extension = File.extname(path)
matched_mime = mime_type(extension)
@@ -488,7 +478,9 @@ protected
# Set the content type for the current request
#
- # @param [String] Content type
+ # @param [String] type Content type
+ # @param [Hash] params
+ # @return [void]
def content_type(type = nil, params={})
return res['Content-Type'] unless type
default = params.delete :default
diff --git a/lib/middleman/cli.rb b/lib/middleman/cli.rb
index 5e2f7c69..f5160ace 100644
--- a/lib/middleman/cli.rb
+++ b/lib/middleman/cli.rb
@@ -1,123 +1,47 @@
require 'thor'
+require "thor/group"
-module Middleman
- class CLI < Thor
- include Thor::Actions
- check_unknown_options!
- default_task :server
-
- class_option "help",
- :type => :boolean,
- :default => false,
- :aliases => "-h"
- def initialize(*)
- super
- help_check if options[:help]
- end
-
- desc "init NAME [options]", "Create new project NAME"
- available_templates = Middleman::Templates.registered.keys.join(", ")
- method_option "template",
- :aliases => "-T",
- :default => "default",
- :desc => "Use a project template: #{available_templates}"
- method_option "css_dir",
- :default => "stylesheets",
- :desc => 'The path to the css files'
- method_option "js_dir",
- :default => "javascripts",
- :desc => 'The path to the javascript files'
- method_option "images_dir",
- :default => "images",
- :desc => 'The path to the image files'
- method_option "rack",
- :type => :boolean,
- :default => false,
- :desc => 'Include a config.ru file'
- method_option "bundler",
- :type => :boolean,
- :default => false,
- :desc => 'Create a Gemfile and use Bundler to manage gems'
- def init(name)
- key = options[:template].to_sym
- unless Middleman::Templates.registered.has_key?(key)
- raise Thor::Error.new "Unknown project template '#{key}'"
- end
-
- thor_group = Middleman::Templates.registered[key]
- thor_group.new([name], options).invoke_all
- end
-
- desc "server [options]", "Start the preview server"
- method_option "environment",
- :aliases => "-e",
- :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development',
- :desc => "The environment Middleman will run under"
- method_option :host,
- :type => :string,
- :aliases => "-h",
- # :required => true,
- :default => "0.0.0.0",
- :desc => "Bind to HOST address"
- method_option "port",
- :aliases => "-p",
- :default => "4567",
- :desc => "The port Middleman will listen on"
- method_option "debug",
- :type => :boolean,
- :default => false,
- :desc => 'Print debug messages'
- def server
- params = {
- :port => options["port"],
- :host => options["host"],
- :environment => options["environment"],
- :debug => options["debug"]
- }
-
- puts "== The Middleman is loading"
- Middleman::Guard.start(params)
- end
-
- desc "build", "Builds the static site for deployment"
- method_option :relative,
- :type => :boolean,
- :aliases => "-r",
- :default => false,
- :desc => 'Force relative urls'
- method_option :clean,
- :type => :boolean,
- :aliases => "-c",
- :default => false,
- :desc => 'Removes orpahand files or directories from build'
- method_option :glob,
- :type => :string,
- :aliases => "-g",
- :default => nil,
- :desc => 'Build a subset of the project'
- def build
- thor_group = Middleman::Builder.new([], options).invoke_all
- end
-
- desc "migrate", "Migrates an older project to the 2.0 structure"
- def migrate
- return if File.exists?("source")
- `mv public source`
- `cp -R views/* source/`
- `rm -rf views`
- end
-
+# CLI Module
+module Middleman::Cli
+
+ class Base < Thor
desc "version", "Show version"
def version
require 'middleman/version'
say "Middleman #{Middleman::VERSION}"
end
- private
-
- def help_check
- help self.class.send(:retrieve_task_name, ARGV.dup)
- exit 0
+ def help(meth = nil, subcommand = false)
+ if meth && !self.respond_to?(meth)
+ klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}")
+ klass.start(["-h", task].compact, :shell => self.shell)
+ else
+ list = []
+ Thor::Util.thor_classes_in(Middleman::Cli).each do |klass|
+ list += klass.printable_tasks(false)
+ end
+ list.sort!{ |a,b| a[0] <=> b[0] }
+
+ shell.say "Tasks:"
+ shell.print_table(list, :ident => 2, :truncate => true)
+ shell.say
+ end
+ end
+
+ def method_missing(meth, *args)
+ meth = meth.to_s
+
+ if self.class.map.has_key?(meth)
+ meth = self.class.map[meth]
+ end
+
+ klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}")
+ args.unshift(task) if task
+ klass.start(args, :shell => self.shell)
end
end
end
+
+require "middleman/cli/init"
+require "middleman/cli/server"
+require "middleman/cli/build"
\ No newline at end of file
diff --git a/lib/middleman/builder.rb b/lib/middleman/cli/build.rb
similarity index 79%
rename from lib/middleman/builder.rb
rename to lib/middleman/cli/build.rb
index f065e7db..6a09fa7b 100644
--- a/lib/middleman/builder.rb
+++ b/lib/middleman/cli/build.rb
@@ -1,11 +1,44 @@
-require "thor"
-require "thor/group"
+require "rack"
require "rack/test"
-require "find"
-module Middleman
- class Builder < Thor::Group
+module Middleman::Cli
+ class Build < Thor
include Thor::Actions
+ check_unknown_options!
+
+ namespace :build
+
+ desc "build [options]", "Builds the static site for deployment"
+ method_option :relative,
+ :type => :boolean,
+ :aliases => "-r",
+ :default => false,
+ :desc => 'Force relative urls'
+ method_option :clean,
+ :type => :boolean,
+ :aliases => "-c",
+ :default => false,
+ :desc => 'Removes orpahand files or directories from build'
+ method_option :glob,
+ :type => :string,
+ :aliases => "-g",
+ :default => nil,
+ :desc => 'Build a subset of the project'
+ def build
+ if options.has_key?("relative") && options["relative"]
+ self.class.shared_instance.activate :relative_assets
+ end
+
+ self.class.shared_rack
+
+ opts = {}
+ opts[:glob] = options["glob"] if options.has_key?("glob")
+ opts[:clean] = options["clean"] if options.has_key?("clean")
+
+ action GlobAction.new(self, self.class.shared_instance, opts)
+
+ self.class.shared_instance.run_hook :after_build, self
+ end
class << self
def shared_instance
@@ -13,11 +46,11 @@ module Middleman
set :environment, :build
end
end
-
+
def shared_server
@_shared_server ||= shared_instance.class
end
-
+
def shared_rack
@_shared_rack ||= begin
mock = ::Rack::MockSession.new(shared_server.to_rack_app)
@@ -28,6 +61,8 @@ module Middleman
end
end
+ source_root(shared_instance.root)
+
# @private
module ThorActions
# Render a template to a file.
@@ -36,12 +71,12 @@ module Middleman
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first || source
- request_path = destination.sub(/^#{::Middleman::Builder.shared_instance.build_dir}/, "")
+ request_path = destination.sub(/^#{self.class.shared_instance.build_dir}/, "")
begin
- destination, request_path = ::Middleman::Builder.shared_instance.reroute_builder(destination, request_path)
+ destination, request_path = self.class.shared_instance.reroute_builder(destination, request_path)
- response = ::Middleman::Builder.shared_rack.get(request_path.gsub(/\s/, "%20"))
+ response = self.class.shared_rack.get(request_path.gsub(/\s/, "%20"))
create_file(destination, response.body, config)
@@ -52,36 +87,8 @@ module Middleman
end
end
end
+
include ThorActions
-
- class_option :relative, :type => :boolean, :aliases => "-r", :default => false, :desc => 'Override the config.rb file and force relative urls'
- class_option :glob, :type => :string, :aliases => "-g", :default => nil, :desc => 'Build a subset of the project'
-
- def initialize(*args)
- super
-
- if options.has_key?("relative") && options["relative"]
- self.class.shared_instance.activate :relative_assets
- end
- end
-
- def source_paths
- @source_paths ||= [
- self.class.shared_instance.root
- ]
- end
-
- def build_all_files
- self.class.shared_rack
-
- opts = { }
- opts[:glob] = options["glob"] if options.has_key?("glob")
- opts[:clean] = options["clean"] if options.has_key?("clean")
-
- action GlobAction.new(self, self.class.shared_instance, opts)
-
- self.class.shared_instance.run_hook :after_build, self
- end
end
# @private
@@ -92,9 +99,9 @@ module Middleman
@app = app
source = @app.source
@destination = @app.build_dir
-
+
@source = File.expand_path(base.find_in_source_paths(source.to_s))
-
+
super(base, destination, config)
end
@@ -109,7 +116,7 @@ module Middleman
end
protected
-
+
def clean!
files = @cleaning_queue.select { |q| File.file? q }
directories = @cleaning_queue.select { |q| File.directory? q }
@@ -124,7 +131,7 @@ module Middleman
base.remove_file d, :force => true if directory_empty? d
end
end
-
+
def cleaning?
@config.has_key?(:clean) && @config[:clean]
end
@@ -142,20 +149,20 @@ module Middleman
end
end if File.exist?(@destination)
end
-
+
def execute!
sort_order = %w(.png .jpeg .jpg .gif .bmp .svg .svgz .ico .woff .otf .ttf .eot .js .css)
-
+
paths = @app.sitemap.all_paths.sort do |a, b|
a_ext = File.extname(a)
b_ext = File.extname(b)
-
+
a_idx = sort_order.index(a_ext) || 100
b_idx = sort_order.index(b_ext) || 100
-
+
a_idx <=> b_idx
end
-
+
paths.each do |path|
file_source = path
file_destination = File.join(given_destination, file_source.gsub(source, '.'))
@@ -168,15 +175,17 @@ module Middleman
elsif @app.sitemap.ignored?(file_source)
next
end
-
+
if @config[:glob]
next unless File.fnmatch(@config[:glob], file_source)
end
-
+
file_destination = base.tilt_template(file_source, file_destination, { :force => true })
@cleaning_queue.delete(file_destination) if cleaning?
end
end
end
-end
+
+ Base.map({ "b" => "build" })
+end
\ No newline at end of file
diff --git a/lib/middleman/cli/init.rb b/lib/middleman/cli/init.rb
new file mode 100644
index 00000000..1ba260d9
--- /dev/null
+++ b/lib/middleman/cli/init.rb
@@ -0,0 +1,47 @@
+module Middleman::Cli
+ class Init < Thor
+ check_unknown_options!
+
+ namespace :init
+
+ desc "init NAME [options]", "Create new project NAME"
+ available_templates = ::Middleman::Templates.registered.keys.join(", ")
+ # argument :name
+ method_option "template",
+ :aliases => "-T",
+ :default => "default",
+ :desc => "Use a project template: #{available_templates}"
+ method_option "css_dir",
+ :default => "stylesheets",
+ :desc => 'The path to the css files'
+ method_option "js_dir",
+ :default => "javascripts",
+ :desc => 'The path to the javascript files'
+ method_option "images_dir",
+ :default => "images",
+ :desc => 'The path to the image files'
+ method_option "rack",
+ :type => :boolean,
+ :default => false,
+ :desc => 'Include a config.ru file'
+ method_option "bundler",
+ :type => :boolean,
+ :default => false,
+ :desc => 'Create a Gemfile and use Bundler to manage gems'
+ def init(name)
+ key = options[:template].to_sym
+ unless ::Middleman::Templates.registered.has_key?(key)
+ raise Thor::Error.new "Unknown project template '#{key}'"
+ end
+
+ thor_group = ::Middleman::Templates.registered[key]
+ thor_group.new([name], options).invoke_all
+ end
+ end
+
+ Base.map({
+ "i" => "init",
+ "new" => "init",
+ "n" => "init"
+ })
+end
\ No newline at end of file
diff --git a/lib/middleman/cli/server.rb b/lib/middleman/cli/server.rb
new file mode 100644
index 00000000..b9befb45
--- /dev/null
+++ b/lib/middleman/cli/server.rb
@@ -0,0 +1,40 @@
+module Middleman::Cli
+ class Server < Thor
+ check_unknown_options!
+
+ namespace :server
+
+ desc "server [options]", "Start the preview server"
+ method_option "environment",
+ :aliases => "-e",
+ :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development',
+ :desc => "The environment Middleman will run under"
+ method_option :host,
+ :type => :string,
+ :aliases => "-h",
+ # :required => true,
+ :default => "0.0.0.0",
+ :desc => "Bind to HOST address"
+ method_option "port",
+ :aliases => "-p",
+ :default => "4567",
+ :desc => "The port Middleman will listen on"
+ method_option "debug",
+ :type => :boolean,
+ :default => false,
+ :desc => 'Print debug messages'
+ def server
+ params = {
+ :port => options["port"],
+ :host => options["host"],
+ :environment => options["environment"],
+ :debug => options["debug"]
+ }
+
+ puts "== The Middleman is loading"
+ Middleman::Guard.start(params)
+ end
+ end
+
+ Base.map({ "s" => "server" })
+end
\ No newline at end of file
diff --git a/lib/middleman/core_extensions/assets.rb b/lib/middleman/core_extensions/assets.rb
index 49c46f54..8db7e1ba 100644
--- a/lib/middleman/core_extensions/assets.rb
+++ b/lib/middleman/core_extensions/assets.rb
@@ -21,6 +21,7 @@ module Middleman::CoreExtensions::Assets
#
# @param [String] path The path (such as "photo.jpg")
# @param [String] prefix The type prefix (such as "images")
+ # @return [String] The fully qualified asset url
def asset_url(path, prefix="")
# Don't touch assets which already have a full path
path.include?("://") ? path : File.join(http_prefix, prefix, path)
diff --git a/lib/middleman/core_extensions/builder.rb b/lib/middleman/core_extensions/builder.rb
index 97076638..5ba2b160 100644
--- a/lib/middleman/core_extensions/builder.rb
+++ b/lib/middleman/core_extensions/builder.rb
@@ -1,13 +1,23 @@
+# Convenience methods to allow config.rb to talk to the Builder
module Middleman::CoreExtensions::Builder
+
+ # Extension registered
class << self
+ # @private
def registered(app)
app.define_hook :after_build
app.extend ClassMethods
app.send :include, InstanceMethods
+ app.delegate :build_reroute, :to => :"self.class"
end
+ alias :included :registered
end
+ # Build Class Methods
module ClassMethods
+ # Get a list of callbacks which can modify a files build path
+ #
+ # @return [Array]
def build_reroute(&block)
@build_rerouters ||= []
@build_rerouters << block if block_given?
@@ -15,11 +25,13 @@ module Middleman::CoreExtensions::Builder
end
end
+ # Build Instance Methods
module InstanceMethods
- def build_reroute(&block)
- self.class.build_reroute(&block)
- end
-
+ # Run through callbacks and get the new values
+ #
+ # @param [String] destination The current destination of the built file
+ # @param [String] request_path The current request path of the file
+ # @return [Array] The new values
def reroute_builder(destination, request_path)
result = [destination, request_path]
diff --git a/lib/middleman/core_extensions/compass.rb b/lib/middleman/core_extensions/compass.rb
index 2b48fb68..97f8b5f1 100644
--- a/lib/middleman/core_extensions/compass.rb
+++ b/lib/middleman/core_extensions/compass.rb
@@ -1,5 +1,10 @@
+# Forward the settings on config.rb and the result of registered extensions
+# to Compass
module Middleman::CoreExtensions::Compass
+
+ # Extension registered
class << self
+ # @private
def registered(app)
require "compass"
@@ -47,7 +52,7 @@ module Middleman::CoreExtensions::Compass
config.output_style = :nested
end
- # Required for relative paths
+ # Change paths when in build mode. Required for relative paths
configure :build do
::Compass.configuration do |config|
config.environment = :production
diff --git a/lib/middleman/core_extensions/data.rb b/lib/middleman/core_extensions/data.rb
index c6f5190b..2bccb7e2 100755
--- a/lib/middleman/core_extensions/data.rb
+++ b/lib/middleman/core_extensions/data.rb
@@ -1,9 +1,17 @@
+# Data formats
require "yaml"
require "active_support/json"
+
+# Using Thor's indifferent hash access
require "thor"
+# The data extension parses YAML and JSON files in the data/ directory
+# and makes them available to config.rb, templates and extensions
module Middleman::CoreExtensions::Data
+
+ # Extension registered
class << self
+ # @private
def registered(app)
app.set :data_dir, "data"
app.send :include, InstanceMethods
@@ -11,7 +19,10 @@ module Middleman::CoreExtensions::Data
alias :included :registered
end
+ # Instance methods
module InstanceMethods
+ # Setup data files before anything else so they are available when
+ # parsing config.rb
def initialize
file_changed DataStore.matcher do |file|
data.touch_file(file) if file.match(%r{^#{data_dir}\/})
@@ -24,43 +35,77 @@ module Middleman::CoreExtensions::Data
super
end
+ # The data object
+ #
+ # @return [DataStore]
def data
@data ||= DataStore.new(self)
end
# Makes a hash available on the data var with a given name
+ #
+ # @param [Symbol] name Name of the data, used for namespacing
+ # @param [Hash] content The content for this data
+ # @return [void]
def data_content(name, content)
DataStore.data_content(name, content)
end
# Makes a hash available on the data var with a given name
+ #
+ # @param [Symbol] name Name of the data, used for namespacing
+ # @return [void]
def data_callback(name, &block)
DataStore.data_callback(name, block)
end
end
+ # The core logic behind the data extension.
class DataStore
+
+ # Static methods
class << self
+
+ # The regex which tells Middleman which files are for data
+ #
+ # @return [Regexp]
def matcher
%r{[\w-]+\.(yml|yaml|json)$}
end
+ # Store static data hash
+ #
+ # @param [Symbol] name Name of the data, used for namespacing
+ # @param [Hash] content The content for this data
+ # @return [void]
def data_content(name, content)
@@local_sources ||= {}
@@local_sources[name.to_s] = content
end
+ # Store callback-based data
+ #
+ # @param [Symbol] name Name of the data, used for namespacing
+ # @param [Proc] proc The callback which will return data
+ # @return [void]
def data_callback(name, proc)
@@callback_sources ||= {}
@@callback_sources[name.to_s] = proc
end
end
+ # Setup data store
+ #
+ # @param [Middleman::Base] app The current instance of Middleman
def initialize(app)
@app = app
@local_data = {}
end
+ # Update the internal cache for a given file path
+ #
+ # @param [String] file The file to be re-parsed
+ # @return [void]
def touch_file(file)
file = File.expand_path(file, @app.root)
extension = File.extname(file)
@@ -74,16 +119,23 @@ module Middleman::CoreExtensions::Data
return
end
- # @app.logger.debug :data_update, Time.now, basename if @app.logging?
@local_data[basename] = recursively_enhance(data)
end
+ # Remove a given file from the internal cache
+ #
+ # @param [String] file The file to be cleared
+ # @return [void]
def remove_file(file)
extension = File.extname(file)
basename = File.basename(file, extension)
@local_data.delete(basename) if @local_data.has_key?(basename)
end
+ # Get a hash hash from either internal static data or a callback
+ #
+ # @param [String, Symbol] path The name of the data namespace
+ # @return [Hash, nil]
def data_for_path(path)
response = nil
@@ -99,6 +151,10 @@ module Middleman::CoreExtensions::Data
response
end
+ # "Magically" find namespaces of data if they exist
+ #
+ # @param [String] path The namespace to search for
+ # @return [Hash, nil]
def method_missing(path)
if @local_data.has_key?(path.to_s)
return @local_data[path.to_s]
@@ -113,6 +169,9 @@ module Middleman::CoreExtensions::Data
super
end
+ # Convert all the data into a static hash
+ #
+ # @return [Hash]
def to_h
data = {}
@@ -134,7 +193,12 @@ module Middleman::CoreExtensions::Data
data
end
- private
+ private
+ # Recursively convert a normal Hash into a HashWithIndifferentAccess
+ #
+ # @private
+ # @param [Hash] data Normal hash
+ # @return [Thor::CoreExt::HashWithIndifferentAccess]
def recursively_enhance(data)
if data.is_a? Hash
data = Thor::CoreExt::HashWithIndifferentAccess.new(data)
diff --git a/lib/middleman/core_extensions/default_helpers.rb b/lib/middleman/core_extensions/default_helpers.rb
index db5665f2..cc5f1a6a 100644
--- a/lib/middleman/core_extensions/default_helpers.rb
+++ b/lib/middleman/core_extensions/default_helpers.rb
@@ -9,8 +9,12 @@ require 'active_support/inflector' # humanize
FileSet.glob_require('../vendor/padrino-helpers-0.10.5/lib/padrino-helpers/**/*.rb', __FILE__)
+# Built-in helpers
module Middleman::CoreExtensions::DefaultHelpers
+
+ # Extension registered
class << self
+ # @private
def registered(app)
app.helpers ::Padrino::Helpers::OutputHelpers
app.helpers ::Padrino::Helpers::TagHelpers
@@ -30,19 +34,34 @@ module Middleman::CoreExtensions::DefaultHelpers
alias :included :registered
end
+ # The helpers
module Helpers
+ # Output a stylesheet link tag based on the current path
+ #
+ # @param [String] separator How to break up path in parts
+ # @return [String]
def auto_stylesheet_link_tag(separator="/")
auto_tag(:css, separator) do |path|
stylesheet_link_tag path
end
end
+ # Output a javascript tag based on the current path
+ #
+ # @param [String] separator How to break up path in parts
+ # @return [String]
def auto_javascript_include_tag(separator="/")
auto_tag(:js, separator) do |path|
javascript_include_tag path
end
end
+ # Output a stylesheet link tag based on the current path
+ #
+ # @param [Symbol] asset_ext The type of asset
+ # @param [String] separator How to break up path in parts
+ # @param [String] asset_dir Where to look for assets
+ # @return [void]
def auto_tag(asset_ext, separator="/", asset_dir=nil)
if asset_dir.nil?
asset_dir = case asset_ext
@@ -61,6 +80,9 @@ module Middleman::CoreExtensions::DefaultHelpers
yield path if sitemap.exists?(File.join(asset_dir, path))
end
+ # Generate body css classes based on the current path
+ #
+ # @return [String]
def page_classes
path = current_path.dup
path << index_file if path.match(%r{/$})
@@ -73,7 +95,11 @@ module Middleman::CoreExtensions::DefaultHelpers
classes.join(' ')
end
- # Padrino's asset handling needs to pass through ours
+ # Get the path of a file of a given type
+ #
+ # @param [Symbol] kind The type of file
+ # @param [String] source The path to the file
+ # @return [String]
def asset_path(kind, source)
return source if source =~ /^http/
asset_folder = case kind
diff --git a/lib/middleman/core_extensions/extensions.rb b/lib/middleman/core_extensions/extensions.rb
index c0644ef6..204a7eab 100644
--- a/lib/middleman/core_extensions/extensions.rb
+++ b/lib/middleman/core_extensions/extensions.rb
@@ -31,9 +31,12 @@
# Using for version parsing
require "rubygems"
+# Namespace extensions module
module Middleman::CoreExtensions::Extensions
+ # Register extension
class << self
+ # @private
def included(app)
# app.set :default_extensions, []
app.define_hook :after_configuration
@@ -43,18 +46,31 @@ module Middleman::CoreExtensions::Extensions
app.extend ClassMethods
app.send :include, InstanceMethods
+ app.delegate :configure, :to => :"self.class"
end
end
+ # Class methods
module ClassMethods
+ # Add a callback to run in a specific environment
+ #
+ # @param [String, Symbol] env The environment to run in
+ # @return [void]
def configure(env, &block)
send("#{env}_config", &block)
end
+ # Alias `extensions` to access registered extensions
+ #
+ # @return [Array] new_extensions Extension modules to register
+ # @return [Array :"self.class"
+
+ # Before parsing config, load the data/ directory
app.before_configuration do
data_path = File.join(root, data_dir)
Find.find(data_path) do |path|
@@ -14,6 +20,7 @@ module Middleman::CoreExtensions::FileWatcher
end if File.exists?(data_path)
end
+ # After config, load everything else
app.ready do
Find.find(root) do |path|
next if File.directory?(path)
@@ -24,13 +31,22 @@ module Middleman::CoreExtensions::FileWatcher
alias :included :registered
end
+ # Class methods
module ClassMethods
+ # Add callback to be run on file change
+ #
+ # @param [nil,Regexp] matcher A Regexp to match the change path against
+ # @return [Array]
def file_changed(matcher=nil, &block)
@_file_changed ||= []
@_file_changed << [block, matcher] if block_given?
@_file_changed
end
+ # Add callback to be run on file deletion
+ #
+ # @param [nil,Regexp] matcher A Regexp to match the deleted path against
+ # @return [Array]
def file_deleted(matcher=nil, &block)
@_file_deleted ||= []
@_file_deleted << [block, matcher] if block_given?
@@ -38,11 +54,12 @@ module Middleman::CoreExtensions::FileWatcher
end
end
+ # Instance methods
module InstanceMethods
- def file_changed(*args, &block)
- self.class.file_changed(*args, &block)
- end
-
+ # Notify callbacks that a file changed
+ #
+ # @param [String] path The file that changed
+ # @return [void]
def file_did_change(path)
file_changed.each do |callback, matcher|
next if path.match(%r{^#{build_dir}/})
@@ -50,11 +67,11 @@ module Middleman::CoreExtensions::FileWatcher
instance_exec(path, &callback)
end
end
-
- def file_deleted(*args)
- self.class.file_deleted(*args)
- end
+ # Notify callbacks that a file was deleted
+ #
+ # @param [String] path The file that was deleted
+ # @return [void]
def file_did_delete(path)
file_deleted.each do |callback, matcher|
next if path.match(%r{^#{build_dir}/})
diff --git a/lib/middleman/core_extensions/front_matter.rb b/lib/middleman/core_extensions/front_matter.rb
index 1e4d3ddd..1d0cc331 100644
--- a/lib/middleman/core_extensions/front_matter.rb
+++ b/lib/middleman/core_extensions/front_matter.rb
@@ -7,6 +7,7 @@ module Middleman::CoreExtensions::FrontMatter
app.set :frontmatter_extensions, %w(.htm .html .php)
app.extend ClassMethods
app.send :include, InstanceMethods
+ app.delegate :frontmatter_changed, :to => :"self.class"
end
alias :included :registered
end
@@ -55,10 +56,6 @@ module Middleman::CoreExtensions::FrontMatter
{ :options => data }
end
end
-
- def frontmatter_changed(*args, &block)
- self.class.frontmatter_changed(*args, &block)
- end
def frontmatter_did_change(path)
frontmatter_changed.each do |callback, matcher|
diff --git a/lib/middleman/core_extensions/rendering.rb b/lib/middleman/core_extensions/rendering.rb
index 5f066f8b..ba6e564e 100644
--- a/lib/middleman/core_extensions/rendering.rb
+++ b/lib/middleman/core_extensions/rendering.rb
@@ -44,6 +44,8 @@ module Middleman::CoreExtensions::Rendering
# the template don't persist for other templates.
context = self.dup
+ @current_locs = locs, @current_opts = opts
+
while ::Tilt[path]
content = render_individual_file(path, locs, opts, context)
path = File.basename(path, File.extname(path))
@@ -60,6 +62,8 @@ module Middleman::CoreExtensions::Rendering
ensure
@current_engine = engine_was
@content_blocks = nil
+ @current_locs = nil
+ @current_opts = nil
end
# Sinatra/Padrino render method signature.
@@ -198,6 +202,12 @@ module Middleman::CoreExtensions::Rendering
layout_path
end
+
+ def wrap_layout(layout_name, &block)
+ content = capture(&block) if block_given?
+ layout_path = locate_layout(layout_name, current_engine)
+ concat render_individual_file(layout_path, @current_locs || {}, @current_opts || {}, self) { content }
+ end
def current_engine
@current_engine ||= nil
diff --git a/lib/middleman/core_extensions/sprockets.rb b/lib/middleman/core_extensions/sprockets.rb
index 56af19f6..32bee098 100644
--- a/lib/middleman/core_extensions/sprockets.rb
+++ b/lib/middleman/core_extensions/sprockets.rb
@@ -1,5 +1,4 @@
require 'pathname'
-require 'rbconfig'
require "sprockets"
module Middleman::CoreExtensions::Sprockets
diff --git a/lib/middleman/guard.rb b/lib/middleman/guard.rb
index c4093365..6473c4ce 100644
--- a/lib/middleman/guard.rb
+++ b/lib/middleman/guard.rb
@@ -6,8 +6,7 @@ require "guard/guard"
require "net/http"
# Support forking on Windows
-require "rbconfig"
-require "win32/process" if RbConfig::CONFIG['host_os'].downcase =~ %r{mingw}
+require "win32/process" if Middleman::WINDOWS
module Middleman::Guard
def self.start(options={})
@@ -21,7 +20,8 @@ module Middleman::Guard
watch(%r{(.*)})
end
},
- :watch_all_modifications => true
+ :watch_all_modifications => true,
+ :no_interactions => true
})
end
end
@@ -45,32 +45,40 @@ module Guard
# Start Middleman in a fork
def start
- @server_job = fork do
- env = (@options[:environment] || "development").to_sym
- is_logging = @options.has_key?(:debug) && (@options[:debug] == "true")
- app = ::Middleman.server.inst do
- set :environment, env
- set :logging, is_logging
- end
-
- require "thin"
- ::Thin::Logging.silent = !is_logging
-
- app_rack = app.class.to_rack_app
-
- opts = @options.dup
- opts[:app] = app_rack
- puts "== The Middleman is standing watch on port #{opts[:port]||4567}"
- ::Middleman.start_server(opts)
+ if ::Middleman::JRUBY
+ thread = Thread.new { bootup }
+ thread.join
+ else
+ @server_job = fork { bootup }
end
end
+ def bootup
+ env = (@options[:environment] || "development").to_sym
+ is_logging = @options.has_key?(:debug) && (@options[:debug] == "true")
+ app = ::Middleman.server.inst do
+ set :environment, env
+ set :logging, is_logging
+ end
+
+ app_rack = app.class.to_rack_app
+
+ opts = @options.dup
+ opts[:app] = app_rack
+ opts[:logging] = is_logging
+ puts "== The Middleman is standing watch on port #{opts[:port]||4567}"
+ ::Middleman.start_server(opts)
+ end
+
# Stop the forked Middleman
def stop
puts "== The Middleman is shutting down"
- Process.kill("KILL", @server_job)
- Process.wait @server_job
- @server_job = nil
+ if ::Middleman::JRUBY
+ else
+ Process.kill(self.class.kill_command, @server_job)
+ Process.wait @server_job
+ @server_job = nil
+ end
end
# Simply stop, then start
@@ -99,6 +107,10 @@ module Guard
paths.each { |path| tell_server(:delete => path) }
end
+ def self.kill_command
+ ::Middleman::WINDOWS ? 1 : :INT
+ end
+
private
# Whether the passed files are config.rb or lib/*.rb
# @param [Array] paths Array of paths to check
@@ -119,7 +131,7 @@ module Guard
end
# Trap the interupt signal and shut down Guard (and thus the server) smoothly
-trap(:INT) do
+trap(::Guard::Middleman.kill_command) do
::Guard.stop
- exit
+ # exit!(0)
end
\ No newline at end of file
diff --git a/lib/middleman/step_definitions.rb b/lib/middleman/step_definitions.rb
index 3849750a..0fa95192 100644
--- a/lib/middleman/step_definitions.rb
+++ b/lib/middleman/step_definitions.rb
@@ -1,7 +1,13 @@
MIDDLEMAN_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
MIDDLEMAN_BIN_PATH = File.join(MIDDLEMAN_ROOT_PATH, "bin")
+ENV['PATH'] = "#{MIDDLEMAN_BIN_PATH}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
+require "aruba/cucumber"
require "middleman/step_definitions/middleman_steps"
require "middleman/step_definitions/builder_steps"
require "middleman/step_definitions/generator_steps"
-require "middleman/step_definitions/server_steps"
\ No newline at end of file
+require "middleman/step_definitions/server_steps"
+
+Before do
+ @aruba_timeout_seconds = 30
+end
\ No newline at end of file
diff --git a/lib/middleman/step_definitions/builder_steps.rb b/lib/middleman/step_definitions/builder_steps.rb
index 7cf02733..16fad844 100644
--- a/lib/middleman/step_definitions/builder_steps.rb
+++ b/lib/middleman/step_definitions/builder_steps.rb
@@ -3,48 +3,40 @@ require 'fileutils'
Given /^app "([^\"]*)" is using config "([^\"]*)"$/ do |path, config_name|
target = File.join(PROJECT_ROOT_PATH, "fixtures", path)
config_path = File.join(target, "config-#{config_name}.rb")
- config_dest = File.join(target, "config.rb")
+ config_dest = File.join(current_dir, "config.rb")
FileUtils.cp(config_path, config_dest)
end
-Given /^a built app at "([^\"]*)"$/ do |path|
- target = File.join(PROJECT_ROOT_PATH, "fixtures", path)
+Given /^a fixture app "([^\"]*)"$/ do |path|
+ step %Q{a directory named "#{path}"}
+
+ target_path = File.join(PROJECT_ROOT_PATH, "fixtures", path)
+ FileUtils.cp_r(target_path, current_dir)
- build_target = File.join(target, "build")
- FileUtils.rm_rf(build_target)
-
- build_cmd = File.join(MIDDLEMAN_BIN_PATH, "middleman build")
- `cd #{target} && #{build_cmd}`
+ step %Q{I cd to "#{path}"}
end
-Then /^cleanup built app at "([^\"]*)"$/ do |path|
- target = File.join(PROJECT_ROOT_PATH, "fixtures", path, "build")
- FileUtils.rm_rf(target)
+Given /^a built app at "([^\"]*)"$/ do |path|
+ step %Q{a fixture app "#{path}"}
+ step %Q{I run `middleman build`}
+end
+
+Given /^was successfully built$/ do
+ step %Q{a directory named "build" should exist}
+ step %Q{the exit status should be 0}
+end
+
+Given /^a successfully built app at "([^\"]*)"$/ do |path|
+ step %Q{a built app at "#{path}"}
+ step %Q{was successfully built}
end
Given /^a built app at "([^\"]*)" with flags "([^\"]*)"$/ do |path, flags|
- target = File.join(PROJECT_ROOT_PATH, "fixtures", path)
- build_cmd = File.join(MIDDLEMAN_BIN_PATH, "middleman build")
- `cd #{target} && #{build_cmd} #{flags}`
+ step %Q{a fixture app "#{path}"}
+ step %Q{I run `middleman build #{flags}`}
end
-Then /^"([^\"]*)" should exist at "([^\"]*)"$/ do |target_file, path|
- target = File.join(PROJECT_ROOT_PATH, "fixtures", path, "build", target_file)
- File.exists?(target).should be_true
-end
-
-Then /^"([^\"]*)" should exist at "([^\"]*)" and include "([^\"]*)"$/ do |target_file, path, expected|
- target = File.join(PROJECT_ROOT_PATH, "fixtures", path, "build", target_file)
- File.exists?(target).should be_true
- File.read(target).should include(expected)
-end
-
-Then /^"([^\"]*)" should not exist at "([^\"]*)"$/ do |target_file, path|
- target = File.join(PROJECT_ROOT_PATH, "fixtures", path, "build", target_file)
- File.exists?(target).should be_false
-end
-
-Then /^the last exit code should be "([^\"]*)"$/ do |exit_code|
- exit_code = exit_code.to_i
- $?.exitstatus.should == exit_code
+Given /^a successfully built app at "([^\"]*)" with flags "([^\"]*)"$/ do |path, flags|
+ step %Q{a built app at "#{path}" with flags "#{flags}"}
+ step %Q{was successfully built}
end
diff --git a/lib/middleman/step_definitions/middleman_steps.rb b/lib/middleman/step_definitions/middleman_steps.rb
index b0c9ed77..8e284a95 100644
--- a/lib/middleman/step_definitions/middleman_steps.rb
+++ b/lib/middleman/step_definitions/middleman_steps.rb
@@ -1,3 +1,5 @@
+require "fileutils"
+
Given /^a project at "([^\"]*)"$/ do |dirname|
@target = File.join(PROJECT_ROOT_PATH, "fixtures", dirname)
end
diff --git a/lib/middleman/templates.rb b/lib/middleman/templates.rb
index 4825833e..0433312a 100644
--- a/lib/middleman/templates.rb
+++ b/lib/middleman/templates.rb
@@ -9,18 +9,20 @@ module Middleman::Templates
class << self
# Get list of registered templates and add new ones
+ #
+ # Middleman::Templates.register(:ext_name, klass)
#
# @param [Symbol] name The name of the template
# @param [Class] klass The class to be executed for this template
# @return [Hash] List of registered templates
- def registered(*args)
+ def register(*args)
@_template_mappings ||= {}
@_template_mappings[args[0]] = args[1] if args.length == 2
@_template_mappings
end
# Middleman::Templates.register(name, klass)
- alias :register :registered
+ alias :registered :register
end
# Base Template class. Handles basic options and paths.
@@ -44,14 +46,20 @@ module Middleman::Templates
# Output a config.ru file for Rack if --rack is passed
class_option :rack, :type => :boolean, :default => false
- def generate_rack
+
+ # Write a Rack config.ru file for project
+ # @return [void]
+ def generate_rack!
return unless options[:rack]
template "shared/config.ru", File.join(location, "config.ru")
end
# Output a Gemfile file for Bundler if --bundler is passed
class_option :bundler, :type => :boolean, :default => false
- def generate_bundler
+
+ # Write a Bundler Gemfile file for project
+ # @return [void]
+ def generate_bundler!
return unless options[:bundler]
template "shared/Gemfile.tt", File.join(location, "Gemfile")
diff --git a/lib/middleman/templates/default.rb b/lib/middleman/templates/default.rb
index 9931aa41..a810bdd9 100644
--- a/lib/middleman/templates/default.rb
+++ b/lib/middleman/templates/default.rb
@@ -2,12 +2,14 @@
class Middleman::Templates::Default < Middleman::Templates::Base
# Template files are relative to this file
+ # @return [String]
def self.source_root
File.dirname(__FILE__)
end
# Actually output the files
- def build_scaffold
+ # @return [void]
+ def build_scaffold!
template "shared/config.tt", File.join(location, "config.rb")
copy_file "default/source/index.html.erb", File.join(location, "source/index.html.erb")
copy_file "default/source/layout.erb", File.join(location, "source/layout.erb")
diff --git a/lib/middleman/templates/html5.rb b/lib/middleman/templates/html5.rb
index 72f11f86..d7872cda 100644
--- a/lib/middleman/templates/html5.rb
+++ b/lib/middleman/templates/html5.rb
@@ -7,12 +7,14 @@ class Middleman::Templates::Html5 < Middleman::Templates::Base
class_option :images_dir, :default => "img"
# Templates are relative to this file
+ # @return [String]
def self.source_root
File.dirname(__FILE__)
end
# Output the files
- def build_scaffold
+ # @return [void]
+ def build_scaffold!
template "shared/config.tt", File.join(location, "config.rb")
directory "html5/source", File.join(location, "source")
empty_directory File.join(location, "source")
diff --git a/lib/middleman/templates/local.rb b/lib/middleman/templates/local.rb
index 1ea76ad3..5d367cd9 100644
--- a/lib/middleman/templates/local.rb
+++ b/lib/middleman/templates/local.rb
@@ -2,18 +2,20 @@
class Middleman::Templates::Local < Middleman::Templates::Base
# Look for templates in ~/.middleman
+ # @return [String]
def self.source_root
- Middleman.templates_path
+ File.join(File.expand_path("~/"), ".middleman")
end
# Just copy from the template path
- def build_scaffold
+ # @return [void]
+ def build_scaffold!
directory options[:template].to_s, location
end
end
# Iterate over the directories in the templates path and register each one.
-Dir[File.join(Middleman.templates_path, "*")].each do |dir|
+Dir[File.join(Middleman::Templates::Local.source_root, "*")].each do |dir|
next unless File.directory?(dir)
Middleman::Templates.register(File.basename(dir).to_sym, Middleman::Templates::Local)
end
diff --git a/lib/middleman/templates/mobile.rb b/lib/middleman/templates/mobile.rb
index bc9e6e35..0b88f100 100644
--- a/lib/middleman/templates/mobile.rb
+++ b/lib/middleman/templates/mobile.rb
@@ -7,12 +7,14 @@ class Middleman::Templates::Mobile < Middleman::Templates::Base
class_option :images_dir, :default => "img"
# Template files are relative to this file
+ # @return [String]
def self.source_root
File.dirname(__FILE__)
end
# Output the files
- def build_scaffold
+ # @return [void]
+ def build_scaffold!
template "shared/config.tt", File.join(location, "config.rb")
directory "mobile/source", File.join(location, "source")
empty_directory File.join(location, "source")
diff --git a/lib/middleman/version.rb b/lib/middleman/version.rb
index 8678de25..551a41cf 100644
--- a/lib/middleman/version.rb
+++ b/lib/middleman/version.rb
@@ -2,8 +2,12 @@
require "rubygems"
module Middleman
- VERSION = "3.0.0.alpha.4"
+ # Current Version
+ # @return [String]
+ VERSION = "3.0.0.alpha.5"
+ # Parsed version for RubyGems
# @private
+ # @return [String]
GEM_VERSION = ::Gem::Version.create(VERSION)
end
diff --git a/middleman-x86-mingw32.gemspec b/middleman-x86-mingw32.gemspec
index 80348d4f..8c39cf68 100644
--- a/middleman-x86-mingw32.gemspec
+++ b/middleman-x86-mingw32.gemspec
@@ -1,6 +1,4 @@
# -*- encoding: utf-8 -*-
-require "rbconfig"
-
$:.push File.expand_path("../lib", __FILE__)
require "middleman/version"
@@ -26,7 +24,7 @@ Gem::Specification.new do |s|
s.add_dependency("tilt", ["~> 1.3.1"])
s.add_dependency("i18n", ["~> 0.6.0"])
s.add_dependency("rack-test", ["~> 0.6.1"])
- s.add_dependency("uglifier", ["~> 1.1.0"])
+ s.add_dependency("uglifier", ["~> 1.2.0"])
s.add_dependency("haml", ["~> 3.1.0"])
s.add_dependency("sass", ["~> 3.1.7"])
s.add_dependency("activesupport", ["~> 3.1.0"])
@@ -34,22 +32,25 @@ Gem::Specification.new do |s|
s.add_dependency("coffee-script", ["~> 2.2.0"])
s.add_dependency("execjs", ["~> 1.2.7"])
s.add_dependency("sprockets", ["~> 2.1.2"])
- s.add_dependency("sprockets-sass", ["~> 0.3.0"])
- s.add_dependency("guard", ["~> 0.8.8"])
+ s.add_dependency("sprockets-sass", ["~> 0.6.0"])
+ s.add_dependency("guard", ["~> 0.9.1"])
+ s.add_dependency("redcarpet", ["~> 2.0.0"])
s.add_dependency("eventmachine", ["1.0.0.beta.4.1"])
s.add_dependency("win32-process", ["~> 0.6.5"])
- s.add_dependency("rb-fchange")
# Development and test
s.add_development_dependency("slim")
- s.add_development_dependency("maruku")
+ s.add_development_dependency("sinatra")
s.add_development_dependency("coffee-filter", ["~> 0.1.1"])
- s.add_development_dependency("liquid", ["~> 2.2.0"])
+ s.add_development_dependency("liquid", ["~> 2.2"])
s.add_development_dependency("cucumber", ["~> 1.1.0"])
+ s.add_development_dependency("aruba")
s.add_development_dependency("rake", ["~> 0.9.2"])
- s.add_development_dependency("rspec", ["~> 2.7.0"])
+ s.add_development_dependency("rspec", ["~> 2.7"])
+ s.add_development_dependency("rdoc", ["~> 3.9"])
+ s.add_development_dependency("yard")
s.add_development_dependency("jquery-rails")
- s.add_development_dependency("bootstrap-rails")
+ s.add_development_dependency("bootstrap-rails", ["0.0.5"])
end
diff --git a/middleman.gemspec b/middleman.gemspec
index 685096da..238e06e5 100644
--- a/middleman.gemspec
+++ b/middleman.gemspec
@@ -1,6 +1,4 @@
# -*- encoding: utf-8 -*-
-require "rbconfig"
-
$:.push File.expand_path("../lib", __FILE__)
require "middleman/version"
@@ -26,7 +24,7 @@ Gem::Specification.new do |s|
s.add_dependency("tilt", ["~> 1.3.1"])
s.add_dependency("i18n", ["~> 0.6.0"])
s.add_dependency("rack-test", ["~> 0.6.1"])
- s.add_dependency("uglifier", ["~> 1.1.0"])
+ s.add_dependency("uglifier", ["~> 1.2.0"])
s.add_dependency("haml", ["~> 3.1.0"])
s.add_dependency("sass", ["~> 3.1.7"])
s.add_dependency("activesupport", ["~> 3.1.0"])
@@ -34,22 +32,20 @@ Gem::Specification.new do |s|
s.add_dependency("coffee-script", ["~> 2.2.0"])
s.add_dependency("execjs", ["~> 1.2.7"])
s.add_dependency("sprockets", ["~> 2.1.2"])
- s.add_dependency("sprockets-sass", ["~> 0.5.0"])
- s.add_dependency("guard", ["~> 0.8.8"])
+ s.add_dependency("sprockets-sass", ["~> 0.6.0"])
+ s.add_dependency("guard", ["~> 0.9.1"])
s.add_dependency("redcarpet", ["~> 2.0.0"])
- # OSX
- s.add_dependency("rb-fsevent")
-
# Development and test
s.add_development_dependency("slim")
s.add_development_dependency("sinatra")
s.add_development_dependency("coffee-filter", ["~> 0.1.1"])
- s.add_development_dependency("liquid", ["~> 2.2.0"])
+ s.add_development_dependency("liquid", ["~> 2.2"])
s.add_development_dependency("cucumber", ["~> 1.1.0"])
+ s.add_development_dependency("aruba")
s.add_development_dependency("rake", ["~> 0.9.2"])
- s.add_development_dependency("rspec", ["~> 2.7.0"])
- s.add_development_dependency("rdoc", ["~> 3.9.4"])
+ s.add_development_dependency("rspec", ["~> 2.7"])
+ s.add_development_dependency("rdoc", ["~> 3.9"])
s.add_development_dependency("yard")
s.add_development_dependency("jquery-rails")
s.add_development_dependency("bootstrap-rails", ["0.0.5"])