earlgrey 0.1.6 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 11cbb8397c02fad28c1a9540138d60fec164964c
4
- data.tar.gz: 56cdee3bd95121a638c3da2c68b1ed2a4959fb17
3
+ metadata.gz: 119eb6c49d0f9ec0a629f2e46b073ea0b27b7098
4
+ data.tar.gz: f28b6a153bd07b865c043667a9d327811f4eb62f
5
5
  SHA512:
6
- metadata.gz: bde9b7f311fc7355be93dd48e27dfdd7e5ec13954a6815ab30f55c56bbad8e436742f8c2490ca126daf81d40bc63c296330401e38dc788d09346064a2d0ec279
7
- data.tar.gz: ff4b8ae1225ae473f0cf4c0a6c85e9b90cb56298fd1c29bfec5ec8172c66d4fcceb20d26eb38bff42ec966e00bc06ebaa20beef1fb706e070818517c08f46d0a
6
+ metadata.gz: 322cb875b7ddce6157ff0205e7c105c98a3a00ad52e40340e5aff81473915e5e504d9ee5a31672c8f93a9149586019cf9f2b6e2b33b3a431d2943b91091084b6
7
+ data.tar.gz: 027b47b75110a4901670b6e87136575dec90600d950ba1df5209ae3e3e37aaaec53be49f4bb52070af3a73dfa4a41ce0abcc3a11e65961d7d8d77df02cde59c2
@@ -15,6 +15,6 @@
15
15
  # See the License for the specific language governing permissions and
16
16
  # limitations under the License.
17
17
 
18
- require_relative '../lib/earlgrey'
18
+ require 'earlgrey/cli'
19
19
 
20
20
  EarlGrey::CLI.start
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright 2016 Google Inc.
2
+ # Copyright 2017 Google Inc.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
5
5
  # you may not use this file except in compliance with the License.
@@ -13,13 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require 'rubygems'
17
- require 'xcodeproj'
18
- require 'colored'
19
- require 'thor'
20
-
21
- require 'fileutils'
22
-
23
- require_relative 'version'
24
- require_relative 'configure_earlgrey'
25
- require_relative 'cli'
16
+ require_relative 'earlgrey/extensions'
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require_relative 'earlgrey/earlgrey'
16
+ require 'earlgrey/configure_earlgrey'
@@ -12,6 +12,8 @@
12
12
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
+ require 'earlgrey/configure_earlgrey'
16
+ require 'thor'
15
17
 
16
18
  # rubocop:disable Metrics/LineLength
17
19
  module EarlGrey
@@ -36,8 +38,6 @@ module EarlGrey
36
38
  def install
37
39
  o = options.dup
38
40
 
39
- # CLI will never use Cocoapod's `post_install do |installer|`
40
- podfile_installer = nil
41
41
  opts = { swift: o[SWIFT], carthage: o[CARTHAGE], swift_version: o[SWIFT_VERSION] }
42
42
 
43
43
  # Use target as the default Scheme name.
@@ -46,7 +46,7 @@ module EarlGrey
46
46
  o[PROJECT] ||= Dir.glob(File.join(Dir.pwd, '*.xcodeproj')).first
47
47
  raise 'No project found' unless o[PROJECT]
48
48
 
49
- EarlGrey.configure_for_earlgrey podfile_installer, o[PROJECT], o[TARGET], o[SCHEME], opts
49
+ EarlGrey.configure_for_earlgrey o[PROJECT], o[TARGET], o[SCHEME], opts
50
50
  end
51
51
  end
52
52
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Copyright 2016 Google Inc.
3
5
  #
@@ -13,19 +15,50 @@
13
15
  # See the License for the specific language governing permissions and
14
16
  # limitations under the License.
15
17
 
16
- # global export for unqualified use in Pods file
17
- def configure_for_earlgrey(*args)
18
- EarlGrey.configure_for_earlgrey(*args)
18
+ require 'colored'
19
+ require 'fileutils'
20
+ require 'xcodeproj'
21
+
22
+ def configure_for_earlgrey(*_)
23
+ EarlGrey.puts_yellow <<-S
24
+ configure_for_earlgrey in post_install is now deprecated, you should safely remove it now.
25
+ EarlGrey pod will automatically set up your project and schemes.
26
+
27
+ for more information, please visit our installation guideline:
28
+ https://github.com/google/EarlGrey/blob/master/docs/install-and-run.md
29
+ S
19
30
  end
20
31
 
21
32
  module EarlGrey
