file_pipeline 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +12 -10
- data/lib/file_pipeline/errors/failed_modification_error.rb +45 -13
- data/lib/file_pipeline/versioned_file.rb +42 -75
- data/lib/file_pipeline/versions/history.rb +106 -0
- data/lib/file_pipeline/versions.rb +22 -0
- data/lib/file_pipeline.rb +1 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b25bf4205819b6d0df2fcbb9a879c7855fc2b0a3cb973774049f44a7d6965b8
|
4
|
+
data.tar.gz: 1191020063c4bb7669e9dfd88a03d539c7b081cd2f422decd87ac6bca288c86e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ccb8dabb09322d7c3b6b258c8e4e06edb3a7774e36c1fc26421794b8c53915b219a85c8c9bf07da2bf203cd949a8fc484a1db1cb8ddf6d8443a5c2ba724d4ff
|
7
|
+
data.tar.gz: 3e5a2ec367ab3a2d7280c9d6daaa41f6e3cadcba9b1b73bfdb891d4fef781bade2e4e5ffe970aee76e175ce43ea3ae82d967367f18b29f59dbffec180825262e
|
data/README.rdoc
CHANGED
@@ -54,7 +54,7 @@ instructions on how to create custom operations).
|
|
54
54
|
==== Basic set up with default operations
|
55
55
|
|
56
56
|
To define an operation, pass the class name of the operation in underscore
|
57
|
-
notation
|
57
|
+
notation without the containing module name, and any options to
|
58
58
|
{#define_operation}[rdoc-ref:FilePipeline::Pipeline#define_operation].
|
59
59
|
|
60
60
|
The example below adds an instance of
|
@@ -87,8 +87,9 @@ call <tt>#define_operation</tt> with the desired operations and options.
|
|
87
87
|
|
88
88
|
When file operations are to be used that are not included in the gem, place
|
89
89
|
the source files for the class definitions in one or more directories and
|
90
|
-
initialize the Pipeline object with the
|
91
|
-
be added to the
|
90
|
+
initialize the Pipeline object with the paths to those directories. The
|
91
|
+
directories will be added to the
|
92
|
+
{source directories}[rdoc-ref:FilePipeline.source_directories].
|
92
93
|
|
93
94
|
Directories are added to the source directories in reverse order, so that
|
94
95
|
directories added later will have precedence when searching source files. The
|
@@ -103,7 +104,7 @@ finally in the included default operations.
|
|
103
104
|
|
104
105
|
The basename for source files _must_ be the class name in underscore notation
|
105
106
|
without the containing module name. If, for example, the operation is
|
106
|
-
<tt>FileOperations::MyOperation</tt>, the source file basename
|
107
|
+
<tt>FileOperations::MyOperation</tt>, the source file basename has to be
|
107
108
|
<tt>'my_operation.rb'</tt>
|
108
109
|
|
109
110
|
my_pipeline = FilePipeline::Pipeline.new('~/custom_operations',
|
@@ -146,7 +147,7 @@ VersionedFile provides access to a files metadata via the
|
|
146
147
|
{#metadata}[rdoc-ref:FilePipeline::VersionedFile#metadata] method of the
|
147
148
|
versioned file instance.
|
148
149
|
|
149
|
-
|
150
|
+
Metadata for the original file, the current (latest) or an arbitrary version can
|
150
151
|
be accessed:
|
151
152
|
|
152
153
|
image = FilePipeline::VersionedFile.new('~/image.jpg')
|
@@ -167,12 +168,13 @@ versions available, pass the <tt>:for_version</tt> option with the symbol
|
|
167
168
|
|
168
169
|
Some file operations can comprise metadata; many image processing libraries
|
169
170
|
will not preserve all _Exif_ tags and their values when converting images to
|
170
|
-
a different format, but only write a
|
171
|
-
|
171
|
+
a different format, but only write a subset of tags to the file they create.
|
172
|
+
In these cases, the
|
172
173
|
{ExifRestoration}[rdoc-ref:FilePipeline::FileOperations::ExifRestoration]
|
173
|
-
operation can be used to try to restore the tags that have been discarded
|
174
|
-
|
175
|
-
not write back to the file
|
174
|
+
operation can be used to try to restore the tags that have been discarded. The
|
175
|
+
operation uses Exiftool to write tags, and Exiftool will not write all tags.
|
176
|
+
It will store any tags and their values that it could not write back to the file
|
177
|
+
and return them as captured data.
|
176
178
|
|
177
179
|
Likewise, if the
|
178
180
|
{ExifRedaction}[rdoc-ref:FilePipeline::FileOperations::ExifRedaction] is applied
|
@@ -8,32 +8,64 @@ module FilePipeline
|
|
8
8
|
# The file opration that caused the error.
|
9
9
|
attr_reader :info
|
10
10
|
|
11
|
-
#
|
11
|
+
# Returns a new instance.
|
12
|
+
#
|
13
|
+
# ===== Arguments
|
14
|
+
#
|
15
|
+
# * +msg+ - error message for the exception. If none provided, the
|
16
|
+
# instance will be initialized with the #default_message.
|
17
|
+
#
|
18
|
+
# ===== Options
|
19
|
+
#
|
20
|
+
# * <tt>info</tt> - a FileOperations::Results object or an object.
|
21
|
+
# * <tt>file</tt> - path to the file thas was being processed.
|
12
22
|
def initialize(msg = nil, info: nil, file: nil)
|
13
23
|
@file = file
|
14
24
|
@info = info
|
15
|
-
|
16
|
-
if info.respond_to?(:operation) && info.respond_to?(:log)
|
17
|
-
msg ||= "#{@info.operation&.name} with options"\
|
18
|
-
" #{@info.operation&.options} failed on #{file}."
|
19
|
-
if original_error
|
20
|
-
msg += "\nException raised by the operation:"\
|
21
|
-
" #{original_error.inspect}. Backtrace:\n"
|
22
|
-
msg += original_backtrace if original_backtrace
|
23
|
-
end
|
24
|
-
else
|
25
|
-
msg ||= 'Operation failed' unless info
|
26
|
-
end
|
25
|
+
msg ||= default_message
|
27
26
|
super msg
|
28
27
|
end
|
29
28
|
|
29
|
+
# Returns the backtrace of the error that caused the exception.
|
30
30
|
def original_backtrace
|
31
31
|
original_error&.backtrace&.join("\n")
|
32
32
|
end
|
33
33
|
|
34
|
+
# Returns the error that caused the exception.
|
34
35
|
def original_error
|
35
36
|
@info.log.find { |item| item.is_a? Exception }
|
36
37
|
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Appends the backtrace of the error that caused the exception to the
|
42
|
+
# #default_message.
|
43
|
+
def append_backtrace(str)
|
44
|
+
return str + "\n" unless original_backtrace
|
45
|
+
|
46
|
+
str + " Backtrace:\n#{original_backtrace}"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Appends the message of the error that caused the exception to the
|
50
|
+
# #default_message.
|
51
|
+
def append_error(str)
|
52
|
+
return str unless original_error
|
53
|
+
|
54
|
+
str += "\nException raised by the operation:"\
|
55
|
+
" #{original_error.inspect}."
|
56
|
+
append_backtrace str
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns a String with the #message for +self+.
|
60
|
+
def default_message
|
61
|
+
if info&.respond_to?(:operation) && info&.respond_to?(:log)
|
62
|
+
msg = "#{info.operation&.name} with options"\
|
63
|
+
" #{info.operation&.options} failed on #{@file}."
|
64
|
+
append_error msg
|
65
|
+
else
|
66
|
+
'Operation failed'
|
67
|
+
end
|
68
|
+
end
|
37
69
|
end
|
38
70
|
end
|
39
71
|
end
|
@@ -19,6 +19,35 @@ module FilePipeline
|
|
19
19
|
# by #finalize is not replacing the original.
|
20
20
|
attr_reader :target_suffix
|
21
21
|
|
22
|
+
extend Forwardable
|
23
|
+
|
24
|
+
# Returns a two-dimesnional array, where each nested array has two items;
|
25
|
+
# the file operation object and data captured by the operartion (if any).
|
26
|
+
#
|
27
|
+
# <tt>[[description_object, data_or_nil], ...]</tt>
|
28
|
+
delegate captured_data: :history
|
29
|
+
|
30
|
+
# Returns any data captured by <tt>operation_name</tt>.
|
31
|
+
#
|
32
|
+
# If multiple instances of one operation class have modified the file,
|
33
|
+
# pass any +options+ the specific instance of the operation was initialized
|
34
|
+
# with as the optional second argument.
|
35
|
+
delegate captured_data_for: :history
|
36
|
+
|
37
|
+
# Returns an array with all data captured by operations with +tag+.
|
38
|
+
#
|
39
|
+
# Tags are defined in FileOperations::CapturedDataTags
|
40
|
+
delegate captured_data_with: :history
|
41
|
+
|
42
|
+
# Returns an array of triplets (arryas with three items each): the name of
|
43
|
+
# the file operation class (a string), options (a hash), and the actual log
|
44
|
+
# (an array).
|
45
|
+
delegate log: :history
|
46
|
+
|
47
|
+
# Returns an array with paths to the version files of +self+ (excluding
|
48
|
+
# #original).
|
49
|
+
delegate versions: :history
|
50
|
+
|
22
51
|
# Returns a new instance with +file+ as the #original.
|
23
52
|
#
|
24
53
|
# ===== Arguments
|
@@ -41,23 +70,10 @@ module FilePipeline
|
|
41
70
|
|
42
71
|
@original = file
|
43
72
|
@basename = File.basename(file, '.*')
|
44
|
-
@history =
|
73
|
+
@history = Versions::History.new
|
45
74
|
@directory = nil
|
46
75
|
@target_suffix = target_suffix
|
47
|
-
|
48
|
-
|
49
|
-
# Copies the file with path _src_ to <em>/dir/filename</em>.
|
50
|
-
def self.copy(src, dir, filename)
|
51
|
-
dest = FilePipeline.path(dir, filename)
|
52
|
-
FileUtils.cp src, dest
|
53
|
-
dest
|
54
|
-
end
|
55
|
-
|
56
|
-
# Moves the file with path _src_ to <em>/dir/filename</em>.
|
57
|
-
def self.move(src, dir, filename)
|
58
|
-
dest = FilePipeline.path(dir, filename)
|
59
|
-
FileUtils.mv src, dest
|
60
|
-
dest
|
76
|
+
history[original] = nil
|
61
77
|
end
|
62
78
|
|
63
79
|
# Adds a new version to #history and returns _self_.
|
@@ -80,37 +96,6 @@ module FilePipeline
|
|
80
96
|
raise e
|
81
97
|
end
|
82
98
|
|
83
|
-
# Returns a two-dimesnional array, where each nested array has two items;
|
84
|
-
# the file operation object and data captured by the operartion (if any).
|
85
|
-
#
|
86
|
-
# <tt>[[description_object, data_or_nil], ...]</tt>
|
87
|
-
def captured_data
|
88
|
-
filter_history :data
|
89
|
-
end
|
90
|
-
|
91
|
-
# Returns any data captured by <tt>operation_name</tt>.
|
92
|
-
#
|
93
|
-
# If multiple instances of one operation class have modified the file,
|
94
|
-
# pass any +options+ the specific instance of the operation was initialized
|
95
|
-
# with as the optional second argument.
|
96
|
-
def captured_data_for(operation_name, **options)
|
97
|
-
raw_data = captured_data.filter do |operation, _|
|
98
|
-
operation.name == operation_name &&
|
99
|
-
options.all? { |k, v| operation.options[k] == v }
|
100
|
-
end
|
101
|
-
raw_data.map(&:last)
|
102
|
-
end
|
103
|
-
|
104
|
-
# Returns an array with all data captured by operations with +tag+ has.
|
105
|
-
#
|
106
|
-
# Tags are defined in FileOperations::CapturedDataTags
|
107
|
-
def captured_data_with(tag)
|
108
|
-
return unless changed?
|
109
|
-
|
110
|
-
captured_data.select { |operation, _| operation.captured_data_tag == tag }
|
111
|
-
.map(&:last)
|
112
|
-
end
|
113
|
-
|
114
99
|
# Returns +true+ if there are #versions (file has been modified).
|
115
100
|
#
|
116
101
|
# *Warning:* It will also return +true+ if the file has been cloned.
|
@@ -122,7 +107,7 @@ module FilePipeline
|
|
122
107
|
# the file to history, but no FileOperations::Results.
|
123
108
|
def clone
|
124
109
|
filename = FilePipeline.new_basename + current_extension
|
125
|
-
clone_file =
|
110
|
+
clone_file = Versions.copy(current, directory, filename)
|
126
111
|
self << clone_file
|
127
112
|
end
|
128
113
|
|
@@ -161,19 +146,11 @@ module FilePipeline
|
|
161
146
|
yield(self) if block_given?
|
162
147
|
filename = overwrite ? replacing_trarget : preserving_taget
|
163
148
|
FileUtils.rm original if overwrite
|
164
|
-
@original =
|
149
|
+
@original = Versions.copy(current, original_dir, filename)
|
165
150
|
ensure
|
166
151
|
reset
|
167
152
|
end
|
168
153
|
|
169
|
-
# Returns an array of triplets (arryas with three items each): the name of
|
170
|
-
# the file operation class (a string), options (a hash), and the actual log
|
171
|
-
# (an array).
|
172
|
-
def log
|
173
|
-
filter_history(:log)
|
174
|
-
.map { |operation, info| [operation.name, operation.options, info] }
|
175
|
-
end
|
176
|
-
|
177
154
|
# Returns the Exif metadata
|
178
155
|
#
|
179
156
|
# ===== Options
|
@@ -186,10 +163,12 @@ module FilePipeline
|
|
186
163
|
#--
|
187
164
|
# TODO: when file is not an image file, this should return other metadata
|
188
165
|
# than exif.
|
189
|
-
# TODO: implement the option to return metadata for a specif version index
|
190
166
|
#++
|
191
167
|
def metadata(for_version: :current)
|
192
|
-
|
168
|
+
if %i[current original].include? for_version
|
169
|
+
file = public_send(for_version)
|
170
|
+
end
|
171
|
+
file ||= for_version
|
193
172
|
read_exif(file).first
|
194
173
|
end
|
195
174
|
|
@@ -218,29 +197,15 @@ module FilePipeline
|
|
218
197
|
# Returns a hash into which all captured data from file operations with the
|
219
198
|
# FileOperations::CapturedDataTags::DROPPED_EXIF_DATA has been merged.
|
220
199
|
def recovered_metadata
|
200
|
+
return unless changed?
|
221
201
|
captured_data_with(FileOperations::CapturedDataTags::DROPPED_EXIF_DATA)
|
222
202
|
&.reduce({}) { |recovered, data| recovered.merge data }
|
223
203
|
end
|
224
204
|
|
225
|
-
# Returns an array with paths to the version files of +self+ (excluding
|
226
|
-
# #original).
|
227
|
-
def versions
|
228
|
-
history.keys
|
229
|
-
end
|
230
|
-
|
231
205
|
alias touch clone
|
232
206
|
|
233
207
|
private
|
234
208
|
|
235
|
-
# item = :data or :log
|
236
|
-
def filter_history(item)
|
237
|
-
history.inject([]) do |results, (_, info)|
|
238
|
-
next results unless info.respond_to?(item) && info.public_send(item)
|
239
|
-
|
240
|
-
results << [info.operation, info.public_send(item)]
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
209
|
# Returns the filename for a target file that will not overwrite the
|
245
210
|
# original.
|
246
211
|
def preserving_taget
|
@@ -256,16 +221,18 @@ module FilePipeline
|
|
256
221
|
# Deletes the work directory and resets #versions
|
257
222
|
def reset
|
258
223
|
FileUtils.rm_r directory, force: true
|
259
|
-
|
224
|
+
history.clear!
|
260
225
|
end
|
261
226
|
|
262
227
|
# Validates if file exists and has been stored in #directory.
|
263
228
|
def validate(file)
|
229
|
+
return current unless file
|
230
|
+
|
264
231
|
raise Errors::MissingVersionFileError, file: file unless File.exist? file
|
265
232
|
|
266
233
|
return file if File.dirname(file) == directory
|
267
234
|
|
268
|
-
|
235
|
+
Versions.move file, directory, File.basename(file)
|
269
236
|
end
|
270
237
|
|
271
238
|
# Creates the directory containing all version files. Directory name is
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FilePipeline
|
4
|
+
module Versions
|
5
|
+
# History objects keep track of a VersionedFile instances versions names and
|
6
|
+
# any associated logs or data for each version.
|
7
|
+
class History
|
8
|
+
# Returns a new instance.
|
9
|
+
def initialize
|
10
|
+
@entries = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Retrieves the _results_ object for the <tt>version_name</tt>.
|
14
|
+
def [](version_name)
|
15
|
+
@entries[version_name]
|
16
|
+
end
|
17
|
+
|
18
|
+
# Associates the +results+ with the <tt>version_name</tt>.
|
19
|
+
def []=(version_name, results)
|
20
|
+
entry = @entries.fetch version_name, []
|
21
|
+
entry << results
|
22
|
+
@entries[version_name] = entry.compact
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns a two-dimensional array, where each nested array has two items:
|
26
|
+
# * the file operation object
|
27
|
+
# * data captured by the operartion (if any).
|
28
|
+
#
|
29
|
+
# <tt>[[file_operation_object, data_or_nil], ...]</tt>
|
30
|
+
def captured_data
|
31
|
+
filter :data
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns any data captured by <tt>operation_name</tt>.
|
35
|
+
#
|
36
|
+
# If multiple instances of one operation class have modified the file,
|
37
|
+
# pass any +options+ the specific instance of the operation was
|
38
|
+
# initialized with as the optional second argument.
|
39
|
+
def captured_data_for(operation_name, **options)
|
40
|
+
return if empty?
|
41
|
+
|
42
|
+
captured_data.filter { |op, _| matches? op, operation_name, options }
|
43
|
+
.map(&:last)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns an array with all data captured by operations with +tag+.
|
47
|
+
# Returns an empty array if there is no data for +tag+.
|
48
|
+
#
|
49
|
+
# Tags are defined in FileOperations::CapturedDataTags
|
50
|
+
def captured_data_with(tag)
|
51
|
+
captured_data.filter { |op, _| op.captured_data_tag == tag }
|
52
|
+
.map(&:last)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Clears all history entries (version names and associated results).
|
56
|
+
def clear!
|
57
|
+
@entries.clear
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns +true+ if +self+ has no entries (version names and associated
|
61
|
+
# results), +true+ otherwise.
|
62
|
+
def empty?
|
63
|
+
@entries.empty?
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns an array of triplets (arryas with three items each):
|
67
|
+
# * Name of the file operation class (String).
|
68
|
+
# * Options for the file operation instance (Hash).
|
69
|
+
# * The log (Array).
|
70
|
+
def log
|
71
|
+
filter(:log).map { |op, results| [op.name, op.options, results] }
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns a two-dimensional Array where every nested Array will consist
|
75
|
+
# of the version name (file path) at index +0+ and +nil+ or an Array with
|
76
|
+
# all _results_ objects for the version at index +1+:
|
77
|
+
#
|
78
|
+
# <tt>[version_name, [results1, ...]]</tt>
|
79
|
+
def to_a
|
80
|
+
@entries.to_a
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns an array with paths to the version files of +self+ (excluding
|
84
|
+
# #original).
|
85
|
+
def versions
|
86
|
+
@entries.keys
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# Filters entries in self by +item+ (<tt>:log</tt> or <tt>:data</tt>).
|
92
|
+
def filter(item)
|
93
|
+
@entries.values.flatten.select(&item).map do |results|
|
94
|
+
[results.operation, results.public_send(item)]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Returns +true+ if +name+ matches the _name_ attribute of +operation+ and
|
99
|
+
# +options+ matches the options the operation instance is initialized
|
100
|
+
# with.
|
101
|
+
def matches?(operation, name, opts)
|
102
|
+
operation.name == name && opts.all? { |k, v| operation.options[k] == v }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'versions/history'
|
4
|
+
|
5
|
+
module FilePipeline
|
6
|
+
# Module that contains classes to work with VersionedFile.
|
7
|
+
module Versions
|
8
|
+
# Copies the file with path _src_ to <em>/dir/filename</em>.
|
9
|
+
def self.copy(src, dir, filename)
|
10
|
+
dest = FilePipeline.path(dir, filename)
|
11
|
+
FileUtils.cp src, dest
|
12
|
+
dest
|
13
|
+
end
|
14
|
+
|
15
|
+
# Moves the file with path _src_ to <em>/dir/filename</em>.
|
16
|
+
def self.move(src, dir, filename)
|
17
|
+
dest = FilePipeline.path(dir, filename)
|
18
|
+
FileUtils.mv src, dest
|
19
|
+
dest
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/file_pipeline.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_pipeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Stein
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_exiftool
|
@@ -38,7 +38,7 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 2.0.16
|
41
|
-
description: The file_pipeline gem provides a framework
|
41
|
+
description: The file_pipeline gem provides a framework for nondestructive application
|
42
42
|
of file operation batches to files.
|
43
43
|
email: loveablelobster@fastmail.fm
|
44
44
|
executables: []
|
@@ -65,6 +65,8 @@ files:
|
|
65
65
|
- lib/file_pipeline/file_operations/results.rb
|
66
66
|
- lib/file_pipeline/pipeline.rb
|
67
67
|
- lib/file_pipeline/versioned_file.rb
|
68
|
+
- lib/file_pipeline/versions.rb
|
69
|
+
- lib/file_pipeline/versions/history.rb
|
68
70
|
homepage: https://github.com/loveablelobster/file_pipeline
|
69
71
|
licenses:
|
70
72
|
- MIT
|
@@ -77,7 +79,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
79
|
requirements:
|
78
80
|
- - ">="
|
79
81
|
- !ruby/object:Gem::Version
|
80
|
-
version: '
|
82
|
+
version: '2.6'
|
81
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
84
|
requirements:
|
83
85
|
- - ">="
|