Merge pull request #4343 from jekyll/pr/cucumber-rspec-expec-jruby-support
Merge pull request 4343
This commit is contained in:
		
						commit
						3e30c72994
					
				|  | @ -16,10 +16,6 @@ matrix: | |||
|   allow_failures: | ||||
|     - rvm: jruby-9.0.3.0 | ||||
|     - rvm: ruby-head | ||||
|   exclude: | ||||
|   - rvm: jruby-9.0.3.0 | ||||
|     env: TEST_SUITE=cucumber | ||||
| 
 | ||||
| env: | ||||
|   matrix: | ||||
|   - TEST_SUITE=test | ||||
|  |  | |||
							
								
								
									
										1
									
								
								Gemfile
								
								
								
								
							
							
						
						
									
										1
									
								
								Gemfile
								
								
								
								
							|  | @ -11,6 +11,7 @@ group :development do | |||
| end | ||||
| 
 | ||||
| group :test do | ||||
|   gem 'rspec-expectations' | ||||
|   gem 'redgreen', '~> 1.2' | ||||
|   gem 'shoulda', '~> 3.5' | ||||
|   gem 'cucumber', '~> 2.1' | ||||
|  |  | |||
|  | @ -1,131 +1,115 @@ | |||
| def file_content_from_hash(input_hash) | ||||
|   matter_hash = input_hash.reject { |k, v| k == "content" } | ||||
|   matter = matter_hash.map { |k, v| "#{k}: #{v}\n" }.join.chomp | ||||
| 
 | ||||
|   content = if input_hash['input'] && input_hash['filter'] | ||||
|     "{{ #{input_hash['input']} | #{input_hash['filter']} }}" | ||||
|   else | ||||
|     input_hash['content'] | ||||
|   end | ||||
| 
 | ||||
|   <<-EOF | ||||
| --- | ||||
| #{matter} | ||||
| --- | ||||
| #{content} | ||||
| EOF | ||||
| end | ||||
| 
 | ||||
| Before do | ||||
|   FileUtils.mkdir_p(TEST_DIR) unless File.exist?(TEST_DIR) | ||||
|   Dir.chdir(TEST_DIR) | ||||
|   FileUtils.mkdir_p(Paths.test_dir) unless Paths.test_dir.directory? | ||||
|   Dir.chdir(Paths.test_dir) | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| After do | ||||
|   FileUtils.rm_rf(TEST_DIR)   if File.exist?(TEST_DIR) | ||||
|   FileUtils.rm(JEKYLL_COMMAND_OUTPUT_FILE) if File.exist?(JEKYLL_COMMAND_OUTPUT_FILE) | ||||
|   FileUtils.rm(JEKYLL_COMMAND_STATUS_FILE) if File.exist?(JEKYLL_COMMAND_STATUS_FILE) | ||||
|   Dir.chdir(File.dirname(TEST_DIR)) | ||||
|   Paths.test_dir.rmtree if Paths.test_dir.exist? | ||||
|   Paths.output_file.delete if Paths.output_file.exist? | ||||
|   Paths.status_file.delete if Paths.status_file.exist? | ||||
|   Dir.chdir(Paths.test_dir.parent) | ||||
| end | ||||
| 
 | ||||
| World do | ||||
|   MinitestWorld.new | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have a blank site in "(.*)"$} do |path| | ||||
|   if !File.exist?(path) | ||||
|     then FileUtils.mkdir_p(path) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Given /^I have a blank site in "(.*)"$/ do |path| | ||||
|   FileUtils.mkdir_p(path) unless File.exist?(path) | ||||
| # | ||||
| 
 | ||||
| Given %r{^I do not have a "(.*)" directory$} do |path| | ||||
|   Paths.test_dir.join(path).directory? | ||||
| end | ||||
| 
 | ||||
| Given /^I do not have a "(.*)" directory$/ do |path| | ||||
|   File.directory?("#{TEST_DIR}/#{path}") | ||||
| end | ||||
| # | ||||
| 
 | ||||
