lib/stashify/file.rb in stashify-3.2.0 vs lib/stashify/file.rb in stashify-3.2.1
- old
+ new
@@ -1,33 +1,94 @@
# frozen_string_literal: true
require "stashify"
module Stashify
+ # A common abstraction for interacting with files. All methods that
+ # need to interact with files are assumed to adhere to the methods
+ # defined here. Specifically the methods {#write}, {#delete},
+ # {#contents} and {#exists?} are guaranteed to exist and behave in a
+ # way that is consistent across all gems. Unless called out
+ # separately, documentation for those methods here will hold true of
+ # any implementations of this class.
class File
- attr_reader :name, :path, :contents
+ # Provides the contents of this file. In the base class, this is
+ # implemented as an attribute, but most implementations will
+ # override this with a method. In most implementations, the
+ # performance cost of reading the file is high enough that we only
+ # want to pay it if it's actually needed.
+ attr_reader :contents
- def initialize(name: nil, path: nil, contents: "")
+ # The name of the file is the actual filename in a directory. In
+ # other words, it is everything that follows the final "/" in the
+ # {#path}. This is always guaranteed to be populated.
+ attr_reader :name
+
+ # The full path to the file this represents. Anything after the
+ # final "/" will also be returned from {#name}. This is not
+ # necessarily guaranteed to be populated, but usually will be.
+ attr_reader :path
+
+ # Basic information associated with a file that is necessary to
+ # enable memory-based interactions.
+ #
+ # @param name [String not containing a "/"] The name of the file. Either this or path must be defined.
+ # @param path [String] The path of the file, will populate name with everything following the final "/".
+ # @param contents [String] The contents of the file, if nil this object will mimic a missing file.
+ def initialize(name: nil, path: nil, contents: nil)
raise StandardError, "name or path must be defined" unless name || path
raise Stashify::InvalidFile, "Name '#{name}' contains a /" if name && name =~ %r{/}
@path = path
@name = name || ::File.basename(path)
@contents = contents
end
+ # Persists the provided contents into {#path}. If that file does
+ # not exist, it creates it in the process. Otherwise it updates
+ # the existing file.
+ #
+ # In general, if {#exists?} returns false before this is called it
+ # will return true after this is called.
+ #
+ # @note For the base implementation, it will assign something to
+ # @contents. The value of this instance variable should not be
+ # relied upon outside of the base implementation though, every
+ # other implementation so far overrides to an action more
+ # appropriate to its storage medium.
+ #
+ # @param contents [String] A String describing the contents of the file.
+ # @return No guarantees are made as to the return value of this method,
+ # it will largely depend on the implementation of the implementing class.
def write(contents)
@contents = contents
end
+ # Deletes the underlying file.
+ #
+ # In general, if {#exists?} returns true prior to this method
+ # being called, it will no longer return true after this method is
+ # called.
+ #
+ # @return No guarantees are made as to the return value of this method,
+ # it will largely depend on the implementation of the implementing class.
def delete
@contents = nil
end
+ # Answers if the file exists. In general, it will always return
+ # true after {#write} is called and always return false after
+ # {#delete} is called.
+ #
+ # @note The base class checks if {#contents} returns nil, but this
+ # is extremely unlikely for other implementations.
def exists?
!contents.nil?
end
+ # Two files are considered equal if they have the same name and
+ # contents. This means that equality holds between files in two
+ # separate directories.
def ==(other)
name == other.name && contents == other.contents
end
end
end