module Hanami::Utils::Files
Files
utilities
@since 1.1.0
Public Class Methods
Adds a new line at the bottom of the file
@param path [String,Pathname] the path to file @param contents [String] the contents to add
@raise [Errno::ENOENT] if the path doesn’t exist
@see .unshift
@since 1.1.0
# File lib/hanami/utils/files.rb, line 146 def self.append(path, contents) mkdir_p(path) content = ::File.readlines(path) content << "\n" if _append_newline?(content) content << "#{contents}\n" write(path, content) end
Copies source into destination. All the intermediate directories are created. If the destination already exists, it overrides the contents.
@param source [String,Pathname] the path to the source file @param destination [String,Pathname] the path to the destination file
@since 1.1.0
# File lib/hanami/utils/files.rb, line 45 def self.cp(source, destination) mkdir_p(destination) FileUtils.cp(source, destination) end
Deletes given path (file).
@param path [String,Pathname] the path to file
@raise [Errno::ENOENT] if the path doesn’t exist
@since 1.1.0
# File lib/hanami/utils/files.rb, line 104 def self.delete(path) FileUtils.rm(path) end
Deletes given path (directory).
@param path [String,Pathname] the path to file
@raise [Errno::ENOENT] if the path doesn’t exist
@since 1.1.0
# File lib/hanami/utils/files.rb, line 115 def self.delete_directory(path) FileUtils.remove_entry_secure(path) end
Checks if ‘path` is a directory
@param path [String,Pathname] the path to directory
@return [TrueClass,FalseClass] the result of the check
@since 1.1.0
@example
require "hanami/utils/files" Hanami::Utils::Files.directory?(__dir__) # => true Hanami::Utils::Files.directory?(__FILE__) # => false Hanami::Utils::Files.directory?("missing_directory") # => false
# File lib/hanami/utils/files.rb, line 359 def self.directory?(path) File.directory?(path) end
Checks if ‘path` exist
@param path [String,Pathname] the path to file
@return [TrueClass,FalseClass] the result of the check
@since 1.1.0
@example
require "hanami/utils/files" Hanami::Utils::Files.exist?(__FILE__) # => true Hanami::Utils::Files.exist?(__dir__) # => true Hanami::Utils::Files.exist?("missing_file") # => false
# File lib/hanami/utils/files.rb, line 340 def self.exist?(path) File.exist?(path) end
Inject ‘contents` in `path` after `target`.
@param path [String,Pathname] the path to file @param target [String,Regexp] the target to replace @param contents [String] the contents to inject
@raise [Errno::ENOENT] if the path doesn’t exist @raise [ArgumentError] if ‘target` cannot be found in `path`
@see .inject_line_before @see .inject_line_before_last @see .inject_line_after_last
@since 1.1.0
# File lib/hanami/utils/files.rb, line 244 def self.inject_line_after(path, target, contents) _inject_line_after(path, target, contents, method(:index)) end
Inject ‘contents` in `path` after last `target`.
@param path [String,Pathname] the path to file @param target [String,Regexp] the target to replace @param contents [String] the contents to inject
@raise [Errno::ENOENT] if the path doesn’t exist @raise [ArgumentError] if ‘target` cannot be found in `path`
@see .inject_line_before @see .inject_line_after @see .inject_line_before_last @see .inject_line_after_last
@since 1.3.0
# File lib/hanami/utils/files.rb, line 263 def self.inject_line_after_last(path, target, contents) _inject_line_after(path, target, contents, method(:rindex)) end
Inject ‘contents` in `path` before `target`.
@param path [String,Pathname] the path to file @param target [String,Regexp] the target to replace @param contents [String] the contents to inject
@raise [Errno::ENOENT] if the path doesn’t exist @raise [ArgumentError] if ‘target` cannot be found in `path`
@see .inject_line_after @see .inject_line_before_last @see .inject_line_after_last
@since 1.1.0
# File lib/hanami/utils/files.rb, line 208 def self.inject_line_before(path, target, contents) _inject_line_before(path, target, contents, method(:index)) end
Inject ‘contents` in `path` after last `target`.
@param path [String,Pathname] the path to file @param target [String,Regexp] the target to replace @param contents [String] the contents to inject
@raise [Errno::ENOENT] if the path doesn’t exist @raise [ArgumentError] if ‘target` cannot be found in `path`
@see .inject_line_before @see .inject_line_after @see .inject_line_after_last
@since 1.3.0
# File lib/hanami/utils/files.rb, line 226 def self.inject_line_before_last(path, target, contents) _inject_line_before(path, target, contents, method(:rindex)) end
Creates a directory for the given path. It assumes that all the tokens in ‘path` are meant to be a directory. All the intermediate directories are created.
@param path [String,Pathname] the path to directory
@since 1.1.0
@see .mkdir_p
@example
require "hanami/utils/files" Hanami::Utils::Files.mkdir("path/to/directory") # => creates the `path/to/directory` directory # WRONG this isn't probably what you want, check `.mkdir_p` Hanami::Utils::Files.mkdir("path/to/file.rb") # => creates the `path/to/file.rb` directory
# File lib/hanami/utils/files.rb, line 69 def self.mkdir(path) FileUtils.mkdir_p(path) end
Creates a directory for the given path. It assumes that all the tokens, but the last, in ‘path` are meant to be a directory, whereas the last is meant to be a file. All the intermediate directories are created.
@param path [String,Pathname] the path to directory
@since 1.1.0
@see .mkdir
@example
require "hanami/utils/files" Hanami::Utils::Files.mkdir_p("path/to/file.rb") # => creates the `path/to` directory, but NOT `file.rb` # WRONG it doesn't create the last directory, check `.mkdir` Hanami::Utils::Files.mkdir_p("path/to/directory") # => creates the `path/to` directory
# File lib/hanami/utils/files.rb, line 93 def self.mkdir_p(path) Pathname.new(path).dirname.mkpath end
Removes ‘target` block from `path`
@param path [String,Pathname] the path to file @param target [String] the target block to remove
@raise [Errno::ENOENT] if the path doesn’t exist @raise [ArgumentError] if ‘target` cannot be found in `path`
@since 1.1.0
@example
require "hanami/utils/files" puts File.read("app.rb") # class App # configure do # root __dir__ # end # end Hanami::Utils::Files.remove_block("app.rb", "configure") puts File.read("app.rb") # class App # end
# File lib/hanami/utils/files.rb, line 311 def self.remove_block(path, target) content = ::File.readlines(path) starting = index(content, path, target) line = content[starting] size = line[/\A[[:space:]]*/].bytesize closing = (" " * size) + (/{/.match?(target) ? "}" : "end") ending = starting + index(content[starting..], path, closing) content.slice!(starting..ending) write(path, content) remove_block(path, target) if match?(content, target) end
Removes line from ‘path`, matching `target`.
@param path [String,Pathname] the path to file @param target [String,Regexp] the target to remove
@raise [Errno::ENOENT] if the path doesn’t exist @raise [ArgumentError] if ‘target` cannot be found in `path`
@since 1.1.0
# File lib/hanami/utils/files.rb, line 276 def self.remove_line(path, target) content = ::File.readlines(path) i = index(content, path, target) content.delete_at(i) write(path, content) end
Replace first line in ‘path` that contains `target` with `replacement`.
@param path [String,Pathname] the path to file @param target [String,Regexp] the target to replace @param replacement [String] the replacement
@raise [Errno::ENOENT] if the path doesn’t exist @raise [ArgumentError] if ‘target` cannot be found in `path`
@see .replace_last_line
@since 1.1.0
# File lib/hanami/utils/files.rb, line 168 def self.replace_first_line(path, target, replacement) content = ::File.readlines(path) content[index(content, path, target)] = "#{replacement}\n" write(path, content) end
Replace last line in ‘path` that contains `target` with `replacement`.
@param path [String,Pathname] the path to file @param target [String,Regexp] the target to replace @param replacement [String] the replacement
@raise [Errno::ENOENT] if the path doesn’t exist @raise [ArgumentError] if ‘target` cannot be found in `path`
@see .replace_first_line
@since 1.1.0
# File lib/hanami/utils/files.rb, line 187 def self.replace_last_line(path, target, replacement) content = ::File.readlines(path) content[-index(content.reverse, path, target) - 1] = "#{replacement}\n" write(path, content) end
Creates an empty file for the given path. All the intermediate directories are created. If the path already exists, it doesn’t change the contents
@param path [String,Pathname] the path to file
@since 1.1.0
# File lib/hanami/utils/files.rb, line 20 def self.touch(path) mkdir_p(path) FileUtils.touch(path) end
Adds a new line at the top of the file
@param path [String,Pathname] the path to file @param line [String] the line to add
@raise [Errno::ENOENT] if the path doesn’t exist
@see .append
@since 1.1.0
# File lib/hanami/utils/files.rb, line 129 def self.unshift(path, line) content = ::File.readlines(path) content.unshift("#{line}\n") write(path, content) end
Creates a new file for the given path and content. All the intermediate directories are created.
@param path [String,Pathname] the path to file @param content [String, Array<String>] the content to write
@since 1.1.0
# File lib/hanami/utils/files.rb, line 32 def self.write(path, *content) mkdir_p(path) open(path, ::File::CREAT | ::File::WRONLY | ::File::TRUNC, *content) # rubocop:disable Security/Open - this isn't a call to `::Kernel.open`, but to `self.open` end
Private Class Methods
@since 1.3.6 @api private
# File lib/hanami/utils/files.rb, line 442 def self._append_newline?(content) return false if content.empty? !content.last.end_with?("\n") end
@since 1.3.0 @api private
# File lib/hanami/utils/files.rb, line 415 def self._inject_line_after(path, target, contents, finder) content = ::File.readlines(path) i = finder.call(content, path, target) content.insert(i + 1, "#{contents}\n") write(path, content) end
@since 1.3.0 @api private
# File lib/hanami/utils/files.rb, line 403 def self._inject_line_before(path, target, contents, finder) content = ::File.readlines(path) i = finder.call(content, path, target) content.insert(i, "#{contents}\n") write(path, content) end
@since 1.1.0 @api private
# File lib/hanami/utils/files.rb, line 385 def self.index(content, path, target) line_number(content, target) or raise ArgumentError.new("Cannot find `#{target}' inside `#{path}'.") end
@since 1.1.0 @api private
# File lib/hanami/utils/files.rb, line 427 def self.line_number(content, target, finder: content.method(:index)) finder.call do |l| case target when ::String l.include?(target) when Regexp l =~ target end end end
@since 1.1.0 @api private
# File lib/hanami/utils/files.rb, line 367 def self.match?(content, target) !line_number(content, target).nil? end
@since 1.1.0 @api private
# File lib/hanami/utils/files.rb, line 375 def self.open(path, mode, *content) ::File.open(path, mode) do |file| file.write(Array(content).flatten.join) end end
@since 1.3.0 @api private
# File lib/hanami/utils/files.rb, line 394 def self.rindex(content, path, target) line_number(content, target, finder: content.method(:rindex)) or raise ArgumentError.new("Cannot find `#{target}' inside `#{path}'.") end