textrepo 0.5.0 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/lib/textrepo/error.rb +15 -4
- data/lib/textrepo/file_system_repository.rb +27 -20
- data/lib/textrepo/repository.rb +18 -4
- data/lib/textrepo/timestamp.rb +266 -5
- data/lib/textrepo/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e768443355f1c5764d5b5061f65c513485446f6df9ebce67b5b5f58a4ac30b20
         | 
| 4 | 
            +
              data.tar.gz: 9062103447a89fd2e7484c448ac80315906a2602fba363e142c47f0d5ecc592d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4889cfefdf5cadbaddd47f83e31a870829a9b144dddb346b8cf6f72d55fac68d6a75c1d7f180e315720f90eeb70801fd2a987920055c2d4334537955bd544678
         | 
| 7 | 
            +
              data.tar.gz: 49c5b9a1d34de8335b815e7e56070d2fa9bfdaa2a9a931f53c93ac28bff6e3da03f307f57c5faf8155bf0c01ef7ee5a61956d0605cc7d372247f184da0b0c3a6
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/). | |
| 7 7 | 
             
            ## [Unreleased]
         | 
| 8 8 | 
             
            Nothing to record here.
         | 
| 9 9 |  | 
| 10 | 
            +
            ## [0.5.5] - 2020-11-10
         | 
| 11 | 
            +
            ### Add
         | 
| 12 | 
            +
            - Add more methods for `Timestamp` class.
         | 
| 13 | 
            +
              - most of them are delegated to Time class
         | 
| 14 | 
            +
              - some of them are useful to manipulate `Timestamp` object as
         | 
| 15 | 
            +
                `String`.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            ## [0.5.4] - 2020-11-05
         | 
| 18 | 
            +
            ### Add
         | 
| 19 | 
            +
            - Add a feature for `Repository#update` to keep timestamp unchanged
         | 
| 20 | 
            +
              - add the third argument as:
         | 
| 21 | 
            +
                - `Repository#update(timestamp, text, keep_stamp = false)`
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ## [0.5.3] - 2020-11-03
         | 
| 24 | 
            +
            ### Changed
         | 
| 25 | 
            +
            - Fix issue #38: fix typo in code for FileSystemRepository.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            ## [0.5.2] - 2020-11-03
         | 
| 28 | 
            +
            ### Changed
         | 
| 29 | 
            +
            - Fix issue #34:
         | 
| 30 | 
            +
              - fix FileSystemRepository#entries to accept "yyyymo" pattern as a
         | 
| 31 | 
            +
                Timestamp pattern.
         | 
| 32 | 
            +
            - Fix issue #33: fix typo in the doc for FileSystemRepository.new.
         | 
| 33 | 
            +
            - Fix issue #31: unfriendly error message of Timestamp.parse_s.
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            ## [0.5.1] - 2020-11-02
         | 
| 36 | 
            +
            ### Changed
         | 
| 37 | 
            +
            - Fix issue #28.
         | 
| 38 | 
            +
              - Modify `Repository#update` to do nothing when the given text is
         | 
| 39 | 
            +
                identical to the one in the repository.
         | 
| 40 | 
            +
             | 
| 10 41 | 
             
            ## [0.5.0] - 2020-11-01
         | 
| 11 42 | 
             
            ### Added
         | 
| 12 43 | 
             
            - Add a new API `Repository#search`.
         | 
    
        data/lib/textrepo/error.rb
    CHANGED
    
    | @@ -22,15 +22,26 @@ module Textrepo | |
| 22 22 |  | 
| 23 23 | 
             
              # :stopdoc:
         | 
| 24 24 | 
             
              module ErrMsg
         | 
| 25 | 
            -
                 | 
| 26 | 
            -
                 | 
| 27 | 
            -
                 | 
| 28 | 
            -
                 | 
| 25 | 
            +
                ARGUMENT_RANGE      = "argument out of range: %s"
         | 
| 26 | 
            +
                UNKNOWN_REPO_TYPE   = "unknown type for repository: %s"
         | 
| 27 | 
            +
                DUPLICATE_TIMESTAMP = "duplicate timestamp: %s"
         | 
