run_loop_tcc 2.1.3
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 +7 -0
- data/LICENSE +21 -0
- data/bin/run-loop +19 -0
- data/lib/run_loop/abstract.rb +18 -0
- data/lib/run_loop/app.rb +372 -0
- data/lib/run_loop/cache/cache.rb +68 -0
- data/lib/run_loop/cli/cli.rb +48 -0
- data/lib/run_loop/cli/codesign.rb +24 -0
- data/lib/run_loop/cli/errors.rb +11 -0
- data/lib/run_loop/cli/instruments.rb +160 -0
- data/lib/run_loop/cli/locale.rb +31 -0
- data/lib/run_loop/cli/simctl.rb +257 -0
- data/lib/run_loop/cli/tcc.rb +139 -0
- data/lib/run_loop/codesign.rb +76 -0
- data/lib/run_loop/core.rb +902 -0
- data/lib/run_loop/core_simulator.rb +960 -0
- data/lib/run_loop/detect_aut/detect.rb +185 -0
- data/lib/run_loop/detect_aut/errors.rb +126 -0
- data/lib/run_loop/detect_aut/xamarin_studio.rb +46 -0
- data/lib/run_loop/detect_aut/xcode.rb +157 -0
- data/lib/run_loop/device.rb +722 -0
- data/lib/run_loop/device_agent/app/CBX-Runner.app.zip +0 -0
- data/lib/run_loop/device_agent/bin/xctestctl +0 -0
- data/lib/run_loop/device_agent/cbxrunner.rb +156 -0
- data/lib/run_loop/device_agent/frameworks/Frameworks.zip +0 -0
- data/lib/run_loop/device_agent/frameworks.rb +65 -0
- data/lib/run_loop/device_agent/ipa/CBX-Runner.app.zip +0 -0
- data/lib/run_loop/device_agent/launcher.rb +51 -0
- data/lib/run_loop/device_agent/xcodebuild.rb +91 -0
- data/lib/run_loop/device_agent/xctestctl.rb +109 -0
- data/lib/run_loop/directory.rb +179 -0
- data/lib/run_loop/dnssd.rb +148 -0
- data/lib/run_loop/dot_dir.rb +87 -0
- data/lib/run_loop/dylib_injector.rb +145 -0
- data/lib/run_loop/encoding.rb +56 -0
- data/lib/run_loop/environment.rb +361 -0
- data/lib/run_loop/fifo.rb +40 -0
- data/lib/run_loop/host_cache.rb +128 -0
- data/lib/run_loop/http/error.rb +15 -0
- data/lib/run_loop/http/request.rb +44 -0
- data/lib/run_loop/http/retriable_client.rb +166 -0
- data/lib/run_loop/http/server.rb +17 -0
- data/lib/run_loop/instruments.rb +436 -0
- data/lib/run_loop/ipa.rb +142 -0
- data/lib/run_loop/l10n.rb +93 -0
- data/lib/run_loop/language.rb +63 -0
- data/lib/run_loop/lipo.rb +132 -0
- data/lib/run_loop/lldb.rb +52 -0
- data/lib/run_loop/locale.rb +101 -0
- data/lib/run_loop/logging.rb +111 -0
- data/lib/run_loop/otool.rb +76 -0
- data/lib/run_loop/patches/awesome_print.rb +17 -0
- data/lib/run_loop/physical_device/life_cycle.rb +268 -0
- data/lib/run_loop/plist_buddy.rb +189 -0
- data/lib/run_loop/process_terminator.rb +128 -0
- data/lib/run_loop/process_waiter.rb +117 -0
- data/lib/run_loop/regex.rb +19 -0
- data/lib/run_loop/shell.rb +103 -0
- data/lib/run_loop/sim_control.rb +1264 -0
- data/lib/run_loop/simctl.rb +275 -0
- data/lib/run_loop/sqlite.rb +61 -0
- data/lib/run_loop/strings.rb +88 -0
- data/lib/run_loop/tcc/TCC.db +0 -0
- data/lib/run_loop/tcc/tcc.rb +240 -0
- data/lib/run_loop/template.rb +61 -0
- data/lib/run_loop/version.rb +182 -0
- data/lib/run_loop/xcode.rb +318 -0
- data/lib/run_loop/xcrun.rb +107 -0
- data/lib/run_loop/xcuitest.rb +550 -0
- data/lib/run_loop.rb +230 -0
- data/plists/simctl/com.apple.UIAutomation.plist +0 -0
- data/plists/simctl/com.apple.UIAutomationPlugIn.plist +0 -0
- data/scripts/calabash_script_uia.js +28184 -0
- data/scripts/lib/json2.min.js +26 -0
- data/scripts/lib/log.js +26 -0
- data/scripts/lib/on_alert.js +224 -0
- data/scripts/read-cmd.sh +2 -0
- data/scripts/run_dismiss_location.js +89 -0
- data/scripts/run_loop_basic.js +34 -0
- data/scripts/run_loop_fast_uia.js +188 -0
- data/scripts/run_loop_host.js +117 -0
- data/scripts/run_loop_shared_element.js +125 -0
- data/scripts/timeout3 +23 -0
- data/scripts/udidetect +0 -0
- data/vendor-licenses/FBSimulatorControl.LICENSE +30 -0
- data/vendor-licenses/xctestctl.LICENSE +32 -0
- metadata +443 -0
@@ -0,0 +1,185 @@
|
|
1
|
+
module RunLoop
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
module DetectAUT
|
5
|
+
|
6
|
+
# @!visibility private
|
7
|
+
def self.detect_app_under_test(options)
|
8
|
+
app = self.detect_app(options)
|
9
|
+
if app.is_a?(RunLoop::App) || app.is_a?(RunLoop::Ipa)
|
10
|
+
{
|
11
|
+
:app => app,
|
12
|
+
:bundle_id => app.bundle_identifier,
|
13
|
+
:is_ipa => app.is_a?(RunLoop::Ipa)
|
14
|
+
}
|
15
|
+
else
|
16
|
+
{
|
17
|
+
:app => nil,
|
18
|
+
:bundle_id => app,
|
19
|
+
:is_ipa => false
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @!visibility private
|
25
|
+
class Detect
|
26
|
+
include RunLoop::DetectAUT::Errors
|
27
|
+
include RunLoop::DetectAUT::XamarinStudio
|
28
|
+
include RunLoop::DetectAUT::Xcode
|
29
|
+
|
30
|
+
# @!visibility private
|
31
|
+
DEFAULTS = {
|
32
|
+
:search_depth => 10
|
33
|
+
}
|
34
|
+
|
35
|
+
# @!visibility private
|
36
|
+
def app_for_simulator
|
37
|
+
path = RunLoop::Environment.path_to_app_bundle
|
38
|
+
return RunLoop::App.new(path) if path
|
39
|
+
|
40
|
+
if xcode_project?
|
41
|
+
apps, search_dirs = detect_xcode_apps
|
42
|
+
elsif xamarin_project?
|
43
|
+
search_dirs = [solution_directory]
|
44
|
+
apps = candidate_apps(search_dirs.first)
|
45
|
+
else
|
46
|
+
search_dirs = [Dir.pwd]
|
47
|
+
apps = candidate_apps(search_dirs.first)
|
48
|
+
end
|
49
|
+
|
50
|
+
if apps.empty?
|
51
|
+
raise_no_simulator_app_found(search_dirs, DEFAULTS[:search_depth])
|
52
|
+
end
|
53
|
+
|
54
|
+
app = select_most_recent_app(apps)
|
55
|
+
|
56
|
+
RunLoop.log_info2("Detected app at path:")
|
57
|
+
RunLoop.log_info2("#{app.path}")
|
58
|
+
time_str = mtime(app).strftime("%a %d %b %Y %H:%M:%S %Z")
|
59
|
+
RunLoop.log_info2("Modification time of app: #{time_str}")
|
60
|
+
RunLoop.log_info2("If this is incorrect, set the APP variable and/or rebuild your app")
|
61
|
+
RunLoop.log_info2("It is your responsibility to ensure you are testing the right app.")
|
62
|
+
|
63
|
+
app
|
64
|
+
end
|
65
|
+
|
66
|
+
# @!visibility private
|
67
|
+
# @param [Array<RunLoop::Detect>] apps
|
68
|
+
def select_most_recent_app(apps)
|
69
|
+
apps.max do |a, b|
|
70
|
+
mtime(a).to_i <=> mtime(b).to_i
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# @!visibility private
|
75
|
+
# @param [String] bundle_path
|
76
|
+
def app_with_bundle(bundle_path)
|
77
|
+
RunLoop::App.new(bundle_path)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @!visibility private
|
81
|
+
# @param [String] base_dir where to start the recursive search
|
82
|
+
def candidate_apps(base_dir)
|
83
|
+
candidates = []
|
84
|
+
|
85
|
+
globs = globs_for_app_search(base_dir)
|
86
|
+
Dir.glob(globs).each do |bundle_path|
|
87
|
+
# Gems, like run-loop, can contain *.app if the user is building
|
88
|
+
# from :git =>, :github =>, or :path => sources.
|
89
|
+
next if bundle_path[/vendor\/cache/, 0] != nil
|
90
|
+
app = app_or_nil(bundle_path)
|
91
|
+
candidates << app if app
|
92
|
+
end
|
93
|
+
candidates
|
94
|
+
end
|
95
|
+
|
96
|
+
# @!visibility private
|
97
|
+
# @param [String] bundle_path path to .app
|
98
|
+
def app_or_nil(bundle_path)
|
99
|
+
return nil if !RunLoop::App.valid?(bundle_path)
|
100
|
+
|
101
|
+
app = app_with_bundle(bundle_path)
|
102
|
+
if app.simulator? && app.calabash_server_version
|
103
|
+
app
|
104
|
+
else
|
105
|
+
nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# @!visibility private
|
110
|
+
# @param [RunLoop::Detect] app
|
111
|
+
def mtime(app)
|
112
|
+
path = File.join(app.path, app.executable_name)
|
113
|
+
File.mtime(path)
|
114
|
+
end
|
115
|
+
|
116
|
+
# @!visibility private
|
117
|
+
def globs_for_app_search(base_dir)
|
118
|
+
search_depth = DEFAULTS[:search_depth]
|
119
|
+
Array.new(search_depth) do |depth|
|
120
|
+
File.join(base_dir, *Array.new(depth) { |_| "*"}, "*.app")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
# @!visibility private
|
128
|
+
def self.app_from_options(options)
|
129
|
+
options[:app] || options[:bundle_id]
|
130
|
+
end
|
131
|
+
|
132
|
+
# @!visibility private
|
133
|
+
def self.app_from_environment
|
134
|
+
app_bundle_path = RunLoop::Environment.path_to_app_bundle
|
135
|
+
|
136
|
+
candidate = app_bundle_path
|
137
|
+
if app_bundle_path && !File.exist?(app_bundle_path)
|
138
|
+
candidate = File.basename(app_bundle_path)
|
139
|
+
end
|
140
|
+
|
141
|
+
candidate || RunLoop::Environment.bundle_id
|
142
|
+
end
|
143
|
+
|
144
|
+
# @!visibility private
|
145
|
+
def self.app_from_constant
|
146
|
+
(defined?(APP_BUNDLE_PATH) && APP_BUNDLE_PATH) ||
|
147
|
+
(defined?(APP) && APP)
|
148
|
+
end
|
149
|
+
|
150
|
+
# @!visibility private
|
151
|
+
def self.app_from_opts_or_env_or_constant(options)
|
152
|
+
self.app_from_options(options) ||
|
153
|
+
self.app_from_environment ||
|
154
|
+
self.app_from_constant
|
155
|
+
end
|
156
|
+
|
157
|
+
# @!visibility private
|
158
|
+
def self.detector
|
159
|
+
RunLoop::DetectAUT::Detect.new
|
160
|
+
end
|
161
|
+
|
162
|
+
# @!visibility private
|
163
|
+
def self.detect_app(options)
|
164
|
+
app = self.app_from_opts_or_env_or_constant(options)
|
165
|
+
|
166
|
+
# Options or constant defined an instance of App or Ipa
|
167
|
+
return app if app && (app.is_a?(RunLoop::App) || app.is_a?(RunLoop::Ipa))
|
168
|
+
|
169
|
+
# User provided no information, so we attempt to auto detect
|
170
|
+
if app.nil? || app == ""
|
171
|
+
return self.detector.app_for_simulator
|
172
|
+
end
|
173
|
+
|
174
|
+
extension = File.extname(app)
|
175
|
+
if extension == ".ipa" && File.exist?(app)
|
176
|
+
RunLoop::Ipa.new(app)
|
177
|
+
elsif extension == ".app" && File.exist?(app)
|
178
|
+
RunLoop::App.new(app)
|
179
|
+
else
|
180
|
+
# Probably a bundle identifier.
|
181
|
+
app
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module RunLoop
|
2
|
+
|
3
|
+
# @!visibility private
|
4
|
+
class SolutionMissingError < RuntimeError ; end
|
5
|
+
|
6
|
+
# @!visibility private
|
7
|
+
class XcodeprojMissingError < RuntimeError; end
|
8
|
+
|
9
|
+
# @!visibility private
|
10
|
+
class MultipleXcodeprojError < RuntimeError; end
|
11
|
+
|
12
|
+
# @!visibility private
|
13
|
+
class NoSimulatorAppFoundError < RuntimeError; end
|
14
|
+
|
15
|
+
# @!visibility private
|
16
|
+
module DetectAUT
|
17
|
+
|
18
|
+
# @!visibility private
|
19
|
+
module Errors
|
20
|
+
|
21
|
+
# @!visibility private
|
22
|
+
#
|
23
|
+
# Raised when XCODEPROJ is defined, but does not exist
|
24
|
+
def raise_xcodeproj_missing(xcodeproj)
|
25
|
+
raise RunLoop::XcodeprojMissingError,
|
26
|
+
%Q[The XCODEPROJ environment variable has been set to:
|
27
|
+
|
28
|
+
#{xcodeproj}
|
29
|
+
|
30
|
+
but no directory exists at that path.
|
31
|
+
|
32
|
+
You should only set XCODEPROJ variable if your Calabash project has more than
|
33
|
+
one .xcodeproj directory or your .xcodeproj directory is located above the
|
34
|
+
current directory (where you run `cucumber` from). Calabash will discover the
|
35
|
+
.xcodeproj if is below the current working directory.
|
36
|
+
|
37
|
+
# .xcodeproj is above the working directory
|
38
|
+
$ ls ../*.xcodeproj
|
39
|
+
MyApp.xcodeproj
|
40
|
+
|
41
|
+
$ XCODEPROJ=../*.xcodeproj cucumber
|
42
|
+
|
43
|
+
# There is more than one .xcodeproj
|
44
|
+
$ ls *.xcodeproj
|
45
|
+
MyiOSApp.xcodeproj
|
46
|
+
MyMacApp.xcodeproj
|
47
|
+
|
48
|
+
$ XCODEPROJ=MyiOSApp.xcodeproj
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!visibility private
|
53
|
+
#
|
54
|
+
# Raised when there are more than > 1 .xcodeproj in **/*
|
55
|
+
# Is not raised when there are 0 .xcodeproj in **/*
|
56
|
+
#
|
57
|
+
# @param [Array<String>] projects a list of paths to .xcodeproj
|
58
|
+
def raise_multiple_xcodeproj(projects)
|
59
|
+
raise RunLoop::MultipleXcodeprojError,
|
60
|
+
%Q[Found multiple .xcodeproj directories:
|
61
|
+
|
62
|
+
#{projects.join($-0)}
|
63
|
+
|
64
|
+
Which project contains the target of the application you are trying to test?
|
65
|
+
|
66
|
+
Set the XCODEPROJ variable to specify the correct .xcodeproj directory.
|
67
|
+
|
68
|
+
# Examples
|
69
|
+
$ XCODEPROJ="../MyApp.xcodeproj" cucumber
|
70
|
+
$ XCODEPROJ="iOS/MyApp.xcodeproj" cucumber
|
71
|
+
]
|
72
|
+
end
|
73
|
+
|
74
|
+
# @!visibility private
|
75
|
+
#
|
76
|
+
# Raised when SOLUTION is defined but does not exist
|
77
|
+
def raise_solution_missing(solution)
|
78
|
+
raise RunLoop::SolutionMissingError,
|
79
|
+
%Q[The SOLUTION environment variable has been set to:
|
80
|
+
|
81
|
+
#{solution}
|
82
|
+
|
83
|
+
but no solution exists at that path.
|
84
|
+
|
85
|
+
You should only set SOLUTION variable if your .sln is not located in
|
86
|
+
the current directory or in the directory just above the current
|
87
|
+
directory (where you run `cucumber` from). Calabash will discover the
|
88
|
+
.snl if it is in the current working directory or the directory just
|
89
|
+
above.
|
90
|
+
|
91
|
+
# Calabash will discover solution - don't set SOLUTION
|
92
|
+
$ ls *.sln => MyApp.sln
|
93
|
+
$ ls ../*.sln => MyApp.sln
|
94
|
+
|
95
|
+
# Calabash will _not_ discover solution
|
96
|
+
$ ls ../../*.sln => MyApp.sln
|
97
|
+
$ SOLUTION=../../MyApp.sln cucumber
|
98
|
+
|
99
|
+
$ ls project/*.sln => MyApp.sln
|
100
|
+
$ SOLUTION=project/MyApp.sln cucumber
|
101
|
+
|
102
|
+
$ ls ~/some/other/directory/*.sln => MyApp.sln
|
103
|
+
$ SOLUTION=~/some/other/directory/MyApp.sln
|
104
|
+
]
|
105
|
+
end
|
106
|
+
|
107
|
+
# @!visibility private
|
108
|
+
# Raised when no app can found by the discovery algorithm
|
109
|
+
def raise_no_simulator_app_found(search_directories, search_depth)
|
110
|
+
raise RunLoop::NoSimulatorAppFoundError,
|
111
|
+
%Q[Recursively searched these directories to depth #{search_depth}:
|
112
|
+
|
113
|
+
#{search_directories.join($-0)}
|
114
|
+
|
115
|
+
but could not find any .app for the simulator that links the Calabash iOS server.
|
116
|
+
|
117
|
+
Make sure you have built your app for a simulator target from Xcode.
|
118
|
+
|
119
|
+
If you are testing a stand-alone .app (you don't have an Xcode project), put
|
120
|
+
your .app in the same directory (or below) the directory you run `cucumber` from.
|
121
|
+
]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module RunLoop
|
2
|
+
# @!visibility private
|
3
|
+
module DetectAUT
|
4
|
+
|
5
|
+
# @!visibility private
|
6
|
+
module XamarinStudio
|
7
|
+
|
8
|
+
# @!visibility private
|
9
|
+
def xamarin_project?
|
10
|
+
solution_directory != nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# @!visibility private
|
14
|
+
def solution_directory
|
15
|
+
solution = RunLoop::Environment.solution
|
16
|
+
|
17
|
+
if solution && !File.exist?(solution)
|
18
|
+
raise_solution_missing(solution)
|
19
|
+
end
|
20
|
+
|
21
|
+
# SOLUTION defined and exists
|
22
|
+
return File.dirname(solution) if solution
|
23
|
+
|
24
|
+
solution_dir = find_solution_directory
|
25
|
+
return nil if solution_dir.nil?
|
26
|
+
|
27
|
+
solution_dir
|
28
|
+
end
|
29
|
+
|
30
|
+
# @!visibility private
|
31
|
+
def find_solution_directory
|
32
|
+
pwd = Dir.pwd
|
33
|
+
solutions = Dir.glob("#{pwd}/*.sln")
|
34
|
+
|
35
|
+
if solutions.empty?
|
36
|
+
solutions = Dir.glob("#{pwd}/../*.sln")
|
37
|
+
end
|
38
|
+
|
39
|
+
return nil if solutions.empty?
|
40
|
+
|
41
|
+
File.expand_path(File.dirname(solutions.first))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module RunLoop
|
2
|
+
# @!visibility private
|
3
|
+
module DetectAUT
|
4
|
+
# @!visibility private
|
5
|
+
module Xcode
|
6
|
+
|
7
|
+
# @!visibility private
|
8
|
+
def xcode_project?
|
9
|
+
xcodeproj != nil
|
10
|
+
end
|
11
|
+
|
12
|
+
# @!visibility private
|
13
|
+
def xcodeproj
|
14
|
+
xcodeproj = RunLoop::Environment.xcodeproj
|
15
|
+
|
16
|
+
if xcodeproj && !File.directory?(xcodeproj)
|
17
|
+
raise_xcodeproj_missing(xcodeproj)
|
18
|
+
end
|
19
|
+
|
20
|
+
# XCODEPROJ defined and exists
|
21
|
+
return xcodeproj if xcodeproj
|
22
|
+
|
23
|
+
projects = find_xcodeproj
|
24
|
+
|
25
|
+
return nil if projects.empty?
|
26
|
+
return projects[0] if projects.count == 1
|
27
|
+
|
28
|
+
raise_multiple_xcodeproj(projects)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @!visibility private
|
32
|
+
def find_xcodeproj
|
33
|
+
xcode_projects = []
|
34
|
+
Dir.glob("#{Dir.pwd}/**/*.xcodeproj").each do |path|
|
35
|
+
next if ignore_xcodeproj?(path)
|
36
|
+
xcode_projects << path
|
37
|
+
end
|
38
|
+
xcode_projects
|
39
|
+
end
|
40
|
+
|
41
|
+
# @!visibility private
|
42
|
+
def ignore_xcodeproj?(path)
|
43
|
+
path[/CordovaLib/, 0] ||
|
44
|
+
path[/Pods/, 0] ||
|
45
|
+
path[/Carthage/, 0] ||
|
46
|
+
path[/Airship(Kit|Lib)/, 0] ||
|
47
|
+
path[/google-plus-ios-sdk/, 0]
|
48
|
+
end
|
49
|
+
|
50
|
+
# @!visibility private
|
51
|
+
def detect_xcode_apps
|
52
|
+
dirs_to_search = derived_data_search_dirs
|
53
|
+
|
54
|
+
dir_from_prefs = xcode_preferences_search_dir
|
55
|
+
if dir_from_prefs
|
56
|
+
dirs_to_search << dir_from_prefs
|
57
|
+
end
|
58
|
+
|
59
|
+
dirs_to_search << Dir.pwd
|
60
|
+
dirs_to_search.uniq!
|
61
|
+
|
62
|
+
apps = []
|
63
|
+
dirs_to_search.each do |dir|
|
64
|
+
# defined in detect_aut/apps.rb
|
65
|
+
candidates = candidate_apps(dir)
|
66
|
+
apps = apps.concat(candidates)
|
67
|
+
end
|
68
|
+
|
69
|
+
return apps, dirs_to_search
|
70
|
+
end
|
71
|
+
|
72
|
+
# @!visibility private
|
73
|
+
PLIST_KEYS = {
|
74
|
+
:workspace => "WorkspacePath",
|
75
|
+
:shared_build => "IDESharedBuildFolderName",
|
76
|
+
:custom_build => "IDECustomBuildProductsPath"
|
77
|
+
}
|
78
|
+
|
79
|
+
# @!visibility private
|
80
|
+
# TODO Needs unit tests
|
81
|
+
def derived_data_search_dirs
|
82
|
+
project = xcodeproj
|
83
|
+
project_name = File.basename(project)
|
84
|
+
matches = []
|
85
|
+
|
86
|
+
# WorkspacePath could be a .xcodeproj or .xcworkspace
|
87
|
+
#
|
88
|
+
# # Exact match.
|
89
|
+
# xcodeproj = path/to/MyApp/MyApp.xcodeproj
|
90
|
+
# WorkspacePath = path/to/MyApp/MyApp.xcodeproj
|
91
|
+
#
|
92
|
+
# # CocoaPods projects are often configured like this. As are legacy
|
93
|
+
# # projects that have been added to a new workspace.
|
94
|
+
# xcodeproj = path/to/MyApp/MyApp.xcodeproj
|
95
|
+
# WorkspacePath = path/to/MyApp/MyApp.xcworkspace
|
96
|
+
#
|
97
|
+
# # This is the Xcode default when creating new iOS project
|
98
|
+
# xcodeproj = path/to/MyApp/MyApp/MyApp.xcodeproj
|
99
|
+
# WorkspacePath = path/to/MyApp/MyApp.xcworkspace
|
100
|
+
key = PLIST_KEYS[:workspace]
|
101
|
+
Dir.glob("#{derived_data}/*/info.plist") do |plist|
|
102
|
+
workspace = pbuddy.plist_read(key, plist)
|
103
|
+
if workspace == project
|
104
|
+
matches << File.dirname(plist)
|
105
|
+
else
|
106
|
+
base_dir = File.dirname(workspace)
|
107
|
+
if File.exist?(File.join(base_dir, project_name))
|
108
|
+
matches << File.dirname(plist)
|
109
|
+
elsif !Dir.glob("#{File.dirname(workspace)}/*/#{project_name}").empty?
|
110
|
+
matches << File.dirname(plist)
|
111
|
+
elsif !Dir.glob("#{File.dirname(workspace)}/**/#{project_name}").empty?
|
112
|
+
matches << File.dirname(plist)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
matches
|
117
|
+
end
|
118
|
+
|
119
|
+
# @!visibility private
|
120
|
+
def xcode_preferences_search_dir
|
121
|
+
plist = xcode_preferences_plist
|
122
|
+
|
123
|
+
shared_build_folder = pbuddy.plist_read(PLIST_KEYS[:shared_build], plist)
|
124
|
+
custom_build_folder = pbuddy.plist_read(PLIST_KEYS[:custom_build], plist)
|
125
|
+
|
126
|
+
if shared_build_folder
|
127
|
+
File.join(derived_data, shared_build_folder, "Products")
|
128
|
+
elsif custom_build_folder
|
129
|
+
File.join(File.dirname(xcodeproj), custom_build_folder)
|
130
|
+
else
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# @!visibility private
|
136
|
+
def derived_data
|
137
|
+
RunLoop::Environment.derived_data ||
|
138
|
+
File.join(RunLoop::Environment.user_home_directory,
|
139
|
+
"Library", "Developer", "Xcode", "DerivedData")
|
140
|
+
end
|
141
|
+
|
142
|
+
# @!visibility private
|
143
|
+
def xcode_preferences_plist
|
144
|
+
File.join(RunLoop::Environment.user_home_directory,
|
145
|
+
"Library",
|
146
|
+
"Preferences",
|
147
|
+
"com.apple.dt.Xcode.plist")
|
148
|
+
end
|
149
|
+
|
150
|
+
# @!visibility private
|
151
|
+
def pbuddy
|
152
|
+
@pbuddy ||= RunLoop::PlistBuddy.new
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|