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.
Files changed (99) hide show
  1. data/.gitignore +6 -1
  2. data/Gemfile +11 -0
  3. data/README.md +23 -132
  4. data/Rakefile +0 -8
  5. data/bin/kang +5 -64
  6. data/bin/kangdoc +21 -0
  7. data/bin/kangviz +21 -0
  8. data/config/kangaroo.yml.sample +12 -2
  9. data/docs/Architecture.md +1 -0
  10. data/docs/Classes.md +67 -0
  11. data/docs/Installation.md +2 -1
  12. data/docs/Usage.md +1 -0
  13. data/kangaroo.gemspec +8 -8
  14. data/lib/kangaroo.rb +3 -2
  15. data/lib/kangaroo/commands/base.rb +123 -0
  16. data/lib/kangaroo/commands/cli.rb +65 -0
  17. data/lib/kangaroo/commands/doc.rb +44 -0
  18. data/lib/kangaroo/commands/endpoint.rb +33 -0
  19. data/lib/kangaroo/commands/viz.rb +58 -0
  20. data/lib/kangaroo/doc.rb +2 -0
  21. data/lib/kangaroo/exception.rb +3 -0
  22. data/lib/kangaroo/hirb.rb +2 -1
  23. data/lib/kangaroo/model/associations.rb +33 -0
  24. data/lib/kangaroo/model/associations/many2one.rb +43 -0
  25. data/lib/kangaroo/model/associations/one2many.rb +41 -0
  26. data/lib/kangaroo/model/attributes.rb +88 -93
  27. data/lib/kangaroo/model/base.rb +44 -15
  28. data/lib/kangaroo/model/condition_normalizer.rb +7 -7
  29. data/lib/kangaroo/model/data_import.rb +28 -0
  30. data/lib/kangaroo/model/default_attributes.rb +20 -14
  31. data/lib/kangaroo/model/dynamic_finder.rb +42 -0
  32. data/lib/kangaroo/model/field.rb +52 -1
  33. data/lib/kangaroo/model/field/readonly.rb +39 -0
  34. data/lib/kangaroo/model/finder.rb +6 -2
  35. data/lib/kangaroo/model/inspector.rb +1 -4
  36. data/lib/kangaroo/model/mass_import.rb +42 -0
  37. data/lib/kangaroo/model/open_object_orm.rb +51 -5
  38. data/lib/kangaroo/model/persistence.rb +43 -19
  39. data/lib/kangaroo/model/readonly_attributes.rb +43 -0
  40. data/lib/kangaroo/model/relation.rb +40 -9
  41. data/lib/kangaroo/model/remote_execute.rb +1 -1
  42. data/lib/kangaroo/model/required_attributes.rb +26 -0
  43. data/lib/kangaroo/railtie.rb +13 -3
  44. data/lib/kangaroo/ruby_adapter/base.rb +2 -1
  45. data/lib/kangaroo/ruby_adapter/class_definition.rb +18 -3
  46. data/lib/kangaroo/ruby_adapter/fields.rb +27 -2
  47. data/lib/kangaroo/ruby_adapter/many2one.rb +38 -0
  48. data/lib/kangaroo/ruby_adapter/one2many.rb +31 -0
  49. data/lib/kangaroo/util/client.rb +29 -4
  50. data/lib/kangaroo/util/configuration.rb +15 -10
  51. data/lib/kangaroo/util/database.rb +8 -8
  52. data/lib/kangaroo/util/loader.rb +18 -22
  53. data/lib/kangaroo/util/loader/information_repository.rb +56 -0
  54. data/lib/kangaroo/util/loader/namespace.rb +1 -1
  55. data/lib/kangaroo/util/loader/reflection.rb +61 -0
  56. data/lib/kangaroo/util/loader/root_namespace.rb +12 -21
  57. data/lib/kangaroo/util/proxy.rb +9 -0
  58. data/lib/kangaroo/util/proxy/common.rb +28 -4
  59. data/lib/kangaroo/util/proxy/db.rb +14 -0
  60. data/lib/kangaroo/util/proxy/object.rb +40 -1
  61. data/lib/kangaroo/util/proxy/superadmin.rb +13 -0
  62. data/lib/kangaroo/version.rb +1 -1
  63. data/lib/kangaroo/viz.rb +1 -0
  64. data/lib/kangaroo/viz/base.rb +92 -0
  65. data/spec/commands/base_spec.rb +42 -0
  66. data/spec/functional/associations/many2one_spec.rb +72 -0
  67. data/spec/functional/associations/one2many_spec.rb +65 -0
  68. data/spec/functional/common_service_spec.rb +25 -0
  69. data/spec/functional/data_import_spec.rb +48 -0
  70. data/spec/functional/dynamic_finder_spec.rb +35 -0
  71. data/spec/functional/exception_handling_spec.rb +18 -0
  72. data/spec/functional/identity_spec.rb +48 -0
  73. data/spec/functional/import_export_spec.rb +39 -0
  74. data/spec/functional/lazy_loading_spec.rb +18 -11
  75. data/spec/functional/ordering_spec.rb +33 -0
  76. data/spec/functional/readonly_attributes_spec.rb +37 -0
  77. data/spec/functional/required_attributes_spec.rb +37 -0
  78. data/spec/functional/root_namespace_spec.rb +19 -0
  79. data/spec/functional/select_relation_spec.rb +26 -0
  80. data/spec/model/attributes_spec.rb +1 -0
  81. data/spec/model/base_spec.rb +1 -0
  82. data/spec/model/default_attributes_spec.rb +3 -1
  83. data/spec/model/finder_spec.rb +2 -1
  84. data/spec/model/inspector_spec.rb +1 -0
  85. data/spec/model/open_object_orm_spec.rb +5 -2
  86. data/spec/model/persistence_spec.rb +1 -0
  87. data/spec/model/relation_spec.rb +2 -2
  88. data/spec/ruby_adapter/class_definition_spec.rb +1 -0
  89. data/spec/server_helper.rb +0 -1
  90. data/spec/spec_helper.rb +4 -1
  91. data/spec/util/loader_spec.rb +6 -6
  92. metadata +152 -159
  93. data/Gemfile.lock +0 -69
  94. data/features/configuration.feature +0 -10
  95. data/features/env.rb +0 -8
  96. data/features/step_definitions/basic_steps.rb +0 -18
  97. data/features/step_definitions/configuration_steps.rb +0 -21
  98. data/features/support/test.yml +0 -11
  99. 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