| 28 | 
            +
                EMPTY_TEXT          = "empty text"
         | 
| 29 | 
            +
                MISSING_TIMESTAMP   = "missing timestamp: %s"
         | 
| 29 30 | 
             
                INVALID_TIMESTAMP_STRING = "invalid string as timestamp: %s"
         | 
| 30 31 | 
             
                INVALID_SEARCH_RESULT = "invalid result by searcher: %s"
         | 
| 31 32 | 
             
              end
         | 
| 32 33 | 
             
              # :startdoc:
         | 
| 33 34 |  | 
| 35 | 
            +
              ##
         | 
| 36 | 
            +
              # An error raised if argument is out of range for Timestamp class.
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              class ArgumentRangeError < Error
         | 
| 39 | 
            +
                def initialize(arg)
         | 
| 40 | 
            +
                  super(ErrMsg::ARGUMENT_RANGE % arg)
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
             | 
| 34 45 | 
             
              ##
         | 
| 35 46 | 
             
              # An error raised if unknown type was specified as the repository
         | 
| 36 47 | 
             
              # type.
         | 
| @@ -67,9 +67,10 @@ module Textrepo | |
| 67 67 | 
             
                # were not defined in `conf`.
         | 
| 68 68 | 
             
                #
         | 
| 69 69 | 
             
                # Be careful to set `:searcher_options`, it must be to specify the
         | 
| 70 | 
            -
                # searcher behavior equivalent to `grep` with "- | 
| 71 | 
            -
                #  | 
| 72 | 
            -
                # grep on macOS), GNU grep, and ripgrep (aka rg).  They | 
| 70 | 
            +
                # searcher behavior equivalent to `grep` with "-inRE".  The
         | 
| 71 | 
            +
                # default values for the searcher options is defined for BSD grep
         | 
| 72 | 
            +
                # (default grep on macOS), GNU grep, and ripgrep (aka rg).  They
         | 
| 73 | 
            +
                # are:
         | 
| 73 74 | 
             
                #
         | 
| 74 75 | 
             
                #   "grep"   => ["-i", "-n", "-R", "-E"]
         | 
| 75 76 | 
             
                #   "egrep"  => ["-i", "-n", "-R"]
         | 
| @@ -77,7 +78,7 @@ module Textrepo | |
| 77 78 | 
             
                #   "gegrep" => ["-i", "-n", "-R"]
         | 
| 78 79 | 
             
                #   "rg"     => ["-S", "-n", "--no-heading", "--color", "never"]
         | 
| 79 80 | 
             
                #
         | 
| 80 | 
            -
                # If use those  | 
| 81 | 
            +
                # If use those searchers, it is not recommended to set
         | 
| 81 82 | 
             
                # `:searcher_options`.  The default value works well in
         | 
| 82 83 | 
             
                # `textrepo`.
         | 
| 83 84 | 
             
                #
         | 
| @@ -129,26 +130,32 @@ module Textrepo | |
| 129 130 | 
             
                end
         | 
| 130 131 |  | 
| 131 132 | 
             
                ##
         | 
| 132 | 
            -
                # Updates the file content in the repository.  A new  | 
| 133 | 
            -
                # will be attached to the text.
         | 
| 133 | 
            +
                # Updates the file content in the repository.  A new Timestamp
         | 
| 134 | 
            +
                # object will be attached to the text.  Then, returns the new
         | 
| 135 | 
            +
                # Timestamp object.
         | 
| 136 | 
            +
                #
         | 
| 137 | 
            +
                # When true is passed as the third argument, keeps the Timestamp
         | 
| 138 | 
            +
                # unchanged, though updates the content.  Then, returns the given
         | 
| 139 | 
            +
                # Timestamp object.
         | 
| 140 | 
            +
                #
         | 
| 141 | 
            +
                # See the documentation of Repository#update to know about errors
         | 
| 142 | 
            +
                # and constraints of this method.
         | 
| 134 143 | 
             
                #
         | 
| 135 144 | 
             
                # :call-seq:
         | 
| 136 | 
            -
                #     update(Timestamp, Array) -> Timestamp
         | 
| 145 | 
            +
                #     update(Timestamp, Array, true or false) -> Timestamp
         | 
