xcodeproj 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/xcodeproj/extconf.rb +8 -0
- data/lib/xcodeproj.rb +2 -2
- data/lib/xcodeproj/config.rb +3 -3
- data/lib/xcodeproj/constants.rb +1 -1
- data/lib/xcodeproj/gem_version.rb +6 -0
- data/lib/xcodeproj/project.rb +163 -90
- data/lib/xcodeproj/project/object.rb +17 -4
- data/lib/xcodeproj/project/object/configuration_list.rb +15 -2
- data/lib/xcodeproj/project/object/file_reference.rb +60 -14
- data/lib/xcodeproj/project/object/group.rb +100 -168
- data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +182 -0
- data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +210 -0
- data/lib/xcodeproj/project/object/native_target.rb +23 -0
- data/lib/xcodeproj/project/project_helper.rb +44 -43
- data/lib/xcodeproj/project/xcproj_helper.rb +55 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17c13e04abd44c7e6dceedf68acf67a1d8ba2f37
|
4
|
+
data.tar.gz: 44fdf17f6e7ea9ca3a9f08dece0112eacffe746c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6cd8393ddfa58f805c14e0e2dface2ae60d24bd4774b78f81faa6c40f228ec2b3d9fd7eb24b6b6ebf05027227db84c1e9c5cc8b52b07235e0ad955b004f35c1
|
7
|
+
data.tar.gz: 979709a8376c2e40be97fcba4d554a0e53277a173a99fe56cf70380c54d240c783c248a6b275cb4ccff589c4e02cf66dc93f722acc136228345debb7960eef8a
|
data/ext/xcodeproj/extconf.rb
CHANGED
@@ -24,6 +24,14 @@ checking_for "-std=c99 option to compiler" do
|
|
24
24
|
$CFLAGS += " -std=c99" if try_compile '', '-std=c99'
|
25
25
|
end
|
26
26
|
|
27
|
+
# From `man ld`:
|
28
|
+
#
|
29
|
+
# -Z Do not search the standard directories when searching for libraries and frameworks.
|
30
|
+
#
|
31
|
+
# This is typically used when you want compilation against Xcode SDK as opposed to the frameworks installed
|
32
|
+
# in the running system, which is our use case.
|
33
|
+
$LDFLAGS.gsub!(/\s-Z\s/,' ')
|
34
|
+
|
27
35
|
unless have_framework('CoreFoundation')
|
28
36
|
if have_library('CoreFoundation')
|
29
37
|
# this is needed for opencflite, assume it's on linux
|
data/lib/xcodeproj.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Xcodeproj
|
2
|
-
VERSION = '0.9.0' unless defined? Xcodeproj::VERSION
|
3
2
|
|
4
3
|
class PlainInformative < StandardError
|
5
4
|
end
|
@@ -10,13 +9,14 @@ module Xcodeproj
|
|
10
9
|
end
|
11
10
|
end
|
12
11
|
|
12
|
+
require 'xcodeproj/user_interface'
|
13
|
+
|
13
14
|
autoload :Command, 'xcodeproj/command'
|
14
15
|
autoload :Config, 'xcodeproj/config'
|
15
16
|
autoload :Constants, 'xcodeproj/constants'
|
16
17
|
autoload :Differ, 'xcodeproj/differ'
|
17
18
|
autoload :Helper, 'xcodeproj/helper'
|
18
19
|
autoload :Project, 'xcodeproj/project'
|
19
|
-
autoload :UI, 'xcodeproj/user_interface'
|
20
20
|
autoload :Workspace, 'xcodeproj/workspace'
|
21
21
|
autoload :XCScheme, 'xcodeproj/scheme'
|
22
22
|
autoload :XcodebuildHelper, 'xcodeproj/xcodebuild_helper'
|
data/lib/xcodeproj/config.rb
CHANGED
@@ -150,9 +150,9 @@ module Xcodeproj
|
|
150
150
|
flags = @attributes['OTHER_LDFLAGS']
|
151
151
|
return unless flags
|
152
152
|
|
153
|
-
frameworks = flags.scan(
|
154
|
-
weak_frameworks = flags.scan(
|
155
|
-
libraries = flags.scan(
|
153
|
+
frameworks = flags.scan(/(?:\A|\s)-framework\s+([^\s]+)/).map { |m| m[0] }
|
154
|
+
weak_frameworks = flags.scan(/(?:\A|\s)-weak_framework\s+([^\s]+)/).map { |m| m[0] }
|
155
|
+
libraries = flags.scan(/(?:\A|\s)-l ?([^\s]+)/).map { |m| m[0] }
|
156
156
|
@frameworks.merge frameworks
|
157
157
|
@weak_frameworks.merge weak_frameworks
|
158
158
|
@libraries.merge libraries
|
data/lib/xcodeproj/constants.rb
CHANGED
data/lib/xcodeproj/project.rb
CHANGED
@@ -3,6 +3,7 @@ require 'pathname'
|
|
3
3
|
require 'xcodeproj/xcodeproj_ext'
|
4
4
|
require 'xcodeproj/project/object'
|
5
5
|
require 'xcodeproj/project/project_helper'
|
6
|
+
require 'xcodeproj/project/xcproj_helper'
|
6
7
|
|
7
8
|
module Xcodeproj
|
8
9
|
|
@@ -41,31 +42,34 @@ module Xcodeproj
|
|
41
42
|
|
42
43
|
include Object
|
43
44
|
|
44
|
-
# @return [
|
45
|
+
# @return [Pathname] the path of the project.
|
45
46
|
#
|
46
|
-
attr_reader :
|
47
|
+
attr_reader :path
|
47
48
|
|
48
|
-
# @
|
49
|
+
# @param [Pathname, String] path @see path
|
50
|
+
# @param [Bool] skip_initialization
|
51
|
+
# Wether the project should be initialized from scratch.
|
49
52
|
#
|
50
|
-
|
51
|
-
|
52
|
-
# @return [String] the objects version.
|
53
|
-
#
|
54
|
-
attr_reader :object_version
|
55
|
-
|
56
|
-
# @return [Hash{String => AbstractObject}] A hash containing all the
|
57
|
-
# objects of the project by UUID.
|
53
|
+
# @example Creating a project
|
54
|
+
# Project.new("path/to/Project.xcodeproj")
|
58
55
|
#
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
56
|
+
def initialize(path, skip_initialization = false)
|
57
|
+
@path = Pathname.new(path)
|
58
|
+
@objects_by_uuid = {}
|
59
|
+
@generated_uuids = []
|
60
|
+
@available_uuids = []
|
61
|
+
unless skip_initialization
|
62
|
+
initialize_from_scratch
|
63
|
+
end
|
64
|
+
unless skip_initialization.is_a?(TrueClass) || skip_initialization.is_a?(FalseClass)
|
65
|
+
raise ArgumentError, "[Xcodeproj] Initialization parameter expected to " \
|
66
|
+
"be a boolean #{skip_initialization}"
|
67
|
+
end
|
68
|
+
end
|
64
69
|
|
65
|
-
#
|
66
|
-
# existing Xcode document.
|
70
|
+
# Opens the project at the given path.
|
67
71
|
#
|
68
|
-
# @param [Pathname, String]
|
72
|
+
# @param [Pathname, String] path
|
69
73
|
# The path to the Xcode project document (xcodeproj).
|
70
74
|
#
|
71
75
|
# @raise If the project versions are more recent than the ones know to
|
@@ -77,57 +81,37 @@ module Xcodeproj
|
|
77
81
|
# malformed.
|
78
82
|
#
|
79
83
|
# @example Opening a project
|
80
|
-
#
|
84
|
+
# Project.open("path/to/Project.xcodeproj")
|
81
85
|
#
|
82
|
-
def
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
86
|
+
def self.open(path)
|
87
|
+
unless Pathname.new(path).exist?
|
88
|
+
raise "[Xcodeproj] Unable to open `#{path}` because it doesn't exist."
|
89
|
+
end
|
90
|
+
project = new(path, true)
|
91
|
+
project.send(:initialize_from_file)
|
92
|
+
project
|
93
|
+
end
|
90
94
|
|
91
|
-
|
92
|
-
|
93
|
-
|
95
|
+
# @return [String] the archive version.
|
96
|
+
#
|
97
|
+
attr_reader :archive_version
|
94
98
|
|
95
|
-
|
96
|
-
|
99
|
+
# @return [Hash] an dictionary whose purpose is unknown.
|
100
|
+
#
|
101
|
+
attr_reader :classes
|
97
102
|
|
98
|
-
|
99
|
-
|
100
|
-
|
103
|
+
# @return [String] the objects version.
|
104
|
+
#
|
105
|
+
attr_reader :object_version
|
101
106
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
@archive_version = Constants::LAST_KNOWN_ARCHIVE_VERSION.to_s
|
107
|
-
@object_version = Constants::LAST_KNOWN_OBJECT_VERSION.to_s
|
108
|
-
@classes = {}
|
109
|
-
|
110
|
-
root_object = new(PBXProject)
|
111
|
-
root_object.main_group = new(PBXGroup)
|
112
|
-
root_object.product_ref_group = root_object.main_group.new_group('Products')
|
113
|
-
|
114
|
-
config_list = new(XCConfigurationList)
|
115
|
-
config_list.default_configuration_name = 'Release'
|
116
|
-
config_list.default_configuration_is_visible = '0'
|
117
|
-
root_object.build_configuration_list = config_list
|
118
|
-
|
119
|
-
%w| Release Debug |.each do |name|
|
120
|
-
build_configuration = new(XCBuildConfiguration)
|
121
|
-
build_configuration.name = name
|
122
|
-
build_configuration.build_settings = Constants::PROJECT_DEFAULT_BUILD_SETTINGS[name.downcase.to_sym].dup
|
123
|
-
config_list.build_configurations << build_configuration
|
124
|
-
end
|
107
|
+
# @return [Hash{String => AbstractObject}] A hash containing all the
|
108
|
+
# objects of the project by UUID.
|
109
|
+
#
|
110
|
+
attr_reader :objects_by_uuid
|
125
111
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
end
|
130
|
-
end
|
112
|
+
# @return [PBXProject] the root object of the project.
|
113
|
+
#
|
114
|
+
attr_reader :root_object
|
131
115
|
|
132
116
|
# Compares the project to another one, or to a plist representation.
|
133
117
|
#
|
@@ -140,16 +124,75 @@ module Xcodeproj
|
|
140
124
|
end
|
141
125
|
|
142
126
|
def to_s
|
143
|
-
"
|
127
|
+
"#<#{self.class}> path:`#{path}` UUID:`#{root_object.uuid}`"
|
144
128
|
end
|
145
129
|
|
146
130
|
alias :inspect :to_s
|
147
131
|
|
132
|
+
# @return [Bool] Whether the xcproj conversion should be disabled.
|
133
|
+
#
|
134
|
+
attr_accessor :disable_xcproj
|
135
|
+
|
136
|
+
|
137
|
+
public
|
138
|
+
|
139
|
+
# @!group Initialization
|
148
140
|
#-------------------------------------------------------------------------#
|
149
141
|
|
142
|
+
# Initializes the instance from scratch.
|
143
|
+
#
|
144
|
+
def initialize_from_scratch
|
145
|
+
@archive_version = Constants::LAST_KNOWN_ARCHIVE_VERSION.to_s
|
146
|
+
@object_version = Constants::LAST_KNOWN_OBJECT_VERSION.to_s
|
147
|
+
@classes = {}
|
148
|
+
|
149
|
+
root_object.remove_referrer(self) if root_object
|
150
|
+
@root_object = new(PBXProject)
|
151
|
+
root_object.add_referrer(self)
|
152
|
+
|
153
|
+
root_object.main_group = new(PBXGroup)
|
154
|
+
root_object.product_ref_group = root_object.main_group.new_group('Products')
|
155
|
+
|
156
|
+
config_list = new(XCConfigurationList)
|
157
|
+
root_object.build_configuration_list = config_list
|
158
|
+
config_list.default_configuration_name = 'Release'
|
159
|
+
config_list.default_configuration_is_visible = '0'
|
160
|
+
add_build_configuration('Debug', :debug)
|
161
|
+
add_build_configuration('Release', :release)
|
162
|
+
|
163
|
+
new_group('Frameworks')
|
164
|
+
end
|
165
|
+
|
166
|
+
# Initializes the instance with the project stored in the `path` attribute.
|
167
|
+
#
|
168
|
+
def initialize_from_file
|
169
|
+
pbxproj_path = path + 'project.pbxproj'
|
170
|
+
plist = Xcodeproj.read_plist(pbxproj_path.to_s)
|
171
|
+
root_object_uuid = plist['rootObject']
|
172
|
+
root_object.remove_referrer(self) if root_object
|
173
|
+
@root_object = new_from_plist(root_object_uuid, plist['objects'], self)
|
174
|
+
@archive_version = plist['archiveVersion']
|
175
|
+
@object_version = plist['objectVersion']
|
176
|
+
@classes = plist['classes']
|
177
|
+
|
178
|
+
unless root_object
|
179
|
+
raise "[Xcodeproj] Unable to find a root object in #{pbxproj_path}."
|
180
|
+
end
|
181
|
+
|
182
|
+
if (archive_version.to_i > Constants::LAST_KNOWN_ARCHIVE_VERSION)
|
183
|
+
raise '[Xcodeproj] Unknown archive version.'
|
184
|
+
end
|
185
|
+
|
186
|
+
if (object_version.to_i > Constants::LAST_KNOWN_OBJECT_VERSION)
|
187
|
+
raise '[Xcodeproj] Unknown object version.'
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
|
150
192
|
public
|
151
193
|
|
152
194
|
# @!group Plist serialization
|
195
|
+
#-------------------------------------------------------------------------#
|
153
196
|
|
154
197
|
# Creates a new object from the given UUID and `objects` hash (of a plist).
|
155
198
|
#
|
@@ -232,27 +275,32 @@ module Xcodeproj
|
|
232
275
|
{
|
233
276
|
'File References' => root_object.main_group.pretty_print.values.first,
|
234
277
|
'Targets' => root_object.targets.map(&:pretty_print),
|
235
|
-
'Build Configurations' => build_configurations.map(&:pretty_print)
|
278
|
+
'Build Configurations' => build_configurations.sort_by(&:name).map(&:pretty_print)
|
236
279
|
}
|
237
280
|
end
|
238
281
|
|
239
|
-
# Serializes the
|
240
|
-
# the given path (`xcodeproj` file).
|
282
|
+
# Serializes the project in the xcodeproj format using the path provided
|
283
|
+
# during initialization or the given path (`xcodeproj` file). If a path is
|
284
|
+
# provided file references depending on the root of the project are not
|
285
|
+
# updated automatically, thus clients are responsible to perform any needed
|
286
|
+
# modification before saving.
|
241
287
|
#
|
242
|
-
# @
|
243
|
-
#
|
288
|
+
# @param [String, Pathname] path
|
289
|
+
# The optional path where the project should be saved.
|
244
290
|
#
|
245
|
-
# @
|
246
|
-
#
|
291
|
+
# @example Saving a project
|
292
|
+
# project.save
|
293
|
+
# project.save
|
247
294
|
#
|
248
|
-
# @return [
|
295
|
+
# @return [void]
|
249
296
|
#
|
250
|
-
def
|
251
|
-
|
252
|
-
FileUtils.mkdir_p(
|
253
|
-
file = File.join(
|
297
|
+
def save(save_path = nil)
|
298
|
+
save_path ||= path
|
299
|
+
FileUtils.mkdir_p(save_path)
|
300
|
+
file = File.join(save_path, 'project.pbxproj')
|
254
301
|
Xcodeproj.write_plist(to_hash, file)
|
255
302
|
fix_encoding(file)
|
303
|
+
XCProjHelper.touch(save_path) unless disable_xcproj
|
256
304
|
end
|
257
305
|
|
258
306
|
# Simple workaround to escape characters which are outside of ASCII
|
@@ -298,12 +346,16 @@ module Xcodeproj
|
|
298
346
|
# attributes, for this reason it is better to use the convenience methods
|
299
347
|
# offered by the {AbstractObject} subclasses or by this class.
|
300
348
|
#
|
301
|
-
# @param [Class] klass
|
302
|
-
# The concrete subclass of AbstractObject for new object
|
349
|
+
# @param [Class, String] klass
|
350
|
+
# The concrete subclass of AbstractObject for new object or its
|
351
|
+
# ISA.
|
303
352
|
#
|
304
353
|
# @return [AbstractObject] the new object.
|
305
354
|
#
|
306
355
|
def new(klass)
|
356
|
+
if klass.is_a?(String)
|
357
|
+
klass = Object.const_get(klass)
|
358
|
+
end
|
307
359
|
object = klass.new(self, generate_uuid)
|
308
360
|
object.initialize_defaults
|
309
361
|
object
|
@@ -467,14 +519,14 @@ module Xcodeproj
|
|
467
519
|
|
468
520
|
# @!group Helpers for generating objects
|
469
521
|
|
470
|
-
# Creates a new file reference
|
522
|
+
# Creates a new file reference in the main group.
|
471
523
|
#
|
472
524
|
# @param @see PBXGroup#new_file
|
473
525
|
#
|
474
526
|
# @return [PBXFileReference] the new file.
|
475
527
|
#
|
476
|
-
def new_file(path,
|
477
|
-
main_group.new_file(path,
|
528
|
+
def new_file(path, source_tree = :group)
|
529
|
+
main_group.new_file(path, source_tree)
|
478
530
|
end
|
479
531
|
|
480
532
|
# Creates a new group at the given subpath of the main group.
|
@@ -483,14 +535,12 @@ module Xcodeproj
|
|
483
535
|
#
|
484
536
|
# @return [PBXGroup] the new group.
|
485
537
|
#
|
486
|
-
def new_group(name, path = nil)
|
487
|
-
main_group.new_group(name, path)
|
538
|
+
def new_group(name, path = nil, source_tree = :group)
|
539
|
+
main_group.new_group(name, path, source_tree)
|
488
540
|
end
|
489
541
|
|
490
|
-
# Adds a file reference for a system framework to the project
|
491
|
-
#
|
492
|
-
# The file reference can then be added to the build files of a
|
493
|
-
# {PBXFrameworksBuildPhase}.
|
542
|
+
# Adds a file reference for a system framework to the project if needed and
|
543
|
+
# adds it to the {PBXFrameworksBuildPhase} of the given target.
|
494
544
|
#
|
495
545
|
# @example Adding QuartzCore
|
496
546
|
#
|
@@ -504,12 +554,12 @@ module Xcodeproj
|
|
504
554
|
# The name of a framework.
|
505
555
|
#
|
506
556
|
# @param [PBXNativeTarget] target
|
507
|
-
# The target
|
557
|
+
# The target to which to add the framework.
|
508
558
|
#
|
509
559
|
# @note This method adds a reference to the highest know SDK for the
|
510
560
|
# given platform.
|
511
561
|
#
|
512
|
-
# @return [PBXFileReference] The
|
562
|
+
# @return [PBXFileReference] The file reference of the framework.
|
513
563
|
#
|
514
564
|
def add_system_framework(name, target)
|
515
565
|
ProjectHelper.add_system_framework(self, name, target)
|
@@ -564,6 +614,29 @@ module Xcodeproj
|
|
564
614
|
ProjectHelper.new_resources_bundle(self, name, platform, product_group)
|
565
615
|
end
|
566
616
|
|
617
|
+
# Adds a new build configuration to the project and populates its with
|
618
|
+
# default settings according to the provided type.
|
619
|
+
#
|
620
|
+
# @param [String] name
|
621
|
+
# The name of the build configuration.
|
622
|
+
#
|
623
|
+
# @param [Symbol] type
|
624
|
+
# The type of the build configuration used to populate the build
|
625
|
+
# settings, must be :debug or :release.
|
626
|
+
#
|
627
|
+
# @return [XCBuildConfiguration] The new build configuration.
|
628
|
+
#
|
629
|
+
def add_build_configuration(name, type)
|
630
|
+
build_configuration_list = root_object.build_configuration_list
|
631
|
+
unless build_configuration_list[name]
|
632
|
+
build_configuration = new(XCBuildConfiguration)
|
633
|
+
build_configuration.name = name
|
634
|
+
build_configuration.build_settings = Constants::PROJECT_DEFAULT_BUILD_SETTINGS[type].dup
|
635
|
+
build_configuration_list.build_configurations << build_configuration
|
636
|
+
build_configuration
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
567
640
|
#-------------------------------------------------------------------------#
|
568
641
|
# Get list of shared schemes in project
|
569
642
|
#
|
@@ -99,8 +99,19 @@ module Xcodeproj
|
|
99
99
|
# @return [void]
|
100
100
|
#
|
101
101
|
def remove_from_project
|
102
|
-
|
103
|
-
|
102
|
+
project.objects_by_uuid.delete(uuid)
|
103
|
+
referrers.each { |referrer| referrer.remove_reference(self) }
|
104
|
+
|
105
|
+
to_one_attributes.each do |attrb|
|
106
|
+
object = attrb.get_value(self)
|
107
|
+
object.remove_referrer(self) if object
|
108
|
+
end
|
109
|
+
|
110
|
+
to_many_attributes.each do |attrb|
|
111
|
+
list = attrb.get_value(self)
|
112
|
+
list.clear
|
113
|
+
end
|
114
|
+
|
104
115
|
raise "[Xcodeproj] BUG: #{self} should have no referrers instead the following objects are still referencing it #{referrers}" unless referrers.count == 0
|
105
116
|
end
|
106
117
|
|
@@ -391,8 +402,10 @@ module Xcodeproj
|
|
391
402
|
end
|
392
403
|
|
393
404
|
def inspect
|
394
|
-
|
395
|
-
"
|
405
|
+
optional = ''
|
406
|
+
optional << " name=`#{self.name}`" if respond_to?(:name) && self.name
|
407
|
+
optional << " path=`#{self.path}`" if respond_to?(:path) && self.path
|
408
|
+
"<#{self.isa}#{optional} UUID=`#{uuid}`>"
|
396
409
|
end
|
397
410
|
end
|
398
411
|
end
|