file_concat 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 198a116a58d9ed469952ec470a1b6064901f1875db1076aca5f176e87d01790c
4
+ data.tar.gz: 989eb7b0018689221c2fc5aadd59018f9a5872bbc7ddce6277005e529e31732f
5
+ SHA512:
6
+ metadata.gz: 43fd08c2591869ece5691b8fa66498a031c74018cfc7a0f38da93e826e309d46497ec51b43aad36a08462b495f655aff5661d9e93c17602f36f0ad8bfced44d8
7
+ data.tar.gz: ae728c63b06ad5229cca07f7b3ac0f5c5a1a8763713cc21fe50f656d83b9e87a228e38416df867af2d2767ed1942c7e67da25c5614d713f8a43e42d21910f4bb
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Namespace for our Gem. This is the root of all of the functionality and the
4
+ # base name for all of our individual classes that contain extended, specific,
5
+ # etc. logic.
6
+ class FileConcat
7
+
8
+ end
9
+
10
+ require 'file_concat/simple_concat'
11
+ require 'file_concat/pre_post_concat'
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FileConcat
4
+ # A more complex file concatenation allowing for the use of some pre and post
5
+ # processing functionality during the actual run. We do our best to rely on
6
+ # the file system wherever possible so we can use the I/O optimization that is
7
+ # written by the experts.
8
+ class PrePostConcat
9
+
10
+ attr_reader :batch_count
11
+
12
+ attr_accessor :batch_first_line
13
+ attr_accessor :file_first_line
14
+ attr_accessor :file_last_line
15
+ attr_accessor :batch_last_line
16
+
17
+ # ==== This method does:
18
+ #
19
+ # Creates a new instance of our PrePostConcat processor.
20
+ #
21
+ # ==== With params:
22
+ #
23
+ # @param file_provider <Proc> - the provider of files to concatenate
24
+ # @param target_dir <String> - the path to store the batch files in
25
+ # @param target_ext <String> - the extension for the batch files
26
+ # @param batch_size <Integer> - the total number of files to concatenate into one
27
+ #
28
+ # ==== And returns:
29
+ #
30
+ # @return batch_count <Integer> - the total number of batch files created
31
+ #
32
+ # ==== And is used like:
33
+ #
34
+ # FileBatcher.new my_proc, '/path/to/output', 'xml', 25
35
+ #
36
+ def initialize(file_provider, target_dir, target_ext, batch_size)
37
+ @file_provider = file_provider
38
+ @target_dir = target_dir
39
+ @target_ext = target_ext
40
+ @batch_size = batch_size
41
+ @batch_count = 0
42
+ end
43
+
44
+ # ==== This method does:
45
+ #
46
+ # Actually executes file concatenation.
47
+ #
48
+ # ==== With params:
49
+ #
50
+ # N/A
51
+ #
52
+ # ==== And returns:
53
+ #
54
+ # @return batch_count <Integer> - the total number of batch files created
55
+ #
56
+ # ==== And is used like:
57
+ #
58
+ # batches = instance.run
59
+ #
60
+ def run
61
+ # reset the batch count
62
+ @batch_count = 0
63
+
64
+ # if the target doesn't exist, create it... if it does, empty it
65
+ FileUtils.remove_dir @target_dir if Dir.exist? @target_dir
66
+ Dir.mkdir @target_dir
67
+
68
+ # loop over all the files
69
+ current_file_index = 0
70
+ active_batch_file = nil
71
+
72
+ @file_provider.call.each do |next_file|
73
+ # create a new file to concatenate to
74
+ current_file_index += 1
75
+ if (current_file_index - 1) % @batch_size == 0
76
+ @batch_count += 1
77
+ end_batch_file(active_batch_file) unless active_batch_file.nil?
78
+ active_batch_file = new_batch_file
79
+ end
80
+
81
+ # concatenate the file
82
+ concat_to active_batch_file, next_file
83
+ end
84
+ end_batch_file(active_batch_file) unless active_batch_file.nil?
85
+
86
+ # return the batch count
87
+ @batch_count
88
+ end
89
+
90
+ private
91
+
92
+ # ==== This method does:
93
+ #
94
+ # Sets up the new batch file to use for processing.
95
+ #
96
+ # ==== With params:
97
+ #
98
+ # N/A
99
+ #
100
+ # ==== And returns:
101
+ #
102
+ # @return file_path <File> - the complete path to the next batch file
103
+ #
104
+ # ==== And is used like:
105
+ #
106
+ # next_file = instance.new_batch_file(@batch_count)
107
+ #
108
+ def new_batch_file
109
+ # basic setup
110
+ formatted_index = batch_count.to_s.rjust(5, '0')
111
+ file_name = "Batch-#{formatted_index}.#{@target_ext}"
112
+ file_path = File.join(@target_dir, file_name)
113
+
114
+ # if we have a batch first line, use it
115
+ unless batch_first_line.nil?
116
+ first_line = batch_first_line.call(file_name)
117
+ File.open(file_path, 'w') { |f| f.puts first_line } unless first_line.nil?
118
+ end
119
+
120
+ # exit
121
+ file_path
122
+ end
123
+
124
+ # ==== This method does:
125
+ #
126
+ # Ends a batch file.
127
+ #
128
+ # ==== With params:
129
+ #
130
+ # @param file <File> - the actual file we are ending work with
131
+ #
132
+ # ==== And returns:
133
+ #
134
+ # N/A
135
+ #
136
+ # ==== And is used like:
137
+ #
138
+ # instance.end_batch_file(active_batch_file)
139
+ #
140
+ def end_batch_file(file)
141
+ unless batch_last_line.nil?
142
+ last_line = batch_last_line.call(file)
143
+ File.open(file, 'a') { |f| f.puts last_line } unless last_line.nil?
144
+ end
145
+ end
146
+
147
+ # ==== This method does:
148
+ #
149
+ # Concatenates the source file to the target file.
150
+ #
151
+ # ==== With params:
152
+ #
153
+ # @param target_file <File> - the file to concatenate the other to
154
+ # @param source_file <String> - path to the file to concatenate to the other
155
+ #
156
+ # ==== And returns:
157
+ #
158
+ # N/A
159
+ #
160
+ # ==== And is used like:
161
+ #
162
+ # instance.concat_to(target_file, source_file)
163
+ #
164
+ def concat_to(target_file, source_file)
165
+ # get the first line
166
+ first_line = file_first_line.nil? ? nil : file_first_line.call(source_file)
167
+ File.open(target_file, 'a') { |f| f.puts first_line } unless blank? first_line
168
+
169
+ # concat the file
170
+ system("cat \"#{source_file}\" >> \"#{target_file}\"")
171
+ exit_code = $?.exitstatus
172
+ raise StandardError, "Error concatenating files : Target[#{target_file}], Source[#{source_file}]" unless exit_code.zero?
173
+
174
+ # get the last line
175
+ last_line = file_last_line.nil? ? nil : file_last_line.call(source_file)
176
+ File.open(target_file, 'a') { |f| f.puts last_line } unless blank? last_line
177
+ end
178
+
179
+ # ==== This method does:
180
+ #
181
+ # Utility method to test if strings are empty.
182
+ #
183
+ # ==== With params:
184
+ #
185
+ # @param string <String> - the string to test
186
+ #
187
+ # ==== And returns:
188
+ #
189
+ # @return blank <Boolean> whether or not the string is blank
190
+ #
191
+ # ==== And is used like:
192
+ #
193
+ # blank? 'something'
194
+ #
195
+ def blank?(string)
196
+ string.to_s.strip.empty?
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FileConcat
4
+ # Simple file concatenation that performs a no-thrills operation. Friendly
5
+ # to small and large amounts of files, this is extremely basic and uses the
6
+ # underlying filesystem to do the actual heavy lifting (there's code written
7
+ # by the I/O experts for this, so don't reinvent the wheel).
8
+ class SimpleConcat
9
+ # TODO: all this
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FileConcat
4
+ # Pulls the current version of the library.
5
+ class Version
6
+ # ==== This method does:
7
+ #
8
+ # Retrieves the version of the library.
9
+ #
10
+ # ==== With params:
11
+ #
12
+ # N/A
13
+ #
14
+ # ==== And returns:
15
+ #
16
+ # @return version <String> - the version of the library
17
+ #
18
+ # ==== And is used like:
19
+ #
20
+ # FileConcat::Version.version
21
+ #
22
+ def self.version
23
+ File.read('VERSION').strip
24
+ end
25
+ end
26
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: file_concat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joe Brutto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-07-04 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: File concatenation library for Ruby with some simple options and some
14
+ complex options.
15
+ email: open.source@revof11.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/file_concat.rb
21
+ - lib/file_concat/pre_post_concat.rb
22
+ - lib/file_concat/simple_concat.rb
23
+ - lib/file_concat/version.rb
24
+ homepage: https://gitlab.com/joe.brutto/ruby-file-concat
25
+ licenses:
26
+ - MIT
27
+ metadata:
28
+ bug_tracker_uri: https://gitlab.com/joe.brutto/ruby-file-concat/issues
29
+ documentation_uri: https://gitlab.com/joe.brutto/ruby-file-concat/wikis/home1
30
+ source_code_uri: https://gitlab.com/joe.brutto/ruby-file-concat/tree/master
31
+ wiki_uri: https://gitlab.com/joe.brutto/ruby-file-concat/wikis/home1
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '2.3'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements:
47
+ - Unix-like OS
48
+ rubyforge_project:
49
+ rubygems_version: 2.7.7
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: file_concat
53
+ test_files: []