gyro 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +42 -797
  3. data/bin/gyro +91 -84
  4. data/documentation/enum.png +0 -0
  5. data/documentation/enum_json.png +0 -0
  6. data/documentation/ignored.png +0 -0
  7. data/documentation/json.png +0 -0
  8. data/documentation/primary_key.png +0 -0
  9. data/documentation/read_only.png +0 -0
  10. data/documentation/simple_entity.png +0 -0
  11. data/documentation/support_annotation.png +0 -0
  12. data/documentation/transformer.png +0 -0
  13. data/documentation/transformers.png +0 -0
  14. data/lib/gyro.rb +18 -29
  15. data/lib/gyro/generator/json.rb +30 -0
  16. data/lib/gyro/generator/liquid.rb +22 -0
  17. data/lib/gyro/generator/liquid/filters.rb +53 -0
  18. data/lib/gyro/generator/liquid/liquid.rb +124 -0
  19. data/lib/gyro/generator/liquid/whitespace_patch.rb +61 -0
  20. data/lib/gyro/log.rb +46 -0
  21. data/lib/gyro/parser/xcdatamodel.rb +20 -0
  22. data/lib/gyro/parser/xcdatamodel/attribute.rb +129 -0
  23. data/lib/gyro/parser/xcdatamodel/entity.rb +195 -0
  24. data/lib/gyro/parser/xcdatamodel/relationship.rb +84 -0
  25. data/lib/gyro/parser/xcdatamodel/xcdatamodel.rb +65 -0
  26. data/lib/gyro/template.rb +68 -0
  27. data/lib/gyro/version.rb +19 -0
  28. data/lib/templates/android/README.md +164 -0
  29. data/lib/templates/android/entity.liquid +49 -0
  30. data/lib/templates/android/entity_filename.liquid +1 -0
  31. data/lib/templates/android/enum.liquid +44 -0
  32. data/lib/templates/android/enum_filename.liquid +1 -0
  33. data/lib/templates/android/inc/_attributes_enum.liquid +17 -0
  34. data/lib/templates/android/inc/_attributes_getter_setter.liquid +58 -0
  35. data/lib/templates/android/inc/_attributes_properties.liquid +35 -0
  36. data/lib/templates/android/inc/_enum_getter_setter.liquid +19 -0
  37. data/lib/templates/android/inc/_primitives.liquid +30 -0
  38. data/lib/templates/android/inc/_relationships_enum.liquid +14 -0
  39. data/lib/templates/android/inc/_relationships_getter_setter.liquid +47 -0
  40. data/lib/templates/android/inc/_relationships_properties.liquid +27 -0
  41. data/lib/templates/android/inc/_type_converter.liquid +22 -0
  42. data/lib/templates/android/inc/_wrapper_type_converter.liquid +22 -0
  43. data/lib/templates/decodable/README.md +34 -0
  44. data/lib/templates/decodable/entity.liquid +57 -0
  45. data/lib/templates/decodable/entity_filename.liquid +1 -0
  46. data/lib/templates/decodable/enum.liquid +0 -0
  47. data/lib/templates/decodable/enum_filename.liquid +0 -0
  48. data/lib/templates/object-mapper/README.md +40 -0
  49. data/lib/templates/object-mapper/entity.liquid +66 -0
  50. data/lib/templates/object-mapper/entity_filename.liquid +1 -0
  51. data/lib/templates/object-mapper/enum.liquid +0 -0
  52. data/lib/templates/object-mapper/enum_filename.liquid +0 -0
  53. data/lib/templates/swift3-variant/README.md +60 -0
  54. data/lib/templates/swift3-variant/entity.liquid +12 -0
  55. data/lib/templates/swift3-variant/entity_filename.liquid +1 -0
  56. data/lib/templates/swift3-variant/enum.liquid +15 -0
  57. data/lib/templates/swift3-variant/enum_filename.liquid +1 -0
  58. data/lib/templates/swift3-variant/inc/_attributes_enum.liquid +13 -0
  59. data/lib/templates/swift3-variant/inc/_attributes_properties.liquid +32 -0
  60. data/lib/templates/swift3-variant/inc/_default_value_converter.liquid +14 -0
  61. data/lib/templates/swift3-variant/inc/_enum_attribute_property.liquid +26 -0
  62. data/lib/templates/swift3-variant/inc/_ignored_properties.liquid +24 -0
  63. data/lib/templates/swift3-variant/inc/_indexed_properties.liquid +19 -0
  64. data/lib/templates/swift3-variant/inc/_inverse_properties.liquid +11 -0
  65. data/lib/templates/swift3-variant/inc/_optional_attribute_property.liquid +5 -0
  66. data/lib/templates/swift3-variant/inc/_primary_key.liquid +5 -0
  67. data/lib/templates/swift3-variant/inc/_relationship_properties.liquid +9 -0
  68. data/lib/templates/swift3-variant/inc/_relationships_enum.liquid +17 -0
  69. data/lib/templates/swift3-variant/inc/_type_converter.liquid +20 -0
  70. data/lib/templates/swift3/README.md +60 -0
  71. data/lib/templates/swift3/entity.liquid +12 -0
  72. data/lib/templates/swift3/entity_filename.liquid +1 -0
  73. data/lib/templates/swift3/enum.liquid +15 -0
  74. data/lib/templates/swift3/enum_filename.liquid +1 -0
  75. data/lib/templates/swift3/inc/_attributes_enum.liquid +13 -0
  76. data/lib/templates/swift3/inc/_attributes_properties.liquid +32 -0
  77. data/lib/templates/swift3/inc/_default_value_converter.liquid +14 -0
  78. data/lib/templates/swift3/inc/_enum_attribute_property.liquid +26 -0
  79. data/lib/templates/swift3/inc/_ignored_properties.liquid +24 -0
  80. data/lib/templates/swift3/inc/_indexed_properties.liquid +19 -0
  81. data/lib/templates/swift3/inc/_inverse_properties.liquid +11 -0
  82. data/lib/templates/swift3/inc/_optional_attribute_property.liquid +5 -0
  83. data/lib/templates/swift3/inc/_primary_key.liquid +5 -0
  84. data/lib/templates/swift3/inc/_relationship_properties.liquid +9 -0
  85. data/lib/templates/swift3/inc/_relationships_enum.liquid +17 -0
  86. data/lib/templates/swift3/inc/_type_converter.liquid +20 -0
  87. metadata +134 -31
  88. data/lib/gyro/realm/java/converter.rb +0 -63
  89. data/lib/gyro/realm/java/enum_generator.rb +0 -128
  90. data/lib/gyro/realm/java/generator.rb +0 -183
  91. data/lib/gyro/realm/java/templates.rb +0 -67
  92. data/lib/gyro/realm/objc/converter.rb +0 -63
  93. data/lib/gyro/realm/objc/enum_generator.rb +0 -86
  94. data/lib/gyro/realm/objc/generator.rb +0 -373
  95. data/lib/gyro/realm/objc/json_category_generator.rb +0 -172
  96. data/lib/gyro/realm/objc/protocol_generator.rb +0 -59
  97. data/lib/gyro/realm/objc/templates.rb +0 -100
  98. data/lib/gyro/realm/swift/converter.rb +0 -74
  99. data/lib/gyro/realm/swift/enum_generator.rb +0 -73
  100. data/lib/gyro/realm/swift/generator.rb +0 -265
  101. data/lib/gyro/realm/swift/object_mapper_generator.rb +0 -124
  102. data/lib/gyro/realm/swift/templates.rb +0 -64
  103. data/lib/gyro/utils/file_utils.rb +0 -31
  104. data/lib/gyro/utils/log.rb +0 -68
  105. data/lib/gyro/utils/raise.rb +0 -23
  106. data/lib/gyro/utils/string_xcdatamodel.rb +0 -58
  107. data/lib/gyro/xcdatamodel/parser/attribute.rb +0 -98
  108. data/lib/gyro/xcdatamodel/parser/entity.rb +0 -234
  109. data/lib/gyro/xcdatamodel/parser/relationship.rb +0 -70
  110. data/lib/gyro/xcdatamodel/parser/xcdatamodel.rb +0 -59
