evva 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/changelog.md +4 -0
- data/lib/evva/analytics_enum.rb +1 -0
- data/lib/evva/analytics_event.rb +7 -3
- data/lib/evva/analytics_property.rb +17 -0
- data/lib/evva/android_generator.rb +125 -74
- data/lib/evva/config.rb +12 -2
- data/lib/evva/google_sheet.rb +43 -25
- data/lib/evva/swift_generator.rb +91 -81
- data/lib/evva/templates/kotlin/base.kt +7 -0
- data/lib/evva/templates/kotlin/destinations.kt +5 -0
- data/lib/evva/templates/kotlin/event_enum.kt +5 -0
- data/lib/evva/templates/kotlin/events.kt +34 -0
- data/lib/evva/templates/kotlin/people_properties.kt +24 -0
- data/lib/evva/templates/kotlin/people_properties_enum.kt +5 -0
- data/lib/evva/templates/kotlin/special_property_enums.kt +10 -0
- data/lib/evva/templates/swift/base.swift +7 -0
- data/lib/evva/templates/swift/destinations.swift +5 -0
- data/lib/evva/templates/swift/events.swift +65 -0
- data/lib/evva/templates/swift/people_properties.swift +49 -0
- data/lib/evva/templates/swift/special_property_enums.swift +10 -0
- data/lib/evva/version.rb +2 -2
- data/lib/evva.rb +12 -2
- data/spec/evva_spec.rb +3 -5
- data/spec/fixtures/sample_public_events.csv +4 -4
- data/spec/fixtures/sample_public_people_properties.csv +4 -3
- data/spec/fixtures/test.yml +3 -1
- data/spec/lib/evva/android_generator_spec.rb +95 -12
- data/spec/lib/evva/config_spec.rb +7 -3
- data/spec/lib/evva/google_sheet_spec.rb +23 -5
- data/spec/lib/evva/swift_generator_spec.rb +152 -39
- metadata +15 -3
- data/evva_config.yml +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f74dbff0766dc7623ca1ac518e7636172440511a4470398d594fefef8364fba9
|
4
|
+
data.tar.gz: 4793e14af612e48d0e7cf85aa313d5c6c4f92c5eb440be7a853503f39fd093e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebbee6abfa8abd7e6717f20246a1271a7d7b35e4b9a42414293ff436cff842e82ac45beb7638dc642cdb00c1408f7c81cb4b8dcfdd7d4ee6dafa04f121388b5a
|
7
|
+
data.tar.gz: 18c42c24f8f2b7d923c9a99b5ec58a43d258340b2523fdb4bf8f136bb0d4d9a075f3497b4c0c8a8176c4e01b07db56f116066b1139389104497db86e6ed9e30b
|
data/README.md
CHANGED
@@ -24,7 +24,6 @@ Evva automatically generates code for triggering events based on a Google Sheets
|
|
24
24
|
|
25
25
|
data_source:
|
26
26
|
type: google_sheet
|
27
|
-
sheet_id: <GOOGLE-DRIVE-SHEET-ID>
|
28
27
|
events_url: <GOOGLE-DRIVE-EVENTS-SHEET-URL>
|
29
28
|
people_properties_url: <GOOGLE-DRIVE-PEOPLE-PROPERTIES-SHEET-URL>
|
30
29
|
enum_classes_url: <GOOGLE-DRIVE-ENUM-CLASSES-SHEET-URL>
|
@@ -33,5 +32,7 @@ Evva automatically generates code for triggering events based on a Google Sheets
|
|
33
32
|
event_file_name: /file/with/tracking/functions
|
34
33
|
event_enum_file_name: /file/with/event/names
|
35
34
|
people_file_name: /file/with/people/properties
|
36
|
-
|
35
|
+
people_file_name: /file/with/people/property/names
|
36
|
+
destinations_file_name: /file/with/destinations
|
37
|
+
special_enum_file_name: /file/with/special/enum/properties/
|
37
38
|
```
|
data/changelog.md
CHANGED
data/lib/evva/analytics_enum.rb
CHANGED
data/lib/evva/analytics_event.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
module Evva
|
2
2
|
class AnalyticsEvent
|
3
|
-
attr_reader :event_name, :properties
|
4
|
-
|
3
|
+
attr_reader :event_name, :properties, :destinations
|
4
|
+
|
5
|
+
def initialize(event_name, properties, destinations)
|
5
6
|
@event_name = event_name
|
6
7
|
@properties = properties
|
8
|
+
@destinations = destinations
|
7
9
|
end
|
8
10
|
|
9
11
|
def ==(other)
|
10
|
-
event_name == other.event_name
|
12
|
+
event_name == other.event_name &&
|
13
|
+
properties == other.properties &&
|
14
|
+
destinations == other.destinations
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Evva
|
2
|
+
class AnalyticsProperty
|
3
|
+
attr_reader :property_name, :type, :destinations
|
4
|
+
|
5
|
+
def initialize(property_name, type, destinations)
|
6
|
+
@property_name = property_name
|
7
|
+
@type = type
|
8
|
+
@destinations = destinations
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
property_name == other.property_name &&
|
13
|
+
type == other.type &&
|
14
|
+
destinations == other.destinations
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,115 +6,158 @@ module Evva
|
|
6
6
|
@package_name = package_name
|
7
7
|
end
|
8
8
|
|
9
|
-
|
9
|
+
BASE_TEMPLATE = File.expand_path("./templates/kotlin/base.kt", __dir__)
|
10
|
+
EVENTS_TEMPLATE = File.expand_path("./templates/kotlin/events.kt", __dir__)
|
11
|
+
EVENT_ENUM_TEMPLATE = File.expand_path("./templates/kotlin/event_enum.kt", __dir__)
|
12
|
+
PEOPLE_PROPERTIES_TEMPLATE = File.expand_path("./templates/kotlin/people_properties.kt", __dir__)
|
13
|
+
PEOPLE_PROPERTIES_ENUM_TEMPLATE = File.expand_path("./templates/kotlin/people_properties_enum.kt", __dir__)
|
14
|
+
SPECIAL_PROPERTY_ENUMS_TEMPLATE = File.expand_path("./templates/kotlin/special_property_enums.kt", __dir__)
|
15
|
+
DESTINATIONS_TEMPLATE = File.expand_path("./templates/kotlin/destinations.kt", __dir__)
|
10
16
|
|
11
|
-
|
17
|
+
TAB_SIZE = " " # \t -> 4 spaces
|
18
|
+
|
19
|
+
NATIVE_TYPES = %w[Long Int String Double Float Boolean Date].freeze
|
20
|
+
|
21
|
+
def events(bundle, file_name, enums_file_name, destinations_file_name)
|
12
22
|
header_footer_wrapper do
|
13
|
-
|
14
|
-
|
23
|
+
class_name = file_name
|
24
|
+
enums_class_name = enums_file_name
|
25
|
+
destinations_class_name = destinations_file_name
|
26
|
+
|
27
|
+
events = bundle.map do |event|
|
28
|
+
properties = event.properties.map do |name, type|
|
29
|
+
param_name = camelize(name.to_s, false)
|
30
|
+
value_fetcher = param_name
|
31
|
+
|
32
|
+
if is_special_property?(type)
|
33
|
+
if type.end_with?('?')
|
34
|
+
# optional value, we need ? to access a parameter
|
35
|
+
value_fetcher += "?"
|
36
|
+
end
|
37
|
+
value_fetcher += ".key"
|
38
|
+
end
|
15
39
|
|
16
|
-
|
40
|
+
{
|
41
|
+
param_name: param_name,
|
42
|
+
value_fetcher: value_fetcher,
|
43
|
+
type: type,
|
44
|
+
name: name.to_s,
|
45
|
+
}
|
46
|
+
end
|
17
47
|
|
18
|
-
|
19
|
-
}"""
|
20
|
-
end
|
21
|
-
end
|
48
|
+
destinations = event.destinations.map { |p| constantize(p) }
|
22
49
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
50
|
+
{
|
51
|
+
class_name: camelize(event.event_name),
|
52
|
+
event_name: constantize(event.event_name),
|
53
|
+
properties: properties,
|
54
|
+
destinations: destinations,
|
55
|
+
is_object: properties.count == 0 && destinations.count == 0,
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
template_from(EVENTS_TEMPLATE).result(binding)
|
28
60
|
end
|
29
61
|
end
|
30
62
|
|
31
63
|
def event_enum(bundle, file_name)
|
32
64
|
header_footer_wrapper do
|
33
|
-
|
34
|
-
|
35
|
-
|
65
|
+
class_name = file_name
|
66
|
+
|
67
|
+
events = bundle.map(&:event_name).map do |event_name|
|
68
|
+
{
|
69
|
+
name: constantize(event_name),
|
70
|
+
value: event_name,
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
template_from(EVENT_ENUM_TEMPLATE).result(binding)
|
36
75
|
end
|
37
76
|
end
|
38
77
|
|
39
|
-
def
|
78
|
+
def people_properties(people_bundle, file_name, enums_file_name, destinations_file_name)
|
40
79
|
header_footer_wrapper do
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
80
|
+
class_name = file_name
|
81
|
+
enums_class_name = enums_file_name
|
82
|
+
destinations_class_name = destinations_file_name
|
83
|
+
|
84
|
+
properties = people_bundle.map do |property|
|
85
|
+
{
|
86
|
+
class_name: camelize(property.property_name),
|
87
|
+
property_name: constantize(property.property_name),
|
88
|
+
type: property.type,
|
89
|
+
is_special_property: is_special_property?(property.type),
|
90
|
+
destinations: property.destinations.map { |p| constantize(p) },
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
template_from(PEOPLE_PROPERTIES_TEMPLATE).result(binding)
|
46
95
|
end
|
47
96
|
end
|
48
97
|
|
49
|
-
|
98
|
+
def people_properties_enum(people_bundle, file_name)
|
99
|
+
header_footer_wrapper do
|
100
|
+
class_name = file_name
|
101
|
+
|
102
|
+
properties = people_bundle.map(&:property_name).map do |property_name|
|
103
|
+
{
|
104
|
+
name: constantize(property_name),
|
105
|
+
value: property_name,
|
106
|
+
}
|
107
|
+
end
|
50
108
|
|
51
|
-
|
52
|
-
|
53
|
-
imports.map { |ev| ev. gsub("packagename", @package_name) }
|
54
|
-
.join("\n") + "\n\n"
|
109
|
+
template_from(PEOPLE_PROPERTIES_ENUM_TEMPLATE).result(binding)
|
110
|
+
end
|
55
111
|
end
|
56
112
|
|
57
|
-
def
|
58
|
-
|
59
|
-
|
113
|
+
def special_property_enums(enums_bundle)
|
114
|
+
header_footer_wrapper do
|
115
|
+
enums = enums_bundle.map do |enum|
|
116
|
+
values = enum.values.map do |value|
|
117
|
+
{
|
118
|
+
name: constantize(value),
|
119
|
+
value: value,
|
120
|
+
}
|
121
|
+
end
|
60
122
|
|
61
|
-
|
62
|
-
|
63
|
-
|
123
|
+
{
|
124
|
+
class_name: enum.enum_name,
|
125
|
+
values: values,
|
126
|
+
}
|
127
|
+
end
|
64
128
|
|
65
|
-
|
66
|
-
|
129
|
+
template_from(SPECIAL_PROPERTY_ENUMS_TEMPLATE).result(binding)
|
130
|
+
end
|
67
131
|
end
|
68
132
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
if !class_arguments.empty?
|
73
|
-
props = props_map(event_data.properties)
|
133
|
+
def destinations(bundle, file_name)
|
134
|
+
header_footer_wrapper do
|
135
|
+
class_name = file_name
|
74
136
|
|
75
|
-
|
76
|
-
\t\t#{class_arguments}
|
77
|
-
\t) : #{superclass_name}(AnalyticsEvents.#{event_data.event_name.upcase}) {
|
78
|
-
#{props}
|
79
|
-
\t}"""
|
137
|
+
destinations = bundle.map { |d| constantize(d) }
|
80
138
|
|
81
|
-
|
82
|
-
"""\tobject #{class_name} : #{superclass_name}(AnalyticsEvents.#{event_data.event_name.upcase})"""
|
139
|
+
template_from(DESTINATIONS_TEMPLATE).result(binding)
|
83
140
|
end
|
84
141
|
end
|
85
142
|
|
86
|
-
|
87
|
-
split_properties =
|
88
|
-
properties
|
89
|
-
.map.with_index do |data, index|
|
90
|
-
name, type = data
|
91
|
-
prop = "\t\t\t\"#{name}\" to #{camelize(name, false)}"
|
143
|
+
private
|
92
144
|
|
93
|
-
|
94
|
-
|
95
|
-
prop = "#{prop}?"
|
96
|
-
end
|
97
|
-
prop = "#{prop}.key"
|
98
|
-
end
|
145
|
+
def header_footer_wrapper
|
146
|
+
package_name = @package_name
|
99
147
|
|
100
|
-
|
101
|
-
|
102
|
-
prop = "#{prop},"
|
103
|
-
end
|
148
|
+
content = yield
|
149
|
+
.chop # trim trailing newlines created by sublime
|
104
150
|
|
105
|
-
|
106
|
-
end
|
107
|
-
.join("\n")
|
108
|
-
|
109
|
-
"\t\toverride val properties = mapOf(\n#{split_properties}\n\t\t)"
|
151
|
+
template_from(BASE_TEMPLATE).result(binding).gsub("\t", TAB_SIZE)
|
110
152
|
end
|
111
153
|
|
112
|
-
def
|
113
|
-
|
114
|
-
end
|
154
|
+
def template_from(path)
|
155
|
+
file = File.read(path)
|
115
156
|
|
116
|
-
|
117
|
-
|
157
|
+
# - 2nd argument (nil) changes nothing
|
158
|
+
# - 3rd argument activates trim mode using "-" so that you can decide to
|
159
|
+
# not include a line (useful on loops and if statements)
|
160
|
+
ERB.new(file, nil, '-')
|
118
161
|
end
|
119
162
|
|
120
163
|
# extracted from Rails' ActiveSupport
|
@@ -127,5 +170,13 @@ Kotlin
|
|
127
170
|
end
|
128
171
|
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub("/", "::")
|
129
172
|
end
|
173
|
+
|
174
|
+
def constantize(string)
|
175
|
+
string.tr(' ', '_').upcase
|
176
|
+
end
|
177
|
+
|
178
|
+
def is_special_property?(type)
|
179
|
+
!NATIVE_TYPES.include?(type.chomp('?'))
|
180
|
+
end
|
130
181
|
end
|
131
182
|
end
|
data/lib/evva/config.rb
CHANGED
@@ -31,18 +31,26 @@ module Evva
|
|
31
31
|
@hash[:event_file_name]
|
32
32
|
end
|
33
33
|
|
34
|
+
def event_enum_file_name
|
35
|
+
@hash[:event_enum_file_name]
|
36
|
+
end
|
37
|
+
|
34
38
|
def people_file_name
|
35
39
|
@hash[:people_file_name]
|
36
40
|
end
|
37
41
|
|
38
|
-
def
|
39
|
-
@hash[:
|
42
|
+
def people_enum_file_name
|
43
|
+
@hash[:people_enum_file_name]
|
40
44
|
end
|
41
45
|
|
42
46
|
def special_enum_file_name
|
43
47
|
@hash[:special_enum_file_name]
|
44
48
|
end
|
45
49
|
|
50
|
+
def destinations_file_name
|
51
|
+
@hash[:destinations_file_name]
|
52
|
+
end
|
53
|
+
|
46
54
|
def package_name
|
47
55
|
@hash[:package_name]
|
48
56
|
end
|
@@ -58,6 +66,8 @@ module Evva
|
|
58
66
|
event_file_name: { type: String },
|
59
67
|
event_enum_file_name: { type: String },
|
60
68
|
people_file_name: { type: String },
|
69
|
+
people_enum_file_name: { type: String },
|
70
|
+
destinations_file_name: { type: String },
|
61
71
|
package_name: { type: String }
|
62
72
|
}
|
63
73
|
}.freeze
|
data/lib/evva/google_sheet.rb
CHANGED
@@ -3,6 +3,17 @@ require 'csv'
|
|
3
3
|
|
4
4
|
module Evva
|
5
5
|
class GoogleSheet
|
6
|
+
EVENT_NAME = 'Event Name'
|
7
|
+
EVENT_PROPERTIES = 'Event Properties'
|
8
|
+
EVENT_DESTINATION = 'Event Destination'
|
9
|
+
|
10
|
+
PROPERTY_NAME = 'Property Name'
|
11
|
+
PROPERTY_TYPE = 'Property Type'
|
12
|
+
PROPERTY_DESTINATION = 'Property Destination'
|
13
|
+
|
14
|
+
ENUM_NAME = 'Enum Name'
|
15
|
+
ENUM_VALUES = 'Possible Values'
|
16
|
+
|
6
17
|
def initialize(events_url, people_properties_url, enum_classes_url)
|
7
18
|
@events_url = events_url
|
8
19
|
@people_properties_url = people_properties_url
|
@@ -10,41 +21,48 @@ module Evva
|
|
10
21
|
end
|
11
22
|
|
12
23
|
def events
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
24
|
+
@events_csv ||= begin
|
25
|
+
Logger.info("Downloading data from Google Sheet at #{@events_url}")
|
26
|
+
get_csv(@events_url)
|
27
|
+
end
|
28
|
+
|
29
|
+
@events ||= @events_csv.map do |row|
|
30
|
+
event_name = row[EVENT_NAME]
|
31
|
+
properties = hash_parser(row[EVENT_PROPERTIES])
|
32
|
+
destinations = row[EVENT_DESTINATION]&.split(',')
|
33
|
+
Evva::AnalyticsEvent.new(event_name, properties, destinations || [])
|
21
34
|
end
|
22
|
-
event_list
|
23
35
|
end
|
24
36
|
|
25
37
|
def people_properties
|
26
|
-
|
27
|
-
|
38
|
+
@people_properties_csv ||= begin
|
39
|
+
Logger.info("Downloading data from Google Sheet at #{@people_properties_url}")
|
40
|
+
get_csv(@people_properties_url)
|
41
|
+
end
|
28
42
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
43
|
+
@people_properties ||= @people_properties_csv.map do |row|
|
44
|
+
property_name = row[PROPERTY_NAME]
|
45
|
+
property_type = row[PROPERTY_TYPE]
|
46
|
+
destinations = row[PROPERTY_DESTINATION]&.split(',')
|
47
|
+
Evva::AnalyticsProperty.new(property_name, property_type, destinations || [])
|
33
48
|
end
|
34
|
-
people_list
|
35
49
|
end
|
36
50
|
|
37
51
|
def enum_classes
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
52
|
+
@enum_classes_csv ||= begin
|
53
|
+
Logger.info("Downloading data from Google Sheet at #{@enum_classes_url}")
|
54
|
+
get_csv(@enum_classes_url)
|
55
|
+
end
|
56
|
+
|
57
|
+
@enum_classes ||= @enum_classes_csv.map do |row|
|
58
|
+
enum_name = row[ENUM_NAME]
|
59
|
+
values = row[ENUM_VALUES].split(',')
|
60
|
+
Evva::AnalyticsEnum.new(enum_name, values)
|
46
61
|
end
|
47
|
-
|
62
|
+
end
|
63
|
+
|
64
|
+
def destinations
|
65
|
+
@destinations ||= events.map(&:destinations).flatten.uniq
|
48
66
|
end
|
49
67
|
|
50
68
|
private
|