| # Like "I have a foo file" but gives a yaml front matter so jekyll actually processes it | ||||
| Given /^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$/ do |file, key, value, text| | ||||
|   File.open(file, 'w') do |f| | ||||
|     f.write <<-EOF | ||||
| Given %r{^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$} do |file, key, value, text| | ||||
|   File.write(file, Jekyll::Utils.strip_heredoc(<<-DATA)) | ||||
|     --- | ||||
|     #{key || 'layout'}: #{value || 'nil'} | ||||
|     --- | ||||
| 
 | ||||
|     #{text} | ||||
| EOF | ||||
|   DATA | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have an? "(.*)" file that contains "(.*)"$} do |file, text| | ||||
|   File.write(file, text) | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have an? (.*) (layout|theme) that contains "(.*)"$} do |name, type, text| | ||||
|   folder = type == "layout" ? "_layouts" : "_theme" | ||||
| 
 | ||||
|   destination_file = Pathname.new(File.join(folder, "#{name}.html")) | ||||
|   FileUtils.mkdir_p(destination_file.parent) unless destination_file.parent.directory? | ||||
|   File.write(destination_file, text) | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have an? "(.*)" file with content:$} do |file, text| | ||||
|   File.write(file, text) | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have an? (.*) directory$} do |dir| | ||||
|   if !File.directory?(dir) | ||||
|     then FileUtils.mkdir_p(dir) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Given /^I have an? "(.*)" file that contains "(.*)"$/ do |file, text| | ||||
|   File.open(file, 'w') do |f| | ||||
|     f.write(text) | ||||
|   end | ||||
| end | ||||
| # | ||||
| 
 | ||||
| Given /^I have an? (.*) (layout|theme) that contains "(.*)"$/ do |name, type, text| | ||||
|   folder = if type == 'layout' | ||||
|     '_layouts' | ||||
|   else | ||||
|     '_theme' | ||||
|   end | ||||
|   destination_file = File.join(folder, name + '.html') | ||||
|   destination_path = File.dirname(destination_file) | ||||
|   unless File.exist?(destination_path) | ||||
|     FileUtils.mkdir_p(destination_path) | ||||
|   end | ||||
|   File.open(destination_file, 'w') do |f| | ||||
|     f.write(text) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Given /^I have an? "(.*)" file with content:$/ do |file, text| | ||||
|   File.open(file, 'w') do |f| | ||||
|     f.write(text) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Given /^I have an? (.*) directory$/ do |dir| | ||||
|   FileUtils.mkdir_p(dir) | ||||
| end | ||||
| 
 | ||||
| Given /^I have the following (draft|page|post)s?(?: (in|under) "([^"]+)")?:$/ do |status, direction, folder, table| | ||||
| Given %r{^I have the following (draft|page|post)s?(?: (in|under) "([^"]+)")?:$} do |status, direction, folder, table| | ||||
|   table.hashes.each do |input_hash| | ||||
|     title = slug(input_hash['title']) | ||||
|     ext = input_hash['type'] || 'markdown' | ||||
|     title = slug(input_hash["title"]) | ||||
|     ext = input_hash["type"] || "markdown" | ||||
|     filename = filename = "#{title}.#{ext}" if %w(draft page).include?(status) | ||||
|     before, after = location(folder, direction) | ||||
|     dest_folder = "_drafts" if status == "draft" | ||||
|     dest_folder = "_posts"  if status ==  "post" | ||||
|     dest_folder = "" if status == "page" | ||||
| 
 | ||||
|     case status | ||||
|     when "draft" | ||||
|       dest_folder = '_drafts' | ||||
|       filename = "#{title}.#{ext}" | ||||
|     when "page" | ||||
|       dest_folder = '' | ||||
|       filename = "#{title}.#{ext}" | ||||
|     when "post" | ||||
|     if status == "post" | ||||
|       parsed_date = Time.xmlschema(input_hash['date']) rescue Time.parse(input_hash['date']) | ||||
|       dest_folder = '_posts' | ||||
|       filename = "#{parsed_date.strftime('%Y-%m-%d')}-#{title}.#{ext}" | ||||
|     end | ||||
| 
 | ||||
|     path = File.join(before, dest_folder, after, filename) | ||||
|     File.open(path, 'w') do |f| | ||||
|       f.write file_content_from_hash(input_hash) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Given /^I have a configuration file with "(.*)" set to "(.*)"$/ do |key, value| | ||||
|   File.open('_config.yml', 'w') do |f| | ||||
|     f.write("#{key}: #{value}\n") | ||||
|     File.write(path, file_content_from_hash(input_hash)) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Given /^I have a configuration file with:$/ do |table| | ||||
|   File.open('_config.yml', 'w') do |f| | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have a configuration file with "(.*)" set to "(.*)"$} do |key, value| | ||||
|   File.write("_config.yml", "#{key}: #{value}\n") | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have a configuration file with:$} do |table| | ||||
|   File.open("_config.yml", "w") do |f| | ||||
|     table.hashes.each do |row| | ||||
|       f.write("#{row["key"]}: #{row["value"]}\n") | ||||
|     end | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| Given /^I have a configuration file with "([^\"]*)" set to:$/ do |key, table| | ||||
|   File.open('_config.yml', 'w') do |f| | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have a configuration file with "([^\"]*)" set to:$} do |key, table| | ||||
|   File.open("_config.yml", "w") do |f| | ||||
|     f.write("#{key}:\n") | ||||
|     table.hashes.each do |row| | ||||
|       f.write("- #{row["value"]}\n") | ||||
|  | @ -133,102 +117,123 @@ Given /^I have a configuration file with "([^\"]*)" set to:$/ do |key, table| | |||
|   end | ||||
| end | ||||
| 
 | ||||
| Given /^I have fixture collections$/ do | ||||
|   FileUtils.cp_r File.join(JEKYLL_SOURCE_DIR, "test", "source", "_methods"), source_dir | ||||
| # | ||||
| 
 | ||||
| Given %r{^I have fixture collections$} do | ||||
|   FileUtils.cp_r Paths.source_dir.join("test", "source", "_methods"), source_dir | ||||
| end | ||||
| 
 | ||||
| Given /^I wait (\d+) second(s?)$/ do |time, plural| | ||||
| # | ||||
| 
 | ||||
| Given %r{^I wait (\d+) second(s?)$} do |time, plural| | ||||
|   sleep(time.to_f) | ||||
| end | ||||
| 
 | ||||
| ################## | ||||
| # | ||||
| # Changing stuff | ||||
| # | ||||
| ################## | ||||
| 
 | ||||
| When /^I run jekyll(.*)$/ do |args| | ||||
|   status = run_jekyll(args) | ||||
| When %r{^I run jekyll(.*)$} do |args| | ||||
|   run_jekyll(args) | ||||
|   if args.include?("--verbose") || ENV["DEBUG"] | ||||
|     $stderr.puts "\n#{jekyll_run_output}\n" | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| When %r{^I run bundle(.*)$} do |args| | ||||
|   run_bundle(args) | ||||
|   if args.include?("--verbose") || ENV['DEBUG'] | ||||
|     $stderr.puts "\n#{jekyll_run_output}\n" | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| When /^I run bundle(.*)$/ do |args| | ||||
|   status = run_bundle(args) | ||||
|   if args.include?("--verbose") || ENV['DEBUG'] | ||||
|     $stderr.puts "\n#{jekyll_run_output}\n" | ||||
|   end | ||||
| end | ||||
| # | ||||
| 
 | ||||
| When /^I change "(.*)" to contain "(.*)"$/ do |file, text| | ||||
|   File.open(file, 'a') do |f| | ||||
| When %r{^I change "(.*)" to contain "(.*)"$} do |file, text| | ||||
|   File.open(file, "a") do |f| | ||||
|     f.write(text) | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| When /^I delete the file "(.*)"$/ do |file| | ||||
| # | ||||
| 
 | ||||
| When %r{^I delete the file "(.*)"$} do |file| | ||||
|   File.delete(file) | ||||
| end | ||||
| 
 | ||||
| ################## | ||||
| # | ||||
| # Checking stuff | ||||
| 
 | ||||
| Then %r{^the (.*) directory should +exist$} do |dir| | ||||
|   expect(Pathname.new(dir)).to exist | ||||
| end | ||||
| 
 | ||||
| # | ||||
| ################## | ||||
| 
 | ||||
| Then /^the (.*) directory should +exist$/ do |dir| | ||||
|   assert File.directory?(dir), "The directory \"#{dir}\" does not exist" | ||||
| Then %r{^the (.*) directory should not exist$} do |dir| | ||||
|   expect(Pathname.new(dir)).not_to exist | ||||
| end | ||||
| 
 | ||||
