Module: Pineapples::Actions

Included in:
AppGenerator
Defined in:
lib/pineapples/actions.rb,
lib/pineapples/actions/get.rb,
lib/pineapples/actions/git.rb,
lib/pineapples/actions/ruby.rb,
lib/pineapples/actions/apply.rb,
lib/pineapples/actions/chmod.rb,
lib/pineapples/actions/shell.rb,
lib/pineapples/actions/bundle.rb,
lib/pineapples/actions/inside.rb,
lib/pineapples/actions/template.rb,
lib/pineapples/actions/copy_file.rb,
lib/pineapples/actions/directory.rb,
lib/pineapples/actions/gsub_file.rb,
lib/pineapples/actions/keep_file.rb,
lib/pineapples/actions/base/action.rb,
lib/pineapples/actions/base/target.rb,
lib/pineapples/actions/create_file.rb,
lib/pineapples/actions/rails/rails.rb,
lib/pineapples/actions/remove_file.rb,
lib/pineapples/actions/empty_directory.rb,
lib/pineapples/actions/insert_into_file.rb,
lib/pineapples/actions/prepend_to_class.rb,
lib/pineapples/actions/rails/copy_migration.rb,
lib/pineapples/actions/rails/erb_converters.rb,
lib/pineapples/actions/rails/new_hash_syntax_converter.rb

Defined Under Namespace

Modules: Rails Classes: Action, CopyFile, CreateFile, Directory, EmptyDirectory, InsertIntoFile, Target

Constant Summary collapse

TEMPLATE_EXTNAME =
'.tt'
DEFAULT_COLOR =
:light_green
FILE_WITH_RUBY_CODE =
'.rb|.erb|.haml|.slim|.rake'

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#behaviourObject (readonly)

Returns the value of attribute behaviour.



33
34
35
# File 'lib/pineapples/actions.rb', line 33

def behaviour
  @behaviour
end

Instance Method Details

#action(instance) ⇒ Object

Executes instance of Action subclass depending on generator behaviour



42
43
44
45
46
47
48
49
# File 'lib/pineapples/actions.rb', line 42

def action(instance) #:nodoc:
  return if instance.skip?
  if behaviour == :invoke
    instance.invoke!
  else
    instance.revoke!
  end
end

#append_to_file(path, *args, &block) ⇒ Object Also known as: append_file

Append text to a file. Since it depends on insert_into_file, it’s reversible.

Parameters

path<String>

path of the file to be changed

data<String>

the data to append to the file, can be also given as a block.

config<Hash>

give :verbose => false to not log the status.

Example

append_to_file 'config/environments/test.rb', 'config.gem "rspec"'

append_to_file 'config/environments/test.rb' do
  'config.gem "rspec"'
end


24
25
26
27
28
# File 'lib/pineapples/actions/insert_into_file.rb', line 24

