remi 0.0.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.bundle/config +2 -0
  3. data/.gitignore +3 -2
  4. data/.rspec +2 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +123 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +94 -3
  10. data/bin/remi +8 -0
  11. data/doc/install-rbenv-os_x.md +47 -0
  12. data/lib/remi.rb +56 -9
  13. data/lib/remi/cli.rb +56 -0
  14. data/lib/remi/core/daru.rb +28 -0
  15. data/lib/remi/core/refinements.rb +21 -0
  16. data/lib/remi/core/string.rb +8 -0
  17. data/lib/remi/cucumber.rb +7 -0
  18. data/lib/remi/cucumber/business_rules.rb +504 -0
  19. data/lib/remi/cucumber/data_source.rb +63 -0
  20. data/lib/remi/data_source.rb +13 -0
  21. data/lib/remi/data_source/csv_file.rb +79 -0
  22. data/lib/remi/data_source/data_frame.rb +10 -0
  23. data/lib/remi/data_source/postgres.rb +58 -0
  24. data/lib/remi/data_source/salesforce.rb +78 -0
  25. data/lib/remi/data_subject.rb +25 -0
  26. data/lib/remi/data_target.rb +15 -0
  27. data/lib/remi/data_target/csv_file.rb +49 -0
  28. data/lib/remi/data_target/data_frame.rb +14 -0
  29. data/lib/remi/data_target/salesforce.rb +49 -0
  30. data/lib/remi/extractor/sftp_file.rb +84 -0
  31. data/lib/remi/field_symbolizers.rb +17 -0
  32. data/lib/remi/job.rb +200 -0
  33. data/lib/remi/lookup/regex_sieve.rb +55 -0
  34. data/lib/remi/project/features/examples.feature +24 -0
  35. data/lib/remi/project/features/formulas.feature +64 -0
  36. data/lib/remi/project/features/sample_job.feature +304 -0
  37. data/lib/remi/project/features/step_definitions/remi_step.rb +310 -0
  38. data/lib/remi/project/features/support/env.rb +10 -0
  39. data/lib/remi/project/features/support/env_app.rb +3 -0
  40. data/lib/remi/project/features/transforms/date_diff.feature +50 -0
  41. data/lib/remi/project/features/transforms/parse_date.feature +34 -0
  42. data/lib/remi/project/features/transforms/prefix.feature +15 -0
  43. data/lib/remi/project/jobs/all_jobs_shared.rb +25 -0
  44. data/lib/remi/project/jobs/copy_source_job.rb +12 -0
  45. data/lib/remi/project/jobs/sample_job.rb +164 -0
  46. data/lib/remi/project/jobs/transforms/date_diff_job.rb +17 -0
  47. data/lib/remi/project/jobs/transforms/parse_date_job.rb +18 -0
  48. data/lib/remi/project/jobs/transforms/prefix_job.rb +16 -0
  49. data/lib/remi/project/jobs/transforms/transform_jobs.rb +3 -0
  50. data/lib/remi/settings.rb +39 -0
  51. data/lib/remi/sf_bulk_helper.rb +265 -0
  52. data/lib/remi/source_to_target_map.rb +93 -0
  53. data/lib/remi/transform.rb +137 -0
  54. data/lib/remi/version.rb +3 -0
  55. data/remi.gemspec +25 -7
  56. data/workbooks/sample_workbook.ipynb +56 -0
  57. data/workbooks/workbook_helper.rb +1 -0
  58. metadata +234 -17
  59. data/lib/noodling.rb +0 -163
  60. data/test/test_NAME.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46611d84305353596aa2b69083c10515284f38fc
4
- data.tar.gz: 455d0e91952b3d0a4961733ce3ee47c9baa6b10f
3
+ metadata.gz: 0e96cbd80b9948b85124da0bb1a7b5618c0692ec
4
+ data.tar.gz: 8eee478cbfdb78fc3c670c5fb2978f076b9d4673
5
5
  SHA512:
6
- metadata.gz: 1ae4ff9142e4e0e856887e6b14922b43f224a4cfc759d70389f6cc09e724afddd73c8fed24d30bac4ea635087a8bc52af9fea58643a32015f3081dbea34b987b
7
- data.tar.gz: fa19b1adbde11aa26792ca1b772540595218e847b69db5cc7c86f70db71d478c82660935b9df223fab0feec560fdb64bb8e1f7013c6bff29343a651f1ba9c789
6
+ metadata.gz: c355c76c0abbbd1bb9f37ff7d4b384b8c54772bbdfad3d1eff0a4531c3da063e9bb777aca0e69936cd5047c7f059b1f393da889b9ac047cbe0d77411d9e9fc18
7
+ data.tar.gz: 87df4f46a2f4f1127ccd885baf89e2466829dd56db840ce2d227c2ae8a7a96ec145873aac2ab9220a15b78158b8ff0afde56f314a6ecfa3a8c5a5523df89a154
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_DISABLE_SHARED_GEMS: '1'
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  *~
2
- /.ruby-version
3
- /.ruby-gemset
2
+ /.yardoc
3
+ /vendor
4
+ /noodling
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # -*- mode: ruby -*-
2
+ source 'https://rubygems.org'
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,123 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ remi (0.2.1)
5
+ activesupport (~> 4.2)
6
+ bond (~> 0.5)
7
+ cucumber (~> 2.1)
8
+ daru (~> 0.1)
9
+ docile (~> 1.1)
10
+ net-sftp (~> 2.1)
11
+ pg (~> 0.18)
12
+ regexp-examples (~> 1.1)
13
+ restforce (~> 2.1)
14
+ rspec (~> 3.3)
15
+ salesforce_bulk_api (= 0.0.12)
16
+
17
+ GEM
18
+ remote: https://rubygems.org/
19
+ specs:
20
+ activesupport (4.2.5)
21
+ i18n (~> 0.7)
22
+ json (~> 1.7, >= 1.7.7)
23
+ minitest (~> 5.1)
24
+ thread_safe (~> 0.3, >= 0.3.4)
25
+ tzinfo (~> 1.1)
26
+ bond (0.5.1)
27
+ builder (3.2.2)
28
+ clbustos-rtf (0.4.2)
29
+ cucumber (2.3.0)
30
+ builder (>= 2.1.2)
31
+ cucumber-core (~> 1.4.0)
32
+ cucumber-wire (~> 0.0.1)
33
+ diff-lcs (>= 1.1.3)
34
+ event-bus (~> 0.1.0)
35
+ gherkin (~> 3.2.0)
36
+ multi_json (>= 1.7.5, < 2.0)
37
+ multi_test (>= 0.1.2)
38
+ cucumber-core (1.4.0)
39
+ gherkin (~> 3.2.0)
40
+ cucumber-wire (0.0.1)
41
+ daru (0.1.1)
42
+ reportbuilder (~> 1.4)
43
+ spreadsheet (~> 1.0.3)
44
+ diff-lcs (1.2.5)
45
+ docile (1.1.5)
46
+ event-bus (0.1.0)
47
+ faraday (0.9.2)
48
+ multipart-post (>= 1.2, < 3)
49
+ faraday_middleware (0.10.0)
50
+ faraday (>= 0.7.4, < 0.10)
51
+ gherkin (3.2.0)
52
+ hashie (3.4.3)
53
+ i18n (0.7.0)
54
+ iruby (0.2.7)
55
+ bond (~> 0.5)
56
+ mimemagic (~> 0.3)
57
+ multi_json (~> 1.11)
58
+ rbczmq (~> 1.7)
59
+ json (1.8.3)
60
+ mimemagic (0.3.1)
61
+ minitest (5.8.3)
62
+ multi_json (1.11.2)
63
+ multi_test (0.1.2)
64
+ multipart-post (2.0.0)
65
+ net-sftp (2.1.2)
66
+ net-ssh (>= 2.6.5)
67
+ net-ssh (3.0.2)
68
+ pg (0.18.4)
69
+ prawn (0.8.4)
70
+ prawn-core (>= 0.8.4, < 0.9)
71
+ prawn-layout (>= 0.8.4, < 0.9)
72
+ prawn-security (>= 0.8.4, < 0.9)
73
+ prawn-core (0.8.4)
74
+ prawn-layout (0.8.4)
75
+ prawn-security (0.8.4)
76
+ prawn-svg (0.9.1.11)
77
+ prawn (>= 0.8.4)
78
+ rbczmq (1.7.9)
79
+ regexp-examples (1.1.4)
80
+ reportbuilder (1.4.2)
81
+ clbustos-rtf (~> 0.4.0)
82
+ prawn (~> 0.8.4)
83
+ prawn-svg (~> 0.9.1)
84
+ text-table (~> 1.2)
85
+ restforce (2.1.2)
86
+ faraday (~> 0.9.0)
87
+ faraday_middleware (>= 0.8.8)
88
+ hashie (>= 1.2.0, < 4.0)
89
+ json (>= 1.7.5, < 1.9.0)
90
+ rspec (3.4.0)
91
+ rspec-core (~> 3.4.0)
92
+ rspec-expectations (~> 3.4.0)
93
+ rspec-mocks (~> 3.4.0)
94
+ rspec-core (3.4.1)
95
+ rspec-support (~> 3.4.0)
96
+ rspec-expectations (3.4.0)
97
+ diff-lcs (>= 1.2.0, < 2.0)
98
+ rspec-support (~> 3.4.0)
99
+ rspec-mocks (3.4.1)
100
+ diff-lcs (>= 1.2.0, < 2.0)
101
+ rspec-support (~> 3.4.0)
102
+ rspec-support (3.4.1)
103
+ ruby-ole (1.2.12)
104
+ salesforce_bulk_api (0.0.12)
105
+ json
106
+ xml-simple
107
+ spreadsheet (1.0.9)
108
+ ruby-ole (>= 1.0)
109
+ text-table (1.2.4)
110
+ thread_safe (0.3.5)
111
+ tzinfo (1.2.2)
112
+ thread_safe (~> 0.1)
113
+ xml-simple (1.1.5)
114
+
115
+ PLATFORMS
116
+ ruby
117
+
118
+ DEPENDENCIES
119
+ iruby (= 0.2.7)
120
+ remi!
121
+
122
+ BUNDLED WITH
123
+ 1.10.6
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 InsideTrack, Inc. ("REMI" name created by Sterling Paramore, all rights reserved.)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,4 +1,95 @@
1
- # Remi
2
- ## Ruby Extract Modify and Integrate
1
+ # Remi - Ruby Extract Map Integrate
3
2
 