| Then /^the (.*) directory should not exist$/ do |dir| | ||||
|   assert !File.directory?(dir), "The directory \"#{dir}\" exists" | ||||
| # | ||||
| Then %r{^I should see "(.*)" in "(.*)"$} do |text, file| | ||||
|   regexp = Regexp.new(text, Regexp::MULTILINE) | ||||
|   expect(file_contents(file)).to match regexp | ||||
| end | ||||
| 
 | ||||
| Then /^I should see "(.*)" in "(.*)"$/ do |text, file| | ||||
|   assert_match Regexp.new(text, Regexp::MULTILINE), file_contents(file) | ||||
| # | ||||
| 
 | ||||
| Then %r{^I should see exactly "(.*)" in "(.*)"$} do |text, file| | ||||
|   expect(file_contents(file).strip).to eq text | ||||
| end | ||||
| 
 | ||||
| Then /^I should see exactly "(.*)" in "(.*)"$/ do |text, file| | ||||
|   assert_equal text, file_contents(file).strip | ||||
| # | ||||
| 
 | ||||
| Then %r{^I should not see "(.*)" in "(.*)"$} do |text, file| | ||||
|   regexp = Regexp.new(text, Regexp::MULTILINE) | ||||
|   expect(file_contents(file)).not_to match regexp | ||||
| end | ||||
| 
 | ||||
| Then /^I should not see "(.*)" in "(.*)"$/ do |text, file| | ||||
|   refute_match Regexp.new(text, Regexp::MULTILINE), file_contents(file) | ||||
| # | ||||
| 
 | ||||
| Then %r{^I should see escaped "(.*)" in "(.*)"$} do |text, file| | ||||
|   regexp = Regexp.new(Regexp.escape(text)) | ||||
|   expect(file_contents(file)).to match regexp | ||||
| end | ||||
| 
 | ||||
| Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file| | ||||
|   assert_match Regexp.new(Regexp.escape(text)), file_contents(file) | ||||
| # | ||||
| 
 | ||||
| Then %r{^the "(.*)" file should +exist$} do |file| | ||||
|   expect(Pathname.new(file)).to exist | ||||
| end | ||||
| 
 | ||||
| Then /^the "(.*)" file should +exist$/ do |file| | ||||
|   file_does_exist = File.file?(file) | ||||
|   unless file_does_exist | ||||
|     all_steps_to_path(file).each do |dir| | ||||
|       STDERR.puts "" | ||||
|       STDERR.puts "Dir #{dir}:" | ||||
|       STDERR.puts Dir["#{dir}/**/*"] | ||||
|     end | ||||
|   end | ||||
|   assert file_does_exist, "The file \"#{file}\" does not exist.\n" | ||||
| # | ||||
| 
 | ||||
| Then %r{^the "(.*)" file should not exist$} do |file| | ||||
|   expect(Pathname.new(file)).to_not exist | ||||
| end | ||||
| 
 | ||||
| Then /^the "(.*)" file should not exist$/ do |file| | ||||
|   assert !File.exist?(file), "The file \"#{file}\" exists" | ||||
| # | ||||
| 
 | ||||