33
+ XCScheme = Xcodeproj::XCScheme
34
+ EnvironmentVariable = XCScheme::EnvironmentVariable
35
+
36
+ XCSCHEME_EXT = '*.xcscheme'.freeze
37
+ ENVIRONMENT_KEY = 'DYLD_INSERT_LIBRARIES'.freeze
38
+ ENVIRONMENT_VALUE = '@executable_path/EarlGrey.framework/EarlGrey'.freeze
39
+
40
+ FRAMEWORK_SEARCH_PATHS = 'FRAMEWORK_SEARCH_PATHS'.freeze
41
+ HEADER_SEARCH_PATHS = 'HEADER_SEARCH_PATHS'.freeze
42
+
43
+ SWIFT_FILETYPE = 'sourcecode.swift'.freeze
44
+ UNITTEST_PRODUCTTYPE = 'com.apple.product-type.bundle.unit-test'.freeze
45
+
46
+ CARTHAGE_BUILD_IOS = '$(SRCROOT)/Carthage/Build/iOS'.freeze
47
+ CARTHAGE_HEADERS_IOS = '$(SRCROOT)/Carthage/Build/iOS/**'.freeze
48
+
49
+ EARLGREY_FRAMEWORK = 'EarlGrey.framework'.freeze
50
+ CARTHAGE_FRAMEWORK_PATH =
51
+ '${SRCROOT}/Carthage/Build/iOS/EarlGrey.framework'.freeze
52
+ POD_FRAMEWORK_PATH =
53
+ '${SRCROOT}/Pods/EarlGrey/EarlGrey/EarlGrey.framework'.freeze
54
+
22
55
  class << self
23
- attr_reader :project_name, :installer, :test_target, :test_target_name, :scheme_file,
24
- :user_project, :carthage, :swift, :swift_version
56
+ attr_reader :project_name, :installer, :test_target, :test_target_name,
57
+ :scheme_file, :user_project, :carthage, :swift, :swift_version
25
58
 
26
59
  # Returns path to Xcode file, prepending current working dir if necessary.
27
- # @param project_name [String] name of the .xcodeproj file
28
- # @param ext [String] xcode file extension
60
+ # @param [String] project_name name of the .xcodeproj file
61
+ # @param [String] ext xcode file extension
29
62
  # @return [String] path to Xcode file
30
63
  def path_for(project_name, ext)
31
64
  ext_match = File.extname(project_name) == ext
@@ -34,64 +67,59 @@ module EarlGrey
34
67
  path ? path : nil
35
68
  end
36
69
 
37
- # Returns the project's directory. If CocoaPods hasn't had it passed in, then the current
38
- # directory is chosen.
70
+ # Returns the project's directory. If CocoaPods hasn't had it passed in,
71
+ # then the current directory is chosen.
39
72
  # @return [String] directory path for the Xcode project
40
73
  def dir_path
41
74
  installer ? installer.config.installation_root : Dir.pwd
42
75
  end
43
76
 
44
77
  # Strips each line in a string
45
- # @param string [String] the string to process
78
+ # @param [String] string the string to process
46
79
  # @return [String] the modified string
47
80
  def strip(string)
48
81
  string.split("\n").map(&:strip).join("\n")
49
82
  end
50
83
 
51
84
  # Raise error message after removing excessive spaces.
52
- # @param message [String] the message to raise
85
+ # @param [String] message the message to raise
53
86
  # @return [nil]
54
87
  def error(message)
55
88
  raise strip(message)
56
89
  end
57
90
 
58
- # Prints string as blue after stripping excess spacing
59
- # @param string [String] the string to print
91
+ # Prints string as magenta after stripping excess spacing
92
+ # @param [String] string the string to print
60
93
  # @return [nil]
61
- def puts_blue(string)
62
- puts strip(string).blue
94
+ def puts_magenta(string)
95
+ puts strip(string).magenta
63
96
  end
64
97
 
65
98
  # Prints string as yellow after stripping excess spacing
66
- # @param string [String] the string to print
99
+ # @param [String] string the string to print
67
100
  # @return [nil]
68
101
  def puts_yellow(string)
69
102
  puts strip(string).yellow
70
103
  end
71
104
 
72
- def set_defaults(installer, project_name, test_target_name, scheme_file, opts = {})
105
+ def set_defaults(project_name, test_target_name, scheme_file, opts = {})
73
106
  @swift = opts.fetch(:swift, false)
74
107
  @carthage = opts.fetch(:carthage, false)
75
108
  @swift_version = opts.fetch(:swift_version, '3.0')
76
- @installer = installer
77
109
 
78
- puts_blue "Checking and Updating #{project_name} for EarlGrey."
79
- pods_project = installer ? installer.pods_project : true
110
+ puts_magenta "Checking and Updating #{project_name} for EarlGrey."
80
111
  project_file = path_for project_name, '.xcodeproj'
81
112
 
82
113
  raise 'No test target provided' unless test_target_name
83
114
 
84
- if pods_project.nil? || project_file.nil?
115
+ if project_file.nil?
85
116
  error <<-E
86
- The target's xcodeproj file could not be found.
87
- Please check if the correct PROJECT_NAME is being passed in the Podfile.
117
+ The target's xcodeproj file could not be found. Please check if the
118
+ correct PROJECT_NAME is being passed in the Podfile.
88
119
  Current PROJECT_NAME is: #{project_name}