4
- Something like SAS, but better.
3
+ **Purpose:** Remi is a Ruby-based ETL package that provides an
4
+ expressive data transformation language and facilitates the
5
+ implementation and validation of non-technical business logic.
6
+
7
+ Borrowing from principles of test/behavior-driven development
8
+ (TDD/BDD), Remi is a system that supports business-rule-driven
9
+ development (BRDD). BRDD captures the idea that the rules that
10
+ describe data transformations should both (1) be accessible to
11
+ non-technical business users and (2) be strictly enforced in the logic
12
+ that executes those transformations. Remi is a Ruby application
13
+ that allows a developer to write data transformation logic and have
14
+ that logic validated according to business rule documentation.
15
+
16
+
17
+ Remi will follow [semantic versioning](http://semver.org/) principles.
18
+ Of course, while we're still on major version zero, little effort will
19
+ be made to maintain backward compatibility.
20
+
21
+ ## Getting Started
22
+
23
+ Add the gem to your Gemfile, `bundle install`, and then initialize your repository as
24
+ Remi project
25
+
26
+ remi --init
27
+
28
+ This command will create two directories: `jobs` and `features`. The
29
+ `jobs` directory contains an example of a Remi job that can be tested
30
+ using the BRDD spec defined in the `features` directory. Test to make
31
+ sure this works by running
32
+
33
+ cucumber
34
+
35
+ All of the test should pass.
36
+
37
+ ## Transforming Data
38
+
39
+ TODO:
40
+
41
+ Describe Daru foundation
42
+
43
+ Examples setting up a job class with
44
+ * csv source
45
+ * sf source
46
+ * dataframe intermediate target
47
+ * csv target
48
+ * parameters
49
+ * maps
50
+
51
+ ## Business Rules
52
+
53
+ TODO: Description of writing Business Rules.
54
+
55
+ ### Conventions to follow when writing features
56
+
57
+ * Sources, targets, examples, field names enclosed in single quotes - `'field name'`
58
+ * Field values enclosed in double quotes - `"field value"`
59
+ * Special functions enclosed in stars - `*function*`
60
+ * Example values encolsed in angular brackets - `<example>`
61
+
62
+ Write whatever in scenario and feature descriptions
63
+
64
+ ### Common step library
65
+
66
+
67
+ `Given the job is 'My Cool Job'`
68
+ `Given the job source 'Client File'`
69
+ `Given the job source 'Salesforce Extract'
70
+ `Given the job target 'Salesforce Contact'`
71
+
72
+ Given the following example record called 'my killer example record':
73
+ | Id | Name |
74
+ | 1234 | OneTwoThreeFour |
75
+
76
+ ... etc ...
77
+
78
+ ## Business Rule Validation
79
+
80
+ TODO: Description of how to write Business Rule validations.
81
+
82
+
83
+
84
+
85
+
86
+ ## Contributing
87
+
88
+ The best way to contribute would be to try it out and provide as much
89
+ feedback as possible.
90
+
91
+ If you want to develop the Remi framework then just fork, code, pull
92
+ request, repeat. Try to follow the
93
+ [Ruby style guide](https://github.com/styleguide/ruby) and suggest
94
+ other best practices. I'm very interested in getting other ETL
95
+ developers contribute their own perspective to the project.
data/bin/remi ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ File.expand_path(File.join(File.dirname(__FILE__),'../lib')).tap {|pwd| $LOAD_PATH.unshift(pwd) unless $LOAD_PATH.include?(pwd)}
3
+
4
+ require 'bundler/setup'
5
+ require 'remi'
6
+ require 'remi/cli'
7
+
8
+ Remi::Cli.execute
@@ -0,0 +1,47 @@
1
+ ## Installation using rbenv on OS X
2
+
3
+ Using instructions found http://robots.thoughtbot.com/using-rbenv-to-manage-rubies-and-gems
4
+ and http://dan.carley.co/blog/2012/02/07/rbenv-and-bundler/. Here's how
5
+ to get started with rbenv on os x
6
+
7
+ brew update
8
+ brew install rbenv
9
+
10
+ Add the following lines to `.bashrc`:
11
+
12
+ # Homebrew rbenv
13
+ #To use Homebrew's directories rather than ~/.rbenv add to your profile:
14
+ export RBENV_ROOT=/usr/local/var/rbenv
15
+ if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi
16
+
17
+ Restart the shell and install
18
+
19
+ brew install rbenv-gem-rehash
20
+ brew install ruby-build
21
+
22
+ Restart the shell and then install the rubies
23
+
24
+ rbenv install 2.2.2
25
+ rbenv global 2.2.2
26
+
27
+ Install rbenv-bundler
28
+
29
+ brew install rbenv-bundler
30
+ rbenv bundler on
31
+
32
+ Install bundler
33
+
34
+ gem update --system
35
+ gem install bundler
36
+ rbenv rehash
37
+
38
+ Configure bundler by adding the following to `~/.bundle/config`
39
+
40
+ ---
41
+ BUNDLE_PATH: vendor/bundle
42
+ BUNDLE_DISABLE_SHARED_GEMS: "1"
43
+
44
+ Finally, move into the Remi directory and install gems
45
+
46
+ bundle install
47
+ rbenv rehash
data/lib/remi.rb CHANGED
@@ -1,12 +1,59 @@
1
- #!/usr/bin/ruby
1
+ File.expand_path(File.dirname(__FILE__)).tap {|pwd| $LOAD_PATH.unshift(pwd) unless $LOAD_PATH.include?(pwd)}
2
2
 
3
- class Hola
4
- def self.hi
5
- puts "Hello world!"
6
- end
7
- def self.bye
8
- puts "Goodbye, cruel world!"
9
- end
10
- end
3
+ # Core libraries
4
+ require 'yaml'
5
+ require 'json'
6
+ require 'tmpdir'
11
7
 
8
+ # Gems
9
+ require 'daru'
10
+ require 'docile'
11
+ require 'net/sftp'
12
+ require 'pg'
12
13
 
14
+ # ActiveSupport extensions
15
+ require 'active_support'
16
+ require 'active_support/core_ext/object/conversions'
17
+ require 'active_support/core_ext/object/blank'
18
+ require 'active_support/core_ext/object/try'
19
+ require 'active_support/core_ext/object/inclusion'
20
+ require 'active_support/core_ext/string/inflections'
21
+ require 'active_support/core_ext/numeric/time'
22
+ require 'active_support/core_ext/numeric/conversions'
23
+ require 'active_support/core_ext/date/calculations'
24
+ require 'active_support/core_ext/time/calculations'
25
+
26
+ # - Should separate SF stuff into separate SF support package
27
+ require 'restforce'
28
+ require 'salesforce_bulk_api'
29
+
30
+
31
+ # Remi
32
+ require 'remi/version.rb'
33
+ require 'remi/core/string.rb'
34
+
35
+ require 'remi/settings'
36
+ require 'remi/job'
37
+ require 'remi/source_to_target_map'
38
+ require 'remi/field_symbolizers'
39
+ require 'remi/data_subject'
40
+ require 'remi/sf_bulk_helper' # separate into SF support package
41
+
42
+ require 'remi/core/daru'
43
+ require 'remi/core/refinements'
44
+
45
+ require 'remi/extractor/sftp_file'
46
+
47
+ require 'remi/data_source.rb'
48
+ require 'remi/data_source/data_frame'
49
+ require 'remi/data_source/csv_file'
50
+ require 'remi/data_source/salesforce'
51
+ require 'remi/data_source/postgres'
52
+
53
+ require 'remi/data_target.rb'
54
+ require 'remi/data_target/data_frame'
55
+ require 'remi/data_target/salesforce'
56
+ require 'remi/data_target/csv_file'
57
+
58
+ require 'remi/lookup/regex_sieve'
59
+ require 'remi/transform'
data/lib/remi/cli.rb ADDED
@@ -0,0 +1,56 @@
1
+ require 'optparse'
2
+ require 'fileutils'
3
+
4
+
5
+ module Remi
6
+ module Cli
7
+ extend self
8
+
9
+ def execute
10
+ parse
11
+ initialize_project if @options[:init] == true
12
+ end
13
+
14
+ def parse(args = ARGV)
15
+ options = {}
16
+
17
+ opt_parser = OptionParser.new do |opts|
18
+ opts.banner = <<-EOT.unindent
19
+ Usage: Command line helpers for Remi.
20
+ EOT
21
+
22
+ opts.on('-h', '--help', 'Show this message') do
23
+ puts opts
24
+ exit
25
+ end
26
+
27
+ options[:init] = false
28
+ opts.on('-i', '--init', 'Initialze a new Remi project') do
29
+ options[:init] = true
30
+ end
31
+ end
32
+ opt_parser.parse!(args)
33
+
34
+ @options = options
35
+ end
36
+
37
+ def initialize_project
38
+ template_dir = File.expand_path(File.join(File.dirname(__FILE__),'project'))
39
+
40
+ FileUtils.mkdir_p "features"
41
+ FileUtils.cp(File.join(template_dir, 'features/sample_job.feature'), 'features')
42
+
43
+ FileUtils.mkdir_p "features/support"
44
+ FileUtils.cp(File.join(template_dir, 'features/support/env.rb'), 'features/support')
45
+ FileUtils.cp(File.join(template_dir, 'features/support/env_app.rb'), 'features/support') unless File.exist?('features/support/env_app.rb')
46
+
47
+ FileUtils.mkdir_p "features/step_definitions"
48
+ FileUtils.cp(File.join(template_dir, 'features/step_definitions/remi_step.rb'), 'features/step_definitions')
49
+
50
+ FileUtils.mkdir_p "jobs"
51
+ FileUtils.cp(File.join(template_dir, 'jobs/all_jobs_shared.rb'), 'jobs') unless File.exist?('jobs/all_jobs_shared.rb')
52
+ FileUtils.cp(File.join(template_dir, 'jobs/sample_job.rb'), 'jobs')
53
+ end
54
+
55
+ end
56
+ end