| Then %r{^I should see today's time in "(.*)"$} do |file| | ||||
|   seconds = seconds_agnostic_time(Time.now) | ||||
|   expect(file_contents(file)).to match Regexp.new(seconds) | ||||
| end | ||||
| 
 | ||||
| Then /^I should see today's time in "(.*)"$/ do |file| | ||||
|   assert_match Regexp.new(seconds_agnostic_time(Time.now)), file_contents(file) | ||||
| # | ||||
| 
 | ||||
| Then %r{^I should see today's date in "(.*)"$} do |file| | ||||
|   regexp = Regexp.new(Date.today.to_s) | ||||
|   expect(file_contents(file)).to match regexp | ||||
| end | ||||
| 
 | ||||
| Then /^I should see today's date in "(.*)"$/ do |file| | ||||
|   assert_match Regexp.new(Date.today.to_s), file_contents(file) | ||||
| # | ||||
| 
 | ||||
| Then %r{^I should see "(.*)" in the build output$} do |text| | ||||
|   regexp = Regexp.new(text) | ||||
|   expect(jekyll_run_output).to match regexp | ||||
| end | ||||
| 
 | ||||
| Then /^I should see "(.*)" in the build output$/ do |text| | ||||
|   assert_match Regexp.new(text), jekyll_run_output | ||||
| end | ||||
| # | ||||
| 
 | ||||
| Then /^I should get a non-zero exit(?:\-| )status$/ do | ||||
|   assert jekyll_run_status > 0 | ||||
| Then %r{^I should get a non-zero exit(?:\-| )status$} do | ||||
|   expect(jekyll_run_status.to_i).to be > 0 | ||||
| end | ||||
|  |  | |||
|  | @ -1,116 +1,155 @@ | |||
| require 'fileutils' | ||||
| require 'posix-spawn' | ||||
| require 'minitest/spec' | ||||
| require 'time' | ||||
| require "fileutils" | ||||
| require "jekyll/utils" | ||||
| require "open3" | ||||
| require "time" | ||||
| 
 | ||||
| class MinitestWorld | ||||
|   extend Minitest::Assertions | ||||
|   attr_accessor :assertions | ||||
| 
 | ||||
|   def initialize | ||||
|     self.assertions = 0 | ||||
|   end | ||||
| class Paths | ||||
|   SOURCE_DIR = Pathname.new(File.expand_path("../..", __dir__)) | ||||
|   def self.test_dir; source_dir.join("tmp", "jekyll"); end | ||||
|   def self.output_file; test_dir.join("jekyll_output.txt"); end | ||||
|   def self.status_file; test_dir.join("jekyll_status.txt"); end | ||||
|   def self.jekyll_bin; source_dir.join("bin", "jekyll"); end | ||||
|   def self.source_dir; SOURCE_DIR; end | ||||
| end | ||||
| 
 | ||||
| JEKYLL_SOURCE_DIR = File.dirname(File.dirname(File.dirname(__FILE__))) | ||||
| TEST_DIR    = File.expand_path(File.join('..', '..', 'tmp', 'jekyll'), File.dirname(__FILE__)) | ||||
| JEKYLL_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll')) | ||||
| JEKYLL_COMMAND_OUTPUT_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_output.txt') | ||||
| JEKYLL_COMMAND_STATUS_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_status.txt') | ||||
| # | ||||
| 
 | ||||
| def file_content_from_hash(input_hash) | ||||
|   matter_hash = input_hash.reject { |k, v| k == "content" } | ||||
|   matter = matter_hash.map do |k, v| "#{k}: #{v}\n" | ||||
|   end | ||||
| 
 | ||||
|   matter = matter.join.chomp | ||||
|   content = \ | ||||
|   if !input_hash['input'] || !input_hash['filter'] | ||||
|     then input_hash['content'] | ||||
|     else "{{ #{input_hash['input']} | " \ | ||||
|       "#{input_hash['filter']} }}" | ||||
|   end | ||||
| 
 | ||||
|   Jekyll::Utils.strip_heredoc(<<-EOF) | ||||
|     --- | ||||
|     #{matter.gsub( | ||||
|       /\n/, "\n    " | ||||
|     )} | ||||
|     --- | ||||
|     #{content} | ||||
|   EOF | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def source_dir(*files) | ||||
|   File.join(TEST_DIR, *files) | ||||
|   return Paths.test_dir(*files) | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def all_steps_to_path(path) | ||||
|   source = Pathname.new(source_dir('_site')).expand_path | ||||
|   source = source_dir | ||||
|   dest = Pathname.new(path).expand_path | ||||
|   paths  = [] | ||||
| 
 | ||||
|   dest.ascend do |f| | ||||
|     break if f.eql? source | ||||
|     break if f == source | ||||
|     paths.unshift f.to_s | ||||
|   end | ||||
| 
 | ||||
|   paths | ||||
| end | ||||
| 
 | ||||
| def jekyll_output_file | ||||
|   JEKYLL_COMMAND_OUTPUT_FILE | ||||
| end | ||||
| 
 | ||||
| def jekyll_status_file | ||||
|   JEKYLL_COMMAND_STATUS_FILE | ||||
| end | ||||
| # | ||||
| 
 | ||||
