data_guru 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +3 -0
- data/.rubocop.yml +10 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +133 -0
- data/Rakefile +6 -0
- data/bin/console +7 -0
- data/bin/setup +7 -0
- data/data_guru.gemspec +29 -0
- data/lib/data_guru/client.rb +81 -0
- data/lib/data_guru/collection.rb +58 -0
- data/lib/data_guru/configuration.rb +10 -0
- data/lib/data_guru/model.rb +54 -0
- data/lib/data_guru/model_configuration.rb +32 -0
- data/lib/data_guru/validation.rb +51 -0
- data/lib/data_guru/validations/configuration.rb +37 -0
- data/lib/data_guru/validations/model_configuration.rb +139 -0
- data/lib/data_guru/version.rb +3 -0
- data/lib/data_guru.rb +31 -0
- metadata +179 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8c8667440f7886044b541e700f46712c984955f9
|
4
|
+
data.tar.gz: 744434dea8207c0c22e68762f7e47414ce2cd518
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c4d50f066499af43eb6aaba731c66b8c129462469248e9a33d25384bf189af9545f3f07f19a62f5da48d700fed8648b7090f9e097c2a6d0fbb1d799ded36f902
|
7
|
+
data.tar.gz: 984c11f90833f18b5ce17fae93e813a7613df62fbe6ac295fd4e9c8217dfd0ae057567a4060ee1ffa275d77df1ee2acacf6b6ed6bc142ff0a39969bd0827b2a7
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
# DataGuru
|
2
|
+
|
3
|
+
Manage configuration stored as JSON data in DataGuru-API server.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'data_guru'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install data_guru
|
20
|
+
|
21
|
+
## Configuration
|
22
|
+
|
23
|
+
Create config file in your app:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# app/config/initializers/data_guru.rb
|
27
|
+
DataGuru.configure do |config|
|
28
|
+
config.api_url = 'url of api server'
|
29
|
+
config.access_token = 'access token'
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Possible configuration values:
|
34
|
+
|
35
|
+
`api_url` - *[mandatory]* api server where data from Permissions is stored
|
36
|
+
|
37
|
+
`access_token` - *[mandatory]* token needed for verifying access to api server
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
If you use default config files (see Permissions section below) you can simply do:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
data = DataGuru::Client.new
|
45
|
+
|
46
|
+
# get collections
|
47
|
+
data.users.all
|
48
|
+
data.projects.all
|
49
|
+
data.github_teams.all
|
50
|
+
data.google_groups.all
|
51
|
+
data.rollbar_teams.all
|
52
|
+
data.toggl_teams.all
|
53
|
+
|
54
|
+
# find in collections by attribute
|
55
|
+
data.projects.find{ |project| project.display_name == 'Some project' }
|
56
|
+
data.users.find{ |user| user.github == 'example' }
|
57
|
+
|
58
|
+
# filter through collections by attributes
|
59
|
+
data.users.select{ |user| user.external }
|
60
|
+
data.users.select{ |user| user.public_key.nil? }.count
|
61
|
+
|
62
|
+
# select key names of all github teams user belongs to
|
63
|
+
user = data.users.first
|
64
|
+
data.github_teams.select{ |team| team.members.include?(user.id) }.map(&:id)
|
65
|
+
```
|
66
|
+
|
67
|
+
The collections have `Enumerable` module included so you can filter models by attributes easily (`data.users.select{ |user| user.some_method }`)
|
68
|
+
|
69
|
+
You can refresh repo and storage at any time, just do:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
data = DataGuru::Client.new
|
73
|
+
data.refresh
|
74
|
+
```
|
75
|
+
|
76
|
+
On a single model you can do:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
data = DataGuru::Client.new
|
80
|
+
user = data.users.all.first
|
81
|
+
|
82
|
+
# to get list of user attributes
|
83
|
+
user.attributes
|
84
|
+
|
85
|
+
# to get list of permitted and required attributes (see Permisions section below)
|
86
|
+
user.permitted_attributes
|
87
|
+
user.required_attributes
|
88
|
+
|
89
|
+
# check if user has all required attributes set
|
90
|
+
user.valid?
|
91
|
+
user.missing_attributes
|
92
|
+
```
|
93
|
+
|
94
|
+
Each model has a set of getter methods (permitted_attributes) so you can for example do `user.github` to get just the github username of the user.
|
95
|
+
Each model also has `id` method which returns the name of the file, for example for the user in a file `john.doe.yml` will return `john.doe`.
|
96
|
+
|
97
|
+
You can check whether configuration (in your rails app) and model configuration (in your permissions repo) is valid by running `DataGuru::Client.new.errors`.
|
98
|
+
|
99
|
+
### Permissions
|
100
|
+
|
101
|
+
A sample permissions repo contains a `config` directory with files like `user.yml`, `project.yml`, `github_team.yml`. In these files you specify attributes for each model with information about whether they are required, what is the default value and what type of value it is.
|
102
|
+
|
103
|
+
```
|
104
|
+
---
|
105
|
+
name:
|
106
|
+
required: true
|
107
|
+
default_value:
|
108
|
+
value_type: string
|
109
|
+
emails:
|
110
|
+
required: true
|
111
|
+
default_value:
|
112
|
+
value_type: array
|
113
|
+
external:
|
114
|
+
required: false
|
115
|
+
default_value: false
|
116
|
+
value_type: boolean
|
117
|
+
```
|
118
|
+
|
119
|
+
The methods `permitted_attributes` and `required_attributes` returns the array of specified attributes.
|
120
|
+
|
121
|
+
All the files should be under the appropriate directory, for example all users under `users` directory, they can be nested if you want.
|
122
|
+
|
123
|
+
For more information see the [permissions template repo](https://github.com/ardhena/permissions-template).
|
124
|
+
|
125
|
+
## Development
|
126
|
+
|
127
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
128
|
+
|
129
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
130
|
+
|
131
|
+
## Contributing
|
132
|
+
|
133
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/netguru/data_guru.
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/data_guru.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "data_guru/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "data_guru"
|
8
|
+
spec.version = DataGuru::VERSION
|
9
|
+
spec.authors = ["Adam Nowak", "Katarzyna Jaskólska", "Jacek Adamek"]
|
10
|
+
spec.email = ["adam.nowak@netguru.co", "katarzyna.jaskolska@netguru.co", "jacek.adamek@netguru.co"]
|
11
|
+
|
12
|
+
spec.summary = "Wrapper for data stored in YAML files"
|
13
|
+
spec.homepage = "https://github.com/netguru/data_guru"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|features)/}) }
|
16
|
+
spec.bindir = "exe"
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "activesupport"
|
21
|
+
spec.add_dependency "git"
|
22
|
+
spec.add_dependency "httparty"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
spec.add_development_dependency "rubocop"
|
29
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module DataGuru
|
2
|
+
class Client
|
3
|
+
require 'httparty'
|
4
|
+
require 'active_support/core_ext/string'
|
5
|
+
|
6
|
+
def method_missing(name)
|
7
|
+
create_model_class(name) if should_create_class?(name)
|
8
|
+
value = DataGuru::Collection.new(collection_name: name, model: model(name))
|
9
|
+
get_variable(name) || set_variable(name, value)
|
10
|
+
end
|
11
|
+
|
12
|
+
def refresh
|
13
|
+
HTTParty.get(refresh_data_url)
|
14
|
+
wipe_collections_cache
|
15
|
+
end
|
16
|
+
|
17
|
+
def errors
|
18
|
+
DataGuru::Validation.new.errors
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def should_create_class?(name)
|
24
|
+
name_exists?(name) && !class_exists?(class_name(name))
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_model_class(name)
|
28
|
+
DataGuru.const_set(class_name(name), Class.new { include Model })
|
29
|
+
end
|
30
|
+
|
31
|
+
def class_name(name)
|
32
|
+
name.to_s.camelize.singularize
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_exists?(class_name)
|
36
|
+
eval("defined?(#{class_name}) && #{class_name}.is_a?(Class)")
|
37
|
+
end
|
38
|
+
|
39
|
+
def name_exists?(name)
|
40
|
+
collection_names.include?(name.to_s)
|
41
|
+
end
|
42
|
+
|
43
|
+
def model(name)
|
44
|
+
"data_guru/#{name}".classify.constantize
|
45
|
+
rescue NameError
|
46
|
+
raise "Collection '#{name}' does not exist"
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_variable(name)
|
50
|
+
instance_variable_get("@#{name}")
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_variable(name, value)
|
54
|
+
instance_variable_set("@#{name}", value)
|
55
|
+
end
|
56
|
+
|
57
|
+
def wipe_collections_cache
|
58
|
+
collection_names.each { |name| instance_variable_set("@#{name}", nil) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def access_token
|
62
|
+
DataGuru.config.access_token
|
63
|
+
end
|
64
|
+
|
65
|
+
def api_url
|
66
|
+
DataGuru.config.api_url
|
67
|
+
end
|
68
|
+
|
69
|
+
def refresh_data_url
|
70
|
+
"#{api_url}/refresh?token=#{access_token}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def collection_names
|
74
|
+
HTTParty.get(collection_names_url)
|
75
|
+
end
|
76
|
+
|
77
|
+
def collection_names_url
|
78
|
+
"#{api_url}/?token=#{access_token}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module DataGuru
|
2
|
+
class Collection
|
3
|
+
include Enumerable
|
4
|
+
require 'httparty'
|
5
|
+
|
6
|
+
attr_reader :collection_name, :model, :config
|
7
|
+
|
8
|
+
def initialize(collection_name:, model:, config: default_config(model))
|
9
|
+
@collection_name = collection_name
|
10
|
+
@model = model
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def all
|
15
|
+
@all ||= build_models(collection_name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def each(&block)
|
19
|
+
all.each(&block)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def default_config(model)
|
25
|
+
DataGuru::ModelConfiguration.new(model: model)
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_models(collection_type)
|
29
|
+
data(collection_type).map do |key, data|
|
30
|
+
model.new(key, data, config, config_data)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def access_token
|
35
|
+
DataGuru.config.access_token
|
36
|
+
end
|
37
|
+
|
38
|
+
def api_url
|
39
|
+
DataGuru.config.api_url
|
40
|
+
end
|
41
|
+
|
42
|
+
def collection_resource_url(collection_type)
|
43
|
+
"#{api_url}/#{collection_type}?token=#{access_token}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def config_resource_url
|
47
|
+
"#{api_url}/config?token=#{access_token}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def config_data
|
51
|
+
@config_data ||= HTTParty.get(config_resource_url)
|
52
|
+
end
|
53
|
+
|
54
|
+
def data(collection_type)
|
55
|
+
HTTParty.get(collection_resource_url(collection_type))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module DataGuru
|
2
|
+
module Model
|
3
|
+
attr_reader :permitted_attributes, :required_attributes, :id
|
4
|
+
|
5
|
+
def initialize(key, attrs, config, config_data)
|
6
|
+
@id = key
|
7
|
+
@permitted_attributes = config.permitted_attributes(config_data)
|
8
|
+
@required_attributes = config.required_attributes(config_data)
|
9
|
+
|
10
|
+
permitted_attributes.each do |attribute|
|
11
|
+
set_attr_getter(attribute)
|
12
|
+
default_value = config.attributes(config_data)[attribute.to_s]["default_value"]
|
13
|
+
set_attr_value(attribute, attrs[attribute.to_s], default_value)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def attributes
|
18
|
+
@attributes ||= all_attributes
|
19
|
+
end
|
20
|
+
|
21
|
+
def valid?
|
22
|
+
present_required_attributes == required_attributes
|
23
|
+
end
|
24
|
+
|
25
|
+
def missing_attributes
|
26
|
+
required_attributes - present_required_attributes
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def set_attr_getter(attribute)
|
32
|
+
self.class.send(:define_method, attribute) do
|
33
|
+
instance_variable_get("@#{attribute}")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_attr_value(attribute, value, default_value)
|
38
|
+
value_to_set = value.nil? ? default_value : value
|
39
|
+
instance_variable_set("@#{attribute}", value_to_set)
|
40
|
+
end
|
41
|
+
|
42
|
+
def present_required_attributes
|
43
|
+
required_attributes.map do |name|
|
44
|
+
!attributes[name].nil? ? name : nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def all_attributes
|
49
|
+
attrs = permitted_attributes
|
50
|
+
.map{ |name| [name, public_send(name)] } << [:id, id]
|
51
|
+
Hash[attrs]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module DataGuru
|
2
|
+
class ModelConfiguration
|
3
|
+
attr_reader :model, :model_name
|
4
|
+
|
5
|
+
def initialize(model:, model_name: default_model_name(model))
|
6
|
+
@model = model
|
7
|
+
@model_name = model_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def attributes(config_data)
|
11
|
+
config_data[model_name]
|
12
|
+
end
|
13
|
+
|
14
|
+
def permitted_attributes(config_data)
|
15
|
+
attributes(config_data).map{ |k, _v| k.to_sym }
|
16
|
+
end
|
17
|
+
|
18
|
+
def required_attributes(config_data)
|
19
|
+
attributes(config_data).map{ |k, v| v["required"] ? k.to_sym : nil }.reject(&:nil?)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def default_model_name(model)
|
25
|
+
model.name.split('::').last
|
26
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
27
|
+
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
28
|
+
.tr("-", "_")
|
29
|
+
.downcase
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module DataGuru
|
2
|
+
class Validation
|
3
|
+
require 'httparty'
|
4
|
+
attr_reader :config, :keys
|
5
|
+
|
6
|
+
TYPES = %w(configuration model_configuration)
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@config = config_data
|
10
|
+
@keys = keys
|
11
|
+
end
|
12
|
+
|
13
|
+
def errors
|
14
|
+
TYPES.flat_map{ |type| send("#{type}_errors") }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def config_data
|
20
|
+
HTTParty.get(config_resource_url)
|
21
|
+
end
|
22
|
+
|
23
|
+
def config_resource_url
|
24
|
+
"#{api_url}/config?token=#{access_token}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def api_url
|
28
|
+
DataGuru.config.api_url
|
29
|
+
end
|
30
|
+
|
31
|
+
def access_token
|
32
|
+
DataGuru.config.access_token
|
33
|
+
end
|
34
|
+
|
35
|
+
def keys
|
36
|
+
HTTParty.get(keys_resource_url)
|
37
|
+
end
|
38
|
+
|
39
|
+
def keys_resource_url
|
40
|
+
"#{api_url}?token=#{access_token}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def configuration_errors
|
44
|
+
DataGuru::ConfigurationValidation.new.errors
|
45
|
+
end
|
46
|
+
|
47
|
+
def model_configuration_errors
|
48
|
+
DataGuru::ModelConfigurationValidation.new(config, keys).errors
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module DataGuru
|
2
|
+
class ConfigurationValidation
|
3
|
+
VALIDATIONS = %w(api_url access_token)
|
4
|
+
|
5
|
+
def errors
|
6
|
+
return [] if valid?
|
7
|
+
build_errors
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def valid?
|
13
|
+
api_url_valid? && access_token_valid?
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_errors
|
17
|
+
VALIDATIONS.flat_map do |name|
|
18
|
+
send("#{name}_valid?") ? [] : send("#{name}_error")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
VALIDATIONS.each do |name|
|
23
|
+
# def api_url_valid?, access_token_valid?
|
24
|
+
define_method("#{name}_valid?") do
|
25
|
+
!DataGuru.config.public_send(name).nil?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def api_url_error
|
30
|
+
'Configuration: no api url'
|
31
|
+
end
|
32
|
+
|
33
|
+
def access_token_error
|
34
|
+
'Configuration: no access token'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
module DataGuru
|
2
|
+
class ModelConfigurationValidation
|
3
|
+
attr_reader :config, :keys
|
4
|
+
|
5
|
+
VALIDATIONS = %w(config model_file model_attributes model_attribute_name
|
6
|
+
model_attribute_content)
|
7
|
+
RESERVED_WORDS = %w(id attributes permitted_attributes required_attributes
|
8
|
+
missing_attributes valid?)
|
9
|
+
ATTRIBUTE_TYPES = %w(required default_value value_type)
|
10
|
+
|
11
|
+
def initialize(config, keys)
|
12
|
+
@config = config
|
13
|
+
@keys = keys
|
14
|
+
end
|
15
|
+
|
16
|
+
def errors
|
17
|
+
return [] if valid?
|
18
|
+
build_errors
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def model_names
|
24
|
+
keys.map(&:singularize) - ['config']
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid?
|
28
|
+
config_valid? && model_file_valid? && model_attributes_valid? &&
|
29
|
+
model_attribute_name_valid? && model_attribute_content_valid?
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_errors
|
33
|
+
VALIDATIONS.flat_map do |name|
|
34
|
+
send("#{name}_valid?") ? [] : send("#{name}_error")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def config_valid?
|
39
|
+
keys.include?('config')
|
40
|
+
end
|
41
|
+
|
42
|
+
def model_file_valid?
|
43
|
+
return false unless config_valid?
|
44
|
+
valid_files = model_names
|
45
|
+
.map{ |name| config.include?(name) }
|
46
|
+
.select{ |name| name }
|
47
|
+
valid_files.size == model_names.size
|
48
|
+
end
|
49
|
+
|
50
|
+
def model_attributes_valid?
|
51
|
+
return false unless model_file_valid?
|
52
|
+
valid_models = model_names
|
53
|
+
.map{ |name| config[name] == false || config[name].nil? }
|
54
|
+
.select{ |name| !name }
|
55
|
+
valid_models.size == model_names.size
|
56
|
+
end
|
57
|
+
|
58
|
+
def model_attribute_name_valid?
|
59
|
+
attributes = present_models.flat_map{ |model| config[model].keys }
|
60
|
+
diff = attributes - RESERVED_WORDS
|
61
|
+
attributes.count == diff.count
|
62
|
+
end
|
63
|
+
|
64
|
+
def model_attribute_content_valid?
|
65
|
+
attributes = present_models.map{ |model| config[model] }
|
66
|
+
invalid_attrs = attributes.flat_map{ |model|
|
67
|
+
model.values.map{ |attributes| attributes.keys.sort == ATTRIBUTE_TYPES.sort }
|
68
|
+
}.select{ |a| !a }
|
69
|
+
invalid_attrs.size == 0
|
70
|
+
end
|
71
|
+
|
72
|
+
def config_error
|
73
|
+
'Model Configuration: no config directory in repo'
|
74
|
+
end
|
75
|
+
|
76
|
+
def model_file_error
|
77
|
+
"Model Configuration: no config file for model - #{missing_models.join(', ')}"
|
78
|
+
end
|
79
|
+
|
80
|
+
def model_attributes_error
|
81
|
+
"Model Configuration: no permitted attributes for model - #{missing_model_contents.join(', ')}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def model_attribute_name_error
|
85
|
+
reserved_model_attributes.map do |model, attrs|
|
86
|
+
"Model Configuration: reserved words used as attributes in model #{model} - #{attrs.join(', ')}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def model_attribute_content_error
|
91
|
+
missing_model_attributes.flat_map do |model, attrs|
|
92
|
+
attrs.map do |name, type|
|
93
|
+
attributes = "attribute #{name} missing #{type.join(', ')}"
|
94
|
+
"Model Configuration: missing attribute declaration in model #{model} - #{attributes}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def missing_models
|
100
|
+
return model_names unless config_valid?
|
101
|
+
model_names.flat_map{ |name| config.include?(name) ? [] : name }
|
102
|
+
end
|
103
|
+
|
104
|
+
def missing_model_contents
|
105
|
+
return model_names unless config_valid?
|
106
|
+
model_names.flat_map do |name|
|
107
|
+
if missing_models.include?(name)
|
108
|
+
name
|
109
|
+
else
|
110
|
+
config[name] == false || config[name].nil? ? name : []
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def present_models
|
116
|
+
model_names - missing_model_contents
|
117
|
+
end
|
118
|
+
|
119
|
+
def reserved_model_attributes
|
120
|
+
wrong_attributes = present_models.map do |model|
|
121
|
+
wrong_attrs = config[model].keys & RESERVED_WORDS
|
122
|
+
[ model, wrong_attrs ]
|
123
|
+
end
|
124
|
+
Hash[wrong_attributes]
|
125
|
+
end
|
126
|
+
|
127
|
+
def missing_model_attributes
|
128
|
+
all = Hash[present_models.map{ |model| [model, config[model]] }]
|
129
|
+
missing = all.map do |model, attributes|
|
130
|
+
attrs = Hash[ attributes.map{ |name, types| [name, ATTRIBUTE_TYPES - types.keys] } ]
|
131
|
+
without_empty = attrs
|
132
|
+
.map{ |name, types| types.empty? ? [] : [name, types] }
|
133
|
+
.reject{ |array| array.empty? }
|
134
|
+
[ model, Hash[without_empty] ]
|
135
|
+
end
|
136
|
+
Hash[missing.reject{ |k, v| v.empty? }]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/lib/data_guru.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "data_guru/version"
|
2
|
+
require "data_guru/configuration"
|
3
|
+
require "data_guru/model_configuration"
|
4
|
+
|
5
|
+
require "data_guru/validation"
|
6
|
+
require "data_guru/validations/configuration"
|
7
|
+
require "data_guru/validations/model_configuration"
|
8
|
+
|
9
|
+
require "data_guru/collection"
|
10
|
+
|
11
|
+
require "data_guru/model"
|
12
|
+
|
13
|
+
require "data_guru/client"
|
14
|
+
|
15
|
+
module DataGuru
|
16
|
+
class << self
|
17
|
+
attr_accessor :config
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.config
|
21
|
+
@config ||= Configuration.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.configure
|
25
|
+
yield(config)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.reset
|
29
|
+
@config = Configuration.new
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: data_guru
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adam Nowak
|
8
|
+
- Katarzyna Jaskólska
|
9
|
+
- Jacek Adamek
|
10
|
+
autorequire:
|
11
|
+
bindir: exe
|
12
|
+
cert_chain: []
|
13
|
+
date: 2015-10-19 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: git
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: httparty
|
45
|
+
requirement: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
type: :runtime
|
51
|
+
prerelease: false
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
- !ruby/object:Gem::Dependency
|
58
|
+
name: bundler
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '1.10'
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - "~>"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '1.10'
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: pry
|
73
|
+
requirement: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
name: rake
|
87
|
+
requirement: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - "~>"
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '10.0'
|
92
|
+
type: :development
|
93
|
+
prerelease: false
|
94
|
+
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - "~>"
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '10.0'
|
99
|
+
- !ruby/object:Gem::Dependency
|
100
|
+
name: rspec
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
type: :development
|
107
|
+
prerelease: false
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: rubocop
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
type: :development
|
121
|
+
prerelease: false
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
description:
|
128
|
+
email:
|
129
|
+
- adam.nowak@netguru.co
|
130
|
+
- katarzyna.jaskolska@netguru.co
|
131
|
+
- jacek.adamek@netguru.co
|
132
|
+
executables: []
|
133
|
+
extensions: []
|
134
|
+
extra_rdoc_files: []
|
135
|
+
files:
|
136
|
+
- ".gitignore"
|
137
|
+
- ".rspec"
|
138
|
+
- ".rubocop.yml"
|
139
|
+
- ".travis.yml"
|
140
|
+
- Gemfile
|
141
|
+
- README.md
|
142
|
+
- Rakefile
|
143
|
+
- bin/console
|
144
|
+
- bin/setup
|
145
|
+
- data_guru.gemspec
|
146
|
+
- lib/data_guru.rb
|
147
|
+
- lib/data_guru/client.rb
|
148
|
+
- lib/data_guru/collection.rb
|
149
|
+
- lib/data_guru/configuration.rb
|
150
|
+
- lib/data_guru/model.rb
|
151
|
+
- lib/data_guru/model_configuration.rb
|
152
|
+
- lib/data_guru/validation.rb
|
153
|
+
- lib/data_guru/validations/configuration.rb
|
154
|
+
- lib/data_guru/validations/model_configuration.rb
|
155
|
+
- lib/data_guru/version.rb
|
156
|
+
homepage: https://github.com/netguru/data_guru
|
157
|
+
licenses: []
|
158
|
+
metadata: {}
|
159
|
+
post_install_message:
|
160
|
+
rdoc_options: []
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
requirements: []
|
174
|
+
rubyforge_project:
|
175
|
+
rubygems_version: 2.4.8
|
176
|
+
signing_key:
|
177
|
+
specification_version: 4
|
178
|
+
summary: Wrapper for data stored in YAML files
|
179
|
+
test_files: []
|