codegen 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0fb21a874b2b82ef308024e2dc66e640d58625d
4
- data.tar.gz: c8533c7d4b5a68d779b68c03c2b305cfadbb1af8
3
+ metadata.gz: 7d90cbb9b6ef4ba1b5ee6d82f0ba667d9ac1a15e
4
+ data.tar.gz: ce4eaba9f69894e0019972987426742fb3d79404
5
5
  SHA512:
6
- metadata.gz: c1ef8f8f8d4eb7d1745e588f77f1f0a290d7f15b6d74a5be1860f8d20857485a2c931b7a817105c4c56f22135de54c938973325bcde815d1a85dfef85c14adac
7
- data.tar.gz: 86c59767d632f81e5988971da7170c1b335ab126933d2bc2a4935a8d1108c7c1c02fee10c01b8f7b1329cd2b9c3378c596d1a43e3f60329410465aa1249c9f7a
6
+ metadata.gz: af211b40bc1ffbacba39c78a0f75bf34ff9b4d64cba0d2c7d3d249a79cfaa015660645c536d07798de49e9de2d72f356c89af29b05b0b0f91f19cadf3cbeda2f
7
+ data.tar.gz: 681857235de46130a4d07f701bbf22f4b23c72035f2af86ff376248d085530a352168480bd86b160d2b3d5d0821f76b2ee264900831886e777f2ce7acef6dedd
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  .DS_Store
4
4
  /**/.DS_Store
5
+ /gen
5
6
  .bundle
6
7
  .config
7
8
  .yardoc
data/README.md CHANGED
@@ -1,12 +1,13 @@
1
- # ArToPojo
1
+ # Codegen
2
2
 
3
- TODO: Write a gem description
3
+ Tired of writing the code twice? Write simple code to generate the sources you need based on your current ruby project.
4
+ For example, if you want to make an android app, you will be able to generate the java entities based on your ruby ones.
4
5
 
5
6
  ## Installation
6
7
 
7
8
  Add this line to your application's Gemfile:
8
9
 
9
- gem 'ar_to_pojo'
10
+ gem 'codegen'
10
11
 
11
12
  And then execute:
12
13
 
@@ -14,11 +15,23 @@ And then execute:
14
15
 
15
16
  Or install it yourself as:
16
17
 
17
- $ gem install ar_to_pojo
18
+ $ gem install codegen
18
19
 
19
20
  ## Usage
20
21
 