| def jekyll_run_output | ||||
|   File.read(jekyll_output_file) if File.file?(jekyll_output_file) | ||||
|   if Paths.output_file.file? | ||||
|     then return Paths.output_file.read | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def jekyll_run_status | ||||
|   (File.read(jekyll_status_file) rescue 0).to_i | ||||
|   if Paths.status_file.file? | ||||
|     then return Paths.status_file.read | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def run_bundle(args) | ||||
|   run_in_shell('bundle', *args.strip.split(' ')) | ||||
|   run_in_shell("bundle", *args.strip.split(' ')) | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def run_jekyll(args) | ||||
|   child = run_in_shell(JEKYLL_PATH, *args.strip.split(' '), "--trace") | ||||
|   child.status.exitstatus == 0 | ||||
|   args = args.strip.split(" ") # Shellwords? | ||||
|   process = run_in_shell(Paths.jekyll_bin.to_s, *args, "--trace") | ||||
|   process.exitstatus == 0 | ||||
| end | ||||
| 
 | ||||
| # ----------------------------------------------------------------------------- | ||||
| # XXX: POSIX::Spawn::Child does not write output when the exit status is > 0 | ||||
| #        for example when doing [:out, :err] => [file, "w"] it will skip | ||||
| #        writing the file entirely, we sould switch to Open. | ||||
| # ----------------------------------------------------------------------------- | ||||
| # | ||||
| 
 | ||||
| def run_in_shell(*args) | ||||
|   spawned = POSIX::Spawn::Child.new(*args) | ||||
|   status = spawned.status.exitstatus | ||||
|   File.write(JEKYLL_COMMAND_STATUS_FILE, status) | ||||
|   File.open(JEKYLL_COMMAND_OUTPUT_FILE, "w+") do |file| | ||||
|     status == 0 ? file.write(spawned.out) : file.write(spawned.err) | ||||
|   i, o, e, p = Open3.popen3(*args) | ||||
|   out = o.read.strip | ||||
|   err = e.read.strip | ||||
| 
 | ||||
|   [i, o, e].each do |m| | ||||
|     m.close | ||||
|   end | ||||
| 
 | ||||
|   spawned | ||||
|   File.write(Paths.status_file, p.value.exitstatus) | ||||
|   File.write(Paths.output_file, out) if p.value.exitstatus == 0 | ||||
|   File.write(Paths.output_file, err) if p.value.exitstatus != 0 | ||||
|   p.value | ||||
| end | ||||
| 
 | ||||
| def slug(title) | ||||
|   if title | ||||
|     title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-') | ||||
|   else | ||||
|     Time.now.strftime("%s%9N") # nanoseconds since the Epoch | ||||
| # | ||||
| 
 | ||||
| def slug(title = nil) | ||||
|   if !title | ||||
|     then Time.now.strftime("%s%9N") # nanoseconds since the Epoch | ||||
|     else title.downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-') | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def location(folder, direction) | ||||
|   if folder | ||||
|     before = folder if direction ==    "in" | ||||
|     after  = folder if direction == "under" | ||||
|   end | ||||
|   [before || '.', after || '.'] | ||||
| 
 | ||||
|   [before || '.', | ||||
|     after || '.'] | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def file_contents(path) | ||||
|   File.open(path) do |file| | ||||
|     file.readlines.join # avoid differences with \n and \r\n line endings | ||||
|   end | ||||
|   return Pathname.new(path).read | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def seconds_agnostic_datetime(datetime = Time.now) | ||||
|   date, time, zone = datetime.to_s.split(" ") | ||||
|   time = seconds_agnostic_time(time) | ||||
| 
 | ||||
|   [ | ||||
|     Regexp.escape(date), | ||||
|     "#{time}:\\d{2}", | ||||
|     Regexp.escape(zone) | ||||
|   ].join("\\ ") | ||||
|   ] \ | ||||
|   .join("\\ ") | ||||
| end | ||||
| 
 | ||||
| # | ||||
| 
 | ||||
| def seconds_agnostic_time(time) | ||||
|   if time.is_a? Time | ||||
|     time = time.strftime("%H:%M:%S") | ||||
|   end | ||||
|   time = time.strftime("%H:%M:%S") if time.is_a?(Time) | ||||
|   hour, minutes, _ = time.split(":") | ||||
|   "#{hour}:#{minutes}" | ||||
| end | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue