moblues 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +44 -0
  7. data/Rakefile +4 -0
  8. data/bin/moblues +5 -0
  9. data/lib/extensions/hash.rb +9 -0
  10. data/lib/moblues/cli.rb +26 -0
  11. data/lib/moblues/data_model/attribute.rb +15 -0
  12. data/lib/moblues/data_model/entity.rb +17 -0
  13. data/lib/moblues/data_model/relationship.rb +17 -0
  14. data/lib/moblues/data_model.rb +3 -0
  15. data/lib/moblues/generator/base.rb +65 -0
  16. data/lib/moblues/generator/human.rb +25 -0
  17. data/lib/moblues/generator/human_header.h.erb +4 -0
  18. data/lib/moblues/generator/human_implementation.m.erb +4 -0
  19. data/lib/moblues/generator/machine.rb +36 -0
  20. data/lib/moblues/generator/machine_header.h.erb +43 -0
  21. data/lib/moblues/generator/machine_implementation.m.erb +7 -0
  22. data/lib/moblues/generator/model.rb +23 -0
  23. data/lib/moblues/generator.rb +4 -0
  24. data/lib/moblues/reader/attribute.rb +23 -0
  25. data/lib/moblues/reader/entity.rb +34 -0
  26. data/lib/moblues/reader/model.rb +31 -0
  27. data/lib/moblues/reader/relationship.rb +22 -0
  28. data/lib/moblues/reader/type.rb +58 -0
  29. data/lib/moblues/reader.rb +5 -0
  30. data/lib/moblues/utils/model_resolver.rb +19 -0
  31. data/lib/moblues/version.rb +3 -0
  32. data/lib/moblues.rb +4 -0
  33. data/moblues.gemspec +33 -0
  34. data/spec/features/moblues_spec.rb +36 -0
  35. data/spec/moblues/cli_spec.rb +50 -0
  36. data/spec/moblues/data_model/attribute_spec.rb +30 -0
  37. data/spec/moblues/data_model/entity_spec.rb +48 -0
  38. data/spec/moblues/data_model/relationship_spec.rb +46 -0
  39. data/spec/moblues/generator/human_spec.rb +74 -0
  40. data/spec/moblues/generator/machine_spec.rb +86 -0
  41. data/spec/moblues/generator/model_spec.rb +27 -0
  42. data/spec/moblues/reader/attribute_spec.rb +22 -0
  43. data/spec/moblues/reader/entity_spec.rb +57 -0
  44. data/spec/moblues/reader/model_spec.rb +66 -0
  45. data/spec/moblues/reader/relationship_spec.rb +22 -0
  46. data/spec/moblues/reader/type_spec.rb +79 -0
  47. data/spec/moblues/utils/model_resolver_spec.rb +28 -0
  48. data/spec/resources/Model.xcdatamodeld/.xccurrentversion +8 -0
  49. data/spec/resources/Model.xcdatamodeld/Model 2.xcdatamodel/contents +28 -0
  50. data/spec/resources/Model.xcdatamodeld/Model.xcdatamodel/contents +18 -0
  51. data/spec/resources/expected/Author.h +4 -0
  52. data/spec/resources/expected/Author.m +4 -0
  53. data/spec/resources/expected/_Author.h +36 -0
  54. data/spec/resources/expected/_Author.m +9 -0
  55. data/spec/resources/expected/_Book.h +19 -0
  56. data/spec/resources/expected/_Book.m +6 -0
  57. data/spec/resources/expected/_Person.h +9 -0
  58. data/spec/resources/expected/_Person.m +6 -0
  59. data/spec/resources/expected/_Team.h +18 -0
  60. data/spec/resources/expected/_Team.m +5 -0
  61. data/spec/resources/expected/human/Playable.h +4 -0
  62. data/spec/resources/expected/human/Playable.m +4 -0
  63. data/spec/resources/expected/human/Playlist.h +5 -0
  64. data/spec/resources/expected/human/Playlist.m +4 -0
  65. data/spec/resources/expected/human/Track.h +4 -0
  66. data/spec/resources/expected/human/Track.m +4 -0
  67. data/spec/resources/expected/human/User.h +4 -0
  68. data/spec/resources/expected/human/User.m +4 -0
  69. data/spec/resources/expected/machine/_Playable.h +9 -0
  70. data/spec/resources/expected/machine/_Playable.m +6 -0
  71. data/spec/resources/expected/machine/_Playlist.h +28 -0
  72. data/spec/resources/expected/machine/_Playlist.m +6 -0
  73. data/spec/resources/expected/machine/_Track.h +14 -0
  74. data/spec/resources/expected/machine/_Track.m +7 -0
  75. data/spec/resources/expected/machine/_User.h +27 -0
  76. data/spec/resources/expected/machine/_User.m +8 -0
  77. data/spec/resources/factories/data_model/attribute_factory.rb +12 -0
  78. data/spec/resources/factories/data_model/entity_factory.rb +13 -0
  79. data/spec/resources/factories/data_model/relationship_factory.rb +14 -0
  80. data/spec/resources/fixtures.rb +34 -0
  81. data/spec/resources/tmp/.gitkeep +0 -0
  82. data/spec/resources/tmp/_Team.h +18 -0
  83. data/spec/resources/tmp/_Team.m +5 -0
  84. data/spec/resources/tmp/human/Playlist.h +5 -0
  85. data/spec/resources/tmp/human/Playlist.m +4 -0
  86. data/spec/spec_helper.rb +15 -0
  87. metadata +285 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d306b405a86b2290eb6c2526748df8fe10a0f8b3
4
+ data.tar.gz: b598e9094d9add99dc8255adb304ac42e07e7102
5
+ SHA512:
6
+ metadata.gz: 81b7c225fa7822b7030dcdab5088047bd7be37d5ca78d55e87c3f7a1b02e3edc1d9166036aa8e6645049bb935c7b432611829d9d0b11093c12f1f4432873deac
7
+ data.tar.gz: 7aa8db60830f0cbb8d810c17901f1c8b0c9dc11b30088c48a9cc5bc2f10dab6d69c89f241779f216148ae5b243eb5b1ac99547d53d3b68c063ecbb5b413ee2e1
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .idea/
16
+ .DS_Store
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ script: bundle exec rake spec
6
+ addons:
7
+ code_climate:
8
+ repo_token: 97374e550763cfe3be1c90ba93d9ea9e5b4ea47e1dead9b554f5f4a18b3a6f75
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Vincent Garrigues
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Moblues [![Build Status](https://magnum.travis-ci.com/garriguv/moblues.svg?token=GCky67DnySmgxHiFqjq3&branch=master)](https://magnum.travis-ci.com/garriguv/moblues) [![Code Climate](https://codeclimate.com/repos/547ac5cfe30ba05abc1d6329/badges/3c5aba53610a96394d9f/gpa.svg)](https://codeclimate.com/repos/547ac5cfe30ba05abc1d6329/feed) [![Test Coverage](https://codeclimate.com/repos/547ac5cfe30ba05abc1d6329/badges/3c5aba53610a96394d9f/coverage.svg)](https://codeclimate.com/repos/547ac5cfe30ba05abc1d6329/feed)
2
+
3
+ Generates files for entities defined in a Core Data model. Inspired by [mogenerator](https://github.com/rentzsch/mogenerator).
4
+
5
+ For each entity in the Core Data model, moblues will create two files: a machine file and a human file. The machine file will be overwritten each time and shouldn't be modified. Moblues will only create the human file if it doesn't exist.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'moblues'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install moblues
22
+
23
+ ## Usage
24
+
25
+ ```
26
+ Usage:
27
+ moblues generate --human=HUMAN --machine=MACHINE --model=MODEL
28
+
29
+ Options:
30
+ --model=MODEL # CoreData model path
31
+ --human=HUMAN # Path where the human files will be stored
32
+ --machine=MACHINE # Path where the machine files will be stored
33
+
34
+ generate the machine and human files
35
+ ```
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it ( https://github.com/garriguv/moblues/fork )
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create a new Pull Request
44
+ 6. You're awesome! :+1:
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new
data/bin/moblues ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'moblues/cli'
4
+
5
+ Moblues::CLI.start(ARGV)
@@ -0,0 +1,9 @@
1
+ class Hash
2
+ def compact
3
+ select { |_,v| !v.nil? }
4
+ end
5
+
6
+ def compact!
7
+ select! { |_,v| !v.nil? }
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ require 'thor'
2
+ require 'moblues/reader/model'
3
+ require 'moblues/generator/model'
4
+
5
+ module Moblues
6
+ class CLI < Thor
7
+ desc 'generate', 'generate the machine and human files'
8
+ option :model, :required => true, :desc => 'Core Data model path'
9
+ option :human, :required => true, :desc => 'Path where the human files will be stored'
10
+ option :machine, :required => true, :desc => 'Path where the machine files will be stored'
11
+ def generate
12
+ mkdir([options[:human], options[:machine]])
13
+ reader = Moblues::Reader::Model.new
14
+ generator = Moblues::Generator::Model.new(human_dir: options[:human], machine_dir: options[:machine])
15
+ entities = reader.model(options[:model])
16
+ generator.generate(entities)
17
+ end
18
+
19
+ private
20
+ def mkdir(dirs)
21
+ dirs.each do |dir|
22
+ Dir.mkdir(dir) unless Dir.exists?(dir)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ require 'extensions/hash'
2
+
3
+ module Moblues
4
+ module DataModel
5
+ class Attribute < Struct.new(:name, :type)
6
+ def initialize(params)
7
+ p = params.compact
8
+ super(
9
+ p.fetch(:name),
10
+ p.fetch(:type)
11
+ )
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ require 'extensions/hash'
2
+
3
+ module Moblues
4
+ module DataModel
5
+ class Entity < Struct.new(:name, :parent_entity, :attributes, :relationships)
6
+ def initialize(params)
7
+ p = params.compact
8
+ super(
9
+ p.fetch(:name),
10
+ p.fetch(:parent_entity, 'NSManagedObject'),
11
+ p.fetch(:attributes, []),
12
+ p.fetch(:relationships, [])
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'extensions/hash'
2
+
3
+ module Moblues
4
+ module DataModel
5
+ class Relationship < Struct.new(:name, :destination_entity, :to_many, :ordered)
6
+ def initialize(params)
7
+ p = params.compact
8
+ super(
9
+ p.fetch(:name),
10
+ p.fetch(:destination_entity),
11
+ p.fetch(:to_many, false),
12
+ p.fetch(:ordered, false)
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ require 'moblues/data_model/attribute'
2
+ require 'moblues/data_model/entity'
3
+ require 'moblues/data_model/relationship'
@@ -0,0 +1,65 @@
1
+ require 'erb'
2
+ require 'moblues/reader/type'
3
+
4
+ module Moblues
5
+ module Generator
6
+ class Base
7
+ def initialize(params)
8
+ @output_dir = params.fetch(:output_dir)
9
+ end
10
+
11
+ protected
12
+ attr_reader :output_dir
13
+
14
+ def write_header(entity)
15
+ write_file(header_file(entity), header(entity))
16
+ end
17
+
18
+ def write_implementation(entity)
19
+ write_file(implementation_file(entity), implementation(entity))
20
+ end
21
+
22
+ def write_file(file, text)
23
+ File.open(file, 'w+') do |f|
24
+ f.write(text)
25
+ end
26
+ end
27
+
28
+ def header_file(entity)
29
+ File.join(output_dir, format_name(entity, 'h'))
30
+ end
31
+
32
+ def implementation_file(entity)
33
+ File.join(output_dir, format_name(entity, 'm'))
34
+ end
35
+
36
+ def format_name(entity, extension)
37
+ raise NotImplemented
38
+ end
39
+
40
+ def header(entity)
41
+ render(header_template, entity)
42
+ end
43
+
44
+ def implementation(entity)
45
+ render(implementation_template, entity)
46
+ end
47
+
48
+ def render(template, entity)
49
+ ERB.new(template, 0, '-').result(entity.send(:binding))
50
+ end
51
+
52
+ def header_template
53
+ raise NotImplemented
54
+ end
55
+
56
+ def implementation_template
57
+ raise NotImplemented
58
+ end
59
+
60
+ def file_template(name)
61
+ File.read(File.expand_path("../#{name}.erb", __FILE__))
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,25 @@
1
+ require 'moblues/generator/base'
2
+
3
+ module Moblues
4
+ module Generator
5
+ class Human < Base
6
+ def generate(entity)
7
+ write_header(entity) unless File.exists?(header_file(entity))
8
+ write_implementation(entity) unless File.exists?(implementation_file(entity))
9
+ end
10
+
11
+ private
12
+ def format_name(entity, extension)
13
+ "#{entity.name}.#{extension}"
14
+ end
15
+
16
+ def header_template
17
+ file_template('human_header.h')
18
+ end
19
+
20
+ def implementation_template
21
+ file_template('human_implementation.m')
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,4 @@
1
+ #import "_<%= entity.name %>.h"
2
+
3
+ @interface <%= entity.name %> : _<%= entity.name %>
4
+ @end
@@ -0,0 +1,4 @@
1
+ #import "<%= entity.name %>.h"
2
+
3
+ @implementation <%= entity.name %>
4
+ @end
@@ -0,0 +1,36 @@
1
+ require 'moblues/generator/base'
2
+
3
+ module Moblues
4
+ module Generator
5
+ class Machine < Base
6
+ def initialize(params)
7
+ @type_reader = Reader::Type.new
8
+ super(params)
9
+ end
10
+
11
+ def generate(entity)
12
+ write_header(entity)
13
+ write_implementation(entity)
14
+ end
15
+
16
+ private
17
+ attr_reader :type_reader
18
+
19
+ def format_name(entity, extension)
20
+ "_#{entity.name}.#{extension}"
21
+ end
22
+
23
+ def capitalized_name(relationship)
24
+ relationship.name.sub(/^./) { |first_character| first_character.upcase }
25
+ end
26
+
27
+ def header_template
28
+ file_template('machine_header.h')
29
+ end
30
+
31
+ def implementation_template
32
+ file_template('machine_implementation.m')
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,43 @@
1
+ #import <%= '<Foundation/Foundation.h>' %>
2
+ #import <%= '<CoreData/CoreData.h>' %>
3
+ <% if entity.parent_entity != 'NSManagedObject' -%>
4
+
5
+ #import "<%= entity.parent_entity %>.h"
6
+ <% end -%>
7
+
8
+ <% for class_name in entity.relationships.map { |rel| rel.destination_entity }.uniq -%>
9
+ @class <%= class_name %>;
10
+ <% end -%>
11
+
12
+ @interface _<%= entity.name %> : <%= entity.parent_entity %>
13
+ <% for attribute in entity.attributes -%>
14
+ @property (<%= type_reader.property_attributes(attribute.type).join(', ') %>) <%= type_reader.property_type(attribute.type)%><%= attribute.name %>;
15
+ <% end -%>
16
+
17
+ <% for relationship in entity.relationships -%>
18
+ @property (nonatomic, strong) <%= type_reader.relationship_type(relationship) %><%= relationship.name %>;
19
+ <% end -%>
20
+ @end
21
+ <% if !entity.relationships.select { |e| e.to_many }.empty? %>
22
+ @interface _<%= entity.name %> (CoreDataGeneratedAccessors)
23
+ <% for relationship in entity.relationships.select { |e| e.to_many } %>
24
+ <% if relationship.ordered -%>
25
+ - (void)insertObject:(<%= relationship.destination_entity %> *)value in<%= capitalized_name(relationship) %>AtIndex:(NSUInteger)index;
26
+ - (void)removeObjectFrom<%= capitalized_name(relationship) %>AtIndex:(NSUInteger)index;
27
+ - (void)insert<%= capitalized_name(relationship) %>:(NSArray *)values atIndexes:(NSIndexSet *)indexes;
28
+ - (void)remove<%= capitalized_name(relationship) %>AtIndexes:(NSIndexSet *)indexes;
29
+ - (void)replaceObjectIn<%= capitalized_name(relationship) %>AtIndex:(NSUInteger)index withObject:(<%= relationship.destination_entity %> *)value;
30
+ - (void)replace<%= capitalized_name(relationship) %>AtIndexes:(NSIndexSet *)indexes with<%= capitalized_name(relationship) %>:(NSArray *)values;
31
+ - (void)add<%= capitalized_name(relationship) %>Object:(<%= relationship.destination_entity %> *)value;
32
+ - (void)remove<%= capitalized_name(relationship) %>Object:(<%= relationship.destination_entity %> *)value;
33
+ - (void)add<%= capitalized_name(relationship) %>:(NSOrderedSet *)values;
34
+ - (void)remove<%= capitalized_name(relationship) %>:(NSOrderedSet *)values;
35
+ <% else -%>
36
+ - (void)add<%= capitalized_name(relationship) %>Object:(<%= relationship.destination_entity %> *)value;
37
+ - (void)remove<%= capitalized_name(relationship) %>Object:(<%= relationship.destination_entity %> *)value;
38
+ - (void)add<%= capitalized_name(relationship) %>:(NSSet *)values;
39
+ - (void)remove<%= capitalized_name(relationship) %>:(NSSet *)values;
40
+ <% end -%>
41
+ <% end %>
42
+ @end
43
+ <% end -%>
@@ -0,0 +1,7 @@
1
+ #import "<%= '_' + entity.name %>.h"
2
+
3
+ @implementation <%= '_' + entity.name %>
4
+ <% for property in entity.attributes + entity.relationships -%>
5
+ @dynamic <%= property.name %>;
6
+ <% end -%>
7
+ @end
@@ -0,0 +1,23 @@
1
+ require 'moblues/generator/machine'
2
+ require 'moblues/generator/human'
3
+
4
+ module Moblues
5
+ module Generator
6
+ class Model
7
+ def initialize(params)
8
+ @human = Human.new(output_dir: params.fetch(:human_dir))
9
+ @machine = Machine.new(output_dir: params.fetch(:machine_dir))
10
+ end
11
+
12
+ def generate(entities)
13
+ entities.each do |entity|
14
+ human.generate(entity)
15
+ machine.generate(entity)
16
+ end
17
+ end
18
+
19
+ private
20
+ attr_reader :human, :machine
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ require 'moblues/generator/base'
2
+ require 'moblues/generator/model'
3
+ require 'moblues/generator/machine'
4
+ require 'moblues/generator/human'
@@ -0,0 +1,23 @@
1
+ require 'rexml/document'
2
+ require 'moblues/data_model/attribute'
3
+ require 'moblues/reader/type'
4
+
5
+ module Moblues
6
+ module Reader
7
+ class Attribute
8
+ def initialize
9
+ @type_reader = Type.new
10
+ end
11
+
12
+ def attribute(xml)
13
+ DataModel::Attribute.new(
14
+ name: xml.attributes['name'],
15
+ type: type_reader.map_type_str(xml.attributes['attributeType'])
16
+ )
17
+ end
18
+
19
+ private
20
+ attr_reader :type_reader
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ require 'rexml/document'
2
+ require 'moblues/reader/attribute'
3
+ require 'moblues/reader/relationship'
4
+ require 'moblues/data_model/entity'
5
+
6
+ module Moblues
7
+ module Reader
8
+ class Entity
9
+ def initialize(params = defaults)
10
+ @attribute_reader = params[:attribute_reader]
11
+ @relationship_reader = params[:relationship_reader]
12
+ end
13
+
14
+ def entity(xml)
15
+ attributes = xml.elements.to_a('attribute').map { |xml_attr| attribute_reader.attribute(xml_attr) }
16
+ relationships = xml.elements.to_a('relationship').map { |xml_rel| relationship_reader.relationship(xml_rel) }
17
+ DataModel::Entity.new(name: xml.attributes['name'],
18
+ parent_entity: xml.attributes['parentEntity'],
19
+ attributes: attributes,
20
+ relationships: relationships)
21
+ end
22
+
23
+ private
24
+ attr_reader :attribute_reader, :relationship_reader
25
+
26
+ def defaults
27
+ {
28
+ attribute_reader: Attribute.new,
29
+ relationship_reader: Relationship.new
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ require 'rexml/document'
2
+ require 'moblues/utils/model_resolver'
3
+ require 'moblues/reader/entity'
4
+
5
+ module Moblues
6
+ module Reader
7
+ class Model
8
+ def initialize(params = defaults)
9
+ @model_resolver = params[:resolver]
10
+ @entity_reader = params[:reader]
11
+ end
12
+
13
+ def model(path)
14
+ raise ArgumentError unless path
15
+ content_path = model_resolver.resolve_model(path)
16
+ xml = REXML::Document.new(File.read(content_path))
17
+ xml.root.elements.to_a('entity').map { |entity| entity_reader.entity(entity) }
18
+ end
19
+
20
+ private
21
+ attr_reader :model_resolver, :entity_reader
22
+
23
+ def defaults
24
+ {
25
+ resolver: Utils::ModelResolver.new,
26
+ reader: Entity.new
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ require 'rexml/document'
2
+ require 'moblues/data_model/relationship'
3
+
4
+ module Moblues
5
+ module Reader
6
+ class Relationship
7
+ def relationship(xml)
8
+ DataModel::Relationship.new(
9
+ name: xml.attributes['name'],
10
+ destination_entity: xml.attributes['destinationEntity'],
11
+ to_many: opt_bool(xml.attributes['toMany']),
12
+ ordered: opt_bool(xml.attributes['ordered'])
13
+ )
14
+ end
15
+
16
+ private
17
+ def opt_bool(str_value)
18
+ str_value == 'YES'
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,58 @@
1
+ module Moblues
2
+ module Reader
3
+ class Type
4
+ def map_type_str(type_str)
5
+ case type_str
6
+ when 'String'
7
+ :string
8
+ when 'Integer 16', 'Integer 32', 'Integer 64', 'Boolean'
9
+ :number
10
+ when 'Date'
11
+ :date
12
+ when 'Binary'
13
+ :data
14
+ when 'Transformable'
15
+ :id
16
+ else
17
+ raise ArgumentError.new("unknown type #{type_str}")
18
+ end
19
+ end
20
+
21
+ def property_type(type)
22
+ case type
23
+ when :string
24
+ 'NSString *'
25
+ when :number
26
+ 'NSNumber *'
27
+ when :date
28
+ 'NSDate *'
29
+ when :data
30
+ 'NSData *'
31
+ when :id
32
+ 'id '
33
+ else
34
+ raise ArgumentError.new("unknown type #{type}")
35
+ end
36
+ end
37
+
38
+ def property_attributes(type)
39
+ case type
40
+ when :string
41
+ %w{nonatomic copy}
42
+ when :number, :date, :data, :id
43
+ %w{nonatomic strong}
44
+ else
45
+ raise ArgumentError.new("unknown type #{type}")
46
+ end
47
+ end
48
+
49
+ def relationship_type(relationship)
50
+ if relationship.to_many
51
+ relationship.ordered ? 'NSOrderedSet *' : 'NSSet *'
52
+ else
53
+ relationship.destination_entity + ' *'
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ require 'moblues/reader/model'
2
+ require 'moblues/reader/attribute'
3
+ require 'moblues/reader/entity'
4
+ require 'moblues/reader/relationship'
5
+ require 'moblues/reader/type'
@@ -0,0 +1,19 @@
1
+ require 'plist'
2
+
3
+ module Moblues
4
+ module Utils
5
+ class ModelResolver
6
+ def resolve_model(path)
7
+ raise ArgumentError, "#{path} not found" unless path && File.directory?(path)
8
+ File.join(path, model_version(path), 'contents')
9
+ end
10
+
11
+ private
12
+
13
+ def model_version(model_path)
14
+ xml = File.open(File.join(model_path, '.xccurrentversion')).read
15
+ Plist::parse_xml(xml)['_XCCurrentVersionName']
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Moblues
2
+ VERSION = '0.0.1'
3
+ end
data/lib/moblues.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'moblues/version'
2
+ require 'moblues/data_model'
3
+ require 'moblues/reader'
4
+ require 'moblues/generator'