kangaroo 0.0.3 → 0.1.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -1
- data/Gemfile +11 -0
- data/README.md +23 -132
- data/Rakefile +0 -8
- data/bin/kang +5 -64
- data/bin/kangdoc +21 -0
- data/bin/kangviz +21 -0
- data/config/kangaroo.yml.sample +12 -2
- data/docs/Architecture.md +1 -0
- data/docs/Classes.md +67 -0
- data/docs/Installation.md +2 -1
- data/docs/Usage.md +1 -0
- data/kangaroo.gemspec +8 -8
- data/lib/kangaroo.rb +3 -2
- data/lib/kangaroo/commands/base.rb +123 -0
- data/lib/kangaroo/commands/cli.rb +65 -0
- data/lib/kangaroo/commands/doc.rb +44 -0
- data/lib/kangaroo/commands/endpoint.rb +33 -0
- data/lib/kangaroo/commands/viz.rb +58 -0
- data/lib/kangaroo/doc.rb +2 -0
- data/lib/kangaroo/exception.rb +3 -0
- data/lib/kangaroo/hirb.rb +2 -1
- data/lib/kangaroo/model/associations.rb +33 -0
- data/lib/kangaroo/model/associations/many2one.rb +43 -0
- data/lib/kangaroo/model/associations/one2many.rb +41 -0
- data/lib/kangaroo/model/attributes.rb +88 -93
- data/lib/kangaroo/model/base.rb +44 -15
- data/lib/kangaroo/model/condition_normalizer.rb +7 -7
- data/lib/kangaroo/model/data_import.rb +28 -0
- data/lib/kangaroo/model/default_attributes.rb +20 -14
- data/lib/kangaroo/model/dynamic_finder.rb +42 -0
- data/lib/kangaroo/model/field.rb +52 -1
- data/lib/kangaroo/model/field/readonly.rb +39 -0
- data/lib/kangaroo/model/finder.rb +6 -2
- data/lib/kangaroo/model/inspector.rb +1 -4
- data/lib/kangaroo/model/mass_import.rb +42 -0
- data/lib/kangaroo/model/open_object_orm.rb +51 -5
- data/lib/kangaroo/model/persistence.rb +43 -19
- data/lib/kangaroo/model/readonly_attributes.rb +43 -0
- data/lib/kangaroo/model/relation.rb +40 -9
- data/lib/kangaroo/model/remote_execute.rb +1 -1
- data/lib/kangaroo/model/required_attributes.rb +26 -0
- data/lib/kangaroo/railtie.rb +13 -3
- data/lib/kangaroo/ruby_adapter/base.rb +2 -1
- data/lib/kangaroo/ruby_adapter/class_definition.rb +18 -3
- data/lib/kangaroo/ruby_adapter/fields.rb +27 -2
- data/lib/kangaroo/ruby_adapter/many2one.rb +38 -0
- data/lib/kangaroo/ruby_adapter/one2many.rb +31 -0
- data/lib/kangaroo/util/client.rb +29 -4
- data/lib/kangaroo/util/configuration.rb +15 -10
- data/lib/kangaroo/util/database.rb +8 -8
- data/lib/kangaroo/util/loader.rb +18 -22
- data/lib/kangaroo/util/loader/information_repository.rb +56 -0
- data/lib/kangaroo/util/loader/namespace.rb +1 -1
- data/lib/kangaroo/util/loader/reflection.rb +61 -0
- data/lib/kangaroo/util/loader/root_namespace.rb +12 -21
- data/lib/kangaroo/util/proxy.rb +9 -0
- data/lib/kangaroo/util/proxy/common.rb +28 -4
- data/lib/kangaroo/util/proxy/db.rb +14 -0
- data/lib/kangaroo/util/proxy/object.rb +40 -1
- data/lib/kangaroo/util/proxy/superadmin.rb +13 -0
- data/lib/kangaroo/version.rb +1 -1
- data/lib/kangaroo/viz.rb +1 -0
- data/lib/kangaroo/viz/base.rb +92 -0
- data/spec/commands/base_spec.rb +42 -0
- data/spec/functional/associations/many2one_spec.rb +72 -0
- data/spec/functional/associations/one2many_spec.rb +65 -0
- data/spec/functional/common_service_spec.rb +25 -0
- data/spec/functional/data_import_spec.rb +48 -0
- data/spec/functional/dynamic_finder_spec.rb +35 -0
- data/spec/functional/exception_handling_spec.rb +18 -0
- data/spec/functional/identity_spec.rb +48 -0
- data/spec/functional/import_export_spec.rb +39 -0
- data/spec/functional/lazy_loading_spec.rb +18 -11
- data/spec/functional/ordering_spec.rb +33 -0
- data/spec/functional/readonly_attributes_spec.rb +37 -0
- data/spec/functional/required_attributes_spec.rb +37 -0
- data/spec/functional/root_namespace_spec.rb +19 -0
- data/spec/functional/select_relation_spec.rb +26 -0
- data/spec/model/attributes_spec.rb +1 -0
- data/spec/model/base_spec.rb +1 -0
- data/spec/model/default_attributes_spec.rb +3 -1
- data/spec/model/finder_spec.rb +2 -1
- data/spec/model/inspector_spec.rb +1 -0
- data/spec/model/open_object_orm_spec.rb +5 -2
- data/spec/model/persistence_spec.rb +1 -0
- data/spec/model/relation_spec.rb +2 -2
- data/spec/ruby_adapter/class_definition_spec.rb +1 -0
- data/spec/server_helper.rb +0 -1
- data/spec/spec_helper.rb +4 -1
- data/spec/util/loader_spec.rb +6 -6
- metadata +152 -159
- data/Gemfile.lock +0 -69
- data/features/configuration.feature +0 -10
- data/features/env.rb +0 -8
- data/features/step_definitions/basic_steps.rb +0 -18
- data/features/step_definitions/configuration_steps.rb +0 -21
- data/features/support/test.yml +0 -11
- data/features/utility_services.feature +0 -33
data/docs/Installation.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
Installation
|
2
|
-
|
2
|
+
=====
|
3
3
|
|
4
4
|
#### Index
|
5
5
|
{file:README.md Readme}
|
@@ -7,6 +7,7 @@ Installation
|
|
7
7
|
{file:docs/Usage.md Usage}
|
8
8
|
{file:docs/Architecture.md Architecture}
|
9
9
|
{file:docs/AdditionalServices.md Additional Services}
|
10
|
+
{file:docs/Classes.md Classes}
|
10
11
|
|
11
12
|
Rails 3
|
12
13
|
-------
|
data/docs/Usage.md
CHANGED
data/kangaroo.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.authors = ["Michael Eickenberg", "Marian Theisen"]
|
11
11
|
s.email = 'marian@cice-online.net'
|
12
12
|
s.summary = "Kang! ActiveRecord-ish OpenObject"
|
13
|
-
s.homepage = "http://github.com/
|
13
|
+
s.homepage = "http://github.com/kayoom/kangaroo"
|
14
14
|
s.description = "ActiveRecord-ish OpenObject Wrapper"
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
@@ -18,14 +18,14 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
-
s.add_dependency
|
22
|
-
s.add_dependency "
|
21
|
+
s.add_dependency "rapuncel", "~> 0.0.5.RC1"
|
22
|
+
s.add_dependency "activemodel", ">= 3.0.0"
|
23
23
|
s.add_dependency "activesupport", ">= 3.0.0"
|
24
24
|
s.add_dependency "hirb"
|
25
|
+
s.add_dependency "highline"
|
26
|
+
s.add_dependency "ruby-graphviz", ">= 1.0.0"
|
25
27
|
|
26
|
-
s.add_development_dependency
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency
|
29
|
-
s.add_development_dependency 'cucumber'
|
30
|
-
s.add_development_dependency 'bundler'
|
28
|
+
s.add_development_dependency "yard"
|
29
|
+
s.add_development_dependency "rspec"
|
30
|
+
s.add_development_dependency "bundler"
|
31
31
|
end
|
data/lib/kangaroo.rb
CHANGED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'highline/import'
|
3
|
+
|
4
|
+
module Kangaroo
|
5
|
+
module Commands
|
6
|
+
class Base
|
7
|
+
attr_reader :configuration
|
8
|
+
|
9
|
+
def initialize *args
|
10
|
+
@configuration = Kangaroo::Util::Configuration::Defaults.dup
|
11
|
+
|
12
|
+
parse_options args
|
13
|
+
end
|
14
|
+
|
15
|
+
def run
|
16
|
+
validate_configuration
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
def validate_configuration
|
21
|
+
unless database_configuration['name']
|
22
|
+
puts "Which database do you want to use?"
|
23
|
+
printf '> '
|
24
|
+
database_configuration['name'] = gets.strip
|
25
|
+
end
|
26
|
+
|
27
|
+
unless database_configuration['user']
|
28
|
+
puts "What's your username at '#{database_configuration['user']}'?"
|
29
|
+
printf '> '
|
30
|
+
database_configuration['user'] = gets.strip
|
31
|
+
end
|
32
|
+
|
33
|
+
unless database_configuration['password']
|
34
|
+
puts "Type your password"
|
35
|
+
database_configuration['password'] = ask('> ') {|q| q.echo = false}.strip
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def database_configuration
|
40
|
+
configuration['database'] ||= {}
|
41
|
+
end
|
42
|
+
|
43
|
+
def logger
|
44
|
+
@logger ||= Logger.new STDOUT
|
45
|
+
end
|
46
|
+
|
47
|
+
def parse_options args
|
48
|
+
option_parser.parse! args
|
49
|
+
end
|
50
|
+
|
51
|
+
def banner
|
52
|
+
"Usage:"
|
53
|
+
end
|
54
|
+
|
55
|
+
def option_parser
|
56
|
+
@option_parser ||= OptionParser.new do |p|
|
57
|
+
p.banner = banner
|
58
|
+
|
59
|
+
setup_options p
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_config file
|
64
|
+
file_options = YAML.load_file file
|
65
|
+
@configuration = file_options
|
66
|
+
end
|
67
|
+
|
68
|
+
def set_user user
|
69
|
+
database_configuration['user'] = user
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_password password
|
73
|
+
database_configuration['password'] = password
|
74
|
+
end
|
75
|
+
|
76
|
+
def set_database name
|
77
|
+
database_configuration['name'] = name
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_namespace namespace
|
81
|
+
database_configuration['namespace'] = namespace
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_host host
|
85
|
+
configuration['host'] = host
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_port port
|
89
|
+
configuration['port'] = port
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_help *_
|
93
|
+
puts option_parser
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
|
97
|
+
def set_models models
|
98
|
+
models = "*" if models.strip == "all"
|
99
|
+
database_configuration['models'] = models.split(':')
|
100
|
+
end
|
101
|
+
|
102
|
+
def setup_options p
|
103
|
+
setup_option p, '--help', "Display this help screen"
|
104
|
+
setup_option p, '--config FILE', 'Specify a configuration file'
|
105
|
+
setup_option p, '--user USER', 'Set user to use to login to OpenERP, must be a valid OpenERP user with sufficient privileges'
|
106
|
+
setup_option p, '--password PASSWORD', 'Set password for user'
|
107
|
+
setup_option p, '--host HOST', 'Set hostname (default: localhost)'
|
108
|
+
setup_option p, '--port PORT', 'Set port (default: 8069)', '-i'
|
109
|
+
setup_option p, '--database DATABASE', 'Set name of database to use'
|
110
|
+
setup_option p, '--namespace NAMESPACE', 'Set namespace / root module to use for models (default: Oo)'
|
111
|
+
setup_option p, '--models MODELS', 'Set models to load eagerly, separate with : (e.g. res.*:product.product:sale.* or "all" to load everything)'
|
112
|
+
end
|
113
|
+
|
114
|
+
def setup_option p, param, desc = '', short = nil
|
115
|
+
param = param.to_s
|
116
|
+
short ||= param.match(/^-(-\w)\w*/)[1]
|
117
|
+
meth_name = param.match(/^--(\w+)/)[1]
|
118
|
+
|
119
|
+
p.on short, param, desc, &method("set_#{meth_name}".to_sym)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'kangaroo/commands/base'
|
2
|
+
require 'irb'
|
3
|
+
require 'irb/completion'
|
4
|
+
require 'hirb'
|
5
|
+
require 'kangaroo/commands/endpoint'
|
6
|
+
|
7
|
+
module IRB
|
8
|
+
mattr_accessor :prompt
|
9
|
+
|
10
|
+
class << self
|
11
|
+
alias init_config_old init_config
|
12
|
+
end
|
13
|
+
|
14
|
+
def IRB.init_config(ap_path)
|
15
|
+
init_config_old ap_path
|
16
|
+
@@prompt ||= "kang"
|
17
|
+
|
18
|
+
@CONF[:PROMPT] = {
|
19
|
+
:CUSTOM => {
|
20
|
+
:PROMPT_I => "#{@@prompt} > ",
|
21
|
+
:PROMPT_S => "#{@@prompt} %l> ",
|
22
|
+
:PROMPT_C => "#{@@prompt} .. ",
|
23
|
+
:PROMPT_N => "#{@@prompt} .. ",
|
24
|
+
:RETURN => "=> %s\n"
|
25
|
+
}
|
26
|
+
}
|
27
|
+
@CONF[:PROMPT_MODE] = :CUSTOM
|
28
|
+
@CONF[:AUTO_INDENT] = true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module Kangaroo
|
33
|
+
module Commands
|
34
|
+
class CLI < Base
|
35
|
+
def run
|
36
|
+
super
|
37
|
+
|
38
|
+
initialize_global_endpoint
|
39
|
+
start_irb
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
def initialize_global_endpoint
|
44
|
+
::Kang.connect configuration, logger
|
45
|
+
::Kang.load_models!
|
46
|
+
end
|
47
|
+
|
48
|
+
def start_irb
|
49
|
+
ARGV.clear
|
50
|
+
|
51
|
+
IRB.prompt = ::Kang.configuration['database'].values_at('user', 'name').join("@")
|
52
|
+
::Hirb.enable
|
53
|
+
::IRB.start
|
54
|
+
end
|
55
|
+
|
56
|
+
def banner
|
57
|
+
"".tap do |s|
|
58
|
+
s << 'kang - The Kangaroo command line interface'
|
59
|
+
s << "\n\n"
|
60
|
+
s << 'Usage:'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'kangaroo/commands/base'
|
2
|
+
require 'kangaroo/commands/endpoint'
|
3
|
+
require 'kangaroo/doc'
|
4
|
+
|
5
|
+
module Kangaroo
|
6
|
+
module Commands
|
7
|
+
class Doc < Base
|
8
|
+
def run
|
9
|
+
super
|
10
|
+
|
11
|
+
initialize_global_endpoint
|
12
|
+
generate_yardoc
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
def set_load_associations
|
17
|
+
@load_associations = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def setup_options p
|
21
|
+
super
|
22
|
+
setup_option p, '--load_associations', 'Wether to load associated models too.'
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize_global_endpoint
|
26
|
+
::Kang.connect configuration, logger
|
27
|
+
::Kang.load_models!
|
28
|
+
::Kang.load_associated_models! if @load_associations
|
29
|
+
end
|
30
|
+
|
31
|
+
def generate_yardoc
|
32
|
+
Kangaroo::Doc::Base.generate ::Kang.namespace
|
33
|
+
end
|
34
|
+
|
35
|
+
def banner
|
36
|
+
"".tap do |s|
|
37
|
+
s << 'kangdoc - Generate yardoc for OpenERP models.'
|
38
|
+
s << ''
|
39
|
+
s << 'Usage:'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Kangaroo
|
2
|
+
module Commands
|
3
|
+
class Endpoint
|
4
|
+
attr_reader :configuration, :config, :client, :logger, :models
|
5
|
+
|
6
|
+
delegate :common, :db, :superadmin, :to => :client
|
7
|
+
delegate :database, :to => :config
|
8
|
+
|
9
|
+
def connect configuration = {}, logger = Logger.new(STDOUT)
|
10
|
+
@logger = logger
|
11
|
+
@configuration = configuration
|
12
|
+
@config = Kangaroo::Util::Configuration.new configuration, logger
|
13
|
+
@client = config.client
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_models!
|
17
|
+
@models = config.load_models
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_associated_models!
|
21
|
+
@models.each do |m|
|
22
|
+
m.fields.each &:relation_class
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def namespace
|
27
|
+
Kernel.const_get config.namespace
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
::Kang = Kangaroo::Commands::Endpoint.new
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'kangaroo/commands/base'
|
2
|
+
require 'kangaroo/commands/endpoint'
|
3
|
+
require 'kangaroo/viz'
|
4
|
+
|
5
|
+
module Kangaroo
|
6
|
+
module Commands
|
7
|
+
class Viz < Base
|
8
|
+
def run
|
9
|
+
super
|
10
|
+
|
11
|
+
initialize_global_endpoint
|
12
|
+
init_viz.generate
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
def set_load_associations *args
|
17
|
+
@load_associations = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_file file
|
21
|
+
@file = file
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_type type
|
25
|
+
@type = type
|
26
|
+
end
|
27
|
+
|
28
|
+
def setup_options p
|
29
|
+
super
|
30
|
+
setup_option p, '--load_associations', 'Wether to load associated models too.'
|
31
|
+
setup_option p, "--type FILE", "Specify output type (e.g. png, pdf, svg, etc. see ruby-graphviz)"
|
32
|
+
setup_option p, "--file TYPE", "Specify output file (e.g. kangaroo_models.png)"
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize_global_endpoint
|
36
|
+
::Kang.connect configuration, logger
|
37
|
+
::Kang.load_models!
|
38
|
+
::Kang.load_associated_models! if @load_associations
|
39
|
+
end
|
40
|
+
|
41
|
+
def init_viz
|
42
|
+
Kangaroo::Viz::Base.new(::Kang.namespace).tap do |viz|
|
43
|
+
viz.namespace.dont_load_models = !@load_associations
|
44
|
+
viz.file = @file || "kangaroo_viz.png"
|
45
|
+
viz.type = @type || "png"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def banner
|
50
|
+
"".tap do |s|
|
51
|
+
s << 'kangviz - Generate graphviz for OpenERP models.'
|
52
|
+
s << ''
|
53
|
+
s << 'Usage:'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/kangaroo/doc.rb
ADDED
data/lib/kangaroo/exception.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
module Kangaroo
|
2
2
|
class Exception < ::Exception ; end
|
3
3
|
class RecordNotFound < Exception ; end
|
4
|
+
class ReadonlyRecord < Exception ; end
|
4
5
|
class RecordSavingFailed < Exception ; end
|
5
6
|
class InstantiatedRecordNeedsIDError < Exception ; end
|
6
7
|
class ChildDefinedBeforeParentError < Exception ; end
|
8
|
+
|
9
|
+
class NoMethodError < ::NoMethodError ; end
|
7
10
|
end
|
data/lib/kangaroo/hirb.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Kangaroo
|
2
|
+
module Model
|
3
|
+
module Associations
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
autoload :Many2one, 'kangaroo/model/associations/many2one'
|
7
|
+
autoload :One2many, 'kangaroo/model/associations/one2many'
|
8
|
+
|
9
|
+
Types = %w(many2one one2many).freeze
|
10
|
+
|
11
|
+
included do
|
12
|
+
include Many2one
|
13
|
+
include One2many
|
14
|
+
end
|
15
|
+
|
16
|
+
def id_for_associated field
|
17
|
+
send(field).first
|
18
|
+
end
|
19
|
+
|
20
|
+
def name_for_associated field
|
21
|
+
send(field).last
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
def association_fields
|
26
|
+
@association_fields ||= fields.select do |field|
|
27
|
+
Types.include? field.type
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|