evva 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32699d4abc90a02f944c069ac0cefc8e26fbf972d42342f86ad55652d198f0c2
4
- data.tar.gz: d9e9c0e5a62a712636ebede3bf3b04a9f47c8bc36bac4f06ea4d27b48ff3703f
3
+ metadata.gz: f74dbff0766dc7623ca1ac518e7636172440511a4470398d594fefef8364fba9
4
+ data.tar.gz: 4793e14af612e48d0e7cf85aa313d5c6c4f92c5eb440be7a853503f39fd093e6
5
5
  SHA512:
6
- metadata.gz: cd70916584265dc7077907d324049b93000f5805bf43bb9dda152547e36181740ba8524980606400a8bd128c556dbf09ad641d4c634d513e714b2748639a4498
7
- data.tar.gz: a9a95c538e9d88011507e5a12e64afb84b91fbee6a5b70e0d48f431a05496a0384347c2f6edc97ad3a3164f80677ff05e0b700d4a2c7ea08bce69d7e59ab8145
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
- special_enum_file_name: //file/with/special/enum/properties/
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
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ## [0.4.0] - 2021-12-21
4
+ - Adds type to people properties
5
+ - Adds a list of destinations to events and people properties
6
+
3
7
  ## [0.3.0] - 2021-12-16
4
8
  - Revamp Android generator to generate events as classes instead of methods.
5
9
 
@@ -1,6 +1,7 @@
1
1
  module Evva
2
2
  class AnalyticsEnum
3
3
  attr_reader :enum_name, :values
4
+
4
5
  def initialize(enum_name, values)
5
6
  @enum_name = enum_name
6
7
  @values = values
@@ -1,13 +1,17 @@
1
1
  module Evva
2
2
  class AnalyticsEvent
3
- attr_reader :event_name, :properties
4
- def initialize(event_name, properties = {})
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
- NATIVE_TYPES = %w[Long Int String Double Float Boolean].freeze
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
- def events(bundle, file_name)
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
- """sealed class #{file_name}(event: AnalyticsEvents) {
14
- \tval name = event.key
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
- \topen val properties: Map<String, Any?>? = null
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
- #{bundle.map { |e| event_class(e, file_name) }.join("\n\n")}
19
- }"""
20
- end
21
- end
48
+ destinations = event.destinations.map { |p| constantize(p) }
22
49
 
23
- def people_properties(people_bundle, file_name)
24
- header_footer_wrapper do
25
- body = "enum class #{file_name}(val key: String) {\n"
26
- body << people_bundle.map { |prop| "\t#{prop.upcase}(\"#{prop}\")" }.join(",\n")
27
- body << ";\n}"
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
- body = "enum class #{file_name}(val key: String) {\n"
34
- body << bundle.map(&:event_name).map { |prop| "\t#{prop.upcase}(\"#{prop}\")" }.join(",\n")
35
- body << ";\n}"
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 special_property_enums(enums)
78
+ def people_properties(people_bundle, file_name, enums_file_name, destinations_file_name)
40
79
  header_footer_wrapper do
41
- enums.map do |enum|
42
- body = "enum class #{enum.enum_name}(val key: String) {\n"
43
- body << enum.values.map { |vals| "\t#{vals.tr(' ', '_').upcase}(\"#{vals}\")"}.join(",\n")
44
- body << ";\n}"
45
- end.join("\n\n")
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
- private
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
- def imports_header(imports = [])
52
- return unless imports.length > 0
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 header_footer_wrapper(imports = [])
58
- <<-Kotlin
59
- package #{@package_name}
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
- #{imports_header(imports)}/**
62
- * This file was automatically generated by evva: https://github.com/hole19/evva
63
- */
123
+ {
124
+ class_name: enum.enum_name,
125
+ values: values,
126
+ }
127
+ end
64
128
 
65
- #{yield.gsub("\t", " ")}
66
- Kotlin
129
+ template_from(SPECIAL_PROPERTY_ENUMS_TEMPLATE).result(binding)
130
+ end
67
131
  end
68
132
 
69
- def event_class(event_data, superclass_name)
70
- class_name = camelize(event_data.event_name)
71
- class_arguments = event_data.properties.map { |name, type| "val #{camelize(name, false)}: #{type}" }.join(', ')
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
- """\tdata class #{class_name}(
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
- else
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
- def props_map(properties)
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
- if special_property?(type)
94
- if optional_property?(type)
95
- prop = "#{prop}?"
96
- end
97
- prop = "#{prop}.key"
98
- end
145
+ def header_footer_wrapper
146
+ package_name = @package_name
99
147
 
100
- if index < properties.size - 1
101
- # add list comma to every property except the last one
102
- prop = "#{prop},"
103
- end
148
+ content = yield
149
+ .chop # trim trailing newlines created by sublime
104
150
 
105
- prop
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 special_property?(type)
113
- !NATIVE_TYPES.include?(type.chomp('?'))
114
- end
154
+ def template_from(path)
155
+ file = File.read(path)
115
156
 
116
- def optional_property?(type)
117
- type.include?('?')
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 event_enum_file_name
39
- @hash[:event_enum_file_name]
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
@@ -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
- Logger.info("Downloading data from Google Sheet at #{@events_url}")
14
- csv = get_csv(@events_url)
15
-
16
- event_list = []
17
- csv.each do |row|
18
- event_name = row['Event Name']
19
- properties = hash_parser(row['Event Properties'])
20
- event_list << Evva::AnalyticsEvent.new(event_name, properties)
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
- Logger.info("Downloading data from Google Sheet at #{@people_properties_url}")
27
- csv = get_csv(@people_properties_url)
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
- people_list = []
30
- csv.each do |row|
31
- value = row['Property Name']
32
- people_list << value
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
- Logger.info("Downloading data from Google Sheet at #{@enum_classes_url}")
39
- csv = get_csv(@enum_classes_url)
40
-
41
- enum_list = []
42
- csv.each do |row|
43
- enum_name = row['Enum Name']
44
- values = row['Possible Values'].split(',')
45
- enum_list << Evva::AnalyticsEnum.new(enum_name, values)
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
- enum_list
62
+ end
63
+
64
+ def destinations
65
+ @destinations ||= events.map(&:destinations).flatten.uniq
48
66
  end
49
67
 
50
68
  private