Commit 8fc38e59 authored by Youhei SASAKI's avatar Youhei SASAKI

New upstream version 2.0.0

parent d45186c8
inherit_gem:
jekyll: .rubocop.yml
AllCops:
TargetRubyVersion: 2.2
Include:
- lib/**/*.rb
Exclude:
- .gitignore
- .rspec
- .rubocop.yml
- .travis.yml
- History.markdown
- Gemfile.lock
- LICENSE.txt
- README.md
- script/**/*
- vendor/**/*
Lint/HandleExceptions:
Exclude:
- lib/jekyll/watcher.rb
Lint/RescueWithoutErrorClass:
Exclude:
- lib/jekyll/watcher.rb
Metrics/BlockLength:
Exclude:
- spec/**/*
Metrics/LineLength:
Exclude:
- jekyll-watch.gemspec
sudo: false
language: ruby
rvm:
- 1.9.3
- 2.0
- 2.1
- 2.2
- 2.3
- 2.4
branches:
only:
- master
install:
- travis_retry script/unbundle
- travis_retry script/bootstrap
script: script/cibuild
notifications:
......
source 'https://rubygems.org'
# frozen_string_literal: true
source "https://rubygems.org"
gemspec
## HEAD
* Remove version lock for dependency listen (#50)
* Inherit Jekyll's rubocop config for consistency (#51)
### Development Fixes
* Update versions for Travis (#43)
* Define path with __dir__ (#48)
* Update jekyll-watch (#53)
* Drop support for old Ruby and old Jekyll (#55)
### Minor Enhancements
* Output regenerated file paths to terminal (#57)
### Major Enhancements
* Remove unnecessary method (#56)
## 1.5.0 / 2016-07-20
* reuse provided site instance if available (#40)
## 1.4.0 / 2016-04-25
* Lock Listen to less than 3.1. (#38)
## 1.3.1 / 2016-01-19
* Test against Jekyll 2 and 3. (#30)
* watcher: set `LISTEN_GEM_DEBUGGING` if `--verbose` flag set (#31)
* Apply Rubocop auditing and fix up (#32)
## 1.3.0 / 2015-09-23
* Lock to Listen 3.x (#25)
......
# frozen_string_literal: true
require "bundler/gem_tasks"
require 'rspec/core/rake_task'
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new(:spec) do |t|
t.verbose = false
end
task default: :spec
task :default => :spec
# coding: utf-8
# frozen_string_literal: true
lib = File.expand_path("lib", __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "jekyll-watch/version"
Gem::Specification.new do |spec|
spec.name = "jekyll-watch"
spec.version = "1.3.0"
spec.version = Jekyll::Watch::VERSION
spec.authors = ["Parker Moore"]
spec.email = ["parkrmoore@gmail.com"]
spec.summary = %q{Rebuild your Jekyll site when a file changes with the `--watch` switch.}
spec.summary = "Rebuild your Jekyll site when a file changes with the `--watch` switch."
spec.homepage = "https://github.com/jekyll/jekyll-watch"
spec.license = "MIT"
spec.files = `git ls-files -z`.split("\x0").grep(%r{(bin|lib)/})
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.files = `git ls-files -z`.split("\x0").grep(%r!(bin|lib)/!)
spec.executables = spec.files.grep(%r!^bin/!) { |f| File.basename(f) }
spec.require_paths = ["lib"]
spec.required_ruby_version = ">= 2.1.0"
spec.add_runtime_dependency "listen", "~> 3.0"
require 'rbconfig'
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
require "rbconfig"
if RbConfig::CONFIG["host_os"] =~ %r!mswin|mingw|cygwin!
spec.add_runtime_dependency "wdm", "~> 0.1.0"
end
spec.add_development_dependency "bundler", "~> 1.6"
spec.add_development_dependency "bundler", "~> 1.15"
spec.add_development_dependency "jekyll", "~> 3.6"
spec.add_development_dependency "rake"
spec.add_development_dependency "rspec", "~> 3.0"
spec.add_development_dependency "jekyll", ">= 2.0"
spec.add_development_dependency "rubocop", "~> 0.51"
end
# frozen_string_literal: true
require "jekyll-watch/version"
require_relative "jekyll/watcher"
require_relative "jekyll/commands/watch"
# frozen_string_literal: true
module Jekyll
module Watch
VERSION = "2.0.0".freeze
end
end
# frozen_string_literal: true
module Jekyll
module Commands
module Watch
extend self
def init_with_program(prog)
end
def init_with_program(prog); end
# Build your jekyll site
# Continuously watch if `watch` is set to true in the config.
def process(options)
Jekyll.logger.log_level = :error if options['quiet']
watch(site, options) if options['watch']
end
# 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)
Jekyll::Watcher.watch(options)
Jekyll.logger.log_level = :error if options["quiet"]
Jekyll::Watcher.watch(options) if options["watch"]
end
end
......
require 'listen'
# frozen_string_literal: true
require "listen"
module Jekyll
module Watcher
extend self
def watch(options)
site = Jekyll::Site.new(options)
# Public: Continuously watch for file changes and rebuild the site
# whenever a change is detected.
#
# If the optional site argument is populated, that site instance will be
# reused and the options Hash ignored. Otherwise, a new site instance will
# be instantiated from the options Hash and used.
#
# options - A Hash containing the site configuration
# site - The current site instance (populated starting with Jekyll 3.2)
# (optional, default: nil)
#
# Returns nothing.
def watch(options, site = nil)
ENV["LISTEN_GEM_DEBUGGING"] ||= "1" if options["verbose"]
site ||= Jekyll::Site.new(options)
listener = build_listener(site, options)
listener.start
Jekyll.logger.info "Auto-regeneration:", "enabled for '#{options['source']}'"
Jekyll.logger.info "Auto-regeneration:", "enabled for '#{options["source"]}'"
unless options['serving']
unless options["serving"]
trap("INT") do
listener.stop
puts " Halting auto-regeneration."
......@@ -20,52 +36,55 @@ module Jekyll
sleep_forever
end
rescue ThreadError => e
rescue ThreadError
# You pressed Ctrl-C, oh my!
end
# TODO: shouldn't be public API
private
def build_listener(site, options)
Listen.to(
options['source'],
:ignore => listen_ignore_paths(options),
:force_polling => options['force_polling'],
&(listen_handler(site))
options["source"],
:ignore => listen_ignore_paths(options),
:force_polling => options["force_polling"],
&listen_handler(site)
)
end
private
def listen_handler(site)
proc { |modified, added, removed|
proc do |modified, added, removed|
t = Time.now
c = modified + added + removed
n = c.length
print Jekyll.logger.message("Regenerating:", "#{n} file(s) changed at #{t.strftime("%Y-%m-%d %H:%M:%S")} ")
begin
site.process
puts "...done in #{Time.now - t} seconds."
rescue => e
puts "...error:"
Jekyll.logger.warn "Error:", e.message
Jekyll.logger.warn "Error:", "Run jekyll build --trace for more information."
Jekyll.logger.info "Regenerating:",
"#{n} file(s) changed at #{t.strftime("%Y-%m-%d %H:%M:%S")}"
c.map { |path| path.sub("#{site.source}/", "") }.each do |file|
Jekyll.logger.info "", file
end
}
process(site, t)
end
end
private
def custom_excludes(options)
Array(options['exclude']).map { |e| Jekyll.sanitized_path(options['source'], e) }
Array(options["exclude"]).map { |e| Jekyll.sanitized_path(options["source"], e) }
end
private
def config_files(options)
%w[yml yaml toml].map do |ext|
Jekyll.sanitized_path(options['source'], "_config.#{ext}")
%w(yml yaml toml).map do |ext|
Jekyll.sanitized_path(options["source"], "_config.#{ext}")
end
end
private
def to_exclude(options)
[
config_files(options),
options['destination'],
custom_excludes(options)
options["destination"],
custom_excludes(options),
].flatten
end
......@@ -74,29 +93,42 @@ module Jekyll
# options - A Hash of options passed to the command
#
# Returns a list of relative paths from source that should be ignored
private
def listen_ignore_paths(options)
source = Pathname.new(options['source']).expand_path
source = Pathname.new(options["source"]).expand_path
paths = to_exclude(options)
paths.map do |p|
absolute_path = Pathname.new(p).expand_path
if absolute_path.exist?
begin
relative_path = absolute_path.relative_path_from(source).to_s
unless relative_path.start_with?('../')
path_to_ignore = Regexp.new(Regexp.escape(relative_path))
Jekyll.logger.debug "Watcher:", "Ignoring #{path_to_ignore}"
path_to_ignore
end
rescue ArgumentError
# Could not find a relative path
next unless absolute_path.exist?
begin
relative_path = absolute_path.relative_path_from(source).to_s
unless relative_path.start_with?("../")
path_to_ignore = Regexp.new(Regexp.escape(relative_path))
Jekyll.logger.debug "Watcher:", "Ignoring #{path_to_ignore}"
path_to_ignore
end
rescue ArgumentError
# Could not find a relative path
end
end.compact + [/\.jekyll\-metadata/]
end.compact + [%r!\.jekyll\-metadata!]
end
private
def sleep_forever
loop { sleep 1000 }
end
private
def process(site, time)
begin
site.process
Jekyll.logger.info "", "...done in #{Time.now - time} seconds."
rescue => e
Jekyll.logger.warn "Error:", e.message
Jekyll.logger.warn "Error:", "Run jekyll build --trace for more information."
end
puts ""
end
end
end
#!/bin/bash
time script/test
time script/fmt
#!/bin/bash
bundle exec rubocop -D -E
#! /bin/bash
rake release
#!/bin/bash
RELEASES_URL="https://github.com/jekyll/jekyll/releases"
JEKYLL_VERSION="2.2.0"
JEKYLL_BUNDLE="jekyll-${JEKYLL_VERSION}.tar.gz"
wget "${RELEASES_URL}/download/v${JEKYLL_VERSION}/${JEKYLL_BUNDLE}"
tar -xzvf ${JEKYLL_BUNDLE}
require 'jekyll'
require File.expand_path('../../lib/jekyll-watch.rb', __FILE__)
TEST_DIR = File.expand_path('..', __FILE__)
# frozen_string_literal: true
require "jekyll"
require File.expand_path("../lib/jekyll-watch.rb", __dir__)
TEST_DIR = __dir__
RSpec.configure do |config|
# These two settings work together to allow you to limit a spec run
......@@ -17,7 +19,7 @@ RSpec.configure do |config|
# Use the documentation formatter for detailed output,
# unless a formatter has already been configured
# (e.g. via a command-line flag).
config.default_formatter = 'doc'
config.default_formatter = "doc"
end
# Print the 10 slowest examples and example groups at the
......@@ -65,10 +67,10 @@ RSpec.configure do |config|
end
def source_dir(*files)
test_dir('test-site', *files)
test_dir("test-site", *files)
end
def dest_dir(*files)
source_dir('_site', *files)
source_dir("_site", *files)
end
end
require 'spec_helper'
# frozen_string_literal: true
require "spec_helper"
describe(Jekyll::Watcher) do
let(:base_opts) do
{
'source' => source_dir,
'destination' => dest_dir
"source" => source_dir,
"destination" => dest_dir,
}
end
let(:options) { base_opts }
let(:site) { instance_double(Jekyll::Site) }
let(:default_ignored) { [/_config\.yml/, /_site/, /\.jekyll\-metadata/] }
let(:default_ignored) { [%r!_config\.yml!, %r!_site!, %r!\.jekyll\-metadata!] }
subject { described_class }
before(:each) do
FileUtils.mkdir(options['destination']) if options['destination']
FileUtils.mkdir(options["destination"]) if options["destination"]
end
after(:each) do
FileUtils.rm_rf(options['destination']) if options['destination']
FileUtils.rm_rf(options["destination"]) if options["destination"]
end
describe "#watch" do
let(:listener) { instance_double(Listen::Listener) }
let(:opts) { { ignore: default_ignored, force_polling: options['force_polling'] } }
let(:opts) do
{ :ignore => default_ignored, :force_polling => options["force_polling"] }
end
before do
allow(Listen).to receive(:to).with(options['source'], opts).and_return(listener)
allow(Listen).to receive(:to).with(options["source"], opts).and_return(listener)
allow(listener).to receive(:start)
......@@ -38,34 +42,65 @@ describe(Jekyll::Watcher) do
subject.watch(options)
end
it 'starts the listener' do
it "starts the listener" do
expect(listener).to have_received(:start)
end
it 'sleeps' do
it "sleeps" do
expect(subject).to have_received(:sleep_forever)
end
it "ignores the config and site by default" do
expect(Listen).to have_received(:to).with(anything, hash_including(ignore: default_ignored))
expect(Listen)
.to have_received(:to)
.with(anything, hash_including(:ignore => default_ignored))
end
it "defaults to no force_polling" do
expect(Listen).to have_received(:to).with(anything, hash_including(force_polling: nil))
expect(Listen)
.to have_received(:to)
.with(anything, hash_including(:force_polling => nil))
end
context "with force_polling turned on" do
let(:options) { base_opts.merge('force_polling' => true) }
let(:options) { base_opts.merge("force_polling" => true) }
it "respects the custom value of force_polling" do
expect(Listen).to have_received(:to).with(anything, hash_including(force_polling: true))
expect(Listen)
.to have_received(:to)
.with(anything, hash_including(:force_polling => true))
end
end
end
describe "#watch using site instance" do
let(:listener) { instance_double(Listen::Listener) }
let(:opts) { { :ignore => default_ignored, :force_polling => nil } }
before do
allow(Listen)
.to receive(:to)
.with(options["source"], opts)
.and_return(listener)
allow(listener).to receive(:start)
allow(Jekyll.logger).to receive(:info)
allow(subject).to receive(:sleep_forever)
subject.watch(options, site)
end
it "does not create a new site instance" do
expect(listener).to have_received(:start)
end
end
context "#listen_ignore_paths" do
let(:ignored) { subject.listen_ignore_paths(options) }
let(:metadata_path) { Jekyll.sanitized_path(options['source'], '.jekyll-metadata') }
let(:ignored) { subject.send(:listen_ignore_paths, options) }
let(:metadata_path) { Jekyll.sanitized_path(options["source"], ".jekyll-metadata") }
before(:each) { FileUtils.touch(metadata_path) }
after(:each) { FileUtils.rm(metadata_path) }
......@@ -75,31 +110,33 @@ describe(Jekyll::Watcher) do
end
context "with something excluded" do
let(:excluded) { ['README.md', 'LICENSE'] }
let(:excluded_absolute) { excluded.map { |p| Jekyll.sanitized_path(options['source'], p) }}
let(:options) { base_opts.merge('exclude' => excluded) }
let(:excluded) { ["README.md", "LICENSE"] }
let(:excluded_absolute) do
excluded.map { |p| Jekyll.sanitized_path(options["source"], p) }
end
let(:options) { base_opts.merge("exclude" => excluded) }
before(:each) { FileUtils.touch(excluded_absolute) }
after(:each) { FileUtils.rm(excluded_absolute) }
it "ignores the excluded files" do
expect(ignored).to include(/README\.md/)
expect(ignored).to include(/LICENSE/)
expect(ignored).to include(%r!README\.md!)
expect(ignored).to include(%r!LICENSE!)
end
end
context "with a custom destination" do
let(:default_ignored) { [/_config\.yml/, /_dest/, /\.jekyll\-metadata/] }
let(:default_ignored) { [%r!_config\.yml!, %r!_dest!, %r!\.jekyll\-metadata!] }
context "when source is absolute" do
context "when destination is absolute" do
let(:options) { base_opts.merge('destination' => source_dir('_dest')) }
let(:options) { base_opts.merge("destination" => source_dir("_dest")) }
it "ignores the destination" do
expect(ignored).to eql(default_ignored)
end
end
context "when destination is relative" do
let(:options) { base_opts.merge('destination' => 'spec/test-site/_dest') }
let(:options) { base_opts.merge("destination" => "spec/test-site/_dest") }
it "ignores the destination" do
expect(ignored).to eql(default_ignored)
end
......@@ -107,24 +144,27 @@ describe(Jekyll::Watcher) do
end
context "when source is relative" do
let(:base_opts) { {'source' => Pathname.new(source_dir).relative_path_from(Pathname.new('.').expand_path).to_s } }
let(:base_opts) do
{ "source" => Pathname
.new(source_dir)
.relative_path_from(Pathname.new(".")
.expand_path).to_s, }
end
context "when destination is absolute" do
let(:options) { base_opts.merge('destination' => source_dir('_dest')) }
let(:options) { base_opts.merge("destination" => source_dir("_dest")) }
it "ignores the destination" do
expect(ignored).to eql(default_ignored)
end
end
context "when destination is relative" do
let(:options) { base_opts.merge('destination' => 'spec/test-site/_dest') }
let(:options) { base_opts.merge("destination" => "spec/test-site/_dest") }
it "ignores the destination" do
expect(ignored).to eql(default_ignored)
end
end
end
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment