diff --git a/bin/middleman b/bin/middleman index b6b64011..46e999f7 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,25 @@ 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 - -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 ARGV.length < 1 || %w(server build migrate).include?(ARGV.first) + 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/lib/middleman.rb b/lib/middleman.rb index c84d559e..33de9f81 100755 --- a/lib/middleman.rb +++ b/lib/middleman.rb @@ -12,11 +12,16 @@ module Middleman # 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 :Templates, "middleman/cli/templates" + autoload :Server, "middleman/cli/server" + end + # Custom Renderers module Renderers autoload :Haml, "middleman/renderers/haml" @@ -161,12 +166,6 @@ module Middleman class << self - # Where to look for custom templates - # @return [String] - def templates_path - File.join(File.expand_path("~/"), ".middleman") - end - # Automatically load extensions from available RubyGems # which contain the EXTENSION_FILE # diff --git a/lib/middleman/cli.rb b/lib/middleman/cli.rb index 5e2f7c69..bc2ac6be 100644 --- a/lib/middleman/cli.rb +++ b/lib/middleman/cli.rb @@ -1,10 +1,11 @@ require 'thor' +require "thor/group" -module Middleman - class CLI < Thor +# CLI Module +module Middleman::CLI + + class Base < Thor include Thor::Actions - check_unknown_options! - default_task :server class_option "help", :type => :boolean, @@ -15,98 +16,6 @@ module Middleman 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 - desc "version", "Show version" def version require 'middleman/version' @@ -121,3 +30,7 @@ module Middleman end end end + +require "middleman/cli/templates" +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 78% rename from lib/middleman/builder.rb rename to lib/middleman/cli/build.rb index f065e7db..37d854a3 100644 --- a/lib/middleman/builder.rb +++ b/lib/middleman/cli/build.rb @@ -1,11 +1,42 @@ -require "thor" -require "thor/group" +require "rack" require "rack/test" -require "find" -module Middleman - class Builder < Thor::Group +module Middleman::CLI + class Build < Thor::Group include Thor::Actions + check_unknown_options! + + desc "build [options]" + class_option :relative, + :type => :boolean, + :aliases => "-r", + :default => false, + :desc => 'Force relative urls' + class_option :clean, + :type => :boolean, + :aliases => "-c", + :default => false, + :desc => 'Removes orpahand files or directories from build' + class_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 +44,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 +59,8 @@ module Middleman end end + source_root(shared_instance.root) + # @private module ThorActions # Render a template to a file. @@ -36,12 +69,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 +85,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 +97,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 +114,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 +129,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 +147,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 +173,18 @@ 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.register(Build, :build, "build [options]", "Builds the static site for deployment") + Base.map({ "b" => "build" }) +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..48f9ad12 --- /dev/null +++ b/lib/middleman/cli/server.rb @@ -0,0 +1,40 @@ +module Middleman::CLI + class Server < Thor::Group + check_unknown_options! + + desc "server [options]" + class_option "environment", + :aliases => "-e", + :default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development', + :desc => "The environment Middleman will run under" + class_option :host, + :type => :string, + :aliases => "-h", + # :required => true, + :default => "0.0.0.0", + :desc => "Bind to HOST address" + class_option "port", + :aliases => "-p", + :default => "4567", + :desc => "The port Middleman will listen on" + class_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.register(Server, :server, "server [options]", "Start the preview server") + Base.map({ "s" => "server" }) + Base.default_task :server +end \ No newline at end of file diff --git a/lib/middleman/cli/templates.rb b/lib/middleman/cli/templates.rb new file mode 100644 index 00000000..5db200ae --- /dev/null +++ b/lib/middleman/cli/templates.rb @@ -0,0 +1,46 @@ +module Middleman::CLI + class Templates < Thor::Group + check_unknown_options! + + desc "init NAME [options]" + available_templates = ::Middleman::Templates.registered.keys.join(", ") + argument :name + class_option "template", + :aliases => "-T", + :default => "default", + :desc => "Use a project template: #{available_templates}" + class_option "css_dir", + :default => "stylesheets", + :desc => 'The path to the css files' + class_option "js_dir", + :default => "javascripts", + :desc => 'The path to the javascript files' + class_option "images_dir", + :default => "images", + :desc => 'The path to the image files' + class_option "rack", + :type => :boolean, + :default => false, + :desc => 'Include a config.ru file' + class_option "bundler", + :type => :boolean, + :default => false, + :desc => 'Create a Gemfile and use Bundler to manage gems' + def init + 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.register(Templates, :init, "init NAME [options]", "Create new project NAME") + Base.map({ + "i" => "init", + "new" => "init", + "n" => "init" + }) +end \ No newline at end of file diff --git a/lib/middleman/templates/local.rb b/lib/middleman/templates/local.rb index d818790c..5d367cd9 100644 --- a/lib/middleman/templates/local.rb +++ b/lib/middleman/templates/local.rb @@ -4,7 +4,7 @@ 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 @@ -15,7 +15,7 @@ class Middleman::Templates::Local < Middleman::Templates::Base 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