lib/guard/guardfile/generator.rb
# frozen_string_literal: true
require "guard/plugin_util"
require "guard/ui"
module Guard
module Guardfile
# This class is responsible for generating the Guardfile and adding Guard'
# plugins' templates into it.
#
# @see Guard::CLI
#
class Generator
# @private
INFO_TEMPLATE_ADDED =
"%s template added to Guardfile, feel free to edit it"
# @private
# The Guardfile template for `guard init`
GUARDFILE_TEMPLATE = File.expand_path(
"../../guard/templates/Guardfile",
__dir__
)
# The location of user defined templates
begin
HOME_TEMPLATES = Pathname.new("~/.guard/templates").expand_path
rescue ArgumentError
# home isn't defined. Set to the root of the drive. Trust that there
# won't be user defined templates there
HOME_TEMPLATES = Pathname.new("/").expand_path
end
# @private
class Error < RuntimeError
end
class NoSuchPlugin < Error
attr_reader :plugin_name, :class_name
def initialize(plugin_name)
@plugin_name = plugin_name
@class_name = plugin_name.delete("-").capitalize
end
def message
"Could not load 'guard/#{plugin_name}'"\
" or '~/.guard/templates/#{plugin_name}'"\
" or find class Guard::#{class_name}\n"
end
end
# Creates the initial Guardfile template when it does not
# already exist.
#
# @see Guard::CLI#init
#
def create_guardfile
path = Pathname.new("Guardfile").expand_path
if path.exist?
UI.error("Guardfile already exists at #{path}")
abort
end
UI.info("Writing new Guardfile to #{path}")
FileUtils.cp(GUARDFILE_TEMPLATE, path.to_s)
end
# Adds the Guardfile template of a Guard plugin to an existing Guardfile.
#
# @see Guard::CLI#init
#
def initialize_template(plugin_name)
guardfile = Pathname.new("Guardfile")
plugin_util = PluginUtil.new(plugin_name)
if plugin_util.valid?
begin
plugin_util.add_to_guardfile
rescue Errno::ENOENT => e
UI.error("Found class #{plugin_util.plugin_class} but loading its template failed.")
UI.error("Error is: #{e}")
return
end
return
end
template_code = (HOME_TEMPLATES + plugin_name).read
guardfile.binwrite(format("\n%<template>s\n", template: template_code), open_args: ["a"])
UI.info(format(INFO_TEMPLATE_ADDED, plugin_name))
rescue Errno::ENOENT
fail NoSuchPlugin, plugin_name.downcase
end
# Adds the templates of all installed Guard implementations to an
# existing Guardfile.
#
# @see Guard::CLI#init
#
def initialize_all_templates
PluginUtil.plugin_names.each { |g| initialize_template(g) }
end
end
end
end