declarative_mapper 0.0.5 → 0.1.1

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