file_pipeline 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 626e9aa686a528bc8bbcf08ba8a238cdfbae8d8b56918654cded4156964f831e
4
- data.tar.gz: ffa0eeb52c3af6789362d0886b6f90c1ae03e647f9a94e7323bfe8b9ae71149b
3
+ metadata.gz: 2669b6e193cbdf383b4db7bf1fe9e16a4519cefb152b394e34310ea9690d4ed6
4
+ data.tar.gz: 5c07a106071954420545dfec51b1110f71027614384e77d553f4132322848faa
5
5
  SHA512:
6
- metadata.gz: 577eeca6ca8df866f7521a534219290c3827208d28909c5b2cf1bab4f9dcaa33a5ac4cdd64860365eb4f49105208e95ce73951c24677b1f36563b3b9c8ef98d5
7
- data.tar.gz: a5ce5a25f0be6ee92f2afde5a7b37d52de0ede4063be0b0c1cbb919ba1a3a0bf81b2cdb05dfcde50f875ba9d16afa79865cbc3f69b552df72cf2d73207a324df
6
+ metadata.gz: b193249acfb972b2a0bc167728a2147d9e7c39e4469a4f3808ed9ff23b3db0cdbfa06000e3477a83058918a31174bad854821a95287abfb964965e6db02421d4
7
+ data.tar.gz: 265d513deaf12846e01c767c71a63c481bb0f21a8bc81d7b00e7ba2ea2291afb0c3d99cd9c3830fd37715772a8c807e3455fdfb3c4f14d558e5df5cc9ba52183
data/lib/file_pipeline.rb CHANGED
@@ -33,7 +33,7 @@ module FilePipeline
33
33
  def self.load(file_operation)
34
34
  const = file_operation.split('_').map(&:capitalize).join
35
35
  FilePipeline.load_file(file_operation) unless const_defined? const
36
- const_get 'FileOperations::' + const
36
+ const_get "FileOperations::#{const}"
37
37
  rescue NameError
38
38
  # TODO: implement autogenerating module names from file_operation src path
39
39
  const_get const
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'errors/failed_modification_error'
4
+ require_relative 'errors/misplaced_version_file_error'
4
5
  require_relative 'errors/missing_version_file_error'
5
6
  require_relative 'errors/source_directory_error'
6
7
  require_relative 'errors/source_file_error'
@@ -41,9 +41,9 @@ module FilePipeline
41
41
  # Appends the backtrace of the error that caused the exception to the
42
42
  # #default_message.
43
43
  def append_backtrace(str)
44
- return str + "\n" unless original_backtrace
44
+ return "#{str}\n" unless original_backtrace
45
45
 
46
- str + " Backtrace:\n#{original_backtrace}"
46
+ "#{str} Backtrace:\n#{original_backtrace}"
47
47
  end
48
48
 
49
49
  # Appends the message of the error that caused the exception to the
@@ -58,7 +58,7 @@ module FilePipeline
58
58
 
59
59
  # Returns a String with the #message for +self+.
60
60
  def default_message
61
- if info&.respond_to?(:operation) && info&.respond_to?(:log)
61
+ if info.respond_to?(:operation) && info.respond_to?(:log)
62
62
  msg = "#{info.operation&.name} with options"\
63
63
  " #{info.operation&.options} failed on #{@file}."
64
64
  append_error msg
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FilePipeline
4
+ module Errors
5
+ # Error class for exceptions that are raised when a new version is added,
6
+ # but the file is not in the VersionedFile's working directory.
7
+ class MisplacedVersionFileError < StandardError
8
+ # Path for of the misplaced file for the version.
9
+ attr_reader :file
10
+
11
+ # Path for the directory where the file should have been (the
12
+ # VersionedFile's working directory).
13
+ attr_reader :directory
14
+
15
+ def initialize(msg = nil, file: nil, directory: nil)
16
+ @file = file
17
+ @directory = directory
18
+ msg ||= default_message
19
+ super msg
20
+ end
21
+
22
+ private
23
+
24
+ def default_message
25
+ "File #{File.basename @file} was expected in #{@directory},"\
26
+ " but was in #{File.dirname @file}."
27
+ end
28
+ end
29
+ end
30
+ end
@@ -24,7 +24,7 @@ module FilePipeline
24
24
  end
25
25
 
26
26
  def self.strip_path(str) # :nodoc:
27
- str.sub(%r{ - \/?(\/|[-:.]+|\w+)+\.\w+$}, '')
27
+ str.sub(%r{ - /?(/|[-:.]+|\w+)+\.\w+$}, '')
28
28
  end
29
29
 
30
30
  # Redacts (deletes) all <tt>tags_to_delete</tt> in <tt>out_file</tt>.