data/bin/gyro CHANGED
@@ -1,118 +1,125 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- =begin
4
- Copyright 2016 - Niji
3
+ # Copyright 2016 - Niji
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
5
16
 
6
- Licensed under the Apache License, Version 2.0 (the "License");
7
- you may not use this file except in compliance with the License.
8
- You may obtain a copy of the License at
9
-
10
- http://www.apache.org/licenses/LICENSE-2.0
11
-
12
- Unless required by applicable law or agreed to in writing, software
13
- distributed under the License is distributed on an "AS IS" BASIS,
14
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- See the License for the specific language governing permissions and
16
- limitations under the License.
17
- =end
18
-
19
- if RUBY_VERSION < '2.0.0'
20
- abort 'error: gyro requires Ruby 2 or higher.'
21
- end
17
+ abort 'error: gyro requires Ruby 2 or higher.' if RUBY_VERSION < '2.0.0'
22
18
 
23
19
  require 'gyro'
24
20
  require 'optparse'
21
+ require 'pathname'
25
22
 
26
23
  dir = Dir.pwd
27
24
  options = {
28
- :model => nil,
29
- :android_dir => nil,
30
- :package => nil,
31
- :ios_dir => nil,
32
- :ios_json => false,
33
- :ios_framework => false,
34
- :ios_swift => false
25
+ model: nil,
26
+ template: nil,
27
+ output: nil,
28
+ params: {}
35
29
  }