@@ -7,6 +7,7 @@ Usage
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
  Basics
12
13
  ------
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/cice/kangARoo"
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 'rapuncel', '~> 0.0.2'
22
- s.add_dependency "activerecord", ">= 3.0.0"
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 'yard'
27
- s.add_development_dependency 'rspec'
28
- s.add_development_dependency 'ruby-debug'
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
@@ -1,7 +1,8 @@
1
- require 'kangaroo/railtie' if defined?(Rails)
2
1
  require 'kangaroo/util/configuration'
3
2
  require 'kangaroo/model/base'
4
3
  require 'kangaroo/hirb'
5
4
 
6
5
  module Kangaroo
7
- end
6
+ end
7
+
8
+ require 'kangaroo/railtie' if defined?(Rails)
@@ -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
@@ -0,0 +1,2 @@
1
+ require 'kangaroo/doc/root_namespace'
2
+ require 'kangaroo/doc/klass'
@@ -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
@@ -15,7 +15,8 @@ module Hirb::Views::Kangaroo
15
15
  sorted_columns += (selected_columns - sorted_columns)
16
16
  fields = sorted_columns.map {|e| e.to_sym}
17
17
  end
18
- fields
18
+
19
+ [:id] + fields
19
20
  end
20
21
  end
21
22
 
@@ -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