89
120
  E
90
121
  end
91
122
 
92
- # must reset state on every configure
93
- @add_earlgrey_product = nil
94
-
95
123
  @project_name = project_name
96
124
  @test_target_name = test_target_name
97
125
  @scheme_file = File.basename(scheme_file, '.*') + '.xcscheme'
@@ -108,243 +136,244 @@ module EarlGrey
108
136
 
109
137
  # Main entry point. Configures An Xcode project for use with EarlGrey.
110
138
  #
111
- # @param installer [Installer] Cococapods installer object or nil.
112
- # @param project_name [String] the xcodeproj file name
113
- # @param test_target_name [String] the test target name contained in xcodeproj
114
- # @param scheme_file [String] the scheme file name. defaults to project name when nil.
139
+ # @param [String] project_name
140
+ # the xcodeproj file name
141
+ # @param [String] test_target_name
142
+ # the test target name contained in xcodeproj
143
+ # @param [String] scheme_file
144
+ # the scheme file name. defaults to project name when nil.
115
145
  # @return [nil]
116
- def configure_for_earlgrey(installer, project_name, test_target_name, scheme_file, opts = {})
117
- set_defaults(installer, project_name, test_target_name, scheme_file, opts)
146
+ def configure_for_earlgrey(project_name, test_target_name,
147
+ scheme_file, opts = {})
148
+ set_defaults(project_name, test_target_name, scheme_file, opts)
118
149
 
119
- # Add a Test Action to the User Project Scheme.
120
- scheme = modify_scheme_for_actions
150
+ # Add DYLD_INSERT_LIBRARIES to the schemes
151
+ modify_scheme_for_actions(user_project, [test_target]).each do |_, scheme|
152
+ scheme.save!
153
+ end
121
154
 
122
- # Add a Copy Files Build Phase for EarlGrey.framework to embed it into the app under test.
123
- add_earlgrey_copy_files_script
155
+ # Add a Copy Files Build Phase for EarlGrey.framework to embed it into
156
+ # the app under test.
157
+ framework_ref = add_earlgrey_product user_project, carthage
158
+ add_earlgrey_framework test_target, framework_ref
159
+ add_earlgrey_copy_files_script test_target, framework_ref
124
160
 
125
161
  # Add header/framework search paths for carthage
126
- add_carthage_search_paths
162
+ add_carthage_search_paths test_target if carthage
127
163
 
128
164
  # Adds EarlGrey.swift
129
- copy_swift_files
130
-
131
- save_earlgrey_scheme_changes(scheme) unless scheme.nil?
165
+ copy_swift_files(user_project, test_target, swift_version) if swift
132
166
 
133
- puts_blue <<-S
167
+ user_project.save
168
+ puts_magenta <<-S
134
169
  EarlGrey setup complete.
135
170
  You can use the Test Target: #{test_target_name} for EarlGrey testing.
136
171
  S
137
172
  end
138
173
 
139
- # Scheme changes to ensure that EarlGrey is correctly loaded before main() is called.
140
- def modify_scheme_for_actions
141
- scheme_filename = scheme_file
142
- # If you do not pass on a scheme name, we set it to the project name itself.
143
- scheme_filename = project_name if scheme_filename.to_s == ''
144
-
145
- xcdata_dir = Xcodeproj::XCScheme.user_data_dir(user_project.path)
146
- unless File.exist?(File.join(xcdata_dir, scheme_filename).to_s)
147
- xcdata_dir = Xcodeproj::XCScheme.shared_data_dir(user_project.path)
174
+ # Returns the schemes that contain the given targets
175
+ #
176
+ # @param [Xcodeproj::Project] project
177
+ # @param [Array<Xcodeproj::PBXNativeTarget>] targets
178
+ # @return [Array<Xcodeproj::XCScheme>]
179
+ def schemes_for_native_targets(project, targets)
180
+ schemes = Dir[File.join(XCScheme.shared_data_dir(project.path), XCSCHEME_EXT)] +
181
+ Dir[File.join(XCScheme.user_data_dir(project.path), XCSCHEME_EXT)]
182
+
183
+ schemes = schemes.map { |scheme| [scheme, Xcodeproj::XCScheme.new(scheme)] }
184
+
185
+ targets_names = targets.map(&:name)
186
+ schemes.select do |scheme|
187
+ scheme[1].test_action.testables.any? do |testable|
188
+ testable.buildable_references.any? do |buildable|
189
+ targets_names.include? buildable.target_name
190
+ end
191
+ end
148
192
  end
193
+ end
149
194
 
150
- unless File.exist?(File.join(xcdata_dir, scheme_filename).to_s)
151
- error <<-E
152
- The required scheme "#{scheme_filename}" could not be found.
153
- Please ensure that the required scheme file exists within your project directory.
154
- E
195
+ # Add DYLD_INSERT_LIBRARIES to the launching environments for the test
196
+ # schemes to ensure that EarlGrey is correctly loaded before main() is
197
+ # called.
198
+ #
199
+ # @param [Xcodeproj::Project] project
200
+ # @param [Array<Xcodeproj::PBXNativeTarget>] targets
201
+ # @return [Array<String, Xcodeproj::XCScheme>]
202
+ def modify_scheme_for_actions(project, targets)
203
+ schemes = schemes_for_native_targets(project, targets).uniq do |name, _|
204
+ name
155
205
  end
156
- scheme = Xcodeproj::XCScheme.new File.join(xcdata_dir, scheme_filename)
157
- test_action_key = 'DYLD_INSERT_LIBRARIES'
158
- test_action_value = '@executable_path/EarlGrey.framework/EarlGrey'
159
- unless scheme.test_action.xml_element.to_s.include? test_action_value
160
- scheme = add_environment_variables_to_test_action_scheme(scheme_filename,
161
- scheme,
162
- test_action_key,
163
- test_action_value)
206
+ schemes.each do |name, scheme|
207
+ add_environment_variables_to_test_scheme(name, scheme)
164
208
  end
165
-
166
- scheme
167
209
  end
168
210
 
169
211
  # Load the EarlGrey framework when the app binary is loaded by
170
212
  # the dynamic loader, before the main() method is called.
171
- def add_environment_variables_to_test_action_scheme(scheme_filename,
172
- scheme,
173
- test_action_key,
174
- test_action_value)
213
+ #
214
+ # @param [String] name
215
+ # @param [Xcodeproj::XCScheme] scheme
216
+ def add_environment_variables_to_test_scheme(name, scheme)
217
+ name = File.basename(name, '.xcscheme')
175
218
  test_action = scheme.test_action
176
- if (scheme.test_action.xml_element.to_s.include? test_action_key) ||
177
- (scheme.launch_action.xml_element.to_s.include? test_action_key)
178
- puts_yellow <<-S
179
- //////////////////// EARLGREY SCHEME ISSUE ////////////////////
180
- EarlGrey failed to modify the Test Action part of the scheme: #{scheme_filename}
181
- for one of following reasons:
182
-
183
- 1) DYLD_INSERT_LIBRARIES is already defined under Environment Variables of
184
- the Test Action.
185
- 2) Run Action's environment variables are used for Test Action.
186
-
187
- To ensure correct functioning of EarlGrey, please manually add the
188
- following under Test Action's Environment Variables of the scheme: #{scheme_filename}
189
- Environment Variables or EarlGrey's location will not be found.
190
- Name: DYLD_INSERT_LIBRARIES
191
- Value: @executable_path/EarlGrey.framework/EarlGrey
192
- ///////////////////////////////////////////////////////////////
219
+ test_variables = test_action.environment_variables
220
+
221
+ # If any environment variables or arguments were being used in the test
222
+ # action by being copied from the launch (run) action then copy them over
223
+ # to the test action along with the EarlGrey environment variable.
224
+ if test_action.should_use_launch_scheme_args_env?
225
+ scheme.launch_action.environment_variables.all_variables.each do |var|
226
+ test_variables.assign_variable var
227
+ end
228
+ end
229
+
230
+ env_variable = test_variables[ENVIRONMENT_KEY] ||
231
+ EnvironmentVariable.new(key: ENVIRONMENT_KEY, value: '')
232
+ if env_variable.value.include? ENVIRONMENT_VALUE
233
+ puts_magenta <<-S
234
+ DYLD_INSERT_LIBRARIES is already set up for #{name}, ignored.
193
235
  S
194
- return
236
+ return scheme
195
237
  end
196
- puts strip(<<-S)
238
+ puts_magenta <<-S
197
239
  Adding EarlGrey Framework Location as an Environment Variable
198
- in the App Project's Test Target's Scheme Test Action.
240
+ in the App Project's Test Target's Scheme Test Action #{name}.
199
241
  S
200
242
 
201
- # Check if the test action uses the run action's environment variables and arguments.
202
- launch_action_env_args_present = false
203
- if (scheme.test_action.xml_element.to_s.include? 'shouldUseLaunchSchemeArgsEnv') &&
204
- ((scheme.launch_action.xml_element.to_s.include? '<EnvironmentVariables>') ||
205
- (scheme.launch_action.xml_element.to_s.include? '<CommandLineArguments>'))
206
- launch_action_env_args_present = true
207
- end
208
-
209
- test_action_is_enabled = 'YES'
210
243
  test_action.should_use_launch_scheme_args_env = false
244
+ env_variable.value += env_variable.value.empty? ? '' : ':'
245
+ env_variable.value += ENVIRONMENT_VALUE
246
+ env_variable.enabled = true
247
+ test_variables.assign_variable env_variable
248
+ test_action.environment_variables = test_variables
211
249
 
212
- # If no environment variables are set, then create the element itself.
213
- unless scheme.test_action.xml_element.to_s.include? '<EnvironmentVariables>'
214
- scheme.test_action.xml_element.add_element('EnvironmentVariables')
215
- end
216
-
217
- # If Launch Action Arguments are present and none are present in the test
218
- # action, then please add them in.
219
- if (scheme.launch_action.xml_element.to_s.include? '<CommandLineArguments>') &&
220
- !(scheme.test_action.xml_element.to_s.include? '<CommandLineArguments>')
221
- scheme.test_action.xml_element.add_element('CommandLineArguments')
222
- end
223
-
224
- # Create a new environment variable and add it to the Environment Variables.
225
- test_action_env_vars = scheme.test_action.xml_element.elements['EnvironmentVariables']
226
- test_action_args = scheme.test_action.xml_element.elements['CommandLineArguments']
227
-
228
- earl_grey_environment_variable = REXML::Element.new 'EnvironmentVariable'
229
- earl_grey_environment_variable.attributes['key'] = test_action_key
230
- earl_grey_environment_variable.attributes['value'] = test_action_value
231
- earl_grey_environment_variable.attributes['isEnabled'] = test_action_is_enabled
232
- test_action_env_vars.add_element(earl_grey_environment_variable)
233
-
234
- # If any environment variables or arguments were being used in the test action by
235
- # being copied from the launch (run) action then copy them over to the test action
236
- # along with the EarlGrey environment variable.
237
- if launch_action_env_args_present
238
- launch_action_env_vars = scheme.launch_action.xml_element.elements['EnvironmentVariables']
239
- launch_action_args = scheme.launch_action.xml_element.elements['CommandLineArguments']
240
-
241
- # Add in the Environment Variables
242
- unless launch_action_env_vars.nil?
243
- launch_action_env_vars.elements.each('EnvironmentVariable') do |launch_action_env_var|
244
- environment_variable = REXML::Element.new 'EnvironmentVariable'
245
- launch_attributes = launch_action_env_var.attributes
246
- environment_variable.attributes['key'] = launch_attributes['key']
247
- environment_variable.attributes['value'] = launch_attributes['value']
248
- environment_variable.attributes['isEnabled'] = launch_attributes['isEnabled']
249
- test_action_env_vars.add_element(environment_variable)
250
- end
251
- end
252
-
253
- # Add in the Arguments
254
- unless launch_action_args.nil?
255
- launch_action_args.elements.each('CommandLineArgument') do |launch_action_arg|
256
- argument = REXML::Element.new 'CommandLineArgument'
257
- argument.attributes['argument'] = launch_action_arg.attributes['argument']
258
- argument.attributes['isEnabled'] = launch_action_arg.attributes['isEnabled']
259
- test_action_args.add_element(argument)
260
- end
261
- end
262
-
263
- end
264
- scheme.test_action = test_action
265
- scheme
250
+ scheme.save!
266
251
  end
267
252
 
268
253
  # Adds EarlGrey.framework to products group. Returns file ref.
269
- def add_earlgrey_product
270
- return @add_earlgrey_product if @add_earlgrey_product
254
+ #
255
+ # @param [Xcodeproj::Project] project
256
+ # the xcodeproject that the app is in, and EarlGrey.framework will
257
+ # be added to.
258
+ # @param [Boolean] carthage
259
+ # if the project is carthage
260
+ def add_earlgrey_product(project, carthage)
271
261
  framework_path = if carthage
272
- '${SRCROOT}/Carthage/Build/iOS/EarlGrey.framework'
262
+ CARTHAGE_FRAMEWORK_PATH
273
263
  else
274
- '${SRCROOT}/Pods/EarlGrey/EarlGrey/EarlGrey.framework'
264
+ POD_FRAMEWORK_PATH
275
265
  end
276
266
 
277
- framework_ref = user_project.products_group.files.find { |f| f.path == framework_path }
278
- return @add_earlgrey_product = framework_ref if framework_ref
279
-
280
- framework_ref = user_project.products_group.new_file(framework_path)
281
- framework_ref.source_tree = 'SRCROOT'
282
-
283
- @add_earlgrey_product = framework_ref
267
+ framework_ref = project.products_group.files.find do |f|
268
+ # TODO: should have some md5 check on the actual binary
269
+ f.path == framework_path
270
+ end
271
+ unless framework_ref
272
+ framework_ref = project.products_group.new_file(framework_path)
273
+ framework_ref.source_tree = 'SRCROOT'
274
+ end
275
+ framework_ref
284
276
  end
285
277
 
286
278
  # Generates a copy files build phase to embed the EarlGrey framework into
287
279
  # the app under test.
288
- def add_earlgrey_copy_files_script
280
+ #
281
+ # @param [PBXNativeTarget] target
282
+ # the native target to add a copy script that copies the earlgrey
283
+ # framework into its host app
284
+ # @param [PBXFileReference] framework_ref
285
+ # the framework reference pointing to the EarlGrey.framework
286
+ def add_earlgrey_copy_files_script(target, framework_ref)
289
287
  earlgrey_copy_files_phase_name = 'EarlGrey Copy Files'
290
- earlgrey_copy_files_exists = false
291
- test_target.copy_files_build_phases.each do |copy_files_phase|
292
- if copy_files_phase.name == earlgrey_copy_files_phase_name
293
- earlgrey_copy_files_exists = true
294
- end
288
+ return true if target.copy_files_build_phases.any? do |copy_files_phase|
289
+ copy_files_phase.name == earlgrey_copy_files_phase_name
295
290
  end
296
291
 
297
- unless earlgrey_copy_files_exists
298
- name = earlgrey_copy_files_phase_name
299
- new_copy_files_phase = test_target.new_copy_files_build_phase(name)
300
- new_copy_files_phase.dst_path = '$(TEST_HOST)/../'
301
- new_copy_files_phase.dst_subfolder_spec = '0'
292
+ return false unless target.product_type.eql? UNITTEST_PRODUCTTYPE
293
+ new_copy_files_phase = target.new_copy_files_build_phase(earlgrey_copy_files_phase_name)
294
+ new_copy_files_phase.dst_path = '$(TEST_HOST)/../'
295
+ new_copy_files_phase.dst_subfolder_spec = '0'
302
296
 
303
- file_ref = add_earlgrey_product
304
- build_file = new_copy_files_phase.add_file_reference(file_ref, true)
305
- build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy'] }
306
- user_project.save
307
- end
297
+ build_file = new_copy_files_phase.add_file_reference framework_ref, true
298
+ build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy'] }
299
+ build_file
308
300
  end
309
301
 
310
- FRAMEWORK_SEARCH_PATHS = 'FRAMEWORK_SEARCH_PATHS'.freeze
311
- HEADER_SEARCH_PATHS = 'HEADER_SEARCH_PATHS'.freeze
312
-
313
- # Updates test target's build configuration framework and header search paths for carthage.
314
- # No-op if carthage isn't true.
315
- def add_carthage_search_paths
316
- return unless carthage
317
- carthage_build_ios = '$(SRCROOT)/Carthage/Build/iOS'
318
- carthage_headers_ios = '$(SRCROOT)/Carthage/Build/iOS/**'
319
-
320
- test_target.build_configurations.each do |config|
302
+ # Updates test target's build configuration framework and header search
303
+ # paths for carthage. Generates a copy files build phase to embed the
304
+ # EarlGrey framework into the app under test.
305
+ #
306
+ # @param [PBXNativeTarget] target
307
+ # @return [PBXNativeTarget] target
308
+ def add_carthage_search_paths(target)
309
+ target.build_configurations.each do |config|
321
310
  settings = config.build_settings
322
311
  settings[FRAMEWORK_SEARCH_PATHS] = Array(settings[FRAMEWORK_SEARCH_PATHS])
323
- unless settings[FRAMEWORK_SEARCH_PATHS].include?(carthage_build_ios)
324
- settings[FRAMEWORK_SEARCH_PATHS] << carthage_build_ios
312
+ unless settings[FRAMEWORK_SEARCH_PATHS].include?(CARTHAGE_BUILD_IOS)
313
+ settings[FRAMEWORK_SEARCH_PATHS] << CARTHAGE_BUILD_IOS
325
314
  end
326
315
 
327
316
  settings[HEADER_SEARCH_PATHS] = Array(settings[HEADER_SEARCH_PATHS])
328
- unless settings[HEADER_SEARCH_PATHS].include?(carthage_headers_ios)
329
- settings[HEADER_SEARCH_PATHS] << carthage_headers_ios
317
+ unless settings[HEADER_SEARCH_PATHS].include?(CARTHAGE_HEADERS_IOS)
318
+ settings[HEADER_SEARCH_PATHS] << CARTHAGE_HEADERS_IOS
330
319
  end
331
320
  end
321
+ target
322
+ end
332
323
 
333
- user_project.save
324
+ # Add Carthage copy phase
325
+ #
326
+ # @param [PBXNativeTarget] target
327
+ def add_carthage_copy_phase(target)
328
+ shell_script_name = 'Carthage copy-frameworks Run Script'
329
+ target_names = target.shell_script_build_phases.map(&:name)
330
+ unless target_names.include?(shell_script_name)
331
+ shell_script = target.new_shell_script_build_phase shell_script_name
332
+ shell_script.shell_path = '/bin/bash'
333
+ shell_script.shell_script = '/usr/local/bin/carthage copy-frameworks'
334
+ shell_script.input_paths = [CARTHAGE_FRAMEWORK_PATH]
335
+ end
334
336
  end
335
337
 
338
+ # Add EarlGrey.framework into the build phase "Link Binary With Libraries"
339
+ #
340
+ # @param [PBXNativeTarget] target
341
+ # @param [PBXFileReference] framework_ref
342
+ # the framework reference pointing to the EarlGrey.framework
343
+ def add_earlgrey_framework(target, framework_ref)
344
+ linked_frameworks = target.frameworks_build_phase.files.map(&:display_name)
345
+ unless linked_frameworks.include? EARLGREY_FRAMEWORK
346
+ target.frameworks_build_phase.add_file_reference framework_ref, true
347
+ end
348
+ end
349
+
350
+ # Check if the target contains a swift source file
351
+ # @param [PBXNativeTarget] target
352
+ # @return [Boolean]
353
+ # rubocop:disable Style/PredicateName
354
+ def has_swift?(target)
355
+ target.source_build_phase.files_references.any? do |ref|
356
+ SWIFT_FILETYPE == (ref.last_known_file_type || ref.explicit_file_type)
357
+ end
358
+ end
359
+ # rubocop:enable Style/PredicateName
360
+
336
361
  # Copies EarlGrey.swift and adds it to the project.
337
- # Adds EarlGrey.swift to project's test target group.
338
- # Adds EarlGrey.swift to testing target's source build phase
339
- # Adds Link Binary With Libraries phase to test target for EarlGrey.framework
340
- # Adds shell script phase that runs Carthage copy-frameworks
362
+ # No op if the target doesn't contain swift.
341
363
  #
342
- # No op if swift isn't true
343
- def copy_swift_files
344
- return unless swift
364
+ # @param [Xcodeproj::Project] project
365
+ # @param [PBXNativeTarget] target
366
+ def copy_swift_files(project, target, swift_version = nil)
367
+ return unless has_swift?(target) || !swift_version.nil?
345
368
 
369
+ project_test_targets = project.main_group.children
370
+ test_target_group = project_test_targets.find { |g| g.display_name == target.name }
371
+
372
+ raise "Test target group not found! #{test_target_group}" unless test_target_group
373
+
374
+ swift_version ||= '3.0'
346
375
  src_root = File.join(__dir__, 'files')
347
- dst_root = File.join(dir_path, test_target_name)
376
+ dst_root = test_target_group.real_path
348
377
  raise "Missing target folder #{dst_root}" unless File.exist? dst_root
349
378
 
350
379
  src_swift_name = 'EarlGrey.swift'
@@ -355,10 +384,6 @@ module EarlGrey
355
384
 
356
385
  FileUtils.copy src_swift, dst_swift
357
386
 
358
- project_test_targets = user_project.main_group.children
359
- test_target_group = project_test_targets.find { |g| g.display_name == test_target_name }
360
- raise "Test target group not found! #{test_target_group}" unless test_target_group
361
-
362
387
  # Add files to testing target group otherwise Xcode can't read them.
363
388
  new_files = [src_swift_name]
364
389
  existing_files = test_target_group.children.map(&:display_name)
@@ -369,30 +394,15 @@ module EarlGrey
369
394
  end
370
395
 
371
396
  # Add EarlGrey.swift to sources build phase
372
- existing_sources = test_target.source_build_phase.files.map(&:display_name)
397
+ existing_sources = target.source_build_phase.files.map(&:display_name)
373
398
  unless existing_sources.include? src_swift_name
374
399
  target_files = test_target_group.files
375
400
  earlgrey_swift_file_ref = target_files.find { |f| f.display_name == src_swift_name }
376
- raise 'EarlGrey.swift not found in testing target' unless earlgrey_swift_file_ref
377
- test_target.source_build_phase.add_file_reference(earlgrey_swift_file_ref, true)
378
- end
379
-
380
- # Link Binary With Libraries - frameworks_build_phase - Add EarlGrey.framework
381
- earlgrey_framework = 'EarlGrey.framework'
382
- existing_frameworks = test_target.frameworks_build_phase.files.map(&:display_name)
383
- unless existing_frameworks.include? earlgrey_framework
384
- framework_ref = add_earlgrey_product
385
- # must pass 'true' to avoid duplicates
386
- test_target.frameworks_build_phase.add_file_reference(framework_ref, true)
401
+ unless earlgrey_swift_file_ref
402
+ raise 'EarlGrey.swift not found in testing target'
403
+ end
404
+ target.source_build_phase.add_file_reference earlgrey_swift_file_ref, true
387
405
  end
388
-
389
- user_project.save
390
- end
391
-
392
- # Save the scheme changes. This is done here to prevent any irreversible changes in case
393
- # of an exception being thrown.
394
- def save_earlgrey_scheme_changes(scheme)
395
- scheme.save!
396
406
  end
397
407
  end
398
408
  end
