burner 1.2.0 → 1.3.0.pre.alpha

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2c3e9af2bbfbf80cd5c5884e05b1282f52871566103baf4ca1b599fc76af8ca
4
- data.tar.gz: e7c2eb8a00086e1937a4d9e39383d38a60c5ebaa5efa1d67da4e6af9741261cd
3
+ metadata.gz: 340ebade1c4d3cc238925cb21718571dd666c3c16b6ee60d8de73c4fe017d562
4
+ data.tar.gz: 33b272e7a4b4a15a8e92b5f7eccb9df7ec6d685f767ecbf8434dedcf7ed901b5
5
5
  SHA512:
6
- metadata.gz: e885c7bf710f613323bbc3fc49162815632d7785aa6e753f3cd53bb04d2b53e74f92be549f75b6997d4dedce5c2dabe01fd032796a6d6e2fadfd6e84c633b168
7
- data.tar.gz: e09d491b3fb7ef1b79932ac6094adedd74f806170a2a11aa1ff1eda838b6bf76cec1684dbfaba12d07a6e071062d432bcd5f3939f275830fc13fb71cabb39f8c
6
+ metadata.gz: a5d082d14302d38e2acf89ab1275004ae69f78087e40da2a68c15e25770a9ebfc7fa2cb8e9e7268d132e2ade6c3d6db9e259ab3e8254ae476fcd1d46a4f40eb2
7
+ data.tar.gz: c1a9bda279afa44c5cb5a41c4ac792a62af317d91985799a14609c7b6d33e5494d322ad14262281b3fead76cc6471bebd7b507e1158dea7f9278196b36ab1726
@@ -1,3 +1,8 @@
1
+ # 1.3.0 (TBD)
2
+
3
+ Additions:
4
+
5
+ * Decoupled storage: `Burner::Disks` factory, `Burner::Disks::Local` reference implementation, and `b/io/*` `disk` option for configuring IO jobs to use custom disks.
1
6
  # 1.2.0 (November 25th, 2020)
2
7
 
3
8
  #### Enhancements:
data/README.md CHANGED
@@ -42,7 +42,7 @@ pipeline = {
42
42
  {
43
43
  name: :output_value,
44
44
  type: 'b/echo',
45
- message: 'The current value is: {__value}'
45
+ message: 'The current value is: {__default_register}'
46
46
  },
47
47
  {
48
48
  name: :parse,
@@ -89,7 +89,7 @@ Some notes:
89
89
 
90
90
  * Some values are able to be string-interpolated using the provided Payload#params. This allows for the passing runtime configuration/data into pipelines/jobs.
91
91
  * The job's ID can be accessed using the `__id` key.
92
- * The current job's payload value can be accessed using the `__value` key.
92
+ * The current payload registers' values can be accessed using the `__<register_name>_register` key.
93
93
  * Jobs can be re-used (just like the output_id and output_value jobs).
94
94
  * If steps is nil then all jobs will execute in their declared order.
95
95
 
@@ -163,7 +163,7 @@ jobs:
163
163
 
164
164
  - name: output_value
165
165
  type: b/echo
166
- message: 'The current value is: {__value}'
166
+ message: 'The current value is: {__default_register}'
167
167
 
168
168
  - name: parse
169
169
  type: b/deserialize/json
@@ -236,9 +236,11 @@ This library only ships with very basic, rudimentary jobs that are meant to just
236
236
 
237
237
  #### IO
238
238
 
239
- * **b/io/exist** [path, short_circuit]: Check to see if a file exists. The path parameter can be interpolated using `Payload#params`. If short_circuit was set to true (defaults to false) and the file does not exist then the pipeline will be short-circuited.
240
- * **b/io/read** [binary, path, register]: Read in a local file. The path parameter can be interpolated using `Payload#params`. If the contents are binary, pass in `binary: true` to open it up in binary+read mode.
241
- * **b/io/write** [binary, path, register]: Write to a local file. The path parameter can be interpolated using `Payload#params`. If the contents are binary, pass in `binary: true` to open it up in binary+write mode.
239
+ By default all jobs will use the `Burner::Disks::Local` disk for its persistence. But this is configurable by implementing and registering custom disk-based classes in the `Burner::Disks` factory. For example: a consumer application may also want to interact with cloud-based storage providers and could leverage this as its job library instead of implementing custom jobs.
240
+
241
+ * **b/io/exist** [disk, path, short_circuit]: Check to see if a file exists. The path parameter can be interpolated using `Payload#params`. If short_circuit was set to true (defaults to false) and the file does not exist then the pipeline will be short-circuited.
242
+ * **b/io/read** [binary, disk, path, register]: Read in a local file. The path parameter can be interpolated using `Payload#params`. If the contents are binary, pass in `binary: true` to open it up in binary+read mode.
243
+ * **b/io/write** [binary, disk, path, register]: Write to a local file. The path parameter can be interpolated using `Payload#params`. If the contents are binary, pass in `binary: true` to open it up in binary+write mode.
242
244
 
243
245
  #### Serialization
244
246
 
@@ -299,7 +301,7 @@ pipeline = {
299
301
  {
300
302
  name: :output_value,
301
303
  type: 'b/echo',
302
- message: 'The current value is: {__value}'
304
+ message: 'The current value is: {__default_register}'
303
305
  },
304
306
  {
305
307
  name: :parse,
@@ -10,6 +10,7 @@
10
10
  require 'acts_as_hashable'
11
11
  require 'benchmark'
12
12
  require 'csv'
13
+ require 'fileutils'
13
14
  require 'forwardable'
14
15
  require 'hash_math'
15
16
  require 'hashematics'
@@ -23,6 +24,7 @@ require 'time'
23
24
  require 'yaml'
24
25
 
25
26
  # Common/Shared
27
+ require_relative 'burner/disks'
26
28
  require_relative 'burner/modeling'
27
29
  require_relative 'burner/side_effects'
28
30
  require_relative 'burner/util'
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2020-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require_relative 'disks/local'
11
+
12
+ module Burner
13
+ # A factory to register and emit instances that conform to the Disk interface with requests
14
+ # the instance responds to: #exist?, #read, and #write. See an example implementation within
15
+ # the lib/burner/disks directory.
16
+ #
17
+ # The benefit to this pluggable disk model is a consumer application can decide which file
18
+ # backend to use and how to store files. For example: an application may choose to use
19
+ # some cloud provider with their own file store implementation. This can be wrapped up
20
+ # in a Disk class and registered here and then referenced in the Pipeline's IO jobs.
21
+ class Disks
22
+ acts_as_hashable_factory
23
+
24
+ register 'local', '', Disks::Local
25
+ end
26
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2020-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ module Burner
11
+ class Disks
12
+ # Operations against the local file system.
13
+ class Local
14
+ acts_as_hashable
15
+
16
+ # Check to see if the passed in path exists within the local file system.
17
+ # It will not make assumptions on what the 'file' is, only that it is recognized
18
+ # by Ruby's File class.
19
+ def exist?(path)
20
+ File.exist?(path)
21
+ end
22
+
23
+ # Open and read the contents of a local file. If binary is passed in as true then the file
24
+ # will be opened in binary mode.
25
+ def read(path, binary: false)
26
+ File.open(path, read_mode(binary), &:read)
27
+ end
28
+
29
+ # Open and write the specified data to a local file. If binary is passed in as true then
30
+ # the file will be opened in binary mode. It is important to note that if the file's
31
+ # directory structure will be automatically created if it does not exist.
32
+ def write(path, data, binary: false)
33
+ ensure_directory_exists(path)
34
+
35
+ File.open(path, write_mode(binary)) { |io| io.write(data) }
36
+
37
+ path
38
+ end
39
+
40
+ private
41
+
42
+ def ensure_directory_exists(path)
43
+ dirname = File.dirname(path)
44
+
45
+ return if File.exist?(dirname)
46
+
47
+ FileUtils.mkdir_p(dirname)
48
+
49
+ nil
50
+ end
51
+
52
+ def write_mode(binary)
53
+ binary ? 'wb' : 'w'
54
+ end
55
+
56
+ def read_mode(binary)
57
+ binary ? 'rb' : 'r'
58
+ end
59
+ end
60
+ end
61
+ end
@@ -7,8 +7,6 @@
7
7
  # LICENSE file in the root directory of this source tree.
8
8
  #
9
9
 
10
- require_relative 'base'
11
-
12
10
  module Burner
13
11
  module Library
14
12
  module IO
@@ -17,13 +15,14 @@ module Burner
17
15
  #
18
16
  # Note: this does not use Payload#registers.
19
17
  class Exist < Job
20
- attr_reader :path, :short_circuit
18
+ attr_reader :disk, :path, :short_circuit
21
19
 
22
- def initialize(name:, path:, short_circuit: false)
20
+ def initialize(name:, path:, disk: {}, short_circuit: false)
23
21
  super(name: name)
24
22
 
25
23
  raise ArgumentError, 'path is required' if path.to_s.empty?
26
24
 
25
+ @disk = Disks.make(disk)
27
26
  @path = path.to_s
28
27
  @short_circuit = short_circuit || false
29
28
  end
@@ -31,7 +30,7 @@ module Burner
31
30
  def perform(output, payload)
32
31
  compiled_path = job_string_template(path, output, payload)
33
32
 
34
- exists = File.exist?(compiled_path)
33
+ exists = disk.exist?(compiled_path)
35
34
  verb = exists ? 'does' : 'does not'
36
35
 
37
36
  output.detail("The path: #{compiled_path} #{verb} exist")
@@ -10,16 +10,20 @@
10
10
  module Burner
11
11
  module Library
12
12
  module IO
13
- # Common configuration/code for all IO Job subclasses.
14
- class Base < JobWithRegister
15
- attr_reader :path
13
+ # Common configuration/code for all IO Job subclasses that open a file.
14
+ class OpenFileBase < JobWithRegister
15
+ attr_reader :binary, :disk, :path
16
16
 
17
- def initialize(name:, path:, register: DEFAULT_REGISTER)
17
+ def initialize(name:, path:, binary: false, disk: {}, register: DEFAULT_REGISTER)
18
18
  super(name: name, register: register)
19
19
 
20
20
  raise ArgumentError, 'path is required' if path.to_s.empty?
21
21
 
22
- @path = path.to_s
22
+ @binary = binary || false
23
+ @disk = Disks.make(disk)
24
+ @path = path.to_s
25
+
26
+ freeze
23
27
  end
24
28
  end
25
29
  end
@@ -7,7 +7,7 @@
7
7
  # LICENSE file in the root directory of this source tree.
8
8
  #
9
9
 
10
- require_relative 'base'
10
+ require_relative 'open_file_base'
11
11
 
12
12
  module Burner
13
13
  module Library
@@ -16,29 +16,13 @@ module Burner
16
16
  #
17
17
  # Expected Payload[register] input: nothing.
18
18
  # Payload[register] output: contents of the specified file.
19
- class Read < Base
20
- attr_reader :binary
21
-
22
- def initialize(name:, path:, binary: false, register: DEFAULT_REGISTER)
23
- super(name: name, path: path, register: register)
24
-
25
- @binary = binary || false
26
-
27
- freeze
28
- end
29
-
19
+ class Read < OpenFileBase
30
20
  def perform(output, payload)
31
21
  compiled_path = job_string_template(path, output, payload)
32
22
 
33
23
  output.detail("Reading: #{compiled_path}")
34
24
 
35
- payload[register] = File.open(compiled_path, mode, &:read)
36
- end
37
-
38
- private
39
-
40
- def mode
41
- binary ? 'rb' : 'r'
25
+ payload[register] = disk.read(compiled_path, binary: binary)
42
26
  end
43
27
  end
44
28
  end
@@ -7,7 +7,7 @@
7
7
  # LICENSE file in the root directory of this source tree.
8
8
  #
9
9
 
10
- require_relative 'base'
10
+ require_relative 'open_file_base'
11
11
 
12
12
  module Burner
13
13
  module Library
@@ -16,54 +16,27 @@ module Burner
16
16
  #
17
17
  # Expected Payload[register] input: anything.
18
18
  # Payload[register] output: whatever was passed in.
19
- class Write < Base
20
- attr_reader :binary
21
-
22
- def initialize(name:, path:, binary: false, register: DEFAULT_REGISTER)
23
- super(name: name, path: path, register: register)
24
-
25
- @binary = binary || false
26
-
27
- freeze
28
- end
29
-
19
+ class Write < OpenFileBase
30
20
  def perform(output, payload)
31
- compiled_path = job_string_template(path, output, payload)
32
-
33
- ensure_directory_exists(output, compiled_path)
21
+ logical_filename = job_string_template(path, output, payload)
22
+ physical_filename = nil
34
23
 
35
- output.detail("Writing: #{compiled_path}")
24
+ output.detail("Writing: #{logical_filename}")
36
25
 
37
26
  time_in_seconds = Benchmark.measure do
38
- File.open(compiled_path, mode) { |io| io.write(payload[register]) }
27
+ physical_filename = disk.write(logical_filename, payload[register], binary: binary)
39
28
  end.real
40
29
 
30
+ output.detail("Wrote to: #{physical_filename}")
31
+
41
32
  side_effect = SideEffects::WrittenFile.new(
42
- logical_filename: compiled_path,
43
- physical_filename: compiled_path,
33
+ logical_filename: logical_filename,
34
+ physical_filename: physical_filename,
44
35
  time_in_seconds: time_in_seconds
45
36
  )
46
37
 
47
38
  payload.add_side_effect(side_effect)
48
39
  end
49
-
50
- private
51
-
52
- def ensure_directory_exists(output, compiled_path)
53
- dirname = File.dirname(compiled_path)
54
-
55
- return if File.exist?(dirname)
56
-
57
- output.detail("Outer directory does not exist, creating: #{dirname}")
58
-
59
- FileUtils.mkdir_p(dirname)
60
-
61
- nil
62
- end
63
-
64
- def mode
65
- binary ? 'wb' : 'w'
66
- end
67
40
  end
68
41
  end
69
42
  end
@@ -8,5 +8,5 @@
8
8
  #
9
9
 
10
10
  module Burner
11
- VERSION = '1.2.0'
11
+ VERSION = '1.3.0-alpha'
12
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: burner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0.pre.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-25 00:00:00.000000000 Z
11
+ date: 2020-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acts_as_hashable
@@ -220,6 +220,8 @@ files:
220
220
  - exe/burner
221
221
  - lib/burner.rb
222
222
  - lib/burner/cli.rb
223
+ - lib/burner/disks.rb
224
+ - lib/burner/disks/local.rb
223
225
  - lib/burner/job.rb
224
226
  - lib/burner/job_with_register.rb
225
227
  - lib/burner/jobs.rb
@@ -240,8 +242,8 @@ files:
240
242
  - lib/burner/library/deserialize/json.rb
241
243
  - lib/burner/library/deserialize/yaml.rb
242
244
  - lib/burner/library/echo.rb
243
- - lib/burner/library/io/base.rb
244
245
  - lib/burner/library/io/exist.rb
246
+ - lib/burner/library/io/open_file_base.rb
245
247
  - lib/burner/library/io/read.rb
246
248
  - lib/burner/library/io/write.rb
247
249
  - lib/burner/library/nothing.rb
@@ -290,9 +292,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
290
292
  version: '2.5'
291
293
  required_rubygems_version: !ruby/object:Gem::Requirement
292
294
  requirements:
293
- - - ">="
295
+ - - ">"
294
296
  - !ruby/object:Gem::Version
295
- version: '0'
297
+ version: 1.3.1
296
298
  requirements: []
297
299
  rubygems_version: 3.0.3
298
300
  signing_key: