This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Ansi
|
||||
extend self
|
||||
|
||||
ESCAPE = format("%c", 27)
|
||||
MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix.freeze
|
||||
COLORS = {
|
||||
:red => 31,
|
||||
:green => 32,
|
||||
:black => 30,
|
||||
:magenta => 35,
|
||||
:yellow => 33,
|
||||
:white => 37,
|
||||
:blue => 34,
|
||||
:cyan => 36,
|
||||
}.freeze
|
||||
|
||||
# Strip ANSI from the current string. It also strips cursor stuff,
|
||||
# well some of it, and it also strips some other stuff that a lot of
|
||||
# the other ANSI strippers don't.
|
||||
|
||||
def strip(str)
|
||||
str.gsub MATCH, ""
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
def has?(str)
|
||||
!!(str =~ MATCH)
|
||||
end
|
||||
|
||||
# Reset the color back to the default color so that you do not leak any
|
||||
# colors when you move onto the next line. This is probably normally
|
||||
# used as part of a wrapper so that we don't leak colors.
|
||||
|
||||
def reset(str = "")
|
||||
@ansi_reset ||= format("%c[0m", 27)
|
||||
"#{@ansi_reset}#{str}"
|
||||
end
|
||||
|
||||
# SEE: `self::COLORS` for a list of methods. They are mostly
|
||||
# standard base colors supported by pretty much any xterm-color, we do
|
||||
# not need more than the base colors so we do not include them.
|
||||
# Actually... if I'm honest we don't even need most of the
|
||||
# base colors.
|
||||
|
||||
COLORS.each do |color, num|
|
||||
define_method color do |str|
|
||||
"#{format("%c", 27)}[#{num}m#{str}#{reset}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "open3"
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Exec
|
||||
extend self
|
||||
|
||||
# Runs a program in a sub-shell.
|
||||
#
|
||||
# *args - a list of strings containing the program name and arguments
|
||||
#
|
||||
# Returns a Process::Status and a String of output in an array in
|
||||
# that order.
|
||||
def run(*args)
|
||||
stdin, stdout, stderr, process = Open3.popen3(*args)
|
||||
out = stdout.read.strip
|
||||
err = stderr.read.strip
|
||||
|
||||
[stdin, stdout, stderr].each(&:close)
|
||||
[process.value, out + err]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Internet
|
||||
# Public: Determine whether the present device has a connection to
|
||||
# the Internet. This allows plugin writers which require the outside
|
||||
# world to have a neat fallback mechanism for offline building.
|
||||
#
|
||||
# Example:
|
||||
# if Internet.connected?
|
||||
# Typhoeus.get("https://pages.github.com/versions.json")
|
||||
# else
|
||||
# Jekyll.logger.warn "Warning:", "Version check has been disabled."
|
||||
# Jekyll.logger.warn "", "Connect to the Internet to enable it."
|
||||
# nil
|
||||
# end
|
||||
#
|
||||
# Returns true if a DNS call can successfully be made, or false if not.
|
||||
|
||||
module_function
|
||||
|
||||
def connected?
|
||||
!dns("example.com").nil?
|
||||
end
|
||||
|
||||
def dns(domain)
|
||||
require "resolv"
|
||||
Resolv::DNS.open do |resolver|
|
||||
resolver.getaddress(domain)
|
||||
end
|
||||
rescue Resolv::ResolvError, Resolv::ResolvTimeout
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,67 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module Platforms
|
||||
extend self
|
||||
|
||||
def jruby?
|
||||
RUBY_ENGINE == "jruby"
|
||||
end
|
||||
|
||||
def mri?
|
||||
RUBY_ENGINE == "ruby"
|
||||
end
|
||||
|
||||
def windows?
|
||||
vanilla_windows? || bash_on_windows?
|
||||
end
|
||||
|
||||
# Not a Windows Subsystem for Linux (WSL)
|
||||
def vanilla_windows?
|
||||
rbconfig_host.match?(%r!mswin|mingw|cygwin!) && proc_version.empty?
|
||||
end
|
||||
alias_method :really_windows?, :vanilla_windows?
|
||||
|
||||
# Determine if Windows Subsystem for Linux (WSL)
|
||||
def bash_on_windows?
|
||||
linux_os? && microsoft_proc_version?
|
||||
end
|
||||
|
||||
def linux?
|
||||
linux_os? && !microsoft_proc_version?
|
||||
end
|
||||
|
||||
def osx?
|
||||
rbconfig_host.match?(%r!darwin|mac os!)
|
||||
end
|
||||
|
||||
def unix?
|
||||
rbconfig_host.match?(%r!solaris|bsd!)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def proc_version
|
||||
@proc_version ||= \
|
||||
begin
|
||||
File.read("/proc/version").downcase
|
||||
rescue Errno::ENOENT, Errno::EACCES
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def rbconfig_host
|
||||
@rbconfig_host ||= RbConfig::CONFIG["host_os"].downcase
|
||||
end
|
||||
|
||||
def linux_os?
|
||||
rbconfig_host.include?("linux")
|
||||
end
|
||||
|
||||
def microsoft_proc_version?
|
||||
proc_version.include?("microsoft")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
# Based on the pattern and code from
|
||||
# https://emptysqua.re/blog/an-event-synchronization-primitive-for-ruby/
|
||||
class ThreadEvent
|
||||
attr_reader :flag
|
||||
|
||||
def initialize
|
||||
@lock = Mutex.new
|
||||
@cond = ConditionVariable.new
|
||||
@flag = false
|
||||
end
|
||||
|
||||
def set
|
||||
@lock.synchronize do
|
||||
yield if block_given?
|
||||
@flag = true
|
||||
@cond.broadcast
|
||||
end
|
||||
end
|
||||
|
||||
def wait
|
||||
@lock.synchronize do
|
||||
@cond.wait(@lock) unless @flag
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Jekyll
|
||||
module Utils
|
||||
module WinTZ
|
||||
extend self
|
||||
|
||||
# Public: Calculate the Timezone for Windows when the config file has a defined
|
||||
# 'timezone' key.
|
||||
#
|
||||
# timezone - the IANA Time Zone specified in "_config.yml"
|
||||
#
|
||||
# Returns a string that ultimately re-defines ENV["TZ"] in Windows
|
||||
def calculate(timezone, now = Time.now)
|
||||
External.require_with_graceful_fail("tzinfo") unless defined?(TZInfo)
|
||||
tz = TZInfo::Timezone.get(timezone)
|
||||
|
||||
#
|
||||
# Use period_for_utc and utc_total_offset instead of
|
||||
# period_for and observed_utc_offset for compatibility with tzinfo v1.
|
||||
offset = tz.period_for_utc(now.getutc).utc_total_offset
|
||||
|
||||
#
|
||||
# POSIX style definition reverses the offset sign.
|
||||
# e.g. Eastern Standard Time (EST) that is 5Hrs. to the 'west' of Prime Meridian
|
||||
# is denoted as:
|
||||
# EST+5 (or) EST+05:00
|
||||
# Reference: https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
|
||||
sign = offset.positive? ? "-" : "+"
|
||||
|
||||
rational_hours = offset.abs.to_r / 3600
|
||||
hours = rational_hours.to_i
|
||||
minutes = ((rational_hours - hours) * 60).to_i
|
||||
|
||||
#
|
||||
# Format the hours and minutes as two-digit numbers.
|
||||
time = format("%<hours>02d:%<minutes>02d", :hours => hours, :minutes => minutes)
|
||||
|
||||
Jekyll.logger.debug "Timezone:", "#{timezone} #{sign}#{time}"
|
||||
#
|
||||
# Note: The 3-letter-word below doesn't have a particular significance.
|
||||
"WTZ#{sign}#{time}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user