@@ -0,0 +1,17 @@
1
+ #
2
+ # Copyright 2017 Google Inc.
3
+ #
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
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
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
+
16
+ require_relative 'extensions/aggregate_target_extensions'
17
+ require_relative 'extensions/analyzer_extensions'
@@ -0,0 +1,36 @@
1
+ #
2
+ # Copyright 2017 Google Inc.
3
+ #
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
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
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
+
16
+ require_relative '../configure_earlgrey'
17
+
18
+ module EarlGrey
19
+ module AggregateTargetExtensions
20
+ # rubocop:disable Style/PredicateName
21
+ def is_earlgrey?
22
+ @is_earlgrey ||= specs.any? { |spec| 'EarlGrey'.eql? spec.name }
23
+ end
24
+ # rubocop:enable Style/PredicateName
25
+
26
+ def schemes_for_native_targets
27
+ EarlGrey.schemes_for_native_targets user_project, user_targets
28
+ end
29
+ end
30
+ end
31
+
32
+ module Pod
33
+ class AggregateTarget
34
+ include EarlGrey::AggregateTargetExtensions
35
+ end
36
+ end
@@ -0,0 +1,51 @@
1
+ #
2
+ # Copyright 2017 Google Inc.
3
+ #
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
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
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
+
16
+ require_relative '../configure_earlgrey'
17
+ require_relative 'aggregate_target_extensions'
18
+
19
+ module EarlGrey
20
+ module AnalyzerExtension
21
+ def analyze(*_)
22
+ result = super
23
+ eg_targets = result.targets.select(&:is_earlgrey?).each do |target|
24
+ target.user_targets.each do |native_target|
25
+ EarlGrey.copy_swift_files(target.user_project, native_target,
26
+ target.target_definition.swift_version)
27
+
28
+ framework_ref = EarlGrey.add_earlgrey_product target.user_project, false
29
+ EarlGrey.add_earlgrey_copy_files_script native_target, framework_ref
30
+ EarlGrey.add_earlgrey_framework native_target, framework_ref
31
+ end
32
+ end
33
+
34
+ schemes = eg_targets.map(&:schemes_for_native_targets).flatten(1).uniq do |name, _|
35
+ name
36
+ end
37
+ schemes.each do |name, scheme|
38
+ EarlGrey.add_environment_variables_to_test_scheme(name, scheme)
39
+ end
40
+ result
41
+ end
42
+ end
43
+ end
44
+
45
+ module Pod
46
+ class Installer
47
+ class Analyzer
48
+ prepend EarlGrey::AnalyzerExtension
49
+ end
50
+ end
51
+ end
@@ -14,5 +14,5 @@
14
14
  # limitations under the License.
15
15
 
16
16
  module EarlGrey
17
- VERSION = '0.1.6'.freeze unless defined? ::EarlGrey::VERSION
17
+ VERSION = '0.2.0'.freeze unless defined? ::EarlGrey::VERSION
18
18
  end
metadata CHANGED
@@ -1,16 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: earlgrey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - khandpur
8
8
  - tirodkar
9
9
  - bootstraponline
10
+ - wuhao5
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
- date: 2017-03-18 00:00:00.000000000 Z
14
+ date: 2017-03-30 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: colored
@@ -82,20 +83,6 @@ dependencies:
82
83
  - - ">="
83
84
  - !ruby/object:Gem::Version
84
85
  version: 0.39.0
85
- - !ruby/object:Gem::Dependency
86
- name: coveralls
87
- requirement: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - "~>"
90
- - !ruby/object:Gem::Version
91
- version: 0.8.13
92
- type: :development
93
- prerelease: false
94
- version_requirements: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - "~>"
97
- - !ruby/object:Gem::Version
98
- version: 0.8.13
99
86
  - !ruby/object:Gem::Dependency
100
87
  name: pry
101
88
  requirement: !ruby/object:Gem::Requirement
@@ -132,10 +119,13 @@ extensions: []
132
119
  extra_rdoc_files: []
133
120
  files:
134
121
  - bin/earlgrey
122
+ - lib/cocoapods_plugin.rb
135
123
  - lib/earlgrey.rb
136
124
  - lib/earlgrey/cli.rb
137
125
  - lib/earlgrey/configure_earlgrey.rb
138
- - lib/earlgrey/earlgrey.rb
126
+ - lib/earlgrey/extensions.rb
127
+ - lib/earlgrey/extensions/aggregate_target_extensions.rb
128
+ - lib/earlgrey/extensions/analyzer_extensions.rb
139
129
  - lib/earlgrey/files/Swift-2.3/EarlGrey.swift
140
130
  - lib/earlgrey/files/Swift-3.0/EarlGrey.swift
141
131
  - lib/earlgrey/version.rb
@@ -159,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
149
  version: '0'
160
150
  requirements: []
161
151
  rubyforge_project:
162
- rubygems_version: 2.6.8
152
+ rubygems_version: 2.6.11
163
153
  signing_key:
164
154
  specification_version: 4
165
155
  summary: EarlGrey installer gem