From a97ae67552f82cb309e3cb951947fa082733f77a Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sat, 12 Jul 2014 13:46:49 -0700 Subject: [PATCH] Gracefully require --- lib/jekyll.rb | 109 +++++++++--------- lib/jekyll/commands/build.rb | 2 +- .../converters/markdown/rdiscount_parser.rb | 6 +- .../converters/markdown/redcarpet_parser.rb | 63 +++++----- lib/jekyll/deprecator.rb | 20 +++- lib/jekyll/errors.rb | 2 + 6 files changed, 105 insertions(+), 97 deletions(-) diff --git a/lib/jekyll.rb b/lib/jekyll.rb index bf2f566f..ba892e18 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -18,75 +18,56 @@ require 'rubygems' # stdlib require 'fileutils' require 'time' -require 'safe_yaml/load' require 'English' require 'pathname' require 'logger' # 3rd party +require 'safe_yaml/load' require 'liquid' require 'kramdown' require 'colorator' -# internal requires -require 'jekyll/version' -require 'jekyll/utils' -require 'jekyll/log_adapter' -require 'jekyll/stevenson' -require 'jekyll/deprecator' -require 'jekyll/configuration' -require 'jekyll/document' -require 'jekyll/collection' -require 'jekyll/plugin_manager' -require 'jekyll/frontmatter_defaults' -require 'jekyll/site' -require 'jekyll/convertible' -require 'jekyll/url' -require 'jekyll/layout' -require 'jekyll/page' -require 'jekyll/post' -require 'jekyll/excerpt' -require 'jekyll/draft' -require 'jekyll/filters' -require 'jekyll/static_file' -require 'jekyll/errors' -require 'jekyll/related_posts' -require 'jekyll/cleaner' -require 'jekyll/entry_filter' -require 'jekyll/layout_reader' -require 'jekyll/publisher' -require 'jekyll/renderer' - -# extensions -require 'jekyll/plugin' -require 'jekyll/converter' -require 'jekyll/generator' -require 'jekyll/command' -require 'jekyll/liquid_extensions' - -require_all 'jekyll/commands' -require_all 'jekyll/converters' -require_all 'jekyll/converters/markdown' -require_all 'jekyll/generators' -require_all 'jekyll/tags' - -# plugins -require 'jekyll-coffeescript' -require 'jekyll-sass-converter' - -# Eventually remove these for 3.0 as non-core -require "classifier" -require "pygments.rb" -require "toml" -require "jekyll-paginate" -require "jekyll-gist" -require "jekyll-coffeescript" -require "jekyll-sass-converter" - SafeYAML::OPTIONS[:suppress_warnings] = true module Jekyll + # internal requires + autoload :Cleaner, 'jekyll/cleaner' + autoload :Collection, 'jekyll/collection' + autoload :Configuration, 'jekyll/configuration' + autoload :Convertible, 'jekyll/convertible' + autoload :Deprecator, 'jekyll/deprecator' + autoload :Document, 'jekyll/document' + autoload :Draft, 'jekyll/draft' + autoload :EntryFilter, 'jekyll/entry_filter' + autoload :Errors, 'jekyll/errors' + autoload :Excerpt, 'jekyll/excerpt' + autoload :Filters, 'jekyll/filters' + autoload :FrontmatterDefaults, 'jekyll/frontmatter_defaults' + autoload :Layout, 'jekyll/layout' + autoload :LayoutReader, 'jekyll/layout_reader' + autoload :LogAdapter, 'jekyll/log_adapter' + autoload :Page, 'jekyll/page' + autoload :PluginManager, 'jekyll/plugin_manager' + autoload :Post, 'jekyll/post' + autoload :Publisher, 'jekyll/publisher' + autoload :RelatedPosts, 'jekyll/related_posts' + autoload :Renderer, 'jekyll/renderer' + autoload :Site, 'jekyll/site' + autoload :StaticFile, 'jekyll/static_file' + autoload :Stevenson, 'jekyll/stevenson' + autoload :URL, 'jekyll/url' + autoload :Utils, 'jekyll/utils' + autoload :VERSION, 'jekyll/version' + + # extensions + require 'jekyll/plugin' + require 'jekyll/converter' + require 'jekyll/generator' + require 'jekyll/command' + require 'jekyll/liquid_extensions' + # Public: Tells you which Jekyll environment you are building in so you can skip tasks # if you need to. This is useful when doing expensive compression tasks on css and # images and allows you to skip that when working in development. @@ -149,3 +130,19 @@ module Jekyll end end end + +require_all 'jekyll/commands' +require_all 'jekyll/converters' +require_all 'jekyll/converters/markdown' +require_all 'jekyll/generators' +require_all 'jekyll/tags' + +# Eventually remove these for 3.0 as non-core +Jekyll::Deprecator.gracefully_require(%w[ + classifier + toml + jekyll-paginate + jekyll-gist + jekyll-coffeescript + jekyll-sass-converter +]) diff --git a/lib/jekyll/commands/build.rb b/lib/jekyll/commands/build.rb index 3f187601..140a7ae3 100644 --- a/lib/jekyll/commands/build.rb +++ b/lib/jekyll/commands/build.rb @@ -58,7 +58,7 @@ module Jekyll # # Returns nothing. def watch(site, options) - require 'jekyll-watch' + Deprecator.gracefully_require 'jekyll-watch' Jekyll::Commands::Watch.watch(site, options) end diff --git a/lib/jekyll/converters/markdown/rdiscount_parser.rb b/lib/jekyll/converters/markdown/rdiscount_parser.rb index bfe1a7ca..0c8634e4 100644 --- a/lib/jekyll/converters/markdown/rdiscount_parser.rb +++ b/lib/jekyll/converters/markdown/rdiscount_parser.rb @@ -3,13 +3,9 @@ module Jekyll class Markdown class RDiscountParser def initialize(config) - require 'rdiscount' + Jekyll::Deprecator.gracefully_require "rdiscount" @config = config @rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym } - rescue LoadError - STDERR.puts 'You are missing a library required for Markdown. Please run:' - STDERR.puts ' $ [sudo] gem install rdiscount' - raise FatalException.new("Missing dependency: rdiscount") end def convert(content) diff --git a/lib/jekyll/converters/markdown/redcarpet_parser.rb b/lib/jekyll/converters/markdown/redcarpet_parser.rb index 2c5bb2f8..b69df9b8 100644 --- a/lib/jekyll/converters/markdown/redcarpet_parser.rb +++ b/lib/jekyll/converters/markdown/redcarpet_parser.rb @@ -14,7 +14,7 @@ module Jekyll module WithPygments include CommonMethods def block_code(code, lang) - require 'pygments' + Jekyll::Deprecator.gracefully_require("pygments") lang = lang && lang.split.first || "text" add_code_tags( Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }), @@ -55,45 +55,40 @@ module Jekyll def initialize(config) - require 'redcarpet' + Deprecator.gracefully_require("redcarpet") @config = config @redcarpet_extensions = {} @config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true } - @renderer ||= case @config['highlighter'] - when 'pygments' - Class.new(Redcarpet::Render::HTML) do - include WithPygments - end - when 'rouge' - Class.new(Redcarpet::Render::HTML) do - begin - require 'rouge' - require 'rouge/plugins/redcarpet' - rescue LoadError => e - Jekyll.logger.error "You are missing the 'rouge' gem. Please run:" - Jekyll.logger.error " $ [sudo] gem install rouge" - Jekyll.logger.error "Or add 'rouge' to your Gemfile." - raise FatalException.new("Missing dependency: rouge") - end + @renderer ||= class_with_proper_highlighter(@config['highlighter']) + end - if Rouge.version < '1.3.0' - abort "Please install Rouge 1.3.0 or greater and try running Jekyll again." - end + def class_with_proper_highlighter(highlighter) + case highlighter + when "pygments" + Class.new(Redcarpet::Render::HTML) do + include WithPygments + end + when "rouge" + Class.new(Redcarpet::Render::HTML) do + Jekyll::Deprecator.gracefully_require(%w[ + rouge + rouge/plugins/redcarpet + ]) - include Rouge::Plugins::Redcarpet - include CommonMethods - include WithRouge - end - else - Class.new(Redcarpet::Render::HTML) do - include WithoutHighlighting - end - end - rescue LoadError - STDERR.puts 'You are missing a library required for Markdown. Please run:' - STDERR.puts ' $ [sudo] gem install redcarpet' - raise FatalException.new("Missing dependency: redcarpet") + if Rouge.version < '1.3.0' + abort "Please install Rouge 1.3.0 or greater and try running Jekyll again." + end + + include Rouge::Plugins::Redcarpet + include CommonMethods + include WithRouge + end + else + Class.new(Redcarpet::Render::HTML) do + include WithoutHighlighting + end + end end def convert(content) diff --git a/lib/jekyll/deprecator.rb b/lib/jekyll/deprecator.rb index 47f03b70..6fd94fb2 100644 --- a/lib/jekyll/deprecator.rb +++ b/lib/jekyll/deprecator.rb @@ -1,5 +1,5 @@ module Jekyll - class Deprecator + module Deprecator def self.process(args) no_subcommand(args) arg_is_present? args, "--server", "The --server command has been replaced by the \ @@ -32,5 +32,23 @@ module Jekyll def self.deprecation_message(message) Jekyll.logger.error "Deprecation:", message end + + def self.gracefully_require(gem_name) + Array(gem_name).each do |name| + begin + require name + rescue LoadError => e + Jekyll.logger.error "Dependency Error:", <<-MSG + Yikes! It looks like you don't have #{name} or one of its dependencies installed. + In order to use Jekyll as currently contfigured, you'll need to install this gem. + + The full error message from Ruby is: '#{e.message}' + + If you run into trouble, you can find helpful resources at http://jekyllrb.com/help/! + MSG + raise Errors::MissingDependencyException.new(name) + end + end + end end end diff --git a/lib/jekyll/errors.rb b/lib/jekyll/errors.rb index af03ad84..6801f9b5 100644 --- a/lib/jekyll/errors.rb +++ b/lib/jekyll/errors.rb @@ -1,4 +1,6 @@ module Jekyll class FatalException < StandardError + class MissingDependencyException < FatalException + end end end