36
30
 
37
- OptionParser.new do |opts|
31
+ parser = OptionParser.new do |opts|
38
32
  opts.banner = 'Usage: gyro [options]'
39
- opts.on('-m PATH', '--model PATH', %q(Specify Interface Builder .xcdatamodel file)) do |path|
40
- options[:model] = path
41
- end
42
- opts.on('-a PATH', '--android PATH', %q(Specify Android Realm model classes dir)) do |path|
43
- options[:android_dir] = path
33
+ opts.on('-m PATH', '--model PATH', 'The .xcdatamodel file to use') do |xcdatamodel_path|
34
+ options[:model] = xcdatamodel_path
44
35
  end
45
- opts.on('-p PATH', '--package PATH', %q(Specify Android Realm model classes package name)) do |path|
46
- options[:package] = path
36
+ opts.on('-t DIR', '--template DIR',
37
+ 'Path to the template directory to use, or name of a template embedded in gyro',
38
+ '(see --list for available names)') do |path|
39
+ options[:template] = path
47
40
  end
48
- opts.on('-i PATH', '--ios PATH', %q(Specify iOS Realm model classes dir)) do |path|
49
- options[:ios_dir] = path
41
+ opts.on('-o DIR', '--output DIR',
42
+ 'Path to the output directory where to generate the model files') do |path|
43
+ options[:output] = path
50
44
  end
51
- opts.on('-j', '--json', %q(Additionally generate Realm-JSON categories (Objective-C) or ObjectMapper artifacts (Swift))) do
52
- options[:ios_json] = true
45
+ opts.on('-p KEY:VALUE', '--param KEY:VALUE',
46
+ 'Specify a custom parameter that can be used by the template.',
47
+ 'Can be repeated to add more parameters') do |params|
48
+ (k, *v) = params.split(':')
49
+ options[:params] = options[:params].merge(k.to_s => v.join(':').to_s)
53
50
  end
54
- opts.on('-f', '--framework', %q(If you use CocoaPods Frameworks instead of static libraries)) do
55
- options[:ios_framework] = true
51
+ opts.on('-l', '--list', 'List the names of all available templates provided by gyro') do
52
+ Gyro::Template.print_list
53
+ exit
56
54
  end
57
- opts.on('-s', '--swift', %q(If you use Swift as iOS language)) do
58
- options[:ios_swift] = true
55
+ opts.on('-i', '--info TEMPLATE',
56
+ 'Show information about the given template',
57
+ '(path to directory or name of an embedded template)') do |template|
58
+ Gyro::Template.print_infos(template)
59
+ exit
59
60
  end
60
- opts.on('-n', '--nsnumber', %q(To generate NSNumbers instead of Int/BOOL/Float types)) do
61
- options[:wrappers] = true
61
+ opts.on_tail('-h', '--help', 'Show this message') do
62
+ puts opts
63
+ exit 1
62
64
  end