| 137 146 |  | 
| 138 | 
            -
                def update(timestamp, text)
         | 
| 147 | 
            +
                def update(timestamp, text, keep_stamp = false)
         | 
| 139 148 | 
             
                  raise EmptyTextError if text.empty?
         | 
| 140 | 
            -
                   | 
| 141 | 
            -
                  raise MissingTimestampError, timestamp unless FileTest.exist?(org_abs)
         | 
| 149 | 
            +
                  raise MissingTimestampError, timestamp unless exist?(timestamp)
         | 
| 142 150 |  | 
| 143 | 
            -
                  #  | 
| 144 | 
            -
                   | 
| 145 | 
            -
                  new_abs = abspath(new_stamp)
         | 
| 146 | 
            -
                  write_text(new_abs, text)
         | 
| 151 | 
            +
                  # does nothing if given text is the same in the repository one
         | 
| 152 | 
            +
                  return timestamp if read(timestamp) == text
         | 
| 147 153 |  | 
| 148 | 
            -
                   | 
| 149 | 
            -
                   | 
| 154 | 
            +
                  stamp = keep_stamp ? timestamp : Timestamp.new(Time.now)
         | 
| 155 | 
            +
                  write_text(abspath(stamp), text)
         | 
| 156 | 
            +
                  FileUtils.remove_file(abspath(timestamp)) unless keep_stamp
         | 
| 150 157 |  | 
| 151 | 
            -
                   | 
| 158 | 
            +
                  stamp
         | 
| 152 159 | 
             
                end
         | 
| 153 160 |  | 
| 154 161 | 
             
                ##
         | 
| @@ -182,7 +189,7 @@ module Textrepo | |
| 182 189 | 
             
                    if exist?(stamp)
         | 
| 183 190 | 
             
                      results << stamp
         | 
| 184 191 | 
             
                    end
         | 
| 185 | 
            -
                  when 0, "yyyymoddhhmiss".size, "yyyymodd".size
         | 
| 192 | 
            +
                  when 0, "yyyymoddhhmiss".size, "yyyymodd".size, "yyyymo".size
         | 
| 186 193 | 
             
                    results += find_entries(stamp_pattern)
         | 
| 187 194 | 
             
                  when 4                    # "yyyy" or "modd"
         | 
| 188 195 | 
             
                    pat = nil
         | 
| @@ -317,7 +324,7 @@ module Textrepo | |
| 317 324 | 
             
                    file = abspath(entries[0])
         | 
| 318 325 | 
             
                    o, s = Open3.capture2(searcher, *find_searcher_options(searcher),
         | 
| 319 326 | 
             
                                          pattern, file)
         | 
| 320 | 
            -
                    if s.success? && (! o.empty)
         | 
| 327 | 
            +
                    if s.success? && (! o.empty?)
         | 
