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



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

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



63
64
65
66
# File 'lib/hanami/utils/files.rb', line 63

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



122
123
124
# File 'lib/hanami/utils/files.rb', line 122

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



133
134
135
# File 'lib/hanami/utils/files.rb', line 133

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



377
378
379
# File 'lib/hanami/utils/files.rb', line 377

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



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

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



262
263
264
# File 'lib/hanami/utils/files.rb', line 262

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



281
282
283
# File 'lib/hanami/utils/files.rb', line 281

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



226
227
228
# File 'lib/hanami/utils/files.rb', line 226

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



244
245
246
# File 'lib/hanami/utils/files.rb', line 244

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



87
88
89
# File 'lib/hanami/utils/files.rb', line 87

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



111
112
113
# File 'lib/hanami/utils/files.rb', line 111

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



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

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) + (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



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

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



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

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



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

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



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

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



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



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

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