Module: Hanami::Utils::Files

Defined in:
lib/hanami/utils/files.rb

Overview

Files utilities

Since:

  • 1.1.0

Class Method Summary collapse

Class Method Details

.append(path, contents) ⇒ Object

Adds a new line at the bottom of the file

Parameters:

  • path (String, Pathname)

    the path to file

  • contents (String)

    the contents to add

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

See Also:

Since:

  • 1.1.0



146
147
148
149
150
151
152
153
154
# 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

.cp(source, destination) ⇒ Object

Copies source into destination. All the intermediate directories are created. If the destination already exists, it overrides the contents.

Parameters:

  • source (String, Pathname)

    the path to the source file

  • destination (String, Pathname)

    the path to the destination file

Since:

  • 1.1.0



45
46
47
48
# File 'lib/hanami/utils/files.rb', line 45

def self.cp(source, destination)
  mkdir_p(destination)
  FileUtils.cp(source, destination)
end

.delete(path) ⇒ Object

Deletes given path (file).

Parameters:

  • path (String, Pathname)

    the path to file

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

Since:

  • 1.1.0



104
105
106
# File 'lib/hanami/utils/files.rb', line 104

def self.delete(path)
  FileUtils.rm(path)
end

.delete_directory(path) ⇒ Object

Deletes given path (directory).

Parameters:

  • path (String, Pathname)

    the path to file

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

Since:

  • 1.1.0



115
116
117
# File 'lib/hanami/utils/files.rb', line 115

def self.delete_directory(path)
  FileUtils.remove_entry_secure(path)
end

.directory?(path) ⇒ TrueClass, FalseClass

Checks if ‘path` is a directory

Examples:

require "hanami/utils/files"

Hanami::Utils::Files.directory?(__dir__)  # => true
Hanami::Utils::Files.directory?(__FILE__) # => false

Hanami::Utils::Files.directory?("missing_directory") # => false

Parameters:

  • path (String, Pathname)

    the path to directory

Returns:

  • (TrueClass, FalseClass)

    the result of the check

Since:

  • 1.1.0



359
360
361
# File 'lib/hanami/utils/files.rb', line 359

def self.directory?(path)
  File.directory?(path)
end

.exist?(path) ⇒ TrueClass, FalseClass

Checks if ‘path` exist

Examples:

require "hanami/utils/files"

Hanami::Utils::Files.exist?(__FILE__) # => true
Hanami::Utils::Files.exist?(__dir__)  # => true

Hanami::Utils::Files.exist?("missing_file") # => false

Parameters:

  • path (String, Pathname)

    the path to file

Returns:

  • (TrueClass, FalseClass)

    the result of the check

Since:

  • 1.1.0



340
341
342
# File 'lib/hanami/utils/files.rb', line 340

def self.exist?(path)
  File.exist?(path)
end

.inject_line_after(path, target, contents) ⇒ Object

Inject ‘contents` in `path` after `target`.

Parameters:

  • path (String, Pathname)

    the path to file

  • target (String, Regexp)

    the target to replace

  • contents (String)

    the contents to inject

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

  • (ArgumentError)

    if ‘target` cannot be found in `path`

See Also:

Since:

  • 1.1.0



244
245
246
# 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_line_after_last(path, target, contents) ⇒ Object

Inject ‘contents` in `path` after last `target`.

Parameters:

  • path (String, Pathname)

    the path to file

  • target (String, Regexp)

    the target to replace

  • contents (String)

    the contents to inject

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

  • (ArgumentError)

    if ‘target` cannot be found in `path`

See Also:

Since:

  • 1.3.0



263
264
265
# 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_line_before(path, target, contents) ⇒ Object

Inject ‘contents` in `path` before `target`.

Parameters:

  • path (String, Pathname)

    the path to file

  • target (String, Regexp)

    the target to replace

  • contents (String)

    the contents to inject

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

  • (ArgumentError)

    if ‘target` cannot be found in `path`

See Also:

Since:

  • 1.1.0



208
209
210
# 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_line_before_last(path, target, contents) ⇒ Object

Inject ‘contents` in `path` after last `target`.

Parameters:

  • path (String, Pathname)

    the path to file

  • target (String, Regexp)

    the target to replace

  • contents (String)

    the contents to inject

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

  • (ArgumentError)

    if ‘target` cannot be found in `path`

See Also:

Since:

  • 1.3.0



226
227
228
# 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

.mkdir(path) ⇒ Object

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.

Examples:

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

Parameters:

  • path (String, Pathname)

    the path to directory

See Also:

Since:

  • 1.1.0



69
70
71
# File 'lib/hanami/utils/files.rb', line 69

def self.mkdir(path)
  FileUtils.mkdir_p(path)
end

.mkdir_p(path) ⇒ Object

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.

Examples:

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

Parameters:

  • path (String, Pathname)

    the path to directory

See Also:

Since:

  • 1.1.0



93
94
95
# File 'lib/hanami/utils/files.rb', line 93

def self.mkdir_p(path)
  Pathname.new(path).dirname.mkpath
end

.remove_block(path, target) ⇒ Object

Removes ‘target` block from `path`

Examples:

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

Parameters:

  • path (String, Pathname)

    the path to file

  • target (String)

    the target block to remove

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

  • (ArgumentError)

    if ‘target` cannot be found in `path`

Since:

  • 1.1.0



311
312
313
314
315
316
317
318
319
320
321
322
323
# 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

.remove_line(path, target) ⇒ Object

Removes line from ‘path`, matching `target`.

Parameters:

  • path (String, Pathname)

    the path to file

  • target (String, Regexp)

    the target to remove

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

  • (ArgumentError)

    if ‘target` cannot be found in `path`

Since:

  • 1.1.0



276
277
278
279
280
281
282
# 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(path, target, replacement) ⇒ Object

Replace first line in ‘path` that contains `target` with `replacement`.

Parameters:

  • path (String, Pathname)

    the path to file

  • target (String, Regexp)

    the target to replace

  • replacement (String)

    the replacement

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

  • (ArgumentError)

    if ‘target` cannot be found in `path`

See Also:

Since:

  • 1.1.0



168
169
170
171
172
173
# 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(path, target, replacement) ⇒ Object

Replace last line in ‘path` that contains `target` with `replacement`.

Parameters:

  • path (String, Pathname)

    the path to file

  • target (String, Regexp)

    the target to replace

  • replacement (String)

    the replacement

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

  • (ArgumentError)

    if ‘target` cannot be found in `path`

See Also:

Since:

  • 1.1.0



187
188
189
190
191
192
# 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

.touch(path) ⇒ Object

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

Parameters:

  • path (String, Pathname)

    the path to file

Since:

  • 1.1.0



20
21
22
23
# File 'lib/hanami/utils/files.rb', line 20

def self.touch(path)
  mkdir_p(path)
  FileUtils.touch(path)
end

.unshift(path, line) ⇒ Object

Adds a new line at the top of the file

Parameters:

  • path (String, Pathname)

    the path to file

  • line (String)

    the line to add

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

See Also:

Since:

  • 1.1.0



129
130
131
132
133
134
# 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

.write(path, *content) ⇒ Object

Creates a new file for the given path and content. All the intermediate directories are created.

Parameters:

  • path (String, Pathname)

    the path to file

  • content (String, Array<String>)

    the content to write

Since:

  • 1.1.0



32
33
34
35
# 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