file_concat 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|