Module: Dry::CLI::Utils::Files

Defined in:
lib/dry/cli/utils/files.rb

Overview

Files utilities

Since:

  • 0.3.1

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:

  • 0.3.1


147
148
149
150
151
152
153
154
155
# File 'lib/dry/cli/utils/files.rb', line 147

def self.append(path, contents)
  mkdir_p(path)

  content = ::File.readlines(path)
  content << "\n" unless content.last.end_with?("\n")
  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:

  • 0.3.1


46
47
48
49
# File 'lib/dry/cli/utils/files.rb', line 46

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:

  • 0.3.1


105
106
107
# File 'lib/dry/cli/utils/files.rb', line 105

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:

  • 0.3.1


116
117
118
# File 'lib/dry/cli/utils/files.rb', line 116

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

.directory?(path) ⇒ TrueClass, FalseClass

Checks if `path` is a directory

Examples:

require "dry/cli/utils/files"

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

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

Parameters:

  • path (String, Pathname)

    the path to directory

Returns:

  • (TrueClass, FalseClass)

    the result of the check

Since:

  • 0.3.1


360
361
362
# File 'lib/dry/cli/utils/files.rb', line 360

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

.exist?(path) ⇒ TrueClass, FalseClass

Checks if `path` exist

Examples:

require "dry/cli/utils/files"

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

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

Parameters:

  • path (String, Pathname)

    the path to file

Returns:

  • (TrueClass, FalseClass)

    the result of the check

Since:

  • 0.3.1


341
342
343
# File 'lib/dry/cli/utils/files.rb', line 341

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:

  • 0.3.1


245
246
247
# File 'lib/dry/cli/utils/files.rb', line 245

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


264
265
266
# File 'lib/dry/cli/utils/files.rb', line 264

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:

  • 0.3.1


209
210
211
# File 'lib/dry/cli/utils/files.rb', line 209

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


227
228
229
# File 'lib/dry/cli/utils/files.rb', line 227

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 "dry/cli/utils/files"

Dry::CLI::Utils::Files.mkdir("path/to/directory")  # => creates the `path/to/directory` directory


# WRONG this isn't probably what you want, check `.mkdir_p`
Dry::CLI::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:

  • 0.3.1


70
71
72
# File 'lib/dry/cli/utils/files.rb', line 70

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 "dry/cli/utils/files"

Dry::CLI::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`
Dry::CLI::Utils::Files.mkdir_p("path/to/directory")  # => creates the `path/to` directory

Parameters:

  • path (String, Pathname)

    the path to directory

See Also:

Since:

  • 0.3.1


94
95
96
# File 'lib/dry/cli/utils/files.rb', line 94

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

.remove_block(path, target) ⇒ Object

Removes `target` block from `path`

Examples:

require "dry/cli/utils/files"

puts File.read("app.rb")

# class App
#   configure do
#     root __dir__
#   end
# end

Dry::CLI::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:

  • 0.3.1


312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/dry/cli/utils/files.rb', line 312

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.match?(/{/) ? '}' : '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:

  • 0.3.1


277
278
279
280
281
282
283
# File 'lib/dry/cli/utils/files.rb', line 277

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:

  • 0.3.1


169
170
171
172
173
174
# File 'lib/dry/cli/utils/files.rb', line 169

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:

  • 0.3.1


188
189
190
191
192
193
# File 'lib/dry/cli/utils/files.rb', line 188

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:

  • 0.3.1


20
21
22
23
# File 'lib/dry/cli/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:

  • 0.3.1


130
131
132
133
134
135
# File 'lib/dry/cli/utils/files.rb', line 130

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 or rewrites the contents of an existing 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:

  • 0.3.1


33
34
35
36
# File 'lib/dry/cli/utils/files.rb', line 33

def self.write(path, *content)
  mkdir_p(path)
  open(path, ::File::CREAT | ::File::WRONLY | ::File::TRUNC, *content) # rubocop:disable LineLength, Security/Open - this isn't a call to `::Kernel.open`, but to `self.open`
end