@@ -41,10 +41,7 @@ module FilePipeline
41
41
  # Adds a file operation object #file_operations. The object must implement
42
42
  # a _run_ method (see FileOperations::FileOperation#run for details).
43
43
  def <<(file_operation_instance)
44
- unless file_operation_instance.respond_to? :run
45
- raise TypeError, 'File operations must implement a #run method'
46
- end
47
-
44
+ validate file_operation_instance
48
45
  @file_operations << file_operation_instance
49
46
  end
50
47
 
@@ -106,5 +103,15 @@ module FilePipeline
106
103
  operation.run version, directory, original
107
104
  end
108
105
  end
106
+
107
+ private
108
+
109
+ # Raises TypeError if <tt>file_operation_instance</tt> does not implement a
110
+ # #run method.
111
+ def validate(file_operation_instance)
112
+ return file_operation_instance if file_operation_instance.respond_to? :run
113
+
114
+ raise TypeError, 'File operations must implement a #run method'
115
+ end
109
116
  end
110
117
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'versions/validator'
3
4
  module FilePipeline
4
5
  # VersionedFile creates a directory where it stores any versions of _file_.
5
6
  class VersionedFile
@@ -81,14 +82,10 @@ module FilePipeline
81
82
  # <tt>version_info</tt> must be a path to an existing file or an array with
82
83
  # the path and optionally a FileOperations::Results instance:
83
84
  # <tt>['path/to/file', results_object]</tt>.
84
- # Will move the file to #directory if it is in another directory.
85
+ # Will raise MisplacedVersionFileError if it is in another directory.
85
86
  def <<(version_info)
86
- file, info = version_info
87
- if info&.failure
88
- raise Errors::FailedModificationError.new info: info, file: original
89
- end
90
-
91
- version = validate(file)
87
+ version, info = Versions::Validator[version_info, self]
88
+ version ||= @current
92
89
  @history[version] = info
93
90
  self
94
91
  rescue StandardError => e
@@ -146,7 +143,7 @@ module FilePipeline
146
143
  yield(self) if block_given?
147
144
  return original unless changed?
148
145
 
149
- filename = overwrite ? replacing_trarget : preserving_taget
146
+ filename = overwrite ? replacing_target : preserving_target
150
147
  FileUtils.rm original if overwrite
151
148
  @original = Versions.copy(current, original_dir, filename)
152
149
  ensure
@@ -167,10 +164,12 @@ module FilePipeline
167
164
  # than exif.
168
165
  #++
169
166
  def metadata(for_version: :current)
170
- if %i[current original].include? for_version
171
- file = public_send(for_version)
172
- end
173
- file ||= for_version
167
+ file = case for_version
168
+ when :current, :original
169
+ public_send for_version
170
+ else
171
+ for_version
172
+ end
174
173
  read_exif(file).first
175
174
  end
176
175
 
@@ -211,13 +210,13 @@ module FilePipeline
211
210
 
212
211
  # Returns the filename for a target file that will not overwrite the
213
212
  # original.
214
- def preserving_taget
215
- basename + '_' + target_suffix + current_extension
213
+ def preserving_target
214
+ "#{basename}_#{target_suffix}#{current_extension}"
216
215
  end
217
216
 
218
217
  # Returns the filename for a target file that will overwrite the
219
218
  # original.
220
- def replacing_trarget
219
+ def replacing_target
221
220
  basename + current_extension
222
221
  end
223
222
 
@@ -227,27 +226,13 @@ module FilePipeline
227
226
  history.clear!
228
227
  end
229
228
 
230
- # Validates if file exists and has been stored in #directory.
231
- def validate(file)
232
- return current unless file
233
-
234
- unless File.exist? file
235
- raise Errors::MissingVersionFileError.new file: file
236
- end
237
-
238
- return file if File.dirname(file) == directory
239
-
240
- Versions.move file, directory, File.basename(file)
241
- end
242
-
243
229
  # Creates the directory containing all version files. Directory name is
244
230
  # composed of the basename plus '_version'.
245
231
  #
246
232
  # Raises SystemCallError if the directory already exists.
247
233
  def workdir
248
- subdir = basename + '_versions'
249
234
  filedir = File.dirname(original)
250
- dirname = File.join filedir, subdir
235
+ dirname = File.join filedir, "#{basename}_versions"
251
236
  FileUtils.mkdir(dirname)
252
237
  File.path dirname
253
238
  end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FilePipeline