21
- TODO: Write usage instructions here
22
+ Right now, just watch how the specs are... no cli commands yet :(
23
+
24
+ ## Roadmap
25
+
26
+ They don't need to be in this order:
27
+
28
+ - Write full and comprehensive tests.
29
+ - Split clearly the tests for sources and generators.
30
+ - Implement CLI commands.
31
+ - Make them beautiful like the Rails or Passenger ones.
32
+ - Add other languages other than Java for generating entities.
33
+ - Add REST API building using grape (!).
34
+ - Add REST API comsumption for Java.
22
35
 
23
36
  ## Contributing
24
37
 
data/codegen.gemspec CHANGED
@@ -23,5 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "rspec"
24
24
  spec.add_development_dependency "simplecov"
25
25
 
26
- spec.add_dependency 'activesupport', "~> 3.2"
26
+ spec.add_dependency 'hooks'
27
+ spec.add_dependency 'activesupport'
27
28
  end
@@ -0,0 +1,36 @@
1
+ require 'hooks'
2
+
3
+ module Codegen
4
+ module Generators
5
+ # Sin, this is not DRYed enough, go look Codegen::Sources::Base :(
6
+ class Base
7
+ include Hooks
8
+
9
+ ### Adds registration of types
10
+
11
+ class << self
12
+ attr_accessor :convert_to
13
+ end
14
+
15
+ def self.converts_to * type
16
+ if type.all? { |x| x.is_a? Symbol }
17
+ self.convert_to = type
18
+ else
19
+ self.convert_to = type.map { |t| t.to_s.underscore.to_sym }
20
+ end
21
+ end
22
+
23
+ ### Adds checks for types that are valid
24
+
25
+ define_hooks :before_generate
26
+ before_generate do |params|
27
+ raise Exception.new("Unexpected type!") if not self.class.convert_to.include? params[:type]
28
+ end
29
+
30
+ def generate! params
31
+ self.run_hook :before_generate, params
32
+ generate params
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,10 +1,111 @@
1
- require 'json'
1
+ require 'active_support/inflector'
2
2
 
3
3
  module Codegen
4
4
  module Generators
5
- module JavaPojo
6
- def generate
5
+ class JavaPojo < Base
6
+ converts_to :entity
7
7
 
8
+ def generate options = {}
9
+ if options[:type] == :entity
10
+ generate_entity options
11
+ end
12
+ end
13
+
14
+ private
15
+ def generate_entity options
16
+ entities = options[:entities]
17
+ package = options[:package] || ""
18
+ destination = options[:destination] || "gen/java/"
19
+
20
+ entities.each do |entity|
21
+ code = make_code_for(entity, package)
22
+ filename = make_filename_for(entity, package, destination)
23
+ save filename, code
24
+ end
25
+ end
26
+
27
+ def make_filename_for entity, package, destination
28
+ "#{destination}#{package.gsub(/\./,"/")}/#{entity.name}.java"
29
+ end
30
+
31
+ def save filename, code
32
+ dir = File.dirname(filename)
33
+ FileUtils.mkdir_p(dir)
34
+ f = File.open(filename, "w+")
35
+ f.puts code
36
+ f.flush
37
+ f.close
38
+ puts "Saved: #{filename}"
39
+ end
40
+
41
+ def make_code_for entity, package
42
+ # import packagename;
43
+ define_import(package).append_line do
44
+ # public class classname {
45
+ class_opening(entity.name).append_line do
46
+ # // Attributes declaration
47
+ methods_declaration.append_line do
48
+ # public Type name or public List<Type> name;
49
+ entity.methods.map do |method|
50
+ method_declaration(method)
51
+ end.join("\r\n")
52
+ end.append_line do
53
+ relations_declaration.append_line do
54
+ # public Type name or public List<Type> name;
55
+ entity.relations.map do |relation|
56
+ method_declaration(relation)
57
+ end.join("\r\n")
58
+ end
59
+ end
60
+ end
61
+ end.concat(closing_mark)
62
+ end
63
+
64
+ def closing_mark
65
+ "\r\n}"
66
+ end
67
+
68
+ def method_declaration method
69
+ declaration = "\t"
70
+ if method[:cardinality] == :many
71
+ return declaration += "List<#{resolve_type method[:type]}> #{method[:name]};"
72
+ elsif method[:cardinality] == :one
73
+ return declaration += "#{resolve_type method[:type]} #{method[:name]};"
74
+ end
75
+ raise Exception.new "Unsupported entity cardinality!"
76
+ end
77
+
78
+ def resolve_type type
79
+ case type.to_s
80
+ when "string", "date", "float", "integer"
81
+ return type.to_s.titleize
82
+ when "text"
83
+ return "String"
84
+ when "datetime"
85
+ return "DateTime"
86
+ else
87
+ return type
88
+ end
89
+ end
90
+
91
+ def methods_declaration
92
+ "\r\n\t// Attributes declaration"
93
+ end
94
+
95
+ def relations_declaration
96
+ "\r\n\t// Relations declaration"
97
+ end
98
+
99
+ def define_import package
100
+ if package != nil && package != ""
101
+ "import #{package};"
102
+ else
103
+ ""
104
+ end
105
+ end
106
+
107
+ def class_opening name
108
+ "public class #{name.camelize} {"
8
109
  end
9
110
  end
10
111
  end
@@ -1,3 +1,4 @@
1
+ require_relative 'generators/base'
1
2
  require_relative 'generators/java_pojo'
2
3
  module Codegen
3
4
  module Generators
@@ -1,9 +1,5 @@
1
-
2
-
3
1
  module Codegen
4
2
  module Sources
5
-
6
-
7
3
  class ActiveRecord < Base
8
4
 
9
5
  converts_to :entity
@@ -33,76 +29,75 @@ module Codegen
33
29
  models_and_methods.map { |mm|
34
30
  model_to_entity(mm)
35
31
  }
36
- end
37
-
38
- def model_to_entity mm
39
- model = mm.keys.first
40
- methods = mm[model][:methods]
41
- relations = mm[model][:relations]
32
+ end
42
33
 
43
- normalized_relations = relations.map { |relation|
44
- case relation[:type]
45
- when :has_many, :has_and_belongs_to_many
46
- ref = :many
47
- when :belongs_to, :has_one
48
- ref = :one
49
- else
50
- puts "WARNING: Unexpected relation type for relation: #{relation[:name]} on class #{model}"
51
- ref = :one
52
- end
34
+ def model_to_entity mm
35
+ model = mm.keys.first
36
+ methods = mm[model][:methods]
37
+ relations = mm[model][:relations]
38
+
39
+ normalized_relations = relations.map { |relation|
40
+ case relation[:type]
41
+ when :has_many, :has_and_belongs_to_many
42
+ ref = :many
43
+ when :belongs_to, :has_one
44
+ ref = :one
45
+ else
46
+ puts "WARNING: Unexpected relation type for relation: #{relation[:name]} on class #{model}"
47
+ ref = :one
48
+ end
53
49
 
54
- {
55
- cardinality: ref,
56
- name: relation[:name],
57
- type: relation[:klass]
58
- }
50
+ {
51
+ cardinality: ref,
52
+ name: relation[:name],
53
+ type: relation[:klass]
59
54
  }
55
+ }
60
56
 
61
- normalized_methods = methods.map { |method|
62
- {
63
- cardinality: :one,
64
- name: method[:name],
65
- type: method[:type]
66
- }
57
+ normalized_methods = methods.map { |method|
58
+ {
59
+ cardinality: :one,
60
+ name: method[:name],
61
+ type: method[:type]
67
62
  }
63
+ }
68
64
 
69
- begin
70
- mname = model.class_name
71
- rescue
72
- mname = model.to_s
73
- end
74
-
75
- Codegen::Types::Entity.new name: mname, methods: normalized_methods, relations: normalized_relations
65
+ begin
66
+ mname = model.class_name
67
+ rescue
68
+ mname = model.to_s
76
69
  end
77
70
 
71
+ Codegen::Types::Entity.new name: mname, methods: normalized_methods, relations: normalized_relations
72
+ end
78
73
 
79
- def collect_all_models
80
- begin
81
- Rails.application.eager_load! if defined?(Rails)
82
- ::ActiveRecord::Base.subclasses
83
- rescue
84
- []
85
- end
74
+ def collect_all_models
75
+ begin
76
+ Rails.application.eager_load! if defined?(Rails)
77
+ ::ActiveRecord::Base.subclasses
78
+ rescue
79
+ []
86
80
  end
81
+ end
87
82
 
88
- def model_methods model
89
- model.columns.map { |column|
90
- {
91
- type: column.type.to_s,
92
- name: column.name
93
- }
83
+ def model_methods model
84
+ model.columns.map { |column|
85
+ {
86
+ type: column.type.to_s,
87
+ name: column.name
94
88
  }
95
- end
89
+ }
90
+ end
96
91
 
97
- def model_relations model
98
- model.reflect_on_all_associations.map { |assoc|
99
- {
100
- type: assoc.macro,
101
- name: assoc.name.to_s,
102
- klass: assoc.class_name
103
- }
92
+ def model_relations model
93
+ model.reflect_on_all_associations.map { |assoc|
94
+ {
95
+ type: assoc.macro,
96
+ name: assoc.name.to_s,
97
+ klass: assoc.class_name
104
98
  }
105
- end
99
+ }
106
100
  end
107
101
  end
108
- end
102
+ end
103
+ end
@@ -1,32 +1,34 @@
1
- require 'active_support'
1
+ require 'hooks'
2
2
 
3
3
  module Codegen
4
4
  module Sources
5
5
  class Base
6
- include ActiveSupport::Callbacks
6
+ include Hooks
7
+
8
+ ### Adds registration of types
9
+
7
10
  class << self
8
11
  attr_accessor :convert_to
9
12
  end
10
13
 
11
- def self.converts_to type
12
- if type.is_a? Symbol
14
+ def self.converts_to * type
15
+ if type.all? { |x| x.is_a? Symbol }
13
16
  self.convert_to = type
14
17
  else
15
18
  self.convert_to = type.map { |t| t.to_s.underscore.to_sym }
16
19
  end
17
20
  end
18
21
 
19
- define_callbacks :check_valid
20
- set_callback :check_valid, :before, :convert!
22
+ ### Adds checks for types that are valid
21
23
 
22
- def check_valid params
23
- self.convert_to.include? params[:type]
24
+ define_hooks :before_convert
25
+ before_convert do |params|
26
+ raise Exception.new("Unexpected type!") if not self.class.convert_to.include? params[:type]
24
27
  end
25
28
 
26
- def convert!
27
- run_callbacks :convert! do
28
- convert
29
- end
29
+ def convert! params
30
+ self.run_hook :before_convert, params
31
+ convert params
30
32
  end
31
33
  end
32
34
  end
@@ -0,0 +1,6 @@
1
+ class ::String
2
+ ### Small hack, didnt know if theres another option hehe
3
+ def append_line &block
4
+ (self + "\r\n").concat(yield(block))
5
+ end
6
+ end
@@ -1,3 +1,3 @@
1
1
  module Codegen
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
data/lib/codegen.rb CHANGED
@@ -2,6 +2,7 @@ require 'codegen/version'
2
2
  require_relative 'codegen/sources'
3
3
  require_relative 'codegen/generators'
4
4
  require_relative 'codegen/types'
5
+ require_relative 'codegen/util'
5
6
 
6
7
  module Codegen
7
8
  class Gen
data/spec/codegen_spec.rb CHANGED
@@ -5,53 +5,40 @@ require 'pry'
5
5
  describe Codegen do
6
6
  context "Analyzing ActiveRecord" do
7
7
  before :each do
8
- @ar_class = mock("Entity")
9
-
10
- columns = [
11
- ["name", :string],
12
- ["birth_date", :date],
13
- ["register_date",:datetime],
14
- ["precision",:float],
15
- ["score",:integer],
16
- ["description",:text]
17
- ].map { |item|
18
- column_mock = mock("Object")
19
- column_mock.stub!(:name).and_return(item[0])
20
- column_mock.stub!(:type).and_return(item[1])
21
- column_mock
22
- }
23
-
24
- associations = [
25
- ["Project", :has_and_belongs_to_many, :projects],
26
- ["Comment", :has_many, :comments],
27
- ["Picture", :has_many, :pictures],
28
- ["Profile", :has_one, :profile],
29
- ["Company", :belongs_to, :organization]
30
- ].map { |item|
31
- assoc_mock = mock("Object")
32
- assoc_mock.stub!(:class_name).and_return(item[0])
33
- assoc_mock.stub!(:macro).and_return(item[1])
34
- assoc_mock.stub!(:name).and_return(item[2])
35
- assoc_mock
36
- }
37
-
38
- @ar_class.stub!(:reflect_on_all_associations).and_return(associations)
39
- @ar_class.stub!(:columns).and_return(columns)
40
- @ar_class.stub!(:class_name).and_return("Entity")
41
- @ar_class.stub!(:to_s).and_return("Entity")
42
- @ar_class.stub!(:ancestors).and_return(["ActiveRecord::Base"])
8
+ @ar_class = mock_active_record
43
9
  end
44
10
 
45
11
  it "Should be able to open an ActiveRecord object and detect columns and relations" do
46
12
  @ar_class.columns.size.should_not == 0
47
13
  @ar_class.reflect_on_all_associations.size.should_not == 0
48
-
49
14
  source = Codegen::Sources::ActiveRecord.new
50
- entities = source.convert type: :entity, models: 5.times.map { @ar_class }
15
+ entities = source.convert! type: :entity, models: 5.times.map { @ar_class }
51
16
  entities.size.should == 5
52
17
  entities.first.name.should == "Entity"
53
18
  entities.first.relations.count.should == 5
54
19
  entities.first.methods.count.should == 6
55
20
  end
21
+
22
+ it "Should not convert to any other type rather than the one it declares" do
23
+ source = Codegen::Sources::ActiveRecord.new
24
+ expect {
25
+ entities = source.convert! type: :something_else
26
+ }.to raise_error
27
+ end
28
+ end
29
+
30
+ context "Generating a JavaClass Object" do
31
+ before :each do
32
+ @ar_class = mock_active_record
33
+ end
34
+
35
+ it "Should generate a valid java code for this example" do
36
+ source = Codegen::Sources::ActiveRecord.new
37
+ generator = Codegen::Generators::JavaPojo.new
38
+ entities = source.convert! type: :entity, models: [ @ar_class ]
39
+
40
+ # TODO: Check validity of file
41
+ generator.generate! type: :entity, entities: entities, package: "com.redmintlabs"
42
+ end
56
43
  end
57
44
  end
data/spec/helpers.rb ADDED
@@ -0,0 +1,40 @@
1
+ module Helpers
2
+ def mock_active_record
3
+ ar_class = mock("Entity")
4
+
5
+ columns = [
6
+ ["name", :string],
7
+ ["birth_date", :date],
8
+ ["register_date",:datetime],
9
+ ["precision",:float],
10
+ ["score",:integer],
11
+ ["description",:text]
12
+ ].map { |item|
13
+ column_mock = mock("Object")
14
+ column_mock.stub!(:name).and_return(item[0])
15
+ column_mock.stub!(:type).and_return(item[1])
16
+ column_mock
17
+ }
18
+
19
+ associations = [
20
+ ["Project", :has_and_belongs_to_many, :projects],
21
+ ["Comment", :has_many, :comments],
22
+ ["Picture", :has_many, :pictures],
23
+ ["Profile", :has_one, :profile],
24
+ ["Company", :belongs_to, :organization]
25
+ ].map { |item|
26
+ assoc_mock = mock("Object")
27
+ assoc_mock.stub!(:class_name).and_return(item[0])
28
+ assoc_mock.stub!(:macro).and_return(item[1])
29
+ assoc_mock.stub!(:name).and_return(item[2])
30
+ assoc_mock
31
+ }
32
+
33
+ ar_class.stub!(:reflect_on_all_associations).and_return(associations)
34
+ ar_class.stub!(:columns).and_return(columns)
35
+ ar_class.stub!(:class_name).and_return("Entity")
36
+ ar_class.stub!(:to_s).and_return("Entity")
37
+ ar_class.stub!(:ancestors).and_return(["ActiveRecord::Base"])
38
+ ar_class
39
+ end
40
+ end
data/spec/rspec_helper.rb CHANGED
@@ -5,6 +5,8 @@ end
5
5
 
6
6
  require 'rspec/autorun'
7
7
 
8
+ require_relative 'helpers'
9
+
8
10
  RSpec.configure do |config|
9
11
  # Run specs in random order to surface order dependencies. If you find an
10
12
  # order dependency and want to debug it, you can fix the order by providing
@@ -15,4 +17,5 @@ RSpec.configure do |config|
15
17
  config.formatter = :documentation
16
18
 
17
19
  config.color_enabled = true
20
+ config.include Helpers
18
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codegen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cristian Pereyra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-18 00:00:00.000000000 Z
11
+ date: 2013-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,20 +66,34 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: hooks
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: activesupport
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ~>
87
+ - - '>='
74
88
  - !ruby/object:Gem::Version
75
- version: '3.2'
89
+ version: '0'
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ~>
94
+ - - '>='
81
95
  - !ruby/object:Gem::Version
82
- version: '3.2'
96
+ version: '0'
83
97
  description: A gem for making Java POJOs out of ActiveRecord models
84
98
  email:
85
99
  - criis.pereyra@gmail.com
@@ -96,14 +110,17 @@ files:
96
110
  - codegen.gemspec
97
111
  - lib/codegen.rb
98
112
  - lib/codegen/generators.rb
113
+ - lib/codegen/generators/base.rb
99
114
  - lib/codegen/generators/java_pojo.rb
100
115
  - lib/codegen/sources.rb
101
116
  - lib/codegen/sources/active_record.rb
102
117
  - lib/codegen/sources/base.rb
103
118
  - lib/codegen/types.rb
104
119
  - lib/codegen/types/entity.rb
120
+ - lib/codegen/util.rb
105
121
  - lib/codegen/version.rb
106
122
  - spec/codegen_spec.rb
123
+ - spec/helpers.rb
107
124
  - spec/rspec_helper.rb
108
125
  homepage: ''
109
126
  licenses:
@@ -132,4 +149,5 @@ specification_version: 4
132
149
  summary: Made with Android in mind, but it will maybe be extended to other platforms
133
150
  test_files:
134
151
  - spec/codegen_spec.rb
152
+ - spec/helpers.rb
135
153
  - spec/rspec_helper.rb