codegen 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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