4
+ module Versions
5
+ # Validator objects verify the version file and results returned by a
6
+ # FileOperation.
7
+ #
8
+ # They will validate:
9
+ # - that the version file existst
10
+ # - that it is in the correct directory
11
+ # - that the file operation has not returned any failures
12
+ class Validator
13
+ extend Forwardable
14
+
15
+ # File for the version that resulted from a FileOperation.
16
+ attr_reader :file
17
+
18
+ # FileOperation::Results object.
19
+ attr_reader :info
20
+
21
+ # Returns a new instance.
22
+ #
23
+ # ===== Arguments
24
+ #
25
+ # * <tt>version_info</tt> - path to an existing file or an array with the
26
+ # path and optionally a FileOperations::Results instance.
27
+ # * +directory+ - directory where the file is expected (the working
28
+ # directory of a VersionedFile).
29
+ # * +filename+ - name of the file to be returned if the file operation was
30
+ # was non-modifying (usually the VersionedFile#original).
31
+ def initialize(version_info, directory, filename)
32
+ @file, @info = [version_info].flatten
33
+ @directory = directory
34
+ @filename = filename
35
+ end
36
+
37
+ # Validates file, directory, and info for <tt>version_info</tt> in the
38
+ # context of <tt>versioned_file</tt>.
39
+ #
40
+ # ===== Arguments
41
+ #
42
+ # * <tt>version_info</tt> - path to an existing file or an array with the
43
+ # path and optionally a FileOperations::Results instance.
44
+ # * <tt>versioned_file</tt> - an object that responds to #original and
45
+ # returns a file path, and #directory and returns a directory path.
46
+ def self.[](version_info, versioned_file)
47
+ new(version_info, versioned_file.directory, versioned_file.original)
48
+ .validate_info
49
+ .validate_file
50
+ .validate_directory
51
+ .then { |validator| [validator.file, validator.info] }
52
+ end
53
+
54
+ # Returns +true+ when there is no file for the version (result of a
55
+ # non-modifying file operation), +false+ otherwise.
56
+ def unmodified?
57
+ @file.nil?
58
+ end
59
+
60
+ # Raises MisplacedVersionFileError if #file is not in #directory.
61
+ def validate_directory
62
+ return self if unmodified? || File.dirname(@file) == @directory
63
+
64
+ raise Errors::MisplacedVersionFileError.new file: @file,
65
+ directory: @directory
66
+ end
67
+
68
+ # Raises MissingVersionFileError if #file does not exist on the file
69
+ # system.
70
+ def validate_file
71
+ return self if unmodified? || File.exist?(@file)
72
+
73
+ raise Errors::MissingVersionFileError.new file: @file
74
+ end
75
+
76
+ # Raises FailedModificationError if the file operation generatint the
77
+ # #info failed.
78
+ def validate_info
79
+ return self unless @info&.failure
80
+
81
+ raise Errors::FailedModificationError.new info: @info, file: @filename
82
+ end
83
+ end
84
+ end
85
+ end
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.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Stein
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-26 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multi_exiftool
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.14.0
19
+ version: 0.16.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.14.0
26
+ version: 0.16.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ruby-vips
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -50,6 +50,7 @@ files:
50
50
  - lib/file_pipeline.rb
51
51
  - lib/file_pipeline/errors.rb
52
52
  - lib/file_pipeline/errors/failed_modification_error.rb
53
+ - lib/file_pipeline/errors/misplaced_version_file_error.rb
53
54
  - lib/file_pipeline/errors/missing_version_file_error.rb
54
55
  - lib/file_pipeline/errors/source_directory_error.rb
55
56
  - lib/file_pipeline/errors/source_file_error.rb
@@ -68,11 +69,12 @@ files:
68
69
  - lib/file_pipeline/versioned_file.rb
69
70
  - lib/file_pipeline/versions.rb
70
71
  - lib/file_pipeline/versions/history.rb
72
+ - lib/file_pipeline/versions/validator.rb
71
73
  homepage: https://github.com/loveablelobster/file_pipeline
72
74
  licenses:
73
75
  - MIT
74
76
  metadata: {}
75
- post_install_message:
77
+ post_install_message:
76
78
  rdoc_options: []
77
79
  require_paths:
78
80
  - lib
@@ -80,15 +82,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
82
  requirements:
81
83
  - - ">="
82
84
  - !ruby/object:Gem::Version
83
- version: '2.7'
85
+ version: '3.0'
84
86
  required_rubygems_version: !ruby/object:Gem::Requirement
85
87
  requirements:
86
88
  - - ">="
87
89
  - !ruby/object:Gem::Version
88
90
  version: '0'
89
91
  requirements: []
90
- rubygems_version: 3.1.2
91
- signing_key:
92
+ rubygems_version: 3.2.3
93
+ signing_key:
92
94
  specification_version: 4
93
95
  summary: Nondestructive file processing with a defined batch
94
96
  test_files: []