textrepo 0.5.2 → 0.5.7
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 +29 -2
- data/lib/textrepo/error.rb +15 -4
- data/lib/textrepo/file_system_repository.rb +29 -38
- data/lib/textrepo/repository.rb +72 -6
- data/lib/textrepo/timestamp.rb +259 -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: b85b70f9d672503576cbce911f202dac9d00cf8af3915109f304c4c2745ce32f
|
4
|
+
data.tar.gz: 9ca1decf965281c4f1a34b908a919478aafc915293412b3a9fa6e4903f57de45
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c24a75691c34d72dae4e33c13a22c7dc4a04539d29edcfafa31b93815b8fada5b0c7840f0c90b32b461eb925d28c32d0918dc65a5bda05592379d6f02ddd4bc
|
7
|
+
data.tar.gz: bc16b111bf4bc9cc7ca62942025961ac572ee892925bcce0f6a6b8c2e78ea664affbbcb18d79832cd4168fcaf62b57410f0c058c315e600750e6e348d5541153
|
data/CHANGELOG.md
CHANGED
@@ -7,8 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
## [Unreleased]
|
8
8
|
Nothing to record here.
|
9
9
|
|
10
|
+
## [0.5.7] - 2020-11-16
|
11
|
+
### Fixed
|
12
|
+
- Fix issue #47: mmdd pattern matches incorrectly (`#entries`).
|
13
|
+
|
14
|
+
## [0.5.6] - 2020-11-11
|
15
|
+
### Add
|
16
|
+
- Change `Repository` to enumerable.
|
17
|
+
- add `#each` method to `Repository`, then include `Enumerable`.
|
18
|
+
- Add "-H" option to some searcher default options.
|
19
|
+
|
20
|
+
## [0.5.5] - 2020-11-10
|
21
|
+
### Add
|
22
|
+
- Add more methods for `Timestamp` class.
|
23
|
+
- most of them are delegated to Time class
|
24
|
+
- some of them are useful to manipulate `Timestamp` object as
|
25
|
+
`String`.
|
26
|
+
|
27
|
+
## [0.5.4] - 2020-11-05
|
28
|
+
### Add
|
29
|
+
- Add a feature for `Repository#update` to keep timestamp unchanged
|
30
|
+
- add the third argument as:
|
31
|
+
- `Repository#update(timestamp, text, keep_stamp = false)`
|
32
|
+
|
33
|
+
## [0.5.3] - 2020-11-03
|
34
|
+
### Fixed
|
35
|
+
- Fix issue #38: fix typo in code for FileSystemRepository.
|
36
|
+
|
10
37
|
## [0.5.2] - 2020-11-03
|
11
|
-
###
|
38
|
+
### Fixed
|
12
39
|
- Fix issue #34:
|
13
40
|
- fix FileSystemRepository#entries to accept "yyyymo" pattern as a
|
14
41
|
Timestamp pattern.
|
@@ -16,7 +43,7 @@ Nothing to record here.
|
|
16
43
|
- Fix issue #31: unfriendly error message of Timestamp.parse_s.
|
17
44
|
|
18
45
|
## [0.5.1] - 2020-11-02
|
19
|
-
###
|
46
|
+
### Fixed
|
20
47
|
- Fix issue #28.
|
21
48
|
- Modify `Repository#update` to do nothing when the given text is
|
22
49
|
identical to the one in the repository.
|
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.
|
@@ -130,30 +130,32 @@ module Textrepo
|
|
130
130
|
end
|
131
131
|
|
132
132
|
##
|
133
|
-
# Updates the file content in the repository. A new
|
134
|
-
# 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.
|
135
140
|
#
|
136
141
|
# See the documentation of Repository#update to know about errors
|
137
142
|
# and constraints of this method.
|
138
143
|
#
|
139
144
|
# :call-seq:
|
140
|
-
# update(Timestamp, Array) -> Timestamp
|
145
|
+
# update(Timestamp, Array, true or false) -> Timestamp
|
141
146
|
|
142
|
-
def update(timestamp, text)
|
147
|
+
def update(timestamp, text, keep_stamp = false)
|
143
148
|
raise EmptyTextError if text.empty?
|
144
149
|
raise MissingTimestampError, timestamp unless exist?(timestamp)
|
145
150
|
|
146
151
|
# does nothing if given text is the same in the repository one
|
147
152
|
return timestamp if read(timestamp) == text
|
148
153
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# delete the original text file in the repository
|
154
|
-
FileUtils.remove_file(abspath(timestamp))
|
154
|
+
stamp = keep_stamp ? timestamp : Timestamp.new(Time.now)
|
155
|
+
write_text(abspath(stamp), text)
|
156
|
+
FileUtils.remove_file(abspath(timestamp)) unless keep_stamp
|
155
157
|
|
156
|
-
|
158
|
+
stamp
|
157
159
|
end
|
158
160
|
|
159
161
|
##
|
@@ -188,7 +190,7 @@ module Textrepo
|
|
188
190
|
results << stamp
|
189
191
|
end
|
190
192
|
when 0, "yyyymoddhhmiss".size, "yyyymodd".size, "yyyymo".size
|
191
|
-
results += find_entries(stamp_pattern)
|
193
|
+
results += find_entries("#{stamp_pattern}*")
|
192
194
|
when 4 # "yyyy" or "modd"
|
193
195
|
pat = nil
|
194
196
|
# The following distinction is practically correct, but not
|
@@ -197,10 +199,10 @@ module Textrepo
|
|
197
199
|
# any text (I believe...).
|
198
200
|
if stamp_pattern.to_i > 1231
|
199
201
|
# yyyy
|
200
|
-
pat = stamp_pattern
|
202
|
+
pat = "#{stamp_pattern}*"
|
201
203
|
else
|
202
204
|
# modd
|
203
|
-
pat = "
|
205
|
+
pat = "????#{stamp_pattern}*"
|
204
206
|
end
|
205
207
|
results += find_entries(pat)
|
206
208
|
end
|
@@ -268,7 +270,7 @@ module Textrepo
|
|
268
270
|
end
|
269
271
|
|
270
272
|
def find_entries(stamp_pattern)
|
271
|
-
Dir.glob("#{@path}/**/#{stamp_pattern}
|
273
|
+
Dir.glob("#{@path}/**/#{stamp_pattern}.#{@extname}").map { |e|
|
272
274
|
begin
|
273
275
|
Timestamp.parse_s(timestamp_str(e))
|
274
276
|
rescue InvalidTimestampStringError => _
|
@@ -315,20 +317,7 @@ module Textrepo
|
|
315
317
|
def invoke_searcher_for_entries(searcher, pattern, entries)
|
316
318
|
output = []
|
317
319
|
|
318
|
-
|
319
|
-
if num_of_entries == 1
|
320
|
-
# If the search taget is one file, the output needs special
|
321
|
-
# treatment.
|
322
|
-
file = abspath(entries[0])
|
323
|
-
o, s = Open3.capture2(searcher, *find_searcher_options(searcher),
|
324
|
-
pattern, file)
|
325
|
-
if s.success? && (! o.empty)
|
326
|
-
output += o.lines.map { |line|
|
327
|
-
# add filename at the beginning of the search result line
|
328
|
-
[file, line.chomp].join(":")
|
329
|
-
}
|
330
|
-
end
|
331
|
-
elsif num_of_entries > LIMIT_OF_FILES
|
320
|
+
if entries.size > LIMIT_OF_FILES
|
332
321
|
output += invoke_searcher_for_entries(searcher, pattern, entries[0..(LIMIT_OF_FILES - 1)])
|
333
322
|
output += invoke_searcher_for_entries(searcher, pattern, entries[LIMIT_OF_FILES..-1])
|
334
323
|
else
|
@@ -338,7 +327,7 @@ module Textrepo
|
|
338
327
|
files = find_files(entries)
|
339
328
|
o, s = Open3.capture2(searcher, *find_searcher_options(searcher),
|
340
329
|
pattern, *files)
|
341
|
-
if s.success? && (! o.empty)
|
330
|
+
if s.success? && (! o.empty?)
|
342
331
|
output += o.lines.map(&:chomp)
|
343
332
|
end
|
344
333
|
end
|
@@ -347,14 +336,16 @@ module Textrepo
|
|
347
336
|
end
|
348
337
|
|
349
338
|
SEARCHER_OPTS = {
|
350
|
-
#
|
351
|
-
|
352
|
-
#
|
353
|
-
|
354
|
-
#
|
355
|
-
|
356
|
-
|
357
|
-
"
|
339
|
+
# grep option meaning:
|
340
|
+
# - "-i": case insensitive,
|
341
|
+
# - "-n": print line number,
|
342
|
+
# - "-H": print file name,
|
343
|
+
# - "-R": recursive search,
|
344
|
+
# - "-E": work as egrep
|
345
|
+
"grep" => ["-i", "-n", "-H", "-R", "-E"],
|
346
|
+
"egrep" => ["-i", "-n", "-H", "-R"],
|
347
|
+
"ggrep" => ["-i", "-n", "-H", "-R", "-E"],
|
348
|
+
"gegrep" => ["-i", "-n", "-H", "-R"],
|
358
349
|
# smart case, print line number, no color
|
359
350
|
"rg" => ["-S", "-n", "--no-heading", "--color", "never"],
|
360
351
|
}
|
data/lib/textrepo/repository.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Textrepo
|
2
2
|
class Repository
|
3
3
|
|
4
|
+
include Enumerable
|
5
|
+
|
4
6
|
##
|
5
7
|
# Repository type. It specifies which concrete repository class
|
6
8
|
# will instantiated. For example, the type `:file_system` specifies
|
@@ -44,11 +46,16 @@ module Textrepo
|
|
44
46
|
|
45
47
|
##
|
46
48
|
# Updates the content with given text in the repository, which is
|
47
|
-
# associated to the given
|
48
|
-
# generated during the execution.
|
49
|
+
# associated to the given Timestamp object. Returns the Timestamp
|
50
|
+
# newly generated during the execution.
|
51
|
+
#
|
52
|
+
# When true is passed as the third argument, keeps the Timestamp
|
53
|
+
# unchanged, though updates the content. Then, returns the given
|
54
|
+
# Timestamp object.
|
49
55
|
#
|
50
|
-
# If the given Timestamp is not existed as a Timestamp
|
51
|
-
# text in the repository, raises
|
56
|
+
# If the given Timestamp object is not existed as a Timestamp
|
57
|
+
# attached to text in the repository, raises
|
58
|
+
# MissingTimestampError.
|
52
59
|
#
|
53
60
|
# If the given text is empty, raises EmptyTextError.
|
54
61
|
#
|
@@ -56,9 +63,9 @@ module Textrepo
|
|
56
63
|
# does nothing. Returns the given timestamp itself.
|
57
64
|
#
|
58
65
|
# :call-seq:
|
59
|
-
# update(Timestamp, Array) -> Timestamp
|
66
|
+
# update(Timestamp, Array, true or false) -> Timestamp
|
60
67
|
|
61
|
-
def update(timestamp, text); timestamp; end
|
68
|
+
def update(timestamp, text, keep_stamp = false); timestamp; end
|
62
69
|
|
63
70
|
##
|
64
71
|
# Deletes the content in the repository, which is associated to
|
@@ -120,6 +127,65 @@ module Textrepo
|
|
120
127
|
|
121
128
|
def search(pattern, stamp_pattern = nil); []; end
|
122
129
|
|
130
|
+
##
|
131
|
+
# Calls the given block once for each pair of timestamp and text
|
132
|
+
# in self, passing those pair as parameter. Returns the
|
133
|
+
# repository itself.
|
134
|
+
#
|
135
|
+
# If no block is given, an Enumerator is returned.
|
136
|
+
|
137
|
+
def each(&block)
|
138
|
+
if block.nil?
|
139
|
+
entries.lazy.map { |timestamp| pair(timestamp) }.to_enum(:each)
|
140
|
+
else
|
141
|
+
entries.each { |timestamp| yield pair(timestamp) }
|
142
|
+
self
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
alias each_pair each
|
147
|
+
|
148
|
+
##
|
149
|
+
# Calls the given block once for each timestamp in self, passing
|
150
|
+
# the timestamp as a parameter. Returns the repository itself.
|
151
|
+
#
|
152
|
+
# If no block is given, an Enumerator is returned.
|
153
|
+
|
154
|
+
def each_key(&block)
|
155
|
+
if block.nil?
|
156
|
+
entries.to_enum(:each)
|
157
|
+
else
|
158
|
+
entries.each(&block)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
alias each_timestamp each_key
|
163
|
+
|
164
|
+
##
|
165
|
+
# Calls the given block once for each timestamp in self, passing
|
166
|
+
# the text as a parameter. Returns the repository itself.
|
167
|
+
#
|
168
|
+
# If no block is given, an Enumerator is returned.
|
169
|
+
|
170
|
+
def each_value(&block)
|
171
|
+
if block.nil?
|
172
|
+
entries.lazy.map { |timestamp| read(timestamp) }.to_enum(:each)
|
173
|
+
else
|
174
|
+
entries.each { |timestamp| yield read(timestamp) }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
alias each_text each_value
|
179
|
+
|
180
|
+
# :stopdoc:
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def pair(timestamp)
|
185
|
+
[timestamp, read(timestamp)]
|
186
|
+
end
|
187
|
+
|
188
|
+
# :startdoc:
|
123
189
|
end
|
124
190
|
|
125
191
|
require_relative 'file_system_repository'
|
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
|
##
|
@@ -97,7 +351,7 @@ module Textrepo
|
|
97
351
|
begin
|
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
|
-
rescue InvalidTimestampStringError, ArgumentError =>
|
354
|
+
rescue InvalidTimestampStringError, ArgumentError => _
|
101
355
|
emsg = if stamp_str.nil?
|
102
356
|
"(nil)"
|
103
357
|
elsif stamp_str.empty?
|
@@ -108,7 +362,7 @@ module Textrepo
|
|
108
362
|
raise InvalidTimestampStringError, emsg
|
109
363
|
end
|
110
364
|
end
|
111
|
-
|
112
365
|
end
|
366
|
+
|
113
367
|
end
|
114
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.7
|
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-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|