-
-
Notifications
You must be signed in to change notification settings - Fork 9.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor CLI & Commands For Greater Happiness #2143
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,79 @@ | ||
module Jekyll | ||
class Command | ||
def self.globs(source, destination) | ||
Dir.chdir(source) do | ||
dirs = Dir['*'].select { |x| File.directory?(x) } | ||
dirs -= [destination, File.expand_path(destination), File.basename(destination)] | ||
dirs = dirs.map { |x| "#{x}/**/*" } | ||
dirs += ['*'] | ||
|
||
class << self | ||
|
||
# A list of subclasses of Jekyll::Command | ||
def subclasses | ||
@subclasses ||= [] | ||
end | ||
|
||
# Keep a list of subclasses of Jekyll::Command every time it's inherited | ||
# Called automatically. | ||
# | ||
# base - the subclass | ||
# | ||
# Returns nothing | ||
def inherited(base) | ||
subclasses << base | ||
super(base) | ||
end | ||
|
||
# Listing of all directories (globbed to include subfiles and folders) | ||
# | ||
# source - the source path | ||
# destination - the destination path | ||
# | ||
# Returns an Array of directory globs in the source, excluding the destination | ||
def globs(source, destination) | ||
Dir.chdir(source) do | ||
dirs = Dir['*'].select { |x| File.directory?(x) } | ||
dirs -= [destination, File.expand_path(destination), File.basename(destination)] | ||
dirs = dirs.map { |x| "#{x}/**/*" } | ||
dirs += ['*'] | ||
end | ||
end | ||
|
||
# Run Site#process and catch errors | ||
# | ||
# site - the Jekyll::Site object | ||
# | ||
# Returns nothing | ||
def process_site(site) | ||
site.process | ||
rescue Jekyll::FatalException => e | ||
Jekyll.logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:" | ||
Jekyll.logger.error "", "------------------------------------" | ||
Jekyll.logger.error "", e.message | ||
exit(1) | ||
end | ||
|
||
# Create a full Jekyll configuration with the options passed in as overrides | ||
# | ||
# options - the configuration overrides | ||
# | ||
# Returns a full Jekyll configuration | ||
def configuration_from_options(options) | ||
Jekyll.configuration(options) | ||
end | ||
|
||
# Add common options to a command for building configuration | ||
# | ||
# c - the Jekyll::Command to add these options to | ||
# | ||
# Returns nothing | ||
def add_build_options(c) | ||
c.option 'config', '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file' | ||
c.option 'future', '--future', 'Publishes posts with a future date' | ||
c.option 'limit_posts', '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish' | ||
c.option 'watch', '-w', '--watch', 'Watch for changes and rebuild' | ||
c.option 'lsi', '--lsi', 'Use LSI for improved related posts' | ||
c.option 'show_drafts', '-D', '--drafts', 'Render posts in the _drafts folder' | ||
c.option 'quiet', '-q', '--quiet', 'Silence output.' | ||
c.option 'verbose', '-V', '--verbose', 'Print verbose output.' | ||
end | ||
end | ||
|
||
# Static: Run Site#process and catch errors | ||
# | ||
# site - the Jekyll::Site object | ||
# | ||
# Returns nothing | ||
def self.process_site(site) | ||
site.process | ||
rescue Jekyll::FatalException => e | ||
puts | ||
Jekyll.logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:" | ||
Jekyll.logger.error "", "------------------------------------" | ||
Jekyll.logger.error "", e.message | ||
exit(1) | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,96 @@ | ||
module Jekyll | ||
module Commands | ||
class Build < Command | ||
def self.process(options) | ||
site = Jekyll::Site.new(options) | ||
|
||
Jekyll.logger.log_level = Jekyll::Stevenson::ERROR if options['quiet'] | ||
|
||
build(site, options) | ||
watch(site, options) if options['watch'] | ||
end | ||
|
||
# Private: Build the site from source into destination. | ||
# | ||
# site - A Jekyll::Site instance | ||
# options - A Hash of options passed to the command | ||
# | ||
# Returns nothing. | ||
def self.build(site, options) | ||
source = options['source'] | ||
destination = options['destination'] | ||
Jekyll.logger.info "Source:", source | ||
Jekyll.logger.info "Destination:", destination | ||
print Jekyll.logger.formatted_topic "Generating..." | ||
process_site(site) | ||
puts "done." | ||
end | ||
|
||
# Private: Watch for file changes and rebuild the site. | ||
# | ||
# site - A Jekyll::Site instance | ||
# options - A Hash of options passed to the command | ||
# | ||
# Returns nothing. | ||
def self.watch(site, options) | ||
require 'listen' | ||
|
||
source = options['source'] | ||
destination = options['destination'] | ||
|
||
begin | ||
dest = Pathname.new(destination).relative_path_from(Pathname.new(source)).to_s | ||
ignored = Regexp.new(Regexp.escape(dest)) | ||
rescue ArgumentError | ||
# Destination is outside the source, no need to ignore it. | ||
ignored = nil | ||
|
||
class << self | ||
|
||
# Create the Mercenary command for the Jekyll CLI for this Command | ||
def init_with_program(prog) | ||
prog.command(:build) do |c| | ||
c.syntax 'build [options]' | ||
c.description 'Build your site' | ||
|
||
add_build_options(c) | ||
|
||
c.action do |args, options| | ||
options["serving"] = false | ||
Jekyll::Commands::Build.process(options) | ||
end | ||
end | ||
end | ||
|
||
Jekyll.logger.info "Auto-regeneration:", "enabled" | ||
# Build your jekyll site | ||
# Continuously watch if `watch` is set to true in the config. | ||
def process(options) | ||
options = configuration_from_options(options) | ||
site = Jekyll::Site.new(options) | ||
|
||
listener = Listen.to(source, :ignore => ignored) do |modified, added, removed| | ||
t = Time.now.strftime("%Y-%m-%d %H:%M:%S") | ||
n = modified.length + added.length + removed.length | ||
print Jekyll.logger.formatted_topic("Regenerating:") + "#{n} files at #{t} " | ||
Jekyll.logger.log_level = Jekyll::Stevenson::ERROR if options['quiet'] | ||
|
||
build(site, options) | ||
watch(site, options) if options['watch'] | ||
end | ||
|
||
# Build your Jekyll site. | ||
# | ||
# site - the Jekyll::Site instance to build | ||
# options - the | ||
# | ||
# Returns nothing. | ||
def build(site, options) | ||
source = options['source'] | ||
destination = options['destination'] | ||
Jekyll.logger.info "Source:", source | ||
Jekyll.logger.info "Destination:", destination | ||
Jekyll.logger.info "Generating..." | ||
process_site(site) | ||
puts "...done." | ||
Jekyll.logger.info "", "done." | ||
end | ||
listener.start | ||
|
||
unless options['serving'] | ||
trap("INT") do | ||
listener.stop | ||
puts " Halting auto-regeneration." | ||
exit 0 | ||
# Private: Watch for file changes and rebuild the site. | ||
# | ||
# site - A Jekyll::Site instance | ||
# options - A Hash of options passed to the command | ||
# | ||
# Returns nothing. | ||
def watch(site, options) | ||
require 'listen' | ||
|
||
source = options['source'] | ||
destination = options['destination'] | ||
|
||
begin | ||
dest = Pathname.new(destination).relative_path_from(Pathname.new(source)).to_s | ||
ignored = Regexp.new(Regexp.escape(dest)) | ||
rescue ArgumentError | ||
# Destination is outside the source, no need to ignore it. | ||
ignored = nil | ||
end | ||
|
||
Jekyll.logger.info "Auto-regeneration:", "enabled" | ||
|
||
listener = Listen.to(source, :ignore => ignored) do |modified, added, removed| | ||
t = Time.now.strftime("%Y-%m-%d %H:%M:%S") | ||
n = modified.length + added.length + removed.length | ||
print Jekyll.logger.formatted_topic("Regenerating:") + "#{n} files at #{t} " | ||
process_site(site) | ||
puts "...done." | ||
end | ||
listener.start | ||
|
||
loop { sleep 1000 } | ||
unless options['serving'] | ||
trap("INT") do | ||
listener.stop | ||
puts " Halting auto-regeneration." | ||
exit 0 | ||
end | ||
|
||
loop { sleep 1000 } | ||
end | ||
end | ||
end | ||
|
||
end # end of class << self | ||
|
||
end | ||
end | ||
end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@imathis This is how you print the command help. The
p.go(['-h'])
just results in a big ol' loop that never ends which sucks. If you just print the program, it'll print out the help message as you'd expect.