def append_to_file(path, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  options.merge!(before: /\z/)
  insert_into_file(path, *(args << options), &block)
end

#apply(path, options = {}) ⇒ Object

Loads an external file and execute it in the instance binding.

Parameters

path<String>

The path to the file to execute. Can be a web address or a relative path from the source root.

Examples

apply "http://gist.github.com/103208"

apply "recipes/jquery.rb"


15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/pineapples/actions/apply.rb', line 15

def apply(path, options = {})
  verbose = options.fetch(:verbose, verbose?)
  is_uri  = path =~ %r{^https?\://}
  path    = find_in_source_paths(path) if !is_uri
  color   = options.fetch(:color, DEFAULT_COLOR)

  say_status(:apply, path, color, verbose)

  indent(verbose) do
    if is_uri
      contents = open(path, 'Accept' => 'application/x-thor-template') { |io| io.read }
    else
      contents = open(path) { |io| io.read }
    end

    instance_eval(contents, path)
  end
end

#ask_file_collision(target) ⇒ Object

rubocop:disable MethodLength



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/pineapples/actions/create_file.rb', line 28

def ask_file_collision(target) # rubocop:disable MethodLength
  return true if @always_force
  options = '[Ynaq]'

  question_string = "Overwrite #{target}?"
  options = ['Yes', 'No', 'Always', 'Quit']
  colors = [:light_green, :light_red, :light_yellow, :light_red]
  options_with_color = options.map.with_index { |option, index| option.send(colors[index])}

  loop do
    answer_index = Ask.list(question_string, options_with_color, {clear: false, response: false})
    answer = options[answer_index]

    case answer
    when 'Yes'
      return true
    when 'No'
      return false
    when 'Always'
      return @always_force = true
    when 'Quit'
      say 'Aborting'
      raise SystemExit
    end
  end
end

#bundle(command, options = {}) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
# File 'lib/pineapples/actions/bundle.rb', line 3

def bundle(command, options = {})
  command = "#{command.first.first} #{command.first.last}" if command.is_a?(Hash)
  say_status :bundle, "#{command}"

  _bundle_command = Gem.bin_path('bundler', 'bundle')

  require 'bundler'
  Bundler.with_clean_env do
    output = `"#{Gem.ruby}" "#{_bundle_command}" #{command} #{subcommands}`
    print output if !options[:quiet]
  end
end

#chmod(path, mode, options = {}) ⇒ Object

Changes the mode of the given file or directory.

Parameters

mode<Integer>

the file mode

path<String>

the name of the file to change mode

options<Hash>

give :verbose => false to not log the status.

Example

chmod "script/server", 0755


14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/pineapples/actions/chmod.rb', line 14

def chmod(path, mode, options = {})
  return unless behaviour == :invoke

  verbose = options.fetch(:verbose, verbose?)
  execute = !options.fetch(:pretend, pretend?)
  color   = options.fetch(:color, DEFAULT_COLOR)

  full_path = File.join(app_root, path)
  relative_path = relative_to_app_root(full_path)

  say_status(:chmod, relative_path, color, verbose)

  FileUtils.chmod_R(mode, full_path) if execute
end

#convert_directory_to_new_hash_syntax(target, options = {}) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/pineapples/actions/rails/new_hash_syntax_converter.rb', line 4

def convert_directory_to_new_hash_syntax(target, options = {})
  recursive = options.delete(:recursive) || true

  target_fullpath = File.expand_path(target, app_root)
  target_fullpath = File.join(target_fullpath, '**') if recursive

  excluded_files = Array(options[:exclude])
  exclude_pattern = options[:exclude_pattern]

  files = Dir.glob(target_fullpath, File::FNM_DOTMATCH)
  files.sort.each do |file|
    next if File.directory?(file)
    next if exclude_pattern && file.match(exclude_pattern)
    next if excluded_files.any? do |excluded_file|
      File.basename(excluded_file) == File.basename(file_source)
    end

    case file
    when /#{FILE_WITH_RUBY_CODE}$/
      convert_file_to_new_hash_syntax(file)
    end
  end

end

#convert_file_to_new_hash_syntax(path) ⇒ Object

Converts file to new Ruby hash syntax, cause that is what I prefer Existing solutions on web usually use perl and shell, but we have power of Ruby and cool gsub_file action at our disposal!



31
32
33
34
# File 'lib/pineapples/actions/rails/new_hash_syntax_converter.rb', line 31

def convert_file_to_new_hash_syntax(path)
  regex = /:(\w+)(\s{1})(\s*)=>/
  gsub_file(path, regex, '\1:\3')
end

#copy_file(source, *args, &block) ⇒ Object

Examples

copy_file "README", "doc/README"

copy_file "doc/README"


21
22
23
24
25
26
# File 'lib/pineapples/actions/copy_file.rb', line 21

def copy_file(source, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  target = args.first || source

  action CopyFile.new(self, source, target, options, &block)
end

#create_file(target, *args, &block) ⇒ Object

Create a new file relative to the destination root with the given data, which is the return value of a block or a data string.

Parameters

target<String>

the relative path to the destination root.

content<String|NilClass>

the data to append to the file.

options<Hash>

give :verbose => false to not log the status.

Examples

create_file "lib/fun_party.rb" do
  hostname = ask("What is the virtual hostname I should use?")
  "vhost.name = #{hostname}"
end

create_file "config/apache.conf", "your apache config"


22
23
24
25
26
# File 'lib/pineapples/actions/create_file.rb', line 22

def create_file(target, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  content = args.first
  action CreateFile.new(self, target, block || content, options)
end

#current_app_dirObject



7
8
9
# File 'lib/pineapples/actions/inside.rb', line 7

def current_app_dir
  File.expand_path(File.join(*dir_stack), app_root)
end

#dir_stackObject



3
4
5
# File 'lib/pineapples/actions/inside.rb', line 3

def dir_stack
  @dir_stack ||= []
end

#directory(source, *args, &block) ⇒ Object

Copies recursively the files from source directory to root directory. If any of the files finishes with .tt, it’s considered to be a template and is placed in the destination without the extension .tt. If any empty directory is found, it’s copied and all .empty_directory files are ignored. If any file name is wrapped within % signs, the text within the % signs will be executed as a method and replaced with the returned value. Let’s suppose a doc directory with the following files:

doc/
  components/.empty_directory
  README
  rdoc.rb.tt
  app_name%.rb

When invoked as:

directory "doc"

It will create a doc directory in the destination with the following files (assuming that the ‘app_name` method returns the value “blog”):

doc/
  components/
  README
  rdoc.rb
  blog.rb

Parameters

source<String>

the relative path to the source root.

target<String>

the relative path to the destination root.

options<Hash>

give :verbose => false to not log the status.

If :recursive => false, does not look for paths recursively.
If :mode => :preserve, preserve the file mode from the source.
If :exclude_pattern => /regexp/, prevents copying files that match that regexp.

Examples

directory "doc"
directory "doc", "docs", :recursive => false


43
44
45
46
47
# File 'lib/pineapples/actions/directory.rb', line 43

def directory(source, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  target = args.first || source
  action Directory.new(self, source, target, options, &block)
end

#empty_directory(target, options = {}) ⇒ Object

Creates an empty directory.

Parameters

target<String>

the relative path to the app root.

options<Hash>

give :verbose => false to not log the status.

Examples

empty_directory "doc"


13
14
15
# File 'lib/pineapples/actions/empty_directory.rb', line 13

def empty_directory(target, options = {})
  action EmptyDirectory.new(self, target, options)
end

#empty_directory_with_keep_file(target, options = {}) ⇒ Object



5
6
7
8
# File 'lib/pineapples/actions/keep_file.rb', line 5

def empty_directory_with_keep_file(target, options = {})
  empty_directory(target, options)
  keep_file(target)
end

#find_in_source_paths(file) ⇒ Object

Raises:



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/pineapples/actions.rb', line 79

def find_in_source_paths(file)
  files_to_search = [file, file + TEMPLATE_EXTNAME]
  sources = source_paths_for_search

  sources.each do |source_path|
    files_to_search.each do |file|
      source_file = File.expand_path(file, source_path)
      return source_file if File.exist?(source_file)
    end
  end

  message = "Could not find #{file.inspect} in any of your source paths. "

  unless self.templates_root
    message << "Please set your generator instance template_root to PATH with the PATH containing your templates."
  end

  if sources.empty?
    message << "Currently you have no source paths."
  else
    message << "Your current source paths are: \n#{sources.join("\n")}"
  end

  raise Error, message
end

#get(source, *args, &block) ⇒ Object

Gets the content at the given address and places it at the given relative destination. If a block is given instead of destination, the content of the url is yielded and used as location.

Parameters

source<String>

the address of the given content.

target<String>

the relative path to the destination root.

options<Hash>

give :verbose => false to not log the status.

Examples

get "http://gist.github.com/103208", "doc/README"

get "http://gist.github.com/103208" do |content|
  content.split("\n").first
end


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/pineapples/actions/get.rb', line 22

def get(source, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  target = args.first

  source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ %r{^https?\://}
  render = open(source) { |input| input.binmode.read }

  target ||= if block
               block.arity == 1 ? block.call(render) : block.call
             else
               File.basename(source)
             end

  create_file(target, render, options)
end

#git(commands = {}) ⇒ Object

Run a command in git.

git :init
git add: "this.file that.rb"
git add: "onefile.rb", rm: "badfile.cxx"


8
9
10
11
12
13
14
# File 'lib/pineapples/actions/git.rb', line 8

def git(commands = {})
  if commands.is_a?(Symbol)
    shell "git #{commands}"
  else
    commands.each { |cmd, options| shell "git #{cmd} #{options}" }
  end
end

#gsub_file(path, flag, *args, &block) ⇒ Object

Run a regular expression replacement on a file.

Parameters

path<String>

path of the file to be changed

flag<Regexp|String>

the regexp or string to be replaced

replacement<String>

the replacement, can be also given as a block

config<Hash>

give :verbose => false to not log the status.

Example

gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'

gsub_file 'README', /rake/, :green do |match|
  match << " no more. Use thor!"
end

Raises:



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/pineapples/actions/gsub_file.rb', line 19

def gsub_file(path, flag, *args, &block)
  return unless behaviour == :invoke
  options = args.last.is_a?(Hash) ? args.pop : {}

  verbose = options.fetch(:verbose, verbose?)
  execute = options.fetch(:pretend, execute?)

  fullpath = File.expand_path(path, app_root)
  raise Error, "File #{path} doesn't exist!" if !File.exist?(fullpath)

  say_status :gsub, relative_to_app_root(path), :light_yellow, verbose

  if execute
    content = File.binread(fullpath)
    content.gsub!(flag, *args, &block)
    File.open(fullpath, 'wb') { |file| file.write(content) }
  end
end

#in_app_root(&block) ⇒ Object



53
54
55
# File 'lib/pineapples/actions/inside.rb', line 53

def in_app_root(&block)
  Dir.chdir(app_root, &block)
end

#in_root(options = {}) ⇒ Object

Convenience method to call inside in_root



49
50
51
# File 'lib/pineapples/actions/inside.rb', line 49

def in_root(options = {})
  inside(:root, options) { yield }
end

#indent(verbose = true, level_increment = 1) ⇒ Object



123
124
125
126
127
# File 'lib/pineapples/actions.rb', line 123

def indent(verbose = true, level_increment = 1)
  $terminal.indent_level += level_increment if verbose
  yield
  $terminal.indent_level -= level_increment if verbose
end

#initialize(options) ⇒ Object



35
36
37
38
39
# File 'lib/pineapples/actions.rb', line 35

def initialize(options)
  super

  @behaviour = options.behaviour || :invoke
end

#insert_into_file(target, *args, &block) ⇒ Object



3
4
5
6
7
# File 'lib/pineapples/actions/insert_into_file.rb', line 3

def insert_into_file(target, *args, &block)
  content = block_given? ? block : args.shift
  options = args.shift
  action InsertIntoFile.new(self, target, content, options)
end

#inside(dir = :root, options = {}, &block) ⇒ Object

Do something in the root or on a provided subfolder. The full path to the directory is yielded to the block you provide. The path is set back to the previous path when the method exits.

Parameters

dir<String>

the directory to move to, relative to the app root

config<Hash>

give :verbose => true to log and use padding.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/pineapples/actions/inside.rb', line 19

def inside(dir = :root, options = {}, &block)
  verbose = options.fetch(:verbose, verbose?)
  color = options.fetch(:color, :light_green)

  status_dir = if dir == :root
                 relative_to_app_root(app_root)
               else
                 relative_to_app_root(File.join(current_app_dir, dir))
               end

  say_status(:inside, status_dir, color, verbose)

  indent(verbose) do
    with_directory(dir) do |target_dir|
      if !File.exist?(target_dir) && !pretend?
        FileUtils.mkdir_p(target_dir)
      end

      if pretend?
        block.arity == 1 ? yield(target_dir) : yield
      else
        FileUtils.cd(target_dir) do
          block.arity == 1 ? yield(target_dir) : yield
        end
      end
    end
  end
end

#keep_file(target) ⇒ Object



10
11
12
# File 'lib/pineapples/actions/keep_file.rb', line 10

def keep_file(target)
  create_file("#{target}/.keep")
end

#prepend_to_class(path, klass, *args, &block) ⇒ Object

Injects text right after the class definition. Since it depends on insert_into_file, it’s reversible.

Parameters

path<String>

path of the file to be changed

klass<String|Class>

the class to be manipulated

data<String>

the data to append to the class, can be also given as a block.

config<Hash>

give :verbose => false to not log the status.

Examples

prepend_to_class "app/controllers/application_controller.rb", ApplicationController, "  filter_parameter :password\n"

prepend_to_class "app/controllers/application_controller.rb", ApplicationController do
  "  filter_parameter :password\n"
end


20
21
22
23
24
# File 'lib/pineapples/actions/prepend_to_class.rb', line 20

def prepend_to_class(path, klass, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  options.merge!(after: /class #{klass}\n|class #{klass} .*\n/)
  insert_into_file(path, *(args << options), &block)
end

#prepend_to_file(path, *args, &block) ⇒ Object Also known as: prepend_file

Prepend text to a file. Since it depends on insert_into_file, it’s reversible.

Parameters

path<String>

path of the file to be changed

content<String>

the content to prepend to the file, can be also given as a block.

options<Hash>

give :verbose => false to not log the status.

Example

prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"'

prepend_to_file 'config/environments/test.rb' do
  'config.gem "rspec"'
end


46
47
48
49
50
# File 'lib/pineapples/actions/insert_into_file.rb', line 46

def prepend_to_file(path, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  options.merge!(after: /\A/)
  insert_into_file(path, *(args << options), &block)
end

#relative_to_app_root(dir) ⇒ Object

dir argument must me absolute path



67
68
69
70
71
# File 'lib/pineapples/actions.rb', line 67

def relative_to_app_root(dir)
  @app_root_pathname ||= Pathname.new(app_root)
  path = Pathname.new(dir)
  path.relative_path_from(@app_root_pathname).to_s
end

#relative_to_current_app_dir(dir) ⇒ Object



73
74
75
76
77
# File 'lib/pineapples/actions.rb', line 73

def relative_to_current_app_dir(dir)
  current_app_path = Pathname.new(current_app_dir)
  path = Pathname.new(dir)
  path.relative_path_from(current_app_path).to_s
end

#remove_file(path, options = {}) ⇒ Object Also known as: remove_dir

Removes a file at the given location.

Parameters

path<String>

path of the file to be changed

options<Hash>

give :verbose => false to not log the status.

Example

remove_file 'README'
remove_file 'app/controllers/application_controller.rb'


14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/pineapples/actions/remove_file.rb', line 14

def remove_file(path, options = {})
  return unless behaviour == :invoke
  path  = File.expand_path(path, app_root)

  message = relative_to_app_root(path)
  verbose = options.fetch(:verbose, verbose?)
  color = options.fetch(:color, :light_red)
  execute = options[:pretend] || execute?

  say_status :remove, message, color, verbose
  ::FileUtils.rm_rf(path) if execute && File.exist?(path)
end

#ruby(command, options = {}) ⇒ Object

Executes a ruby script (taking into account WIN32 platform quirks).

Parameters

command<String>

the command to be executed.

options<Hash>

give :verbose => false to not log the status.



10
11
12
13
# File 'lib/pineapples/actions/ruby.rb', line 10

def ruby(command, options = {})
  return if behaviour != :inboke
  shell(command, options.merge(with: ruby_command))
end

#say_status(status, message, color = :light_green, log = true) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/pineapples/actions.rb', line 105

def say_status(status, message, color = :light_green, log = true)
  return if !log

  spaces = ' ' * $terminal.indent_size * 2

  status = status.to_s.rjust(12)
  status = status.colorize(color)

  output = "#{status}#{spaces}#{message}"

  say(output)
end

#say_title(title) ⇒ Object



118
119
120
121
# File 'lib/pineapples/actions.rb', line 118

def say_title(title)
  puts
  puts "== #{title} ==".light_yellow
end

#shell(command, options = {}) ⇒ Object

Executes a command returning the contents of the command.

Parameters

command<String>

the command to be executed.

options<Hash>

give :verbose => false to not log the status, :capture => true to hide to output. Specify :with

to append an executable to command execution.

Example

inside 'vendor' do
  shell 'ln -s ~/edge rails'
end


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/pineapples/actions/shell.rb', line 16

def shell(command, options = {})
  return if behaviour == :revoke

  verbose = options.fetch(:verbose, verbose?)
  execute = !options.fetch(:pretend, pretend?)

  executable = options[:with].to_s

  command = "#{executable} #{command}" if executable.present?

  say_status(:shell, command, DEFAULT_COLOR, verbose)

  if execute
    options[:capture] ? `#{command}` : system("#{command}")
    raise Error, "#{command} failed with status #{$CHILD_STATUS.exitstatus}." if not $CHILD_STATUS.success?
  end
end

#shell_with_app_gemset(command, options = {}) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/pineapples/actions/shell.rb', line 41

def shell_with_app_gemset(command, options = {})
  # we have to use PTY pseudo terminal to able to read shell subprocess output asynchronously.
  # Backticks and Kernel#system buffer output, and since bundle install takes forever to complete
  # it's not very user-friendly and program would seem to hang.
  # We just cd into project directory and invoke RVM in binary mode ('do' command)

  # TODO: add support for rbenv gemsets
  return if behaviour == :revoke
  verbose = options.fetch(:verbose, verbose?)
  execute = !options.fetch(:pretend, pretend?)

  full_command = "export DISABLE_SPRING=0; cd #{File.basename(app_root)}; rvm . do #{command}"
  say_status :shell, full_command, DEFAULT_COLOR, verbose

  if execute
    begin
      PTY.spawn(full_command) do |reader, writer, pid|
        loop do
          line = reader.gets
          break if !line
          puts line
        end
        Process.wait(pid)
      end
    rescue Errno::EIO => error
      nil
    rescue PTY::ChildExited => error
      puts 'The child process exited!'
    end
  end
end

#shell_with_clean_bundler_env(command, options = {}) ⇒ Object



34
35
36
37
38
39
# File 'lib/pineapples/actions/shell.rb', line 34

def shell_with_clean_bundler_env(command, options = {})
  return shell(command, options) if !defined?(Bundler)
  Bundler.with_clean_env do
    shell(command, options)
  end
end

#source_pathsObject



55
56
57
# File 'lib/pineapples/actions.rb', line 55

def source_paths
  @source_paths ||= []
end

#source_paths_for_searchObject



59
60
61
62
63
64
# File 'lib/pineapples/actions.rb', line 59

def source_paths_for_search
  paths = []
  paths += source_paths
  paths << templates_root if templates_root
  paths
end

#template(source, *args, &block) ⇒ Object

Gets an ERB template at the relative source, executes it and makes a copy at the relative destination. If the destination is not given it’s assumed to be equal to the source removing .tt from the filename.

Parameters

source<String>

the relative path to the source root.

target<String>

the relative path to the destination root.

options<Hash>

give :verbose => false to not log the status.

Examples

template "README", "doc/README"

template "doc/README"


20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/pineapples/actions/template.rb', line 20

def template(source, *args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  target = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, '')

  source  = File.expand_path(find_in_source_paths(source.to_s))
  context = options.delete(:context) || binding #instance_eval('binding')


  create_file(target, nil, options) do
    template = File.binread(source)
    content = ERB.new(template, nil, '-').result(context)
    content = block.call(content) if block
    content
  end
end

#templates_rootObject



51
52
53
# File 'lib/pineapples/actions.rb', line 51

def templates_root
  @templates_root ||= File.join(__dir__, 'templates')
end