Module: Ing::Files
- Included in:
- Generator
- Defined in:
- lib/ing/files.rb,
lib/ing/actions/directory.rb,
lib/ing/actions/create_file.rb,
lib/ing/actions/create_link.rb,
lib/ing/actions/empty_directory.rb,
lib/ing/actions/inject_into_file.rb,
lib/ing/actions/file_manipulation.rb
Overview
Provides filesystem actions using the same interface as Thor::Actions
The target class must provide at least:
attr_reader :source_root, :destination_root
attr_reader :shell, :options
and should provide these options (otherwise all defaulted nil): verbose, force, pretend, revoke, quiet, skip.
Defined Under Namespace
Classes: CreateFile, CreateLink, Directory, EmptyDirectory, InjectIntoFile
Instance Method Summary collapse
-
#action(instance) ⇒ Object
Wraps an action object and call it accordingly to the behavior attribute.
-
#append_to_file(path, *args, &block) ⇒ Object
(also: #append_file)
Append text to a file.
-
#chmod(path, mode, config = {}) ⇒ Object
Changes the mode of the given file or directory.
-
#comment_lines(path, flag, *args) ⇒ Object
Comment all lines matching a given regex.
-
#copy_file(source, *args, &block) ⇒ Object
Copies the file from the relative source to the relative destination.
-
#create_file(destination, *args, &block) ⇒ Object
(also: #add_file)
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.
-
#create_link(destination, *args, &block) ⇒ Object
(also: #add_link)
Create a new file relative to the destination root from the given source.
- #current_destination ⇒ Object
-
#directory(source, *args, &block) ⇒ Object
Copies recursively the files from source directory to root directory.
-
#empty_directory(destination, config = {}) ⇒ Object
Creates an empty directory.
-
#find_in_source_paths(file) ⇒ Object
Receives a file or directory and search for it in the source paths.
- #force? ⇒ Boolean
-
#get(source, *args, &block) ⇒ Object
Gets the content at the given address and places it at the given relative destination.
-
#gsub_file(path, flag, *args, &block) ⇒ Object
Run a regular expression replacement on a file.
-
#in_root ⇒ Object
Goes to the current root and execute the given block.
-
#inject_into_class(path, klass, *args, &block) ⇒ Object
Injects text right after the class definition.
-
#insert_into_file(destination, *args, &block) ⇒ Object
(also: #inject_into_file)
Injects the given content into a file.
-
#inside(dir = '', config = {}, &block) ⇒ Object
Do something in the root or on a provided subfolder.
-
#link_file(source, *args, &block) ⇒ Object
Links the file from the relative source to the relative destination.
-
#prepend_to_file(path, *args, &block) ⇒ Object
(also: #prepend_file)
Prepend text to a file.
- #pretend? ⇒ Boolean
- #quiet? ⇒ Boolean
-
#relative_to_original_destination_root(path, remove_dot = true) ⇒ Object
Returns the given path relative to the absolute root (ie, root where the script started).
-
#remove_file(path, config = {}) ⇒ Object
(also: #remove_dir)
Removes a file at the given location.
- #revoke? ⇒ Boolean
- #skip? ⇒ Boolean
-
#template(source, *args, &block) ⇒ Object
Gets an ERB template at the relative source, executes it and makes a copy at the relative destination.
-
#uncomment_lines(path, flag, *args) ⇒ Object
Uncomment all lines matching a given regex.
- #verbose? ⇒ Boolean
Instance Method Details
#action(instance) ⇒ Object
Wraps an action object and call it accordingly to the behavior attribute.
79 80 81 82 83 84 85 |
# File 'lib/ing/files.rb', line 79 def action(instance) #:nodoc: if revoke? instance.revoke! else instance.invoke! 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
172 173 174 175 176 |
# File 'lib/ing/actions/file_manipulation.rb', line 172 def append_to_file(path, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} config.merge!(:before => /\z/) insert_into_file(path, *(args << config), &block) end |
#chmod(path, mode, config = {}) ⇒ 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
- config<Hash>
-
give :verbose => false to not log the status.
Example
chmod "script/*", 0755
128 129 130 131 132 133 |
# File 'lib/ing/actions/file_manipulation.rb', line 128 def chmod(path, mode, config={}) return if revoke? path = File.(path, destination_root) shell.say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true) FileUtils.chmod_R(mode, path) unless [:pretend] end |
#comment_lines(path, flag, *args) ⇒ Object
Comment all lines matching a given regex. It will leave the space which existed before the beginning of the line in tact and will insert a single space after the comment hash.
Parameters
- path<String>
-
path of the file to be changed
- flag<Regexp|String>
-
the regexp or string used to decide which lines to comment
- config<Hash>
-
give :verbose => false to not log the status.
Example
comment_lines 'config/initializers/session_store.rb', /cookie_store/
264 265 266 267 268 |
# File 'lib/ing/actions/file_manipulation.rb', line 264 def comment_lines(path, flag, *args) flag = flag.respond_to?(:source) ? flag.source : flag gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args) end |
#copy_file(source, *args, &block) ⇒ Object
Copies the file from the relative source to the relative destination. If the destination is not given it’s assumed to be equal to the source.
Parameters
- source<String>
-
the relative path to the source root.
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
give :verbose => false to not log the status.
Examples
copy_file "README", "doc/README"
copy_file "doc/README"
21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/ing/actions/file_manipulation.rb', line 21 def copy_file(source, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first || source source = File.(find_in_source_paths(source.to_s)) create_file destination, nil, config do content = File.binread(source) content = block.call(content) if block content end end |
#create_file(destination, *args, &block) ⇒ Object Also known as: add_file
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
- destination<String>
-
the relative path to the destination root.
- data<String|NilClass>
-
the data to append to the file.
- config<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"
23 24 25 26 27 |
# File 'lib/ing/actions/create_file.rb', line 23 def create_file(destination, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} data = args.first action CreateFile.new(self, destination, block || data.to_s, config) end |
#create_link(destination, *args, &block) ⇒ Object Also known as: add_link
Create a new file relative to the destination root from the given source.
Parameters
- destination<String>
-
the relative path to the destination root.
- source<String|NilClass>
-
the relative path to the source root.
- config<Hash>
-
give :verbose => false to not log the status.
-
give :symbolic => false for hard link.
Examples
create_link "config/apache.conf", "/etc/apache.conf"
18 19 20 21 22 |
# File 'lib/ing/actions/create_link.rb', line 18 def create_link(destination, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} source = args.first action CreateLink.new(self, destination, source, config) end |
#current_destination ⇒ Object
73 74 75 |
# File 'lib/ing/files.rb', line 73 def current_destination destination_stack.last 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
Encoded path note: Since Thor internals use Object#respond_to? to check if it can expand %something%, this ‘something` should be a public method in the class calling #directory. If a method is private, Thor stack raises PrivateMethodEncodedError.
Parameters
- source<String>
-
the relative path to the source root.
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
give :verbose => false to not log the status. If :recursive => false, does not look for paths recursively.
Examples
directory "doc"
directory "doc", "docs", :recursive => false
47 48 49 50 51 |
# File 'lib/ing/actions/directory.rb', line 47 def directory(source, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first || source action Directory.new(self, source, destination || source, config, &block) end |
#empty_directory(destination, config = {}) ⇒ Object
Creates an empty directory.
Parameters
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
give :verbose => false to not log the status.
Examples
empty_directory "doc"
14 15 16 |
# File 'lib/ing/actions/empty_directory.rb', line 14 def empty_directory(destination, config={}) action EmptyDirectory.new(self, destination, config) end |
#find_in_source_paths(file) ⇒ Object
Receives a file or directory and search for it in the source paths.
Note that at minimum, the base object must define source_root
. If source_paths
is also defined, those will be used to search for files first.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/ing/files.rb', line 106 def find_in_source_paths(file) relative_root = relative_to_original_destination_root(current_destination, false) source_paths = (respond_to?(:source_paths) ? self.source_paths : []) + [self.source_root] source_paths.each do |source| source_file = File.(file, File.join(source, relative_root)) return source_file if File.exists?(source_file) end = "Could not find #{file.inspect} in any of your source paths. " unless source_root << "Please set the source_root with the path containing your templates." end if source_paths.empty? << "Currently you have no source paths." else << "Your current source paths are: \n#{source_paths.join("\n")}" end raise Ing::FileNotFoundError, end |
#force? ⇒ Boolean
52 53 54 |
# File 'lib/ing/files.rb', line 52 def force? !![:force] 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.
- destination<String>
-
the relative path to the destination root.
- config<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
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/ing/actions/file_manipulation.rb', line 72 def get(source, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first source = File.(find_in_source_paths(source.to_s)) unless source =~ /^https?\:\/\// render = open(source) {|input| input.binmode.read } destination ||= if block_given? block.arity == 1 ? block.call(render) : block.call else File.basename(source) end create_file destination, render, config 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
218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/ing/actions/file_manipulation.rb', line 218 def gsub_file(path, flag, *args, &block) return if revoke? config = args.last.is_a?(Hash) ? args.pop : {} path = File.(path, destination_root) shell.say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) unless [:pretend] content = File.binread(path) content.gsub!(flag, *args, &block) File.open(path, 'wb') { |file| file.write(content) } end end |
#in_root ⇒ Object
Goes to the current root and execute the given block.
168 169 170 |
# File 'lib/ing/files.rb', line 168 def in_root inside(destination_root) { yield } end |
#inject_into_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
inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n"
inject_into_class "app/controllers/application_controller.rb", ApplicationController do
" filter_parameter :password\n"
end
196 197 198 199 200 |
# File 'lib/ing/actions/file_manipulation.rb', line 196 def inject_into_class(path, klass, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/) insert_into_file(path, *(args << config), &block) end |
#insert_into_file(destination, *args, &block) ⇒ Object Also known as: inject_into_file
Injects the given content into a file. Different from gsub_file, this method is reversible.
Parameters
- destination<String>
-
Relative path to the destination root
- data<String>
-
Data to add to the file. Can be given as a block.
- config<Hash>
-
give :verbose => false to not log the status and the flag for injection (:after or :before) or :force => true for insert two or more times the same content.
Examples
insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
gems = ask "Which gems would you like to add?"
gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
end
25 26 27 28 29 30 31 32 |
# File 'lib/ing/actions/inject_into_file.rb', line 25 def insert_into_file(destination, *args, &block) if block_given? data, config = block, args.shift else data, config = args.shift, args.shift end action InjectIntoFile.new(self, destination, data, config) end |
#inside(dir = '', config = {}, &block) ⇒ Object
Do something in the root or on a provided subfolder. If a relative path is given it’s referenced from the current root. The full path 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.
- config<Hash>
-
give :verbose => true to log and use padding.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/ing/files.rb', line 141 def inside(dir='', config={}, &block) verbose = config.fetch(:verbose, verbose?) shell.say_status :inside, dir, verbose shell.padding += 1 if verbose destination_stack.push File.(dir, current_destination) # If the directory doesnt exist and we're not pretending if !File.exist?(current_destination) FileUtils.mkdir_p(current_destination, :noop => pretend?) end if pretend? # In pretend mode, just yield down to the block block.arity == 1 ? yield(current_destination) : yield else FileUtils.cd(current_destination) do block.arity == 1 ? yield(current_destination) : yield end end destination_stack.pop shell.padding -= 1 if verbose end |
#link_file(source, *args, &block) ⇒ Object
Links the file from the relative source to the relative destination. If the destination is not given it’s assumed to be equal to the source.
Parameters
- source<String>
-
the relative path to the source root.
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
give :verbose => false to not log the status.
Examples
link_file "README", "doc/README"
link_file "doc/README"
47 48 49 50 51 52 53 |
# File 'lib/ing/actions/file_manipulation.rb', line 47 def link_file(source, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first || source source = File.(find_in_source_paths(source.to_s)) create_link destination, source, config 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
- data<String>
-
the data to prepend to the file, can be also given as a block.
- config<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
150 151 152 153 154 |
# File 'lib/ing/actions/file_manipulation.rb', line 150 def prepend_to_file(path, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} config.merge!(:after => /\A/) insert_into_file(path, *(args << config), &block) end |
#pretend? ⇒ Boolean
48 49 50 |
# File 'lib/ing/files.rb', line 48 def pretend? !![:pretend] end |
#quiet? ⇒ Boolean
60 61 62 |
# File 'lib/ing/files.rb', line 60 def quiet? !![:quiet] end |
#relative_to_original_destination_root(path, remove_dot = true) ⇒ Object
Returns the given path relative to the absolute root (ie, root where the script started).
90 91 92 93 94 95 96 97 |
# File 'lib/ing/files.rb', line 90 def relative_to_original_destination_root(path, remove_dot=true) path = path.dup if path.gsub!(destination_root, '.') remove_dot ? (path[2..-1] || '') : path else path end end |
#remove_file(path, config = {}) ⇒ Object Also known as: remove_dir
Removes a file at the given location.
Parameters
- path<String>
-
path of the file to be changed
- config<Hash>
-
give :verbose => false to not log the status.
Example
remove_file 'README'
remove_file 'app/controllers/application_controller.rb'
281 282 283 284 285 286 287 |
# File 'lib/ing/actions/file_manipulation.rb', line 281 def remove_file(path, config={}) return if revoke? path = File.(path, destination_root) shell.say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) ::FileUtils.rm_rf(path) if ![:pretend] && File.exists?(path) end |
#revoke? ⇒ Boolean
64 65 66 |
# File 'lib/ing/files.rb', line 64 def revoke? !![:revoke] end |
#skip? ⇒ Boolean
68 69 70 |
# File 'lib/ing/files.rb', line 68 def skip? !![:skip] 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.
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
give :verbose => false to not log the status.
Examples
template "README", "doc/README"
template "doc/README"
103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ing/actions/file_manipulation.rb', line 103 def template(source, *args, &block) config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first || source.sub(/\.tt$/, '') source = File.(find_in_source_paths(source.to_s)) context = instance_eval('binding') create_file destination, nil, config do content = ERB.new(::File.binread(source), nil, '-', '@output_buffer').result(context) content = block.call(content) if block content end end |
#uncomment_lines(path, flag, *args) ⇒ Object
Uncomment all lines matching a given regex. It will leave the space which existed before the comment hash in tact but will remove any spacing between the comment hash and the beginning of the line.
Parameters
- path<String>
-
path of the file to be changed
- flag<Regexp|String>
-
the regexp or string used to decide which lines to uncomment
- config<Hash>
-
give :verbose => false to not log the status.
Example
uncomment_lines 'config/initializers/session_store.rb', /active_record/
245 246 247 248 249 |
# File 'lib/ing/actions/file_manipulation.rb', line 245 def uncomment_lines(path, flag, *args) flag = flag.respond_to?(:source) ? flag.source : flag gsub_file(path, /^(\s*)#\s*(.*#{flag})/, '\1\2', *args) end |
#verbose? ⇒ Boolean
56 57 58 |
# File 'lib/ing/files.rb', line 56 def verbose? !![:verbose] end |