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



162
163
164
165
166
167
168
169
170
# File 'lib/hanami/utils/files.rb', line 162

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



61
62
63
64
# File 'lib/hanami/utils/files.rb', line 61

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



120
121
122
# File 'lib/hanami/utils/files.rb', line 120

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



131
132
133
# File 'lib/hanami/utils/files.rb', line 131

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



375
376
377
# File 'lib/hanami/utils/files.rb', line 375

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



356
357
358
# File 'lib/hanami/utils/files.rb', line 356

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



260
261
262
# File 'lib/hanami/utils/files.rb', line 260

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



279
280
281
# File 'lib/hanami/utils/files.rb', line 279

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



224
225
226
# File 'lib/hanami/utils/files.rb', line 224

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



242
243
244
# File 'lib/hanami/utils/files.rb', line 242

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



85
86
87
# File 'lib/hanami/utils/files.rb', line 85

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



109
110
111
# File 'lib/hanami/utils/files.rb', line 109

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



327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/hanami/utils/files.rb', line 327

def self.remove_block(path, target) # rubocop:disable Metrics/AbcSize
  content  = ::File.readlines(path)
  starting = index(content, path, target)
  line     = content[starting]
  size     = line[/\A[[:space:]]*/].bytesize
  closing  = (" " * size) + (target =~ /{/ ? '}' : 'end')
  ending   = starting + index(content[starting..-1], 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



292
293
294
295
296
297
298
# File 'lib/hanami/utils/files.rb', line 292

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



184
185
186
187
188
189
# File 'lib/hanami/utils/files.rb', line 184

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



203
204
205
206
207
208
# File 'lib/hanami/utils/files.rb', line 203

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

.rewrite(path, *content) ⇒ Object

Rewrites the contents of an existing file. If the path already exists, it replaces the contents.

Parameters:

  • path (String, Pathname)

    the path to file

  • content (String, Array<String>)

    the content to write

Raises:

  • (Errno::ENOENT)

    if the path doesn’t exist

Since:

  • 1.1.0



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

def self.rewrite(path, *content)
  Hanami::Utils::Deprecation.new(
    "`.rewrite' is deprecated, please use `.write'"
  )
  raise Errno::ENOENT unless File.exist?(path)

  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



18
19
20
21
# File 'lib/hanami/utils/files.rb', line 18

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



145
146
147
148
149
150
# File 'lib/hanami/utils/files.rb', line 145

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



30
31
32
33
# File 'lib/hanami/utils/files.rb', line 30

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