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 +7 -0
- data/lib/file_concat.rb +11 -0
- data/lib/file_concat/pre_post_concat.rb +199 -0
- data/lib/file_concat/simple_concat.rb +11 -0
- data/lib/file_concat/version.rb +26 -0
- metadata +53 -0
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
|
data/lib/file_concat.rb
ADDED
@@ -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: []
|