63
- opts.on('-w', '--wrappers', %q(To generate Java primitive wrappers for optional fields instead of primitive types)) do
64
- options[:wrappers] = true
65
+ opts.on_tail('-v', '--version', 'Show version') do
66
+ puts Gyro::VERSION
67
+ exit
65
68
  end
66
- opts.on('-x', '--annotations', %q(To tag code with Android support annotations according to optional/non optional fields)) do
67
- options[:annotations] = true
68
- end
69
- opts.on_tail('-h', '--help', %q(Show this message)) { puts opts; exit 1 }
70
- opts.on_tail('-v', '--version', 'Show version') { puts Gyro::VERSION; exit }
71
- opts.parse!
69
+ end
70
+
71
+ begin
72
+ parser.parse!(ARGV)
73
+ rescue OptionParser::ParseError => e
74
+ Gyro::Log.error(e)
75
+ puts parser
76
+ exit 1
72
77
  end
73
78
 
74
79
  if options[:model].nil?
75
- Gyro::Log::info('No model provided, trying to find one in the local directory…')
76
- options[:model] = Gyro.find_xcdatamodel(dir)
77
- Gyro::Log::info("Unable to find any .xcdatamodel in #{dir}") if options[:model].nil?
80
+ Gyro::Log.info('No model provided, trying to find one in the local directory…')
81
+ options[:model] = Gyro::Parser::XCDataModel.find_in_dir(dir)
82
+ Gyro::Log.info("Unable to find any .xcdatamodel in #{dir}") if options[:model].nil?
78
83
  end
79
84
 
80
85
  if options[:model].nil?
81
- Gyro.exit_with_error('You need to specify .xcdatamodel path using --model option (see --help for more info)')
86
+ Gyro::Log.fail!('You need to specify .xcdatamodel path using --model option (see --help for more info)')
82
87
  else
83
88
  basename = File.basename(options[:model])
84
89
  dirname = File.dirname(options[:model])
85
- Gyro::Log::success("Using #{basename} in #{dirname}")
90
+ Gyro::Log.success("Using #{basename} in #{dirname}")
86
91
  end
87
92
 
88
- # Android
89
- if options[:android_dir].nil?
90
- Gyro::Log::info('You need to specify a dir using --android option to generate Android Realm model classes (see --help for more info)')
91
- else
92
- if Dir.exist?(options[:android_dir])
93
- if options[:package].nil?
94
- Gyro::Log::info('You need to specify an Android package name using --package option (see --help for more info)')
95
- else
96
- xcdatamodel = Gyro::XCDataModel::Parser::XCDataModel.new(options[:model])
97
- Gyro::Realm::Java::Generator.new(options[:android_dir], options[:package], xcdatamodel, options[:wrappers], options[:annotations])
98
- end
99
- else
100
- Gyro::Log::info('You need to specify a valid Android Realm model classes dir')
101
- end
93
+ # Liquid Templates
94
+ if options[:template].nil?
95
+ # Generate JSON if no -t is specified
96
+ Gyro::Log.info('Note: You can specify a template using the --template option (see --help for more info)')
97
+ xcdatamodel = Gyro::Parser::XCDataModel::XCDataModel.new(options[:model])
98
+ Gyro::Generator::Json.new(xcdatamodel)
99
+ exit
102
100
  end
103
101
 
104
- # iOS
105
- if options[:ios_dir].nil?
106
- Gyro::Log::info('You need to specify a dir using --ios option to generate iOS Realm model classes (see --help for more info)')
107
- else
108
- if Dir.exist?(options[:ios_dir])
109
- xcdatamodel = Gyro::XCDataModel::Parser::XCDataModel.new(options[:model])
110
- if options[:ios_swift]
111
- Gyro::Realm::Swift::Generator.new(options[:ios_dir], xcdatamodel, options[:ios_json])
112
- else
113
- Gyro::Realm::ObjC::Generator.new(options[:ios_dir], xcdatamodel, options[:ios_json], options[:ios_framework], options[:wrappers])
114
- end
115
- else
116
- Gyro::Log::info('You need to specify a valid iOS Realm model classes dir')
117
- end
102
+ template_dir = Gyro::Template.find(options[:template])
103
+
104
+ if options[:output].nil?
105
+ Gyro::Log.fail!('You need to specify output directory path using --output option (see --help for more info)')
118
106
  end
