lib/guard/jekyll-plus.rb in guard-jekyll-plus-1.4.10 vs lib/guard/jekyll-plus.rb in guard-jekyll-plus-2.0.0
- old
+ new
@@ -1,93 +1,96 @@
# encoding: UTF-8
-require 'guard'
-require 'guard/guard'
+require 'benchmark'
+require 'guard/plugin'
require 'jekyll'
begin
require 'rack'
- @use_rack = true
rescue LoadError
end
module Guard
- class Jekyllplus < Guard
-
- def initialize (watchers=[], options={})
+ class Jekyllplus < Plugin
+ def initialize(options = {})
super
- default_extensions = ['md','mkd','mkdn','markdown','textile','html','haml','slim','xml','yml']
+ default_extensions = ['md','mkd','mkdn','markdown','textile','html','haml','slim','xml','yml','sass','scss']
@options = {
- :extensions => [],
+ :extensions => [],
:config => ['_config.yml'],
:serve => false,
:rack_config => nil,
:drafts => false,
:future => false,
:config_hash => nil,
:silent => false,
:msg_prefix => 'Jekyll'
}.merge(options)
- # The config_hash option should be a hash ready to be consumed by Jekyll's Site class.
- #
- @config = jekyll_config(@options)
-
- # Override configuration with guard option values
- #
- @config['show_drafts'] ||= @options[:drafts]
- @config['future'] ||= @options[:future]
-
- # Store vars for easy internal access
- #
+ @config = load_config(@options)
@source = local_path @config['source']
@destination = local_path @config['destination']
@msg_prefix = @options[:msg_prefix]
-
+
# Convert array of extensions into a regex for matching file extensions eg, /\.md$|\.markdown$|\.html$/i
- #
+ #
extensions = @options[:extensions].concat(default_extensions).flatten.uniq
@extensions = Regexp.new extensions.map { |e| (e << '$').gsub('\.', '\\.') }.join('|'), true
- # set Jekyll server process id to nil
- #
- @pid = nil
+ # set Jekyll server thread to nil
+ @server_thread = nil
- # Create a Jekyll site
- #
- @site = ::Jekyll::Site.new @config
- @rack = ::Rack::Server.new(rack_config(@destination)) if @use_rack
+ end
+ def load_config(options)
+ config = jekyll_config(options)
+
+ # Override configuration with guard option values
+ config['show_drafts'] ||= options[:drafts]
+ config['future'] ||= options[:future]
+ config
end
+ def reload_config!
+ UI.info "Reloading Jekyll configuration!"
+ @config = load_config(@options)
+ end
+
def start
if @options[:serve]
- start_server
build
+ start_server
UI.info "#{@msg_prefix} " + "watching and serving at #{@config['host']}:#{@config['port']}#{@config['baseurl']}" unless @config[:silent]
else
build
UI.info "#{@msg_prefix} " + "watching" unless @config[:silent]
end
end
- def restart
- stop if alive?
+ def reload
+ stop if !@server_thread.nil? and @server_thread.alive?
+ reload_config!
start
end
+ def reload_server
+ stop_server
+ start_server
+ end
def stop
stop_server
end
def run_on_modifications(paths)
+ # At this point we know @options[:config] is going to be an Array
+ # thanks to the call the jekyll_config earlier.
+ reload_config! if @options[:config].map { |f| paths.include?(f) }.any?
matched = jekyll_matches paths
unmatched = non_jekyll_matches paths
-
if matched.size > 0
build(matched, "Files changed: ", " ~ ".yellow)
elsif unmatched.size > 0
copy(unmatched)
end
@@ -124,14 +127,13 @@
if files
puts '| ' # spacing
files.each { |file| puts '|' + mark + file }
puts '| ' # spacing
end
- @site.process
- UI.info "#{@msg_prefix} " + "build complete ".green + "#{@source} → #{@destination}" unless @config[:silent]
-
- rescue Exception => e
+ elapsed = Benchmark.realtime { build_site(@config) }
+ UI.info "#{@msg_prefix} " + "build completed in #{elapsed.round(2)}s ".green + "#{@source} → #{@destination}" unless @config[:silent]
+ rescue Exception
UI.error "#{@msg_prefix} build has failed" unless @config[:silent]
stop_server
throw :task_has_failed
end
end
@@ -145,18 +147,22 @@
message = 'copied file'
message += 's' if files.size > 1
UI.info "#{@msg_prefix} #{message.green}" unless @config[:silent]
puts '| ' #spacing
files.each do |file|
- path = destination_path file
- FileUtils.mkdir_p File.dirname(path)
- FileUtils.cp file, path
- puts '|' + " → ".green + path
+ if(!check_jekyll_exclude(file))
+ path = destination_path file
+ FileUtils.mkdir_p File.dirname(path)
+ FileUtils.cp file, path
+ puts '|' + " → ".green + path
+ else
+ puts '|' + " ~ ".yellow + "Jekyll exclude: Ignoring changes to #{file}".yellow
+ end
end
puts '| ' #spacing
- rescue Exception => e
+ rescue Exception
UI.error "#{@msg_prefix} copy has failed" unless @config[:silent]
UI.error e
stop_server
throw :task_has_failed
end
@@ -169,11 +175,11 @@
ignore = ENV['GUARD_STITCH_PLUS_FILES'].split(',')
files.reject {|f| ignore.include? f }
else
files
end
-
+
end
# Remove deleted source file/directories from destination
#
def remove(files=[])
@@ -193,17 +199,17 @@
puts '|' + " x ".red + path
end
dir = File.dirname path
if Dir[dir+'/*'].empty?
- FileUtils.rm_r(dir)
+ FileUtils.rm_r(dir)
puts '|' + " x ".red + dir
end
end
puts '| ' #spacing
- rescue Exception => e
+ rescue Exception
UI.error "#{@msg_prefix} remove has failed" unless @config[:silent]
UI.error e
stop_server
throw :task_has_failed
end
@@ -224,80 +230,71 @@
config = options[:config_hash]
elsif options[:config]
options[:config] = [options[:config]] unless options[:config].is_a? Array
config = options
end
- ::Jekyll.configuration(config)
+ Jekyll.configuration(config)
end
+ def check_jekyll_exclude(path)
+ return @config['exclude'].any? {|f| File.fnmatch?(path, f)}
+ end
+
def rack_config(root)
ENV['RACK_ROOT'] = root
default_config = File.expand_path("../rack/config.ru", File.dirname(__FILE__))
local_config = File.exist?('config.ru') ? 'config.ru' : nil
config = (@config['rack_config'] || local_config || default_config)
- { :config => config, :Port => @config['port'], :Host => @config['host'] }
+ { :config => config, :Port => @config['port'], :Host => @config['host'], :environment => 'development' }
end
def local_path(path)
Dir.chdir('.')
current = Dir.pwd
path = path.sub current, ''
if path == ''
'./'
- else
- path.sub /^\//, ''
+ else
+ path.sub(/^\//, '')
end
end
+
+ def build_site(options)
+ Jekyll.logger.log_level = :error
+ site = Jekyll::Site.new(options)
+ Jekyll.logger.log_level = :info
+ site.process
+ end
+
def destination_path(file)
if @source =~ /^\./
File.join @destination, file
else
- file.sub /^#{@source}/, "#{@destination}"
+ file.sub(/^#{@source}/, "#{@destination}")
end
end
- # Remove
- def ignore_underscores(paths)
- paths.select { |file| file =~ /^[^_]/ }
- end
-
def server(config)
- if @rack
- proc{ Process.fork { @rack.start } }
+ if defined? ::Rack
+ Thread.new { ::Rack::Server.start(rack_config(@destination)) }
+ UI.info "#{@msg_prefix} running Rack" unless @config[:silent]
else
- proc{ Process.fork { ::Jekyll::Commands::Serve.process(config) } }
+ Thread.new { Jekyll::Commands::Serve.process(config) }
end
end
- def kill
- proc{|pid| Process.kill("INT", pid)}
- end
-
def start_server
- return @pid if alive?
- @pid = instance_eval &server(@config)
+ if @server_thread.nil?
+ @server_thread = server(@config)
+ else
+ UI.warning "#{@msg_prefix} using an old server thread!"
+ end
end
def stop_server
- if alive?
- instance_eval do
- kill.call(@pid)
- @pid = nil
- end
- end
+ @server_thread.kill unless @server_thread.nil?
+ @server_thread = nil
end
-
- def alive?
- return false unless @pid
-
- begin
- Process.getpgid(@pid)
- true
- rescue Errno::ESRCH => e
- false
- end
- end
end
end
-