| 321 328 | 
             
                      output += o.lines.map { |line|
         | 
| 322 329 | 
             
                        # add filename at the beginning of the search result line
         | 
| 323 330 | 
             
                        [file, line.chomp].join(":")
         | 
| @@ -333,7 +340,7 @@ module Textrepo | |
| 333 340 | 
             
                    files = find_files(entries)
         | 
| 334 341 | 
             
                    o, s = Open3.capture2(searcher, *find_searcher_options(searcher),
         | 
| 335 342 | 
             
                                          pattern, *files)
         | 
| 336 | 
            -
                    if s.success? && (! o.empty)
         | 
| 343 | 
            +
                    if s.success? && (! o.empty?)
         | 
| 337 344 | 
             
                      output += o.lines.map(&:chomp)
         | 
| 338 345 | 
             
                    end
         | 
| 339 346 | 
             
                  end
         | 
    
        data/lib/textrepo/repository.rb
    CHANGED
    
    | @@ -43,13 +43,27 @@ module Textrepo | |
| 43 43 | 
             
                def read(timestamp); []; end
         | 
| 44 44 |  | 
| 45 45 | 
             
                ##
         | 
| 46 | 
            -
                # Updates the content with text in the repository, which is
         | 
| 47 | 
            -
                # associated to the  | 
| 46 | 
            +
                # Updates the content with given text in the repository, which is
         | 
| 47 | 
            +
                # associated to the given Timestamp object.  Returns the Timestamp
         | 
| 48 | 
            +
                # newly generated during the execution.
         | 
| 49 | 
            +
                #
         | 
| 50 | 
            +
                # When true is passed as the third argument, keeps the Timestamp
         | 
| 51 | 
            +
                # unchanged, though updates the content.  Then, returns the given
         | 
| 52 | 
            +
                # Timestamp object.
         | 
| 53 | 
            +
                #
         | 
| 54 | 
            +
                # If the given Timestamp object is not existed as a Timestamp
         | 
| 55 | 
            +
                # attached to text in the repository, raises
         | 
| 56 | 
            +
                # MissingTimestampError.
         | 
| 57 | 
            +
                #
         | 
| 58 | 
            +
                # If the given text is empty, raises EmptyTextError.
         | 
| 59 | 
            +
                #
         | 
| 60 | 
            +
                # If the given text is identical to the text in the repository,
         | 
| 61 | 
            +
                # does nothing.  Returns the given timestamp itself.
         | 
| 48 62 | 
             
                #
         | 
| 49 63 | 
             
                # :call-seq:
         | 
| 50 | 
            -
                #     update(Timestamp, Array) -> Timestamp
         | 
| 64 | 
            +
                #     update(Timestamp, Array, true or false) -> Timestamp
         | 
| 51 65 |  | 
| 52 | 
            -
                def update(timestamp, text); timestamp; end
         | 
| 66 | 
            +
                def update(timestamp, text, keep_stamp = false); timestamp; end
         | 
| 53 67 |  | 
| 54 68 | 
             
                ##
         | 
| 55 69 | 
             
                # Deletes the content in the repository, which is associated to
         | 
    
        data/lib/textrepo/timestamp.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            require "forwardable"
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module Textrepo
         | 
| 2 4 | 
             
              ##
         | 
| 3 5 | 
             
              # Timestamp is generated from a Time object.  It converts a time to
         | 
| @@ -18,6 +20,7 @@ module Textrepo | |
| 18 20 |  | 
| 19 21 | 
             
              class Timestamp
         | 
| 20 22 | 
             
                include Comparable
         | 
| 23 | 
            +
                extend Forwardable
         | 
| 21 24 |  | 
| 22 25 | 
             
                ##
         | 
| 23 26 | 
             
                # Time object which generates the Timestamp object.
         | 
| @@ -29,16 +32,28 @@ module Textrepo | |
| 29 32 |  | 
| 30 33 | 
             
                attr_reader :suffix
         | 
| 31 34 |  | 
| 35 | 
            +
                ##
         | 
| 36 | 
            +
                # String object which is regarded as a value of Timestamp object.
         | 
| 37 | 
            +
                # The value is generated from @time and @suffix.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                attr_reader :str
         | 
| 40 | 
            +
             | 
| 32 41 | 
             
                ##
         | 
| 33 42 | 
             
                # Creates a Timestamp object from a Time object.  In addition, an
         | 
| 34 43 | 
             
                # Integer can be passed as a suffix use.
         | 
| 35 44 | 
             
                #
         | 
| 45 | 
            +
                # Since Textrepo adapts 1 second as the time resolution, the
         | 
| 46 | 
            +
                # subsec part of a given time will be ignored.
         | 
| 47 | 
            +
                #
         | 
| 36 48 | 
             
                # :call-seq:
         | 
| 37 49 | 
             
                #   new(Time, Integer = nil) -> Timestamp
         | 
| 38 50 |  | 
| 39 51 | 
             
                def initialize(time, suffix = nil)
         | 
| 40 | 
            -
                   | 
| 52 | 
            +
                  raise ArgumentRangeError, suffix unless is_valid_suffix?(suffix)
         | 
| 53 | 
            +
                  parts = [:year, :mon, :day, :hour, :min, :sec].map{ |s| time.send(s) }
         | 
| 54 | 
            +
                  @time = Time.new(*parts)
         | 
| 41 55 | 
             
                  @suffix = suffix
         | 
| 56 | 
            +
                  @str = time_to_str(@time, @suffix)
         | 
| 42 57 | 
             
                end
         | 
| 43 58 |  | 
| 44 59 | 
             
                def <=>(other)              # :nodoc:
         | 
| @@ -51,19 +66,257 @@ module Textrepo | |
| 51 66 | 
             
                end
         | 
| 52 67 |  | 
| 53 68 | 
             
                ##
         | 
| 54 | 
            -
                #  | 
| 69 | 
            +
                # Generates an obvious time string.
         | 
| 55 70 | 
             
                #
         | 
| 56 71 | 
             
                #    %Y   %m %d %H %M %S  suffix
         | 
| 57 72 | 
             
                #   "2020-12-30 12:34:56  (0 | nil)" -> "20201230123456"
         | 
| 58 73 | 
             
                #   "2020-12-30 12:34:56  (7)"       -> "20201230123456_007"
         | 
| 59 74 |  | 
| 60 75 | 
             
                def to_s
         | 
| 76 | 
            +
                  @str
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                alias to_str to_s
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                # :stopdoc:
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                # delegators to Time object
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                def_instance_delegators :@time, :year, :mon, :day, :hour, :min, :sec
         | 
| 86 | 
            +
                def_instance_delegators :@time, :wday, :monday?, :tuesday?, :wednesday?, :thursday?, :friday?, :saturday?, :sunday?
         | 
| 87 | 
            +
                def_instance_delegators :@time, :asctime, :ctime, :strftime
         | 
| 88 | 
            +
                def_instance_delegators :@time, :subsec, :nsec, :usec
         | 
| 89 | 
            +
                def_instance_delegators :@time, :tv_nsec, :tv_sec, :tv_usec
         | 
| 90 | 
            +
                def_instance_delegators :@time, :to_f, :to_i, :to_r
         | 
| 91 | 
            +
                def_instance_delegators :@time, :yday, :mday
         | 
| 92 | 
            +
                def_instance_delegators :@time, :month
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                # :startdoc:
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                def hash                    # :nodoc:
         | 
| 97 | 
            +
                  @str[0, 14].to_i * 1000 + @suffix.to_i
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                def eql?(other)             # :nodoc:
         | 
| 101 | 
            +
                  other.is_a?(Timestamp) && @time == other.time && @suffix == other.suffix
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                ##
         | 
| 105 | 
            +
                # Returns a new Timestamp object which is given seconds ahead.
         | 
| 106 | 
            +
                # Even if the suffix is not nil, the new Timestamp object will
         | 
| 107 | 
            +
                # always have nil as its suffix.
         | 
| 108 | 
            +
                #
         | 
| 109 | 
            +
                # :call-seq:
         | 
| 110 | 
            +
                #     +(Integer) -> Timestamp
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                def +(seconds)
         | 
| 113 | 
            +
                  Timestamp.new(@time + seconds, nil)
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                ##
         | 
| 117 | 
            +
                # Returns difference of seconds between self and an argument.  If
         | 
| 118 | 
            +
                # the argument is an Integer object, returns a new Timestamp
         | 
| 119 | 
            +
                # object which is the given seconds behind.
         | 
| 120 | 
            +
                #
         | 
| 121 | 
            +
                # Even if the suffix is not nil, the new Timestamp object will
         | 
| 122 | 
            +
                # always have nil as its suffix.
         | 
| 123 | 
            +
                #
         | 
| 124 | 
            +
                # :call-seq:
         | 
| 125 | 
            +
                #     -(Time) -> Float
         | 
| 126 | 
            +
                #     -(Timetamp) -> Float
         | 
| 127 | 
            +
                #     -(Integer) -> Timestamp
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                def -(arg)
         | 
| 130 | 
            +
                  case arg
         | 
| 131 | 
            +
                  when Time
         | 
| 132 | 
            +
                    @time - arg
         | 
| 133 | 
            +
                  when Timestamp
         | 
| 134 | 
            +
                    @time - arg.time
         | 
| 135 | 
            +
                  when Integer
         | 
| 136 | 
            +
                    Timestamp.new(@time - arg, nil)
         | 
| 137 | 
            +
                  when NilClass
         | 
| 138 | 
            +
                    raise TypeError, "can't convert nil into an exact number"
         | 
| 139 | 
            +
                  else
         | 
| 140 | 
            +
                    raise ArgumentError, arg
         | 
| 141 | 
            +
                  end
         | 
| 142 | 
            +
                end
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                ##
         | 
| 145 | 
            +
                # Generates an array contains components of the Timestamp object.
         | 
| 146 | 
            +
                # Components means "year", "mon", "day", "hour", "min", "sec", and
         | 
| 147 | 
            +
                # "suffix".
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                def to_a
         | 
| 150 | 
            +
                  a = [:year, :mon, :day, :hour, :min, :sec, :suffix].map { |s| self.send(s) }
         | 
| 151 | 
            +
                  a.delete_at(-1) if a[-1].nil?
         | 
| 152 | 
            +
                  a
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                # :stopdoc:
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                # delegators to String object
         | 
| 158 | 
            +
                
         | 
| 159 | 
            +
                def_instance_delegators :@str, :size, :length
         | 
| 160 | 
            +
                def_instance_delegators :@str, :include?, :match, :match?
         | 
| 161 | 
            +
             | 
| 162 | 
            +
                # :startdoc:
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                ##
         | 
| 165 | 
            +
                # Returns a character or sub-string specified with args.
         | 
| 166 | 
            +
                #
         | 
| 167 | 
            +
                # Following type of objects could be used as args:
         | 
| 168 | 
            +
                #
         | 
| 169 | 
            +
                # - Integer          : specifies an index
         | 
| 170 | 
            +
                # - Integer, Integer : specified an start index and length of sub-string
         | 
| 171 | 
            +
                # - Range            : specified range of sub-string
         | 
| 172 | 
            +
                # - Symbol           : specified a type of part
         | 
| 173 | 
            +
                #
         | 
| 174 | 
            +
                # Following symbols could be specified:
         | 
| 175 | 
            +
                #
         | 
| 176 | 
            +
                # - :year
         | 
| 177 | 
            +
                # - :mon, or :month
         | 
| 178 | 
            +
                # - :day
         | 
| 179 | 
            +
                # - :hour
         | 
| 180 | 
            +
                # - :min
         | 
| 181 | 
            +
                # - :sec
         | 
| 182 | 
            +
                # - :suffix
         | 
| 183 | 
            +
                #
         | 
| 184 | 
            +
                # :call-seq:
         | 
| 185 | 
            +
                #     self[nth as Integer] -> String | nil
         | 
| 186 | 
            +
                #     self[nth as Integer, len as Integer] -> String | nil
         | 
| 187 | 
            +
                #     self[range as Range] -> String
         | 
| 188 | 
            +
                #     self[symbol as Symbol] -> String
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                def [](*args)
         | 
| 191 | 
            +
                  raise ArgumentError, "wrong number of arguments (given %s, execpted 1..2)" % args.size unless (1..2).include?(args.size)
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                  arg = args[0]
         | 
| 194 | 
            +
                  case arg
         | 
| 195 | 
            +
                  when Symbol, String
         | 
| 196 | 
            +
                    key = arg.to_sym
         | 
| 197 | 
            +
                    if key == :suffix
         | 
| 198 | 
            +
                      @suffix.nil? ? nil : FMTSTRS[key] % @suffix
         | 
| 199 | 
            +
                    elsif FMTSTRS.keys.include?(key)
         | 
| 200 | 
            +
                      @time.strftime(FMTSTRS[key])
         | 
| 201 | 
            +
                    else
         | 
| 202 | 
            +
                      nil
         | 
| 203 | 
            +
                    end
         | 
| 204 | 
            +
                  else
         | 
| 205 | 
            +
                    @str[*args]
         | 
| 206 | 
            +
                  end
         | 
| 207 | 
            +
                end
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                alias slice []
         | 
| 210 | 
            +
             | 
| 211 | 
            +
                ##
         | 
| 212 | 
            +
                # Returns a Timestamp object which has a next Time object.
         | 
| 213 | 
            +
                #
         | 
| 214 | 
            +
                # If true was passed as an argument, use incremented suffix as
         | 
| 215 | 
            +
                # base instead of a next Time object.
         | 
| 216 | 
            +
                #
         | 
| 217 | 
            +
                # For example,
         | 
| 218 | 
            +
                #
         | 
| 219 | 
            +
                #     "20201110160100"     -> "20201110160101"     (false as arg)
         | 
| 220 | 
            +
                #     "20201110160100"     -> "20201110160100_001" (true as arg)
         | 
| 221 | 
            +
                #     "20201110160200_001" -> "20201110160201"     (false as arg)
         | 
| 222 | 
            +
                #     "20201110160200_001" -> "20201110160200_002" (true as arg)
         | 
| 223 | 
            +
                #
         | 
| 224 | 
            +
                # If suffix was 999 before call this method, raises
         | 
| 225 | 
            +
                # ArgumentRangeError.
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                def next(use_suffix = nil)
         | 
| 228 | 
            +
                  if use_suffix
         | 
| 229 | 
            +
                    Timestamp.new(@time, increase_suffix(@suffix.to_i, 1))
         | 
| 230 | 
            +
                  else
         | 
| 231 | 
            +
                    Timestamp.new(@time + 1, nil)
         | 
| 232 | 
            +
                  end
         | 
| 233 | 
            +
                end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                alias succ next
         | 
| 236 | 
            +
             | 
| 237 | 
            +
                ##
         | 
| 238 | 
            +
                # Updates the time value to a next Time destructively.  See the
         | 
| 239 | 
            +
                # document for Timestamp#next for more details.
         | 
| 240 | 
            +
                #
         | 
| 241 | 
            +
                # If suffix was 999 before call this method, raises
         | 
| 242 | 
            +
                # ArgumentRangeError.
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                def next!(use_suffix = nil)
         | 
| 245 | 
            +
                  if use_suffix
         | 
| 246 | 
            +
                    @suffix = increase_suffix(@suffix.to_i, 1)
         | 
| 247 | 
            +
                  else
         | 
| 248 | 
            +
                    @time += 1
         | 
| 249 | 
            +
                    @suffix = nil
         | 
| 250 | 
            +
                  end
         | 
| 251 | 
            +
                  @str = time_to_str(@time, @suffix)
         | 
| 252 | 
            +
                  self
         | 
| 253 | 
            +
                end
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                alias succ! next!
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                ##
         | 
| 258 | 
            +
                # Splits the timestamp string into array of time parts, such as
         | 
| 259 | 
            +
                # year, month, day, hour, minute, and second.  Then, returns the
         | 
| 260 | 
            +
                # array.
         | 
| 261 | 
            +
                #
         | 
| 262 | 
            +
                # When a block was passed, it would apply to each part of the
         | 
| 263 | 
            +
                # array.  Then, returns self.
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                def split(_ = $;, _ = 0, &blk)
         | 
| 266 | 
            +
                  parts = Timestamp.split_stamp(@str)
         | 
| 267 | 
            +
                  if blk.nil?
         | 
| 268 | 
            +
                    parts
         | 
| 269 | 
            +
                  else
         | 
| 270 | 
            +
                    parts.each { |p| yield p }
         | 
| 271 | 
            +
                    self
         | 
| 272 | 
            +
                  end
         | 
| 273 | 
            +
                end
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                # :stopdoc:
         | 
| 276 | 
            +
             | 
| 277 | 
            +
                def initialize_copy(_)
         | 
| 278 | 
            +
                  @time = @time.dup
         | 
| 279 | 
            +
                  @suffix = @suffix
         | 
| 280 | 
            +
                  @str = @str.dup
         | 
| 281 | 
            +
                end
         | 
| 282 | 
            +
             | 
| 283 | 
            +
                def freeze;  @time.freeze;  @suffix.freeze;  @str.freeze;  end
         | 
| 284 | 
            +
                def taint;   @time.taint;   @suffix.taint;   @str.taint;   end
         | 
| 285 | 
            +
                def untaint; @time.untaint; @suffix.untaint; @str.untaint; end
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                private
         | 
| 288 | 
            +
             | 
| 289 | 
            +
                def is_valid_suffix?(suffix)
         | 
| 290 | 
            +
                  suffix.nil? || (0..999).include?(suffix)
         | 
| 291 | 
            +
                end
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                def increase_suffix(suffix, num)
         | 
| 294 | 
            +
                  increased = suffix + num
         | 
| 295 | 
            +
                  raise ArgumentRangeError, suffix unless is_valid_suffix?(increased)
         | 
| 296 | 
            +
                  increased
         | 
| 297 | 
            +
                end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                def time_to_str(time, suffix = nil)
         | 
| 61 300 | 
             
                  s = @time.strftime("%Y%m%d%H%M%S")
         | 
| 62 301 | 
             
                  s += "_#{"%03u" % @suffix}" unless @suffix.nil? || @suffix == 0
         | 
| 63 302 | 
             
                  s
         | 
| 64 303 | 
             
                end
         | 
| 65 304 |  | 
| 305 | 
            +
                FMTSTRS = {
         | 
| 306 | 
            +
                  :year => "%Y", :mon => "%m", :month => "%m", :day => "%d",
         | 
| 307 | 
            +
                  :hour => "%H", :min => "%M", :sec => "%S", :suffix => "%03u",
         | 
| 308 | 
            +
                }
         | 
| 309 | 
            +
             | 
| 310 | 
            +
                # :startdoc:
         | 
| 66 311 | 
             
                class << self
         | 
| 312 | 
            +
             | 
| 313 | 
            +
                  ##
         | 
| 314 | 
            +
                  # Returns a Timestamp object generated from the current time.
         | 
| 315 | 
            +
             | 
| 316 | 
            +
                  def now(suffix = nil)
         | 
| 317 | 
            +
                    Timestamp.new(Time.now, suffix)
         | 
| 318 | 
            +
                  end
         | 
| 319 | 
            +
             | 
| 67 320 | 
             
                  ##
         | 
| 68 321 | 
             
                  # Splits a string which represents a timestamp into components.
         | 
| 69 322 | 
             
                  # Each component represents a part of constructs to instantiate
         | 
| @@ -79,7 +332,8 @@ module Textrepo | |
| 79 332 | 
             
                    raise InvalidTimestampStringError, stamp_str if stamp_str.nil?
         | 
| 80 333 | 
             
                    #    yyyy  mo    dd    hh    mi      ss      sfx
         | 
| 81 334 | 
             
                    a = [0..3, 4..5, 6..7, 8..9, 10..11, 12..13, 15..17].map {|r| stamp_str[r]}
         | 
| 82 | 
            -
                    a[-1].nil? | 
| 335 | 
            +
                    a.delete_at(-1) if a[-1].nil?
         | 
| 336 | 
            +
                    a
         | 
| 83 337 | 
             
                  end
         | 
| 84 338 |  | 
| 85 339 | 
             
                  ##
         | 
| @@ -98,10 +352,17 @@ module Textrepo | |
| 98 352 | 
             
                      ye, mo, da, ho, mi, se, sfx = split_stamp(stamp_str).map(&:to_i)
         | 
| 99 353 | 
             
                      Timestamp.new(Time.new(ye, mo, da, ho, mi, se), sfx)
         | 
| 100 354 | 
             
                    rescue InvalidTimestampStringError, ArgumentError => _
         | 
| 101 | 
            -
                       | 
| 355 | 
            +
                      emsg = if stamp_str.nil?
         | 
| 356 | 
            +
                        "(nil)"
         | 
| 357 | 
            +
                      elsif stamp_str.empty?
         | 
| 358 | 
            +
                        "(empty string)"
         | 
| 359 | 
            +
                      else
         | 
| 360 | 
            +
                        stamp_str
         | 
| 361 | 
            +
                      end
         | 
| 362 | 
            +
                      raise InvalidTimestampStringError, emsg
         | 
| 102 363 | 
             
                    end
         | 
| 103 364 | 
             
                  end
         | 
| 104 | 
            -
             | 
| 105 365 | 
             
                end
         | 
| 366 | 
            +
             | 
| 106 367 | 
             
              end
         | 
| 107 368 | 
             
            end
         | 
    
        data/lib/textrepo/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: textrepo
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.5. | 
| 4 | 
            +
              version: 0.5.5
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - mnbi
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2020-11- | 
| 11 | 
            +
            date: 2020-11-10 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         |