107
+
108
+ output_dir = Pathname.new(options[:output])
109
+
110
+ unless output_dir.exist?
111
+ Gyro::Log.fail!("The output directory #{output_dir} does not exist. Please create it first.")
112
+ end
113
+
114
+ puts <<-INFO.gsub(/ \|/, '')
115
+ |
116
+ |#===================================
117
+ |# Template : #{template_dir}
118
+ |# Output Dir : #{output_dir}
119
+ |# Params : #{options[:params].inspect}
120
+ |#===================================
121
+ INFO
122
+
123
+ xcdatamodel = Gyro::Parser::XCDataModel::XCDataModel.new(options[:model])
124
+ gen = Gyro::Generator::Liquid.new(template_dir, output_dir, options[:params])
125
+ gen.generate(xcdatamodel)
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
data/lib/gyro.rb CHANGED
@@ -1,32 +1,21 @@
1
- =begin
2
- Copyright 2016 - Niji
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
3
14
 
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
15
+ require 'gyro/version'
7
16
 
8
- http://www.apache.org/licenses/LICENSE-2.0
17
+ require 'gyro/parser/xcdatamodel'
18
+ require 'gyro/generator/json'
19
+ require 'gyro/generator/liquid'
9
20
 
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
- =end
16
-
17
- require File.expand_path('gyro/xcdatamodel/parser/xcdatamodel', File.dirname(__FILE__))
18
- require File.expand_path('gyro/realm/java/generator', File.dirname(__FILE__))
19
- require File.expand_path('gyro/realm/objc/generator', File.dirname(__FILE__))
20
- require File.expand_path('gyro/realm/swift/generator', File.dirname(__FILE__))
21
- require File.expand_path('gyro/utils/log', File.dirname(__FILE__))
22
- require File.expand_path('gyro/utils/file_utils', File.dirname(__FILE__))
23
-
24
- module Gyro
25
- VERSION = '0.4.0'
26
-
27
- def self.exit_with_error(message)
28
- Gyro::Log::error message
29
- exit 1
30
- end
31
-
32
- end
21
+ require 'gyro/log'
@@ -0,0 +1,30 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'json'
16
+ require 'gyro/parser/xcdatamodel'
17
+
18
+ module Gyro
19
+ module Generator
20
+ # Generates the JSON representation of the input datamodel
21
+ #
22
+ class Json
23
+ # PUBLIC METHODS #######################################################
24
+ def initialize(xcdatamodel)
25
+ Gyro::Log.title('Generating JSON')
26
+ puts JSON.pretty_generate(xcdatamodel.to_h)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'liquid'
16
+ require 'pathname'
17
+
18
+ require 'gyro/parser/xcdatamodel'
19
+ require 'gyro/template'
20
+ require 'gyro/generator/liquid/liquid'
21
+ require 'gyro/generator/liquid/whitespace_patch'
22
+ require 'gyro/generator/liquid/filters'
@@ -0,0 +1,53 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Gyro
16
+ module Generator
17
+ # Declare some custom Liquid Filters used by the template, then render it
18
+ #
19
+ module LiquidFilters
20
+ def escape_quotes(input)
21
+ input.gsub('"', '\"')
22
+ end
23
+
24
+ def snake_to_camel_case(input)
25
+ input.split('_').map(&:capitalize).join
26
+ end
27
+
28
+ def snake_case(input)
29
+ input.gsub(/::/, '/')
30
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
31
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
32
+ .tr('-', '_')
33
+ .downcase
34
+ end
35
+
36
+ def uncapitalize(input)
37
+ input_strip = input.strip
38
+ input_strip[0, 1].downcase + input_strip[1..-1]
39
+ end
40
+
41
+ def titleize(input)
42
+ input_strip = input.strip
43
+ input_strip[0, 1].upcase + input_strip[1..-1]
44
+ end
45
+
46
+ def delete_objc_prefix(input)
47
+ i = 0
48
+ i += 1 while i < input.length - 1 && /[[:upper:]]/.match(input[i + 1])
49
+ input[i..input.length]
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,124 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Gyro
16
+ module Generator
17
+ # Generates arbitrary output from the input datamodel, using a Liquid template provided by the user
18
+ #
19
+ class Liquid
20
+ attr_accessor :params, :output_dir
21
+
22
+ # PUBLIC METHODS #######################################################
23
+
24
+ # rubocop:disable Metrics/AbcSize
25
+ def initialize(template_dir, output_dir, params)
26
+ Gyro::Log.title('Generating Model')
27
+
28
+ @params = params
29
+ @output_dir = Pathname.new(output_dir)
30
+
31
+ # Define Template path for Liquid file system to use Include Tag
32
+ ::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(template_dir)
33
+
34
+ @entity_template = load_template(template_dir + 'entity.liquid', false)
35
+ @entity_filename_template = load_template(template_dir + 'entity_filename.liquid', true)
36
+ @enum_template = load_template(template_dir + 'enum.liquid', false)
37
+ enum_fn_tpl = template_dir + 'enum_filename.liquid'
38
+ enum_fn_tpl = template_dir + 'filename.liquid' unless enum_fn_tpl.exist?
39
+ @enum_filename_template = load_template(enum_fn_tpl, true)
40
+ end
41
+ # rubocop:enable Metrics/AbcSize
42
+
43
+ def generate(xcdatamodel)
44
+ generate_entities(xcdatamodel)
45
+ Gyro::Log.success('Model objects are generated !')
46
+ end
47
+
48
+ private ################################################################
49
+
50
+ def load_template(template_path, prevent_return_line)
51
+ unless template_path.exist?
52
+ Gyro::Log.fail!('Bad template directory content ! Your template needs a ' + template_path.to_s + ' file')
53
+ end
54
+ template_path_string = template_path.read
55
+ if prevent_return_line && template_path_string.include?("\n")
56
+ msg = 'The given template ' + template_path.to_s + ' contains return line(s). This can lead to side effets.'
57
+ Gyro::Log.error(msg)
58
+ end
59
+ ::Liquid::Template.parse(template_path_string)
60
+ end
61
+
62
+ def generate_entities(xcdatamodel)
63
+ xcdatamodel.to_h['entities'].each do |entity|
64
+ entity_context = { 'params' => @params, 'entity' => entity }
65
+ # Rendering template using entity and params context
66
+ output = render_entity(entity_context)
67
+ # Don't generate empty output
68
+ next if output.delete("\n").empty?
69
+
70
+ filename_context = { 'params' => @params, 'name' => entity['name'] }
71
+ # Rendering filename template using entity name and params context
72
+ filename = render_filename(filename_context)
73
+ Gyro::Log.success("#{filename} is created !")
74
+ # Write model object
75
+ File.write(@output_dir + filename, output)
76
+ # Generate model object enums
77
+ generate_enums(entity['attributes'])
78
+ end
79
+ end
80
+
81
+ def generate_enums(attributes)
82
+ enums = []
83
+ attributes.each do |attribute|
84
+ enum_type = attribute['enum_type']
85
+ next if enums.include?(enum_type) || enum_type.empty?
86
+ enums.push(enum_type)
87
+
88
+ enum_context = { 'params' => @params, 'attribute' => attribute }
89
+ # Rendering enum template using attribute and params context
90
+ output = render_enum(enum_context)
91
+ # Don't generate empty output
92
+ next if output.delete("\n").empty?
93
+
94
+ generate_enum(enum_type, output)
95
+ end
96
+ end
97
+
98
+ def generate_enum(enum_name, output)
99
+ # Rendering enum filename template using enum name and params context
100
+ enum_filename_context = { 'params' => @params, 'name' => enum_name }
101
+ enum_filename = render_enum_filename(enum_filename_context)
102
+ File.write(@output_dir + enum_filename, output)
103
+ end
104
+
105
+ def render_entity(context)
106
+ @entity_template.render(context, filters: [Gyro::Generator::LiquidFilters])
107
+ .gsub(/^ +$/, '')
108
+ end
109
+
110
+ def render_filename(context)
111
+ @entity_filename_template.render(context).chomp
112
+ end
113
+
114
+ def render_enum(context)
115
+ @enum_template.render(context, filters: [Gyro::Generator::LiquidFilters])
116
+ .gsub(/^ +$/, '')
117
+ end
118
+
119
+ def render_enum_filename(context)
120
+ @enum_filename_template.render(context).chomp
121
+ end
122
+ end
123
+ end
124
+ end