ios_analytics_cli 1.0.0

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 (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +135 -0
  3. data/.rubocop.yml +2 -0
  4. data/Gemfile +7 -0
  5. data/Gemfile.lock +62 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +48 -0
  8. data/Rakefile +10 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/exe/analytics +34 -0
  12. data/ios_analytics_cli.gemspec +35 -0
  13. data/lib/ios_analytics_cli.rb +52 -0
  14. data/lib/ios_analytics_cli/commands/command.rb +6 -0
  15. data/lib/ios_analytics_cli/commands/generate.rb +77 -0
  16. data/lib/ios_analytics_cli/commands/init.rb +55 -0
  17. data/lib/ios_analytics_cli/error_handler.rb +22 -0
  18. data/lib/ios_analytics_cli/helpers/terminal.rb +11 -0
  19. data/lib/ios_analytics_cli/info.rb +16 -0
  20. data/lib/ios_analytics_cli/interactors/event.rb +22 -0
  21. data/lib/ios_analytics_cli/interactors/interactor.rb +8 -0
  22. data/lib/ios_analytics_cli/interactors/user_property.rb +12 -0
  23. data/lib/ios_analytics_cli/io/config.rb +18 -0
  24. data/lib/ios_analytics_cli/io/io.rb +10 -0
  25. data/lib/ios_analytics_cli/serializers/base.rb +43 -0
  26. data/lib/ios_analytics_cli/serializers/objc/analytics.rb +126 -0
  27. data/lib/ios_analytics_cli/serializers/objc/enums.rb +67 -0
  28. data/lib/ios_analytics_cli/serializers/objc/event.rb +182 -0
  29. data/lib/ios_analytics_cli/serializers/objc/logger.rb +53 -0
  30. data/lib/ios_analytics_cli/serializers/objc/objc.rb +23 -0
  31. data/lib/ios_analytics_cli/serializers/objc/screen.rb +90 -0
  32. data/lib/ios_analytics_cli/serializers/objc/user_property.rb +120 -0
  33. data/lib/ios_analytics_cli/serializers/swift/analytics.rb +63 -0
  34. data/lib/ios_analytics_cli/serializers/swift/event.rb +121 -0
  35. data/lib/ios_analytics_cli/serializers/swift/logger.rb +38 -0
  36. data/lib/ios_analytics_cli/serializers/swift/screen.rb +55 -0
  37. data/lib/ios_analytics_cli/serializers/swift/swift.rb +20 -0
  38. data/lib/ios_analytics_cli/serializers/swift/user_property.rb +69 -0
  39. data/lib/ios_analytics_cli/templates/header.erb +7 -0
  40. data/lib/ios_analytics_cli/templates/templates.rb +12 -0
  41. data/lib/ios_analytics_cli/version.rb +4 -0
  42. metadata +172 -0
@@ -0,0 +1,182 @@
1
+ require_relative '../base'
2
+
3
+ module Analytics
4
+ module Serializer
5
+ class ObjC < Base
6
+ class Event
7
+ def initialize(src)
8
+ @src = src
9
+ end
10
+
11
+ def save(path)
12
+ @class_name = 'AnalyticsEvent'
13
+
14
+ @file_name = @class_name + '.h'
15
+ output_path = File.join(path, @file_name)
16
+ File.write(output_path, render_h)
17
+
18
+ @file_name = @class_name + '.m'
19
+ output_path = File.join(path, @file_name)
20
+ File.write(output_path, render_m)
21
+ end
22
+
23
+ private
24
+
25
+ def render_h
26
+ ERB.new(template_h, nil, '-').result(binding)
27
+ end
28
+
29
+ def template_h
30
+ <<~TEMPLATE
31
+ <%= ERB.new(Analytics::Templates.tmpl_at('header.erb')).result(binding) %>
32
+
33
+ #import <Foundation/Foundation.h>
34
+ #import "AnalyticsEnums.h"
35
+
36
+ NS_ASSUME_NONNULL_BEGIN
37
+
38
+ __swift_unavailable("This class is only available in ObjC.")
39
+ @interface <%= @class_name %> : NSObject
40
+
41
+ @property (nonatomic, strong, readonly) NSString *name;
42
+ @property (nonatomic, strong, readonly, nullable) NSDictionary<NSString *, id> *properties;
43
+
44
+ - (instancetype)init NS_UNAVAILABLE;
45
+ + (instancetype)new NS_UNAVAILABLE;
46
+
47
+ # pragma mark - Events
48
+
49
+ <% @src["events"].each do |event| -%>
50
+ /// <%= event["description"] %>
51
+ <% if event["properties"].nil? -%>
52
+ + (instancetype)<%= event["name"].camel_case %>;
53
+ <% else -%>
54
+ <% event['properties'].each do |property| -%>
55
+ /// @param <%= property['name'].camel_case %> <%= property['description'] %>
56
+ <% end -%>
57
+ + (instancetype)<%= event["name"].camel_case -%><%= format_method_params(event['properties']) %>;
58
+ <% end %>
59
+ <% end -%>
60
+ @end
61
+
62
+ NS_ASSUME_NONNULL_END
63
+ TEMPLATE
64
+ end
65
+
66
+ def render_m
67
+ ERB.new(template_m, nil, '-').result(binding)
68
+ end
69
+
70
+ def template_m
71
+ <<~TEMPLATE
72
+ <%= ERB.new(Analytics::Templates.tmpl_at('header.erb')).result(binding) %>
73
+
74
+ #import "<%= @class_name + '.h' %>"
75
+
76
+ @implementation <%= @class_name %>
77
+
78
+ - (instancetype)initWithName:(NSString *)name properties:(NSDictionary<NSString *, id> *)properties
79
+ {
80
+ if (self = [super init]) {
81
+ _name = name;
82
+ _properties = properties;
83
+ }
84
+ return self;
85
+ }
86
+
87
+ # pragma mark - Events
88
+
89
+ <% @src['events'].each do |event| -%>
90
+ <% if event['properties'].nil? -%>
91
+ + (instancetype)<%= event['name'].camel_case %>
92
+ {
93
+ return [[self alloc] initWithName:@"<%= event['name'] %>" properties: nil];
94
+ }
95
+ <% else -%>
96
+ + (instancetype)<%= event['name'].camel_case -%><%= format_method_params(event['properties']) %>
97
+ {
98
+ <% Interactor::Event.enum_properties_from_event(event).each do |property| -%>
99
+ NSString *<%= property['name'].camel_case %>Value;
100
+ switch (<%= property['name'].camel_case %>) {
101
+ <% property['values'].each do |value| -%>
102
+ case <%= 'AE' + property['name'].pascal_case + value.pascal_case %>:
103
+ <%= property['name'].camel_case %>Value = @"<%= value %>";
104
+ break;
105
+ <% end -%>
106
+ }
107
+
108
+ <% end -%>
109
+ return [[self alloc] initWithName:@"<%= event['name'] %>" properties: <%= format_init_properties(event['properties']) %>];
110
+ }
111
+ <% end -%>
112
+
113
+ <% end -%>
114
+ @end
115
+ TEMPLATE
116
+ end
117
+
118
+ ## Helper methods called from the ERB template
119
+
120
+ # Formats the parameters in ObjC method.
121
+ def format_method_params(properties)
122
+ params = properties.map.with_index do |property, i|
123
+ name = if i == 0
124
+ property['name'].pascal_case # 'num_of_items' -> 'NumOfItems'
125
+ else
126
+ property['name'].camel_case # 'num_of_items' -> 'numOfItems'
127
+ end
128
+
129
+ "#{name}:(#{format_property_type(property)})#{property['name'].camel_case}"
130
+ end
131
+
132
+ "With#{params.join(' ')}"
133
+ end
134
+
135
+ # Maps the property type to ObjC type.
136
+ def format_property_type(property)
137
+ # if it doesn't have values, it's not an enum,
138
+ # and if it does, we'll return capitalized property name prefixed with 'AE',
139
+ # because an enum with the same name will be generated as well
140
+ if property['values'].nil?
141
+ case property['type']
142
+ when 'text'
143
+ 'NSString *'
144
+ when 'number'
145
+ 'NSInteger'
146
+ when 'decimal'
147
+ 'double'
148
+ else
149
+ 'unknown-type'
150
+ end
151
+ else
152
+ 'AE' + property['name'].pascal_case
153
+ end
154
+ end
155
+
156
+ # Formats the properties passed to Event's init.
157
+ def format_init_properties(properties)
158
+ result = properties
159
+ .map.with_index { |property, _i| "@\"#{property['name']}\": #{format_init_property_value(property)}" }
160
+ .join(', ')
161
+
162
+ "@{#{result}}"
163
+ end
164
+
165
+ # Formats the property's value (used as NSDictionary's value) value depending on the property's type.
166
+ def format_init_property_value(property)
167
+ # if it doesn't have values, it's not an enum
168
+ if property['values'].nil?
169
+ case property['type']
170
+ when 'number', 'decimal'
171
+ "@(#{property['name'].camel_case})"
172
+ else
173
+ property['name'].camel_case
174
+ end
175
+ else
176
+ property['name'].camel_case + 'Value'
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,53 @@
1
+ require_relative '../base'
2
+
3
+ module Analytics
4
+ module Serializer
5
+ class ObjC < Base
6
+ class Logger
7
+ def initialize(src)
8
+ @src = src
9
+ end
10
+
11
+ def save(path)
12
+ @protocol_name = 'AnalyticsLogger'
13
+
14
+ @file_name = @protocol_name + '.h'
15
+ output_path = File.join(path, @file_name)
16
+ File.write(output_path, render_h)
17
+ end
18
+
19
+ private
20
+
21
+ def render_h
22
+ ERB.new(template_h, nil, '-').result(binding)
23
+ end
24
+
25
+ def template_h
26
+ <<~TEMPLATE
27
+ <%= ERB.new(Analytics::Templates.tmpl_at('header.erb')).result(binding) %>
28
+
29
+ #import <Foundation/Foundation.h>
30
+
31
+ @class AnalyticsEvent;
32
+ @class AnalyticsScreen;
33
+ @class AnalyticsUserProperty;
34
+
35
+ NS_ASSUME_NONNULL_BEGIN
36
+
37
+ __swift_unavailable("This protocol is only available in ObjC.")
38
+ @protocol <%= @protocol_name %> <NSObject>
39
+
40
+ - (void)setEnabled:(BOOL)enabled;
41
+ - (void)logEvent:(AnalyticsEvent *)event;
42
+ - (void)trackScreen:(AnalyticsScreen *)screen;
43
+ - (void)setUserProperty:(AnalyticsUserProperty *)userProperty;
44
+
45
+ @end
46
+
47
+ NS_ASSUME_NONNULL_END
48
+ TEMPLATE
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,23 @@
1
+ require_relative '../base'
2
+
3
+ module Analytics
4
+ module Serializer
5
+ class ObjC < Base
6
+ # An abstract method used to save a file at provided path.
7
+ def save(path)
8
+ files = [
9
+ AnalyticsFile,
10
+ Enums,
11
+ Event,
12
+ Logger,
13
+ Screen,
14
+ UserProperty
15
+ ]
16
+
17
+ files.each do |f|
18
+ f.new(@src).save(path)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,90 @@
1
+ require_relative '../base'
2
+
3
+ module Analytics
4
+ module Serializer
5
+ class ObjC < Base
6
+ class Screen
7
+ def initialize(src)
8
+ @src = src
9
+ end
10
+
11
+ def save(path)
12
+ @class_name = 'AnalyticsScreen'
13
+
14
+ @file_name = @class_name + '.h'
15
+ output_path = File.join(path, @file_name)
16
+ File.write(output_path, render_h)
17
+
18
+ @file_name = @class_name + '.m'
19
+ output_path = File.join(path, @file_name)
20
+ File.write(output_path, render_m)
21
+ end
22
+
23
+ private
24
+
25
+ def render_h
26
+ ERB.new(template_h, nil, '-').result(binding)
27
+ end
28
+
29
+ def template_h
30
+ <<~TEMPLATE
31
+ <%= ERB.new(Analytics::Templates.tmpl_at('header.erb')).result(binding) %>
32
+
33
+ #import <Foundation/Foundation.h>
34
+
35
+ NS_ASSUME_NONNULL_BEGIN
36
+
37
+ __swift_unavailable("This class is only available in ObjC.")
38
+ @interface <%= @class_name %> : NSObject
39
+
40
+ @property (nonatomic, strong, readonly) NSString *name;
41
+
42
+ - (instancetype)init NS_UNAVAILABLE;
43
+ + (instancetype)new NS_UNAVAILABLE;
44
+
45
+ #pragma mark - Screens
46
+ <% @src['screens'].each do |screen| %>
47
+ /// <%= screen['description'] %>
48
+ + (instancetype)<%= screen['name'].camel_case %>;
49
+ <% end %>
50
+ @end
51
+
52
+ NS_ASSUME_NONNULL_END
53
+ TEMPLATE
54
+ end
55
+
56
+ def render_m
57
+ ERB.new(template_m, nil, '-').result(binding)
58
+ end
59
+
60
+ def template_m
61
+ <<~TEMPLATE
62
+ <%= ERB.new(Analytics::Templates.tmpl_at('header.erb')).result(binding) %>
63
+
64
+ #import "<%= @class_name + '.h' %>"
65
+
66
+ @implementation <%= @class_name %>
67
+
68
+ - (instancetype)initWithName:(NSString *)name
69
+ {
70
+ if (self = [super init]) {
71
+ _name = name;
72
+ }
73
+ return self;
74
+ }
75
+
76
+ #pragma mark - Screens
77
+ <% @src['screens'].each do |screen| %>
78
+ + (instancetype)<%= screen['name'].camel_case %>
79
+ {
80
+ return [[self alloc] initWithName:@"<%= screen['name'] %>"];
81
+ }
82
+ <% end -%>
83
+
84
+ @end
85
+ TEMPLATE
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,120 @@
1
+ require_relative '../base'
2
+
3
+ module Analytics
4
+ module Serializer
5
+ class ObjC < Base
6
+ class UserProperty
7
+ def initialize(src)
8
+ @src = src
9
+ end
10
+
11
+ def save(path)
12
+ @class_name = 'AnalyticsUserProperty'
13
+
14
+ @file_name = @class_name + '.h'
15
+ output_path = File.join(path, @file_name)
16
+ File.write(output_path, render_h)
17
+
18
+ @file_name = @class_name + '.m'
19
+ output_path = File.join(path, @file_name)
20
+ File.write(output_path, render_m)
21
+ end
22
+
23
+ private
24
+
25
+ def render_h
26
+ ERB.new(template_h, nil, '-').result(binding)
27
+ end
28
+
29
+ def template_h
30
+ <<~TEMPLATE
31
+ <%= ERB.new(Analytics::Templates.tmpl_at('header.erb')).result(binding) %>
32
+
33
+ #import <Foundation/Foundation.h>
34
+ #import "AnalyticsEnums.h"
35
+
36
+ NS_ASSUME_NONNULL_BEGIN
37
+
38
+ __swift_unavailable("This class is only available in ObjC.")
39
+ @interface <%= @class_name %> : NSObject
40
+
41
+ @property (nonatomic, strong, readonly) NSString *name;
42
+ @property (nonatomic, strong, readonly, nullable) NSString *value;
43
+
44
+ - (instancetype)init NS_UNAVAILABLE;
45
+ + (instancetype)new NS_UNAVAILABLE;
46
+
47
+ #pragma mark - User properties
48
+ <% @src["userProperties"].each do |user_property| %>
49
+ /// <%= user_property['description'] %>
50
+ <% if user_property['values'].nil? -%>
51
+ /// @param value The value of the user property, or `nil` if You want to remove the user property.
52
+ <% else -%>
53
+ /// @param value The value of the user property, or use `<%= 'AUP' + user_property['name'].pascal_case + 'Nil' %>` if You want to remove the user property.
54
+ <% end -%>
55
+ + (instancetype)<%= user_property['name'].camel_case %>WithValue:(<%= format_method_parameter(user_property) %>)value;
56
+ <% end %>
57
+ @end
58
+
59
+ NS_ASSUME_NONNULL_END
60
+ TEMPLATE
61
+ end
62
+
63
+ def render_m
64
+ ERB.new(template_m, nil, '-').result(binding)
65
+ end
66
+
67
+ def template_m
68
+ <<~TEMPLATE
69
+ <%= ERB.new(Analytics::Templates.tmpl_at('header.erb')).result(binding) %>
70
+
71
+ #import "<%= @class_name + '.h' %>"
72
+
73
+ @implementation <%= @class_name %>
74
+
75
+ - (instancetype)initWithName:(NSString *)name value:(NSString * _Nullable)value
76
+ {
77
+ if (self = [super init]) {
78
+ _name = name;
79
+ _value = value;
80
+ }
81
+ return self;
82
+ }
83
+
84
+ #pragma mark - User properties
85
+ <% @src["userProperties"].each do |user_property| %>
86
+ + (instancetype)<%= user_property['name'].camel_case %>WithValue:(<%= format_method_parameter(user_property) %>)value
87
+ {
88
+ <% unless user_property['values'].nil? -%>
89
+ NSString *rawValue;
90
+ switch (value) {
91
+ <% user_property['values'].each do |value| -%>
92
+ case <%= 'AUP' + user_property['name'].pascal_case + value.pascal_case %>:
93
+ rawValue = @"<%= value %>";
94
+ break;
95
+ <% end -%>
96
+ case <%= 'AUP' + user_property['name'].pascal_case + 'Nil' %>:
97
+ rawValue = nil;
98
+ break;
99
+ }
100
+ return [[self alloc] initWithName:@"<%= user_property['name'] %>" value:rawValue];
101
+ <% else -%>
102
+ return [[self alloc] initWithName:@"<%= user_property['name'] %>" value:value];
103
+ <% end -%>
104
+ }
105
+ <% end %>
106
+ @end
107
+ TEMPLATE
108
+ end
109
+
110
+ def format_method_parameter(user_property)
111
+ if user_property['values'].nil?
112
+ "NSString * _Nullable"
113
+ else
114
+ 'AUP' + user_property['name'].pascal_case
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end