declarative_mapper 0.0.5 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9cc46c045e5764992d7b1d32bcb3592b7ba9c5395c3fab5b4310235ea034d99
4
- data.tar.gz: 3b71e5d8bd29438990e45658072cc0fbc1626f7c7bf81f3b8a96dbece9985b65
3
+ metadata.gz: 6c029ea7248f2073b26234203b42a300ce9c45ebb31d1af048849505d85241ed
4
+ data.tar.gz: 3cf2c8725c01030166dfdf8a12c8d63ab82daeca2d116da2dc146a7886bb6c35
5
5
  SHA512:
6
- metadata.gz: 30b6ddb1acec922cd238a5d84afd8dae98ebc3939661442df68d1bb41b50bb4bf4669b068dbd9a11601ddc43cc331d5db518e699fb4678c45022719ca61f7322
7
- data.tar.gz: 13e3e1545dd01dbd12108884fa103338b7a7be64b80a882ebd7aca0b2ec2f158522d13b9f5549957609e057c38e3ef9d8ab6d11d912e972b986e64c210b6f1c9
6
+ metadata.gz: 06aa80ec644a7644cc871551d69b954ac062030ada18a53205d1afb535109acdb94f267751f7f524748d21011d7cfa549509752431124afdc8c9942566dd932e
7
+ data.tar.gz: fc42f26ff109fe9c61e04b14814f469028d2fc7dc4144d33ae8ce6991a0c481698b045106d4ae32e2c6417296b957f79a3675bcc4d59bb8c9a7aa27381412c23
@@ -1,42 +1,93 @@
1
- require_relative 'csv_parser'
1
+ require 'active_support/core_ext/hash/keys.rb'
2
+ require 'active_support/core_ext/string'
2
3
 
3
4
  class DeclarativeMapper
4
- attr_reader :client_path, :client_name, :project_path
5
+ def self.convert(mapper_methods, mapping_hash, csv_row)
6
+ deep_transform_values_with_path(mapping_hash) do |csv_field_name, path|
7
+ field_name = path.last
5
8
 
6
- def initialize(client_path)
7
- @client_path = client_path
8
- @client_name = client_path.split('/').last
9
- @project_path = client_path.sub("/#{@client_name}", '')
9
+ if needs_method?(csv_field_name)
10
+ parsed_signature =
11
+ parse_signature(csv_field_name, field_name)
10
12
 
11
- require_client_mapper_methods
12
- require_shared_mapper_methods
13
+ args = argument_values(parsed_signature[:arguments], csv_row)
14
+ method_name = parsed_signature[:method_name]
15
+
16
+ unless shared_method?(csv_field_name)
17
+ method_name = path[0..-2].push(method_name).join('_')
18
+ end
19
+
20
+ mapper_methods.send(method_name, *args)
21
+ else
22
+ csv_row[csv_field_name]
23
+ end
24
+ end
13
25
  end
14
26
 
15
- def convert(csv_row, yml_file_name)
16
- parser = CSVParser.new(yml_path(yml_file_name), client_name)
27
+ def self.required_csv_fields(mapping_hash)
28
+ deep_inject(mapping_hash, []) do |value, sum|
29
+ if needs_method?(value)
30
+ sum += (parse_signature(value)[:arguments])
31
+ else
32
+ sum.push(value)
33
+ end
34
+ end.uniq.compact
35
+ end
17
36
 
18
- parser.parse(csv_row)
37
+ def self.argument_values(argument_names, csv_row)
38
+ argument_names.map { |name| csv_row[name] }
19
39
  end
20
40
 
21
- private
41
+ def self.parse_signature(signature, field_name=nil)
42
+ match = signature.match(/^(.*)\((.*)\)/)
43
+
44
+ method_name = match[1]
45
+ method_name = field_name if method_name.empty?
22
46
 
23
- def yml_path(yml_file_name)
24
- "#{client_path}/#{yml_file_name}.yml"
47
+ {
48
+ arguments: match[2].gsub(/,\s+/, ',').split(','),
49
+ method_name: method_name
50
+ }
25
51
  end
26
52
 
27
- def client_mapper_methods_dir_path
28
- "#{client_path}/mapper_methods"
53
+ def self.shared_method?(signature)
54
+ !!(signature =~ /^.+\(.*\)/)
29
55
  end
30
56
 
31
- def shared_mapper_methods_dir_path
32
- "#{project_path}/shared"
57
+ def self.needs_method?(signature)
58
+ !!(signature =~ /\(.*\)/)
33
59
  end
34
60
 
35
- def require_client_mapper_methods
36
- Dir["#{client_mapper_methods_dir_path}/**/*.rb"].each { |file| require file }
61
+ # Example of usage:
62
+ #
63
+ # my_hash = {a: 0, b: {c: 1, d: 2, e: {f: 3}}}
64
+ # values = %w(mother washed the ceiling)
65
+ #
66
+ # result = deep_transform_values_with_path(my_hash) do |value, path|
67
+ # path.join('/') + '/' + values[value]
68
+ # end
69
+ #
70
+ # {:a=>"a/mother", :b=>{:c=>"b/c/washed", :d=>"b/d/the", :e=>{:f=>"b/e/f/ceiling"}}}
71
+ #
72
+ def self.deep_transform_values_with_path(object, path=[], &block)
73
+ case object
74
+ when Hash
75
+ object.map { |k, v| [k, deep_transform_values_with_path(v, path + [k], &block)] }.to_h
76
+ when Array
77
+ object.map { |e| deep_transform_values_with_path(e, path, &block) }
78
+ else
79
+ yield(object, path)
80
+ end
37
81
  end
38
82
 
39
- def require_shared_mapper_methods
40
- Dir["#{shared_mapper_methods_dir_path}/**/*.rb"].each { |file| require file }
83
+ def self.deep_inject(object, acc, &block)
84
+ case object
85
+ when Hash
86
+ object.inject(acc) { |a, (k, v)| deep_inject(v, a, &block) }
87
+ when Array
88
+ object.inject(acc) { |a, e| deep_inject(e, a, &block) }
89
+ else
90
+ yield(object, acc)
91
+ end
41
92
  end
42
93
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: declarative_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nemytchenko
@@ -9,35 +9,30 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-12-18 00:00:00.000000000 Z
12
+ date: 2021-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '0'
20
+ version: '1.0'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ">="
25
+ - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '0'
27
+ version: '1.0'
28
28
  description:
29
29
  email: install.vv@gmail.com
30
- executables:
31
- - declarative_mapper_generate
30
+ executables: []
32
31
  extensions: []
33
32
  extra_rdoc_files: []
34
33
  files:
35
- - bin/declarative_mapper_generate
36
- - lib/csv_parser.rb
37
34
  - lib/declarative_mapper.rb
38
- - lib/module_helper.rb
39
- - templates/mapper_methods.rb.erb
40
- homepage: https://gitlab.com/installero/sync_prototype
35
+ homepage: https://github.com/installero/declarative_mapper
41
36
  licenses:
42
37
  - MIT
43
38
  metadata: {}
@@ -56,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
51
  - !ruby/object:Gem::Version
57
52
  version: '0'
58
53
  requirements: []
59
- rubygems_version: 3.0.6
54
+ rubygems_version: 3.1.4
60
55
  signing_key:
61
56
  specification_version: 4
