earlgrey 0.1.6 → 0.2.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
  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