textrepo 0.5.1 → 0.5.6
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 +31 -39
- data/lib/textrepo/repository.rb +72 -6
- 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: 0032a2287829a2a4beb5d2561a99f716a04d6d6ea5a2d99da93fed6dfb187eff
|
4
|
+
data.tar.gz: 3af5842649ea9db629117699d44941742104aec93d35b87378d729b8d020ec98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8048e13e77c8aa8be78444b4c3e18aa955636434fb7f15f205f37b039f4c94122515f4481b3a4881923bb37661f8de968e2c80b8bf8fa2d9a101cf19ab7f9341
|
7
|
+
data.tar.gz: 5d1aeda6151c09f0c9249aa6b6d2800f54749b5a1a5050a21e1d56bb1562e4935c5b0755b92be070164acb108db7c7db488a03e0ca4d99c3493adc1b3879f55d
|
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.6] - 2020-11-11
|
11
|
+
### Add
|
12
|
+
- Change `Repository` to enumerable.
|
13
|
+
- add `#each` method to `Repository`, then include `Enumerable`.
|
14
|
+
- Add "-H" option to some searcher default options.
|
15
|
+
|
16
|
+
## [0.5.5] - 2020-11-10
|
17
|
+
### Add
|
18
|
+
- Add more methods for `Timestamp` class.
|
19
|
+
- most of them are delegated to Time class
|
20
|
+
- some of them are useful to manipulate `Timestamp` object as
|
21
|
+
`String`.
|
22
|
+
|
23
|
+
## [0.5.4] - 2020-11-05
|
24
|
+
### Add
|
25
|
+
- Add a feature for `Repository#update` to keep timestamp unchanged
|
26
|
+
- add the third argument as:
|
27
|
+
- `Repository#update(timestamp, text, keep_stamp = false)`
|
28
|
+
|
29
|
+
## [0.5.3] - 2020-11-03
|
30
|
+
### Changed
|
31
|
+
- Fix issue #38: fix typo in code for FileSystemRepository.
|
32
|
+
|
33
|
+
## [0.5.2] - 2020-11-03
|
34
|
+
### Changed
|
35
|
+
- Fix issue #34:
|
36
|
+
- fix FileSystemRepository#entries to accept "yyyymo" pattern as a
|
37
|
+
Timestamp pattern.
|
38
|
+
- Fix issue #33: fix typo in the doc for FileSystemRepository.new.
|
39
|
+
- Fix issue #31: unfriendly error message of Timestamp.parse_s.
|
40
|
+
|
10
41
|
## [0.5.1] - 2020-11-02
|
11
42
|
### Changed
|
12
43
|
- Fix issue #28.
|
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,30 +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.
|
134
140
|
#
|
135
141
|
# See the documentation of Repository#update to know about errors
|
136
142
|
# and constraints of this method.
|
137
143
|
#
|
138
144
|
# :call-seq:
|
139
|
-
# update(Timestamp, Array) -> Timestamp
|
145
|
+
# update(Timestamp, Array, true or false) -> Timestamp
|
140
146
|
|
141
|
-
def update(timestamp, text)
|
147
|
+
def update(timestamp, text, keep_stamp = false)
|
142
148
|
raise EmptyTextError if text.empty?
|
143
149
|
raise MissingTimestampError, timestamp unless exist?(timestamp)
|
144
150
|
|
145
151
|
# does nothing if given text is the same in the repository one
|
146
152
|
return timestamp if read(timestamp) == text
|
147
153
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
# delete the original text file in the repository
|
153
|
-
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
|
154
157
|
|
155
|
-
|
158
|
+
stamp
|
156
159
|
end
|
157
160
|
|
158
161
|
##
|
@@ -186,7 +189,7 @@ module Textrepo
|
|
186
189
|
if exist?(stamp)
|
187
190
|
results << stamp
|
188
191
|
end
|
189
|
-
when 0, "yyyymoddhhmiss".size, "yyyymodd".size
|
192
|
+
when 0, "yyyymoddhhmiss".size, "yyyymodd".size, "yyyymo".size
|
190
193
|
results += find_entries(stamp_pattern)
|
191
194
|
when 4 # "yyyy" or "modd"
|
192
195
|
pat = nil
|
@@ -314,20 +317,7 @@ module Textrepo
|
|
314
317
|
def invoke_searcher_for_entries(searcher, pattern, entries)
|
315
318
|
output = []
|
316
319
|
|
317
|
-
|
318
|
-
if num_of_entries == 1
|
319
|
-
# If the search taget is one file, the output needs special
|
320
|
-
# treatment.
|
321
|
-
file = abspath(entries[0])
|
322
|
-
o, s = Open3.capture2(searcher, *find_searcher_options(searcher),
|
323
|
-
pattern, file)
|
324
|
-
if s.success? && (! o.empty)
|
325
|
-
output += o.lines.map { |line|
|
326
|
-
# add filename at the beginning of the search result line
|
327
|
-
[file, line.chomp].join(":")
|
328
|
-
}
|
329
|
-
end
|
330
|
-
elsif num_of_entries > LIMIT_OF_FILES
|
320
|
+
if entries.size > LIMIT_OF_FILES
|
331
321
|
output += invoke_searcher_for_entries(searcher, pattern, entries[0..(LIMIT_OF_FILES - 1)])
|
332
322
|
output += invoke_searcher_for_entries(searcher, pattern, entries[LIMIT_OF_FILES..-1])
|
333
323
|
else
|
@@ -337,7 +327,7 @@ module Textrepo
|
|
337
327
|
files = find_files(entries)
|
338
328
|
o, s = Open3.capture2(searcher, *find_searcher_options(searcher),
|
339
329
|
pattern, *files)
|
340
|
-
if s.success? && (! o.empty)
|
330
|
+
if s.success? && (! o.empty?)
|
341
331
|
output += o.lines.map(&:chomp)
|
342
332
|
end
|
343
333
|
end
|
@@ -346,14 +336,16 @@ module Textrepo
|
|
346
336
|
end
|
347
337
|
|
348
338
|
SEARCHER_OPTS = {
|
349
|
-
#
|
350
|
-
|
351
|
-
#
|
352
|
-
|
353
|
-
#
|
354
|
-
|
355
|
-
|
356
|
-
"
|
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"],
|
357
349
|
# smart case, print line number, no color
|
358
350
|
"rg" => ["-S", "-n", "--no-heading", "--color", "never"],
|
359
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
|
##
|
@@ -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.6
|
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-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|