62
57
  summary: Creates an object from a csv row according to yml-file with mapping rules
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'active_support/core_ext/string'
4
- require 'active_support/core_ext/hash/keys.rb'
5
-
6
- require 'yaml'
7
- require 'erb'
8
- require 'fileutils'
9
-
10
- require_relative '../lib/module_helper'
11
-
12
- def normalize_args(string)
13
- return if string.nil?
14
-
15
- string.delete('() ').split(',').join(', ')
16
- end
17
-
18
- def customer_methods_only(hash)
19
- hash.reject do |_, value|
20
- !ModuleHelper.needs_method?(value) || ModuleHelper.shared_method?(value)
21
- end
22
- end
23
-
24
- unless ARGV[0]
25
- puts "Yaml file name needed, example:"
26
- puts
27
- puts "ruby generate.rb akme/customers.yml"
28
- puts
29
- exit 1
30
- end
31
-
32
- yml_path = ARGV[0]
33
-
34
- # Getting client & table names from yml file path
35
- client_dir, yml_filename = File.split(yml_path)
36
-
37
- table_name = File.basename(yml_filename, '.yml')
38
- client_name = client_dir.split(File::SEPARATOR).last
39
-
40
- # Getting list of methods (with arrays of args) from yml file
41
- client_mapping = YAML.load_file(yml_path).deep_symbolize_keys[:mapping]
42
-
43
- methods =
44
- customer_methods_only(client_mapping)
45
- .map { |key, value| [key, normalize_args(value)] }
46
- .to_h
47
-
48
- puts "Methods #{methods.keys.join(', ')} found"
49
-
50
- # Getting mapper methods file template
51
- template_path = "#{__dir__}/../templates/mapper_methods.rb.erb"
52
- template = ERB.new(File.read(template_path), nil, '-')
53
-
54
- # Constructing path for the methods file
55
- methods_file_dir = File.join(client_dir, ModuleHelper::CLIENT_METHODS_FOLDER)
56
- methods_file_name = "#{table_name}.rb"
57
- methods_file_path = File.join(methods_file_dir, methods_file_name)
58
-
59
- # Creating directory
60
- FileUtils.mkdir_p(methods_file_dir) unless File.directory?(methods_file_dir)
61
-
62
- # Writing to file
63
- if File.exist?(methods_file_path)
64
- puts "File #{methods_file_name} already exists!"
65
- puts
66
- else
67
- File.write(methods_file_path, template.result(binding))
68
-
69
- puts "Wrote to #{methods_file_name}!"
70
- puts
71
- end
data/lib/csv_parser.rb DELETED
@@ -1,58 +0,0 @@
1
- require 'yaml'
2
-
3
- require 'active_support/core_ext/hash/keys.rb'
4
- require 'active_support/core_ext/string'
5
-
6
- require_relative 'module_helper'
7
-
8
- class CSVParser
9
- attr_reader :yml_path, :client_name, :table_name
10
-
11
- def initialize(yml_path, client_name)
12
- @yml_path = yml_path
13
- @client_name = client_name
14
- @table_name = File.basename(yml_path, '.yml')
15
- end
16
-
17
- def yml
18
- @yml ||= YAML.load_file(yml_path).deep_symbolize_keys
19
- end
20
-
21
- def parse(csv_row)
22
- ModuleHelper.deep_transform_values_with_path(mapping_hash) do |csv_field_name, path|
23
- field_name = path.last
24
-
25
- if ModuleHelper.needs_method?(csv_field_name)
26
- parsed_signature =
27
- ModuleHelper.parse_signature(csv_field_name, client_name, table_name, field_name)
28
-
29
- args = argument_values(parsed_signature[:arguments], csv_row)
30
-
31
- module_path = parsed_signature[:path]
32
- module_path += path[0..-2] unless ModuleHelper.shared_method?(csv_field_name)
33
-
34
- call_shared_or_client_method(
35
- module_path,
36
- parsed_signature[:method_name],
37
- *args
38
- )
39
- else
40
- csv_row[csv_field_name]
41
- end
42
- end
43
- end
44
-
45
- private
46
-
47
- def mapping_hash
48
- yml[:mapping]
49
- end
50
-
51
- def call_shared_or_client_method(path, method_name, *args)
52
- path.map(&:to_s).map(&:camelize).join('::').constantize.send(method_name, *args)
53
- end
54
-
55
- def argument_values(argument_names, csv_row)
56
- argument_names.map { |name| csv_row[name] }
57
- end
58
- end
data/lib/module_helper.rb DELETED
@@ -1,52 +0,0 @@
1
- module ModuleHelper
2
- CLIENT_METHODS_FOLDER = 'mapper_methods'
3
- # 'shared/phone/number/normalize(phonenumber)'
4
- # -> ['shared', 'phone', 'number'], 'normalize', ['phonenumber']
5
- #
6
- # '(status)', client_name: 'reliable', field_name: 'active'
7
- # -> ['reliable', 'mapper_methods'], 'active', ['status']
8
- def self.parse_signature(signature, client_name=nil, table_name=nil, field_name=nil)
9
- match = signature.match(/^(.*)\((.*)\)/)
10
-
11
- result = {arguments: match[2].gsub(/,\s+/, ',').split(',')}
12
-
13
- if shared_method?(signature)
14
- path = match[1].split('/')
15
-
16
- result[:method_name] = path.pop.to_sym
17
- result[:path] = path
18
- else
19
- result[:method_name] = field_name
20
- result[:path] = [client_name, CLIENT_METHODS_FOLDER, table_name]
21
- end
22
-
23
- result
24
- end
25
-
26
- def self.shared_method?(signature)
27
- !!(signature =~ /^shared\//)
28
- end
29
-
30
- def self.needs_method?(signature)
31
- !!(signature =~ /\(.*\)/)
32
- end
33
-
34
- # Example of usage:
35
- #
36
- # my_hash = {a: 0, b: {c: 1, d: 2, e: {f: 3}}}
37
- # values = %w(mother washed the ceiling)
38
- #
39
- # result = deep_transform_values_with_path(my_hash) do |value, path|
40
- # path.join('/') + '/' + values[value]
41
- # end
42
- #
43
- # {:a=>"a/mother", :b=>{:c=>"b/c/washed", :d=>"b/d/the", :e=>{:f=>"b/e/f/ceiling"}}}
44
- #
45
- def self.deep_transform_values_with_path(object, path=[], &block)
46
- return yield(object, path) unless object.is_a?(Hash)
47
-
48
- object.map do |key, value|
49
- [key, deep_transform_values_with_path(value, path + [key], &block)]
50
- end.to_h
51
- end
52
- end
@@ -1,12 +0,0 @@
1
- module <%= client_name.camelize %>
2
- module MapperMethods
3
- module <%= table_name.camelize %>
4
- <% methods.each_with_index do |(method_name, arg_names), index| -%>
5
- def self.<%= method_name %>(<%= arg_names %>)
6
- # Implement method <%= method_name %> here
7
- end
8
- <%= "\n" unless index == methods.count - 1 -%>
9
- <% end -%>
10
- end
11
- end
12
- end