moblues 0.0.1

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.
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'