xcoder 0.1.6 → 0.1.7
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.
- data/.gitignore +2 -0
- data/Gemfile +2 -0
- data/README.md +56 -3
- data/Rakefile +8 -2
- data/lib/xcode/buildfile.rb +1 -1
- data/lib/xcode/configuration.rb +77 -4
- data/lib/xcode/configuration_owner.rb +86 -0
- data/lib/xcode/configurations/array_property.rb +6 -2
- data/lib/xcode/configurations/boolean_property.rb +4 -0
- data/lib/xcode/configurations/key_value_array_property.rb +42 -0
- data/lib/xcode/configurations/space_delimited_string_property.rb +4 -0
- data/lib/xcode/configurations/string_property.rb +4 -0
- data/lib/xcode/configurations/targeted_device_family_property.rb +13 -3
- data/lib/xcode/project.rb +13 -31
- data/lib/xcode/project_reference.rb +55 -0
- data/lib/xcode/provisioning_profile.rb +19 -1
- data/lib/xcode/registry.rb +9 -4
- data/lib/xcode/resource.rb +7 -5
- data/lib/xcode/target.rb +0 -64
- data/lib/xcode/test/ocunit_report_parser.rb +11 -2
- data/lib/xcode/version.rb +1 -1
- data/lib/xcoder/rake_task.rb +218 -0
- data/spec/Provisioning/AdHoc.mobileprovision +0 -0
- data/spec/Provisioning/AppStore.mobileprovision +0 -0
- data/spec/configuration_spec.rb +152 -34
- data/spec/project_spec.rb +14 -0
- data/spec/provisioning_profile_spec.rb +53 -0
- metadata +22 -12
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -43,7 +43,7 @@ You can either use the user's login keychain, another named keychain, or simply
|
|
43
43
|
|
44
44
|
#### Creating a temporary keychain
|
45
45
|
|
46
|
-
Xcode::Keychain.
|
46
|
+
Xcode::Keychain.temp do |keychain|
|
47
47
|
# import certs into the keychain
|
48
48
|
# perform builds within this keychain's context
|
49
49
|
end # Keychain is deleted
|
@@ -130,10 +130,63 @@ You can also optionally set a .proxy= property or just set the HTTP_PROXY enviro
|
|
130
130
|
You can invoke your test target/bundle from the builder
|
131
131
|
|
132
132
|
builder.test do |report|
|
133
|
-
report.
|
133
|
+
report.debug = false # default false, set to true to see raw output from xcodebuild
|
134
|
+
|
135
|
+
# The following is the default setup, you wouldnt normally need to do this unless
|
136
|
+
# you want to add new formatters
|
137
|
+
report.formatters = []
|
138
|
+
report.add_formatter :junit, 'test-reports' # Output JUnit format results to test-reports/
|
139
|
+
report.add_formatter :stdout # Output a simplified output to STDOUT
|
134
140
|
end
|
135
141
|
|
136
|
-
This will invoke the test target, capture the output and write the junit reports to the test-reports directory. Currently only junit is supported.
|
142
|
+
This will invoke the test target, capture the output and write the junit reports to the test-reports directory. Currently only junit is supported, although you can write your own formatter quite easily (for an example, look at Xcode::Test::Formatters::JunitFormatter).
|
143
|
+
|
144
|
+
## Rake Tasks
|
145
|
+
|
146
|
+
Xcoder provides a rake task to assist with make it easier to perform common Xcode project actions from the command-line.
|
147
|
+
|
148
|
+
Within your `Rakefile` add the following:
|
149
|
+
|
150
|
+
require 'xcoder/rake_task'
|
151
|
+
|
152
|
+
Then define your Rake Task:
|
153
|
+
|
154
|
+
Xcode::RakeTask.new
|
155
|
+
|
156
|
+
By default this will generate rake tasks within the 'xcode' namespace for
|
157
|
+
all the projects (within the current working directory), all their targets,
|
158
|
+
and all their configs. This will also generate tasks for all of a projects
|
159
|
+
schemes as well.
|
160
|
+
|
161
|
+
All names from the project, schemes, targets, and configs are remove
|
162
|
+
the camel-casing and replacing the cameling with underscores. Spaces
|
163
|
+
are replaced with dashes (-)
|
164
|
+
|
165
|
+
This will generate rake tasks that appear similar to the following:
|
166
|
+
|
167
|
+
rake xcode:project-name:targetname:debug:build
|
168
|
+
rake xcode:project-name:targetname:debug:clean
|
169
|
+
# ...
|
170
|
+
|
171
|
+
You can specify a parameter to change the root rake namespace:
|
172
|
+
|
173
|
+
Xcode::RakeTask.new :apple
|
174
|
+
|
175
|
+
# Resulting Rake Tasks:
|
176
|
+
# rake apple:project-name:targetname:debug:build
|
177
|
+
# rake apple:project-name:targetname:debug:clean
|
178
|
+
# ...
|
179
|
+
|
180
|
+
You can also supply a block to provide additional configuration to specify the folder to search for projects and the projects that should generate tasks for:
|
181
|
+
|
182
|
+
Xcode::RakeTask.new :hudson do |xcoder|
|
183
|
+
xcoder.directory = "projects"
|
184
|
+
xcoder.projects = [ "Project Alpha", "Project Beta" ]
|
185
|
+
end
|
186
|
+
|
187
|
+
rake hudson:project-alpha:targetname:debug:build
|
188
|
+
# ...
|
189
|
+
|
137
190
|
|
138
191
|
## Manipulating a Project
|
139
192
|
|
data/Rakefile
CHANGED
@@ -16,7 +16,7 @@ namespace :doc do
|
|
16
16
|
desc "Generate YARD docs"
|
17
17
|
YARD::Rake::YardocTask.new(:generate) do |t|
|
18
18
|
t.files = ['lib/**/*.rb', '-', 'README.md'] # optional
|
19
|
-
t.options = ["-o ../xcoder-doc"]
|
19
|
+
# t.options = ["-o ../xcoder-doc"]
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -27,7 +27,7 @@ namespace :test_project do
|
|
27
27
|
task :reset do
|
28
28
|
puts "Reseting the TestProject Project File"
|
29
29
|
system "git co -- spec/TestProject"
|
30
|
-
puts "Removing any User schemes generated
|
30
|
+
puts "Removing any User schemes generated in the project"
|
31
31
|
system "rm -rf spec/TestProject/TestProject.xcodeproj/xcuserdata"
|
32
32
|
puts "Removing any installed files"
|
33
33
|
system "git clean -df spec/TestProject"
|
@@ -35,3 +35,9 @@ namespace :test_project do
|
|
35
35
|
|
36
36
|
end
|
37
37
|
|
38
|
+
|
39
|
+
require './lib/xcoder/rake_task'
|
40
|
+
|
41
|
+
Xcode::RakeTask.new :xcode do |xcoder|
|
42
|
+
xcoder.directory = 'spec'
|
43
|
+
end
|
data/lib/xcode/buildfile.rb
CHANGED
@@ -54,7 +54,7 @@ module Xcode
|
|
54
54
|
puts "[#{label}] Set build profile to #{@values[:profile]}"
|
55
55
|
end
|
56
56
|
|
57
|
-
Keychain.
|
57
|
+
Keychain.temp do |kc|
|
58
58
|
kc.import @values[:certificate], @values[:password]
|
59
59
|
|
60
60
|
builder.identity = @values[:identity] || kc.identities.first
|
data/lib/xcode/configuration.rb
CHANGED
@@ -4,6 +4,7 @@ require 'xcode/configurations/targeted_device_family_property'
|
|
4
4
|
require 'xcode/configurations/string_property'
|
5
5
|
require 'xcode/configurations/boolean_property'
|
6
6
|
require 'xcode/configurations/array_property'
|
7
|
+
require 'xcode/configurations/key_value_array_property'
|
7
8
|
|
8
9
|
module Xcode
|
9
10
|
|
@@ -84,7 +85,18 @@ module Xcode
|
|
84
85
|
# Define a getter method
|
85
86
|
|
86
87
|
define_method property_name do
|
87
|
-
|
88
|
+
|
89
|
+
# When the build setting is missing from the existing configuration, look
|
90
|
+
# for the configuration of the target's project (only if we are currently
|
91
|
+
# at the Target level).
|
92
|
+
|
93
|
+
if not build_settings.key?(setting_name) and target.is_a?(Target)
|
94
|
+
project_config = target.project.global_config(name)
|
95
|
+
project_config.send(property_name)
|
96
|
+
else
|
97
|
+
substitute type.open(build_settings[setting_name])
|
98
|
+
end
|
99
|
+
|
88
100
|
end
|
89
101
|
|
90
102
|
# Define a setter method
|
@@ -92,7 +104,39 @@ module Xcode
|
|
92
104
|
define_method "#{property_name}=" do |value|
|
93
105
|
build_settings[setting_name] = unsubstitute(type.save(value))
|
94
106
|
end
|
107
|
+
|
108
|
+
# Define an append method
|
109
|
+
|
110
|
+
define_method "append_to_#{property_name}" do |value|
|
111
|
+
build_settings[setting_name] = unsubstitute type.append(build_settings[setting_name],value)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Define a environment name method (to return the settings name)
|
115
|
+
|
116
|
+
define_method "env_#{property_name}" do
|
117
|
+
setting_name
|
118
|
+
end
|
119
|
+
|
120
|
+
# Define a raw getter
|
121
|
+
|
122
|
+
define_method "raw_#{property_name}" do
|
123
|
+
build_settings[setting_name]
|
124
|
+
end
|
125
|
+
|
126
|
+
# Define a raw setter
|
127
|
+
|
128
|
+
define_method "raw_#{property_name}=" do |value|
|
129
|
+
build_settings[setting_name] = value
|
130
|
+
end
|
131
|
+
|
95
132
|
|
133
|
+
@setting_name_to_property = {} unless @setting_name_to_property
|
134
|
+
@setting_name_to_property[setting_name] = property_name
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.setting_name_to_property(name)
|
139
|
+
@setting_name_to_property[name]
|
96
140
|
end
|
97
141
|
|
98
142
|
#
|
@@ -149,7 +193,7 @@ module Xcode
|
|
149
193
|
# @attribute
|
150
194
|
# Build Setting - "OTHER_CFLAGS"
|
151
195
|
# @see https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW17
|
152
|
-
property :other_c_flags, "OTHER_CFLAGS",
|
196
|
+
property :other_c_flags, "OTHER_CFLAGS", KeyValueArrayProperty
|
153
197
|
|
154
198
|
# @attribute
|
155
199
|
# Build Setting - "GCC_C_LANGUAGE_STANDARD"
|
@@ -202,6 +246,11 @@ module Xcode
|
|
202
246
|
# @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW144
|
203
247
|
property :copy_phase_strip, "COPY_PHASE_STRIP", BooleanProperty
|
204
248
|
|
249
|
+
# @attribute
|
250
|
+
# Build Setting - "OTHER_LDFLAGS"
|
251
|
+
# @see https://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW76
|
252
|
+
property :other_linker_flags, "OTHER_LDFLAGS", SpaceDelimitedString
|
253
|
+
|
205
254
|
#
|
206
255
|
# Opens the info plist associated with the configuration and allows you to
|
207
256
|
# edit the configuration.
|
@@ -236,7 +285,11 @@ module Xcode
|
|
236
285
|
# @return [String,Array,Hash] the value stored for the specified configuration
|
237
286
|
#
|
238
287
|
def get(name)
|
239
|
-
|
288
|
+
if Configuration.setting_name_to_property(name)
|
289
|
+
send Configuration.setting_name_to_property(name)
|
290
|
+
else
|
291
|
+
build_settings[name]
|
292
|
+
end
|
240
293
|
end
|
241
294
|
|
242
295
|
#
|
@@ -246,7 +299,27 @@ module Xcode
|
|
246
299
|
# @param [String,Array,Hash] value the value to store for the specific setting
|
247
300
|
#
|
248
301
|
def set(name, value)
|
249
|
-
|
302
|
+
if Configuration.setting_name_to_property(name)
|
303
|
+
send("#{Configuration.setting_name_to_property(name)}=",value)
|
304
|
+
else
|
305
|
+
build_settings[name] = value
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
#
|
310
|
+
# Append a value to the the configuration value for the given name
|
311
|
+
#
|
312
|
+
# @param [String] name of the the configuration setting
|
313
|
+
# @param [String,Array,Hash] value the value to store for the specific setting
|
314
|
+
#
|
315
|
+
def append(name, value)
|
316
|
+
if Configuration.setting_name_to_property(name)
|
317
|
+
send("append_to_#{Configuration.setting_name_to_property(name)}",value)
|
318
|
+
else
|
319
|
+
# @todo this will likely raise some errors if trying to append a string
|
320
|
+
# to an array, but that likely means a new property should be defined.
|
321
|
+
build_settings[name] = build_settings[name] + value
|
322
|
+
end
|
250
323
|
end
|
251
324
|
|
252
325
|
#
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Xcode
|
2
|
+
module ConfigurationOwner
|
3
|
+
|
4
|
+
#
|
5
|
+
# @return [Array<BuildConfiguration>] the configurations that this target
|
6
|
+
# or project supports. These are generally 'Debug' or 'Release' but may be
|
7
|
+
# custom created configurations.
|
8
|
+
#
|
9
|
+
def configs
|
10
|
+
build_configuration_list.build_configurations.map do |config|
|
11
|
+
config.target = self
|
12
|
+
config
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Return a specific build configuration.
|
18
|
+
#
|
19
|
+
# @note an exception is raised if no configuration matches the specified name.
|
20
|
+
#
|
21
|
+
# @param [String] name of a configuration to return
|
22
|
+
#
|
23
|
+
# @return [BuildConfiguration] a specific build configuration that
|
24
|
+
# matches the specified name.
|
25
|
+
#
|
26
|
+
def config(name)
|
27
|
+
config = configs.select {|config| config.name == name.to_s }.first
|
28
|
+
raise "No such config #{name}, available configs are #{configs.map {|c| c.name}.join(', ')}" if config.nil?
|
29
|
+
yield config if block_given?
|
30
|
+
config
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Create a configuration for the target or project.
|
35
|
+
#
|
36
|
+
# @example creating a new 'App Store Submission' configuration for a project
|
37
|
+
#
|
38
|
+
# project.create_config 'App Store Submission' # => Configuration
|
39
|
+
#
|
40
|
+
# @example creating a new 'Ad Hoc' configuration for a target
|
41
|
+
#
|
42
|
+
# target.create_config 'Ad Hoc' do |config|
|
43
|
+
# # configuration the new debug config.
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# @param [String] name of the configuration to create
|
47
|
+
# @return [BuildConfiguration] that is created
|
48
|
+
#
|
49
|
+
def create_configuration(name)
|
50
|
+
# To create a configuration, we need to create or retrieve the configuration list
|
51
|
+
|
52
|
+
created_config = build_configuration_list.create_config(name) do |config|
|
53
|
+
yield config if block_given?
|
54
|
+
end
|
55
|
+
|
56
|
+
created_config
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Create multiple configurations for a target or project.
|
61
|
+
#
|
62
|
+
# @example creating 'Release' and 'Debug for a new target
|
63
|
+
#
|
64
|
+
# new_target = project.create_target 'UniversalBinary'
|
65
|
+
# new_target.create_configurations 'Debug', 'Release' do |config|
|
66
|
+
# # set up the configurations
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# @param [String,Array<String>] configuration_names the names of the
|
70
|
+
# configurations to create.
|
71
|
+
#
|
72
|
+
def create_configurations(*configuration_names)
|
73
|
+
|
74
|
+
configuration_names.compact.flatten.map do |config_name|
|
75
|
+
created_config = create_configuration config_name do |config|
|
76
|
+
yield config if block_given?
|
77
|
+
end
|
78
|
+
|
79
|
+
created_config.save!
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -16,7 +16,7 @@ module Xcode
|
|
16
16
|
# @param [Array] value to be parsed into the correct format
|
17
17
|
#
|
18
18
|
def open(value)
|
19
|
-
value
|
19
|
+
Array(value)
|
20
20
|
end
|
21
21
|
|
22
22
|
#
|
@@ -24,7 +24,11 @@ module Xcode
|
|
24
24
|
# be in a multitude of formats as long as it responds_to? #to_a
|
25
25
|
#
|
26
26
|
def save(value)
|
27
|
-
value
|
27
|
+
Array(value)
|
28
|
+
end
|
29
|
+
|
30
|
+
def append(original,value)
|
31
|
+
(Array(original) + Array(value)).uniq
|
28
32
|
end
|
29
33
|
|
30
34
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module Xcode
|
3
|
+
module Configuration
|
4
|
+
|
5
|
+
#
|
6
|
+
# Within the a build settings for a configuration there are a number of
|
7
|
+
# settings that are stored as key-value pairs in Arrays.
|
8
|
+
#
|
9
|
+
module KeyValueArrayProperty
|
10
|
+
extend self
|
11
|
+
|
12
|
+
#
|
13
|
+
# As arrays are stored as arrays this is not particularly different.
|
14
|
+
#
|
15
|
+
# @param [Array] value to be parsed into the correct format
|
16
|
+
#
|
17
|
+
def open(value)
|
18
|
+
Array(value)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# @param [Nil,Array,String] value that is being saved back which can
|
23
|
+
# be in a multitude of formats as long as it responds_to? #to_a
|
24
|
+
#
|
25
|
+
def save(value)
|
26
|
+
Array(value)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# To ensure uniqueness, the original value array is added to the new value
|
31
|
+
# array and then all the key-values pairs are placed in a Hash then mapped
|
32
|
+
# back out to a key=value pair array.
|
33
|
+
#
|
34
|
+
def append(original,value)
|
35
|
+
all_values = (Array(original) + Array(value)).map {|key_value| key_value.split("=") }.flatten
|
36
|
+
Hash[*all_values].map {|k,v| "#{k}=#{v}" }
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -23,16 +23,26 @@ module Xcode
|
|
23
23
|
end
|
24
24
|
|
25
25
|
#
|
26
|
-
# @param [Array<String>] value convert the array of platform names
|
26
|
+
# @param [String,Array<String>] value convert the array of platform names
|
27
27
|
# @return [String] the comma-delimited list of numeric values representing
|
28
28
|
# the platforms.
|
29
29
|
#
|
30
30
|
def save(value)
|
31
31
|
Array(value).map do |platform_name|
|
32
32
|
platforms.map {|number,name| number if name.to_s == platform_name.to_s.downcase }
|
33
|
-
end.flatten.compact.join(",")
|
33
|
+
end.flatten.compact.uniq.join(",")
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
#
|
37
|
+
# @param [String] original is the current string value stored in the configuration
|
38
|
+
# that needs to be converted into an Array of names.
|
39
|
+
# @param [String,Array<String>] value the new values to include in the device
|
40
|
+
# family.
|
41
|
+
#
|
42
|
+
def append(original,value)
|
43
|
+
save(open(original) + Array(value))
|
44
|
+
end
|
45
|
+
|
36
46
|
private
|
37
47
|
|
38
48
|
def platforms
|
data/lib/xcode/project.rb
CHANGED
@@ -9,9 +9,9 @@ module Xcode
|
|
9
9
|
# folder that contains a number of workspace files and project files like
|
10
10
|
# `project.pbxproj`.
|
11
11
|
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
12
|
+
#
|
13
|
+
# The Project represents encapsulates the an actual Resource that is ProjectReference
|
14
|
+
# and other objects.
|
15
15
|
#
|
16
16
|
class Project
|
17
17
|
|
@@ -78,6 +78,14 @@ module Xcode
|
|
78
78
|
@registry.archive_version
|
79
79
|
end
|
80
80
|
|
81
|
+
def global_configs
|
82
|
+
@project.configs
|
83
|
+
end
|
84
|
+
|
85
|
+
def global_config(name)
|
86
|
+
@project.config(name)
|
87
|
+
end
|
88
|
+
|
81
89
|
#
|
82
90
|
# Returns the main group of the project where all the files reside.
|
83
91
|
#
|
@@ -115,31 +123,9 @@ module Xcode
|
|
115
123
|
# @return [Group] the group with the specified name.
|
116
124
|
#
|
117
125
|
def group(name,options = {},&block)
|
118
|
-
|
119
|
-
options = { :create => true }.merge(options)
|
120
|
-
|
121
|
-
current_group = @project.main_group
|
122
|
-
|
123
|
-
# @todo consider this traversing and find/create as a normal procedure when
|
124
|
-
# traversing the project.
|
125
|
-
|
126
|
-
name.split("/").each do |path_component|
|
127
|
-
found_group = current_group.group(path_component).first
|
128
|
-
|
129
|
-
if options[:create] and found_group.nil?
|
130
|
-
found_group = current_group.create_group(path_component)
|
131
|
-
end
|
132
|
-
|
133
|
-
current_group = found_group
|
134
|
-
|
135
|
-
break unless current_group
|
136
|
-
end
|
137
|
-
|
138
|
-
current_group.instance_eval(&block) if block_given? and current_group
|
139
|
-
|
140
|
-
current_group
|
126
|
+
@project.group(name,options,&block)
|
141
127
|
end
|
142
|
-
|
128
|
+
|
143
129
|
#
|
144
130
|
# Return the file that matches the specified path. This will traverse
|
145
131
|
# the project's groups and find the file at the end of the path.
|
@@ -159,9 +145,7 @@ module Xcode
|
|
159
145
|
# @return [Group] the 'Products' group of the project.
|
160
146
|
def products_group
|
161
147
|
current_group = groups.group('Products').first
|
162
|
-
|
163
148
|
current_group.instance_eval(&block) if block_given? and current_group
|
164
|
-
|
165
149
|
current_group
|
166
150
|
end
|
167
151
|
|
@@ -173,9 +157,7 @@ module Xcode
|
|
173
157
|
# @return [Group] the 'Frameworks' group of the projet.
|
174
158
|
def frameworks_group
|
175
159
|
current_group = groups.group('Frameworks').first
|
176
|
-
|
177
160
|
current_group.instance_eval(&block) if block_given? and current_group
|
178
|
-
|
179
161
|
current_group
|
180
162
|
end
|
181
163
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Xcode
|
2
|
+
|
3
|
+
module ProjectReference
|
4
|
+
|
5
|
+
#
|
6
|
+
# Returns the group specified. If any part of the group does not exist along
|
7
|
+
# the path the group is created. Also paths can be specified to make the
|
8
|
+
# traversing of the groups easier.
|
9
|
+
#
|
10
|
+
# @note this will attempt to find the paths specified, if it fails to find them
|
11
|
+
# it will create one and then continue traversing.
|
12
|
+
#
|
13
|
+
# @example Traverse a path through the various sub-groups.
|
14
|
+
#
|
15
|
+
# project.group('Vendor/MyCode/Support Files')
|
16
|
+
# # is equivalent to ...
|
17
|
+
# project.group('Vendor').first.group('MyCode').first.group('Supporting Files')
|
18
|
+
#
|
19
|
+
# @note this path functionality current is only exercised from the project level
|
20
|
+
# all groups will treat the path division `/` as simply a character.
|
21
|
+
#
|
22
|
+
# @param [String] name the group name to find/create
|
23
|
+
#
|
24
|
+
# @return [Group] the group with the specified name.
|
25
|
+
#
|
26
|
+
def group(name,options = {},&block)
|
27
|
+
# By default create missing groups along the way
|
28
|
+
options = { :create => true }.merge(options)
|
29
|
+
|
30
|
+
current_group = main_group
|
31
|
+
|
32
|
+
# @todo consider this traversing and find/create as a normal procedure when
|
33
|
+
# traversing the project.
|
34
|
+
|
35
|
+
name.split("/").each do |path_component|
|
36
|
+
found_group = current_group.group(path_component).first
|
37
|
+
|
38
|
+
if options[:create] and found_group.nil?
|
39
|
+
found_group = current_group.create_group(path_component)
|
40
|
+
end
|
41
|
+
|
42
|
+
current_group = found_group
|
43
|
+
|
44
|
+
break unless current_group
|
45
|
+
end
|
46
|
+
|
47
|
+
current_group.instance_eval(&block) if block_given? and current_group
|
48
|
+
|
49
|
+
current_group
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -1,17 +1,31 @@
|
|
1
1
|
module Xcode
|
2
2
|
class ProvisioningProfile
|
3
|
-
attr_reader :path, :name, :uuid, :identifiers
|
3
|
+
attr_reader :path, :name, :uuid, :identifiers, :devices, :appstore
|
4
4
|
def initialize(path)
|
5
5
|
|
6
6
|
raise "Provisioning profile '#{path}' does not exist" unless File.exists? path
|
7
7
|
|
8
8
|
@path = path
|
9
9
|
@identifiers = []
|
10
|
+
@devices = []
|
11
|
+
@appstore = true
|
10
12
|
|
11
13
|
# TODO: im sure this could be done in a nicer way. maybe read out the XML-like stuff and use the plist -> json converter
|
12
14
|
uuid = nil
|
13
15
|
File.open(path, "rb") do |f|
|
14
16
|
input = f.read
|
17
|
+
|
18
|
+
if input=~/ProvisionedDevices/
|
19
|
+
@appstore = false
|
20
|
+
end
|
21
|
+
|
22
|
+
if input=~/<key>ProvisionedDevices<\/key>.*?<array>(.*?)<\/array>/im
|
23
|
+
$1.split(/<string>/).each do |id|
|
24
|
+
next if id.nil? or id.strip==""
|
25
|
+
@devices << id.gsub(/<\/string>/,'').strip
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
15
29
|
input=~/<key>UUID<\/key>.*?<string>(.*?)<\/string>/im
|
16
30
|
@uuid = $1.strip
|
17
31
|
|
@@ -26,6 +40,10 @@ module Xcode
|
|
26
40
|
end
|
27
41
|
|
28
42
|
end
|
43
|
+
|
44
|
+
def appstore?
|
45
|
+
@appstore
|
46
|
+
end
|
29
47
|
|
30
48
|
def self.profiles_path
|
31
49
|
File.expand_path "~/Library/MobileDevice/Provisioning\\ Profiles/"
|