xcodeproj 0.28.2 → 1.0.0.beta.1

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: eae456c17889ae1b3dc65acb3e95122776f584f5
4
- data.tar.gz: 30e4ee588cfccff194ad57520a64737e2bf7434e
3
+ metadata.gz: 55e5e01727aa2cef3b7bc6e1682340c8b795adfd
4
+ data.tar.gz: df9be60720e81d807f9206ef7e1aac6bbf2f47f2
5
5
  SHA512:
6
- metadata.gz: e149c929d82e0593c8accbbdedd4bb6a23405b976aefcfb551d50381aada69b8b39725240ff4c34f99918c3aaa57c178cc939dae69537eb04516e1cb0ea5d3d9
7
- data.tar.gz: 82e272ca562aae5487bd0ef985e411f1576a55b1e6056a3dd6b4434e88f5700632e236e06b98acad5d6af8acc8c292e3bca7d1c5a756a24a06bf79910e1934be
6
+ metadata.gz: e26720ad177f765056a554e514a9c4465aa94b4619fbd8947e0a221704926f8df605e8cc9a1a46c97e87dd4574023834e169144df4d0f4dce5e01460cfd937af
7
+ data.tar.gz: 72832c119af852d63ae64df30ebda2f7cb5090c83b57684b07b1cb57f3cd3686850c292dd2d66ece72c8ca3960ac54db87885aff33c0f60ea41df37e65da85fb
data/lib/xcodeproj.rb CHANGED
@@ -20,7 +20,7 @@ module Xcodeproj
20
20
  autoload :Constants, 'xcodeproj/constants'
21
21
  autoload :Differ, 'xcodeproj/differ'
22
22
  autoload :Helper, 'xcodeproj/helper'
23
- autoload :PlistHelper, 'xcodeproj/plist_helper'
23
+ autoload :Plist, 'xcodeproj/plist'
24
24
  autoload :Project, 'xcodeproj/project'
25
25
  autoload :Workspace, 'xcodeproj/workspace'
26
26
  autoload :XCScheme, 'xcodeproj/scheme'
@@ -23,7 +23,7 @@ module Xcodeproj
23
23
 
24
24
  def initialize(argv)
25
25
  self.xcodeproj_path = argv.shift_argument
26
- @output_path = Pathname(argv.shift_argument || '.')
26
+ @output_path = Pathname(argv.shift_argument || '.')
27
27
 
28
28
  super
29
29
  end
@@ -82,7 +82,7 @@ module Xcodeproj
82
82
  def to_s(prefix = nil)
83
83
  include_lines = includes.map { |path| "#include \"#{normalized_xcconfig_path(path)}\"" }
84
84
  settings = to_hash(prefix).sort_by(&:first).map { |k, v| "#{k} = #{v}".strip }
85
- [include_lines + settings].join("\n")
85
+ (include_lines + settings).join("\n") << "\n"
86
86
  end
87
87
 
88
88
  # Writes the serialized representation of the internal data to the given
@@ -275,9 +275,17 @@ module Xcodeproj
275
275
  #
276
276
  def merge_attributes!(attributes)
277
277
  @attributes.merge!(attributes) do |_, v1, v2|
278
- v1, v2 = v1.strip, v2.strip
279
- existing = v1.strip.shellsplit
280
- existing.include?(v2) ? v1 : "#{v1} #{v2}"
278
+ v1 = v1.strip
279
+ v2 = v2.strip
280
+ v1_split = v1.shellsplit
281
+ v2_split = v2.shellsplit
282
+ if (v2_split - v1_split).empty? || v1_split.first(v2_split.size) == v2_split
283
+ v1
284
+ elsif v2_split.first(v1_split.size) == v1_split
285
+ v2
286
+ else
287
+ "#{v1} #{v2}"
288
+ end
281
289
  end
282
290
  end
283
291
 
@@ -317,7 +325,8 @@ module Xcodeproj
317
325
  def extract_key_value(line)
318
326
  match = line.match(KEY_VALUE_PATTERN)
319
327
  if match
320
- key, value = match[1], match[2]
328
+ key = match[1]
329
+ value = match[2]
321
330
  [key.strip, value.strip]
322
331
  else
323
332
  []
@@ -8,7 +8,7 @@ module Xcodeproj
8
8
  # @return [Hash{Symbol, Array[String]}] Splits the given
9
9
  # other linker flags value by type.
10
10
  #
11
- # @param [String] flags
11
+ # @param [String, Array] flags
12
12
  # The other linker flags value.
13
13
  #
14
14
  def self.parse(flags)
@@ -21,7 +21,10 @@ module Xcodeproj
21
21
  }
22
22
 
23
23
  key = nil
24
- split(flags).each do |token|
24
+ if flags.is_a? String
25
+ flags = split(flags)
26
+ end
27
+ flags.each do |token|
25
28
  case token
26
29
  when '-framework'
27
30
  key = :frameworks
@@ -4,17 +4,17 @@ module Xcodeproj
4
4
  module Constants
5
5
  # @return [String] The last known iOS SDK (stable).
6
6
  #
7
- LAST_KNOWN_IOS_SDK = '9.0'
7
+ LAST_KNOWN_IOS_SDK = '9.2'
8
8
 
9
9
  # @return [String] The last known OS X SDK (stable).
10
10
  #
11
- LAST_KNOWN_OSX_SDK = '10.11'
11
+ LAST_KNOWN_OSX_SDK = '10.11'
12
12
 
13
- # @return [String] The last known tvOS SDK (unstable).
14
- LAST_KNOWN_TVOS_SDK = '9.0'
13
+ # @return [String] The last known tvOS SDK (stable).
14
+ LAST_KNOWN_TVOS_SDK = '9.1'
15
15
 
16
- # @return [String] The last known watchOS SDK.
17
- LAST_KNOWN_WATCHOS_SDK = '2.0'
16
+ # @return [String] The last known watchOS SDK (stable).
17
+ LAST_KNOWN_WATCHOS_SDK = '2.1'
18
18
 
19
19
  # @return [String] The last known archive version to Xcodeproj.
20
20
  #
@@ -25,15 +25,15 @@ module Xcodeproj
25
25
 
26
26
  # @return [String] The last known object version to Xcodeproj.
27
27
  #
28
- LAST_KNOWN_OBJECT_VERSION = 47
28
+ LAST_KNOWN_OBJECT_VERSION = 47
29
29
 
30
30
  # @return [String] The last known object version to Xcodeproj.
31
31
  #
32
- LAST_UPGRADE_CHECK = '0700'
32
+ LAST_UPGRADE_CHECK = '0700'
33
33
 
34
34
  # @return [String] The last known object version to Xcodeproj.
35
35
  #
36
- LAST_SWIFT_UPGRADE_CHECK = '0700'
36
+ LAST_SWIFT_UPGRADE_CHECK = '0720'
37
37
 
38
38
  # @return [String] The version of `.xcscheme` files supported by Xcodeproj
39
39
  #
@@ -119,6 +119,7 @@ module Xcodeproj
119
119
  :watch2_app => 'com.apple.product-type.application.watchapp2',
120
120
  :watch_extension => 'com.apple.product-type.watchkit-extension',
121
121
  :watch2_extension => 'com.apple.product-type.watchkit2-extension',
122
+ :tv_extension => 'com.apple.product-type.tv-app-extension',
122
123
  }.freeze
123
124
 
124
125
  # @return [Hash] The extensions or the various product UTIs.
@@ -138,13 +139,16 @@ module Xcodeproj
138
139
  #
139
140
  COMMON_BUILD_SETTINGS = {
140
141
  :all => {
141
- 'PRODUCT_NAME' => '$(TARGET_NAME)',
142
142
  'ENABLE_STRICT_OBJC_MSGSEND' => 'YES',
143
+ 'GCC_NO_COMMON_BLOCKS' => 'YES',
144
+ 'PRODUCT_NAME' => '$(TARGET_NAME)',
143
145
  }.freeze,
144
146
  [:debug] => {
147
+ 'DEBUG_INFORMATION_FORMAT' => 'dwarf',
145
148
  'MTL_ENABLE_DEBUG_INFO' => 'YES',
146
149
  }.freeze,
147
150
  [:release] => {
151
+ 'DEBUG_INFORMATION_FORMAT' => 'dwarf-with-dsym',
148
152
  'MTL_ENABLE_DEBUG_INFO' => 'NO',
149
153
  }.freeze,
150
154
  [:ios] => {
@@ -163,23 +167,18 @@ module Xcodeproj
163
167
  # Empty?
164
168
  }.freeze,
165
169
  [:release, :osx] => {
166
- 'DEBUG_INFORMATION_FORMAT' => 'dwarf-with-dsym',
170
+ # Empty?
167
171
  }.freeze,
168
172
  [:debug, :ios] => {
169
173
  # Empty?
170
174
  }.freeze,
171
175
  [:debug, :application, :swift] => {
172
176
  'SWIFT_OPTIMIZATION_LEVEL' => '-Onone',
173
- 'ENABLE_TESTABILITY' => 'YES',
174
177
  }.freeze,
175
- [:debug, :dynamic_library, :swift] => {
176
- 'ENABLE_TESTABILITY' => 'YES',
177
- }.freeze,
178
- [:debug, :framework, :swift] => {
179
- 'ENABLE_TESTABILITY' => 'YES',
178
+ [:debug, :swift] => {
179
+ 'SWIFT_OPTIMIZATION_LEVEL' => '-Onone',
180
180
  }.freeze,
181
181
  [:debug, :static_library, :swift] => {
182
- 'ENABLE_TESTABILITY' => 'YES',
183
182
  }.freeze,
184
183
  [:framework] => {
185
184
  'VERSION_INFO_PREFIX' => '',
@@ -200,25 +199,43 @@ module Xcodeproj
200
199
  [:osx, :framework] => {
201
200
  'LD_RUNPATH_SEARCH_PATHS' => ['$(inherited)', '@executable_path/../Frameworks', '@loader_path/Frameworks'],
202
201
  'FRAMEWORK_VERSION' => 'A',
202
+ 'CODE_SIGN_IDENTITY' => '-',
203
203
  'COMBINE_HIDPI_IMAGES' => 'YES',
204
204
  }.freeze,
205
+ [:watchos, :framework] => {
206
+ 'APPLICATION_EXTENSION_API_ONLY' => 'YES',
207
+ 'LD_RUNPATH_SEARCH_PATHS' => ['$(inherited)', '@executable_path/Frameworks', '@loader_path/Frameworks'],
208
+ 'TARGETED_DEVICE_FAMILY' => '4',
209
+ }.freeze,
210
+ [:tvos, :framework] => {
211
+ 'LD_RUNPATH_SEARCH_PATHS' => ['$(inherited)', '@executable_path/Frameworks', '@loader_path/Frameworks'],
212
+ 'TARGETED_DEVICE_FAMILY' => '3',
213
+ }.freeze,
205
214
  [:framework, :swift] => {
206
215
  'DEFINES_MODULE' => 'YES',
207
216
  }.freeze,
208
- [:debug, :framework, :swift] => {
209
- 'SWIFT_OPTIMIZATION_LEVEL' => '-Onone',
210
- }.freeze,
211
217
  [:osx, :static_library] => {
218
+ 'CODE_SIGN_IDENTITY' => '-',
212
219
  'EXECUTABLE_PREFIX' => 'lib',
213
220
  }.freeze,
214
221
  [:ios, :static_library] => {
222
+ 'CODE_SIGN_IDENTITY[sdk=iphoneos*]' => 'iPhone Developer',
223
+ 'OTHER_LDFLAGS' => '-ObjC',
224
+ 'SKIP_INSTALL' => 'YES',
225
+ }.freeze,
226
+ [:watchos, :static_library] => {
227
+ 'OTHER_LDFLAGS' => '-ObjC',
228
+ 'SKIP_INSTALL' => 'YES',
229
+ }.freeze,
230
+ [:tvos, :static_library] => {
215
231
  'OTHER_LDFLAGS' => '-ObjC',
216
232
  'SKIP_INSTALL' => 'YES',
217
233
  }.freeze,
218
234
  [:osx, :dynamic_library] => {
219
- 'EXECUTABLE_PREFIX' => 'lib',
235
+ 'CODE_SIGN_IDENTITY' => '-',
220
236
  'DYLIB_COMPATIBILITY_VERSION' => '1',
221
237
  'DYLIB_CURRENT_VERSION' => '1',
238
+ 'EXECUTABLE_PREFIX' => 'lib',
222
239
  }.freeze,
223
240
  [:application] => {
224
241
  'ASSETCATALOG_COMPILER_APPICON_NAME' => 'AppIcon',
@@ -226,12 +243,26 @@ module Xcodeproj
226
243
  [:ios, :application] => {
227
244
  'CODE_SIGN_IDENTITY[sdk=iphoneos*]' => 'iPhone Developer',
228
245
  'LD_RUNPATH_SEARCH_PATHS' => ['$(inherited)', '@executable_path/Frameworks'],
246
+ 'TARGETED_DEVICE_FAMILY' => '1,2',
229
247
  }.freeze,
230
248
  [:osx, :application] => {
231
249
  'COMBINE_HIDPI_IMAGES' => 'YES',
232
250
  'CODE_SIGN_IDENTITY' => '-',
233
251
  'LD_RUNPATH_SEARCH_PATHS' => ['$(inherited)', '@executable_path/../Frameworks'],
234
252
  }.freeze,
253
+ [:watchos, :application] => {
254
+ 'SKIP_INSTALL' => 'YES',
255
+ 'TARGETED_DEVICE_FAMILY' => '4',
256
+ }.freeze,
257
+ [:watchos, :application, :swift] => {
258
+ 'EMBEDDED_CONTENT_CONTAINS_SWIFT' => 'YES',
259
+ }.freeze,
260
+ [:tvos, :application] => {
261
+ 'ASSETCATALOG_COMPILER_APPICON_NAME' => 'App Icon & Top Shelf Image',
262
+ 'ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME' => 'LaunchImage',
263
+ 'TARGETED_DEVICE_FAMILY' => '3',
264
+ 'LD_RUNPATH_SEARCH_PATHS' => ['$(inherited)', '@executable_path/Frameworks'],
265
+ }.freeze,
235
266
  [:bundle] => {
236
267
  'PRODUCT_NAME' => '$(TARGET_NAME)',
237
268
  'WRAPPER_EXTENSION' => 'bundle',
@@ -241,9 +272,10 @@ module Xcodeproj
241
272
  'SDKROOT' => 'iphoneos',
242
273
  }.freeze,
243
274
  [:osx, :bundle] => {
275
+ 'CODE_SIGN_IDENTITY' => '-',
244
276
  'COMBINE_HIDPI_IMAGES' => 'YES',
245
- 'SDKROOT' => 'macosx',
246
277
  'INSTALL_PATH' => '$(LOCAL_LIBRARY_DIR)/Bundles',
278
+ 'SDKROOT' => 'macosx',
247
279
  }.freeze,
248
280
  }.freeze
249
281
 
@@ -281,6 +313,7 @@ module Xcodeproj
281
313
  :debug => {
282
314
  'ONLY_ACTIVE_ARCH' => 'YES',
283
315
  'COPY_PHASE_STRIP' => 'NO',
316
+ 'ENABLE_TESTABILITY' => 'YES',
284
317
  'GCC_DYNAMIC_NO_PIC' => 'NO',
285
318
  'GCC_OPTIMIZATION_LEVEL' => '0',
286
319
  'GCC_PREPROCESSOR_DEFINITIONS' => ['DEBUG=1', '$(inherited)'],
@@ -313,6 +346,6 @@ module Xcodeproj
313
346
 
314
347
  # @return [Array] The extensions which are associated with header files.
315
348
  #
316
- HEADER_FILES_EXTENSIONS = %w(.h .hh .hpp .ipp .tpp).freeze
349
+ HEADER_FILES_EXTENSIONS = %w(.h .hh .hpp .ipp .tpp .hxx .def).freeze
317
350
  end
318
351
  end
@@ -43,8 +43,8 @@ module Xcodeproj
43
43
  # @return [Nil] if the given values are equal.
44
44
  #
45
45
  def self.diff(value_1, value_2, options = {})
46
- options[:key_1] ||= 'value_1'
47
- options[:key_2] ||= 'value_2'
46
+ options[:key_1] ||= 'value_1'
47
+ options[:key_2] ||= 'value_2'
48
48
  options[:id_key] ||= nil
49
49
 
50
50
  if value_1.class == value_2.class
@@ -1,5 +1,5 @@
1
1
  module Xcodeproj
2
2
  # The version of the xcodeproj gem.
3
3
  #
4
- VERSION = '0.28.2' unless defined? Xcodeproj::VERSION
4
+ VERSION = '1.0.0.beta.1'.freeze unless defined? Xcodeproj::VERSION
5
5
  end
@@ -0,0 +1,89 @@
1
+ module Xcodeproj
2
+ # Provides support for loading and serializing property list files.
3
+ #
4
+ module Plist
5
+ autoload :FFI, 'xcodeproj/plist/ffi'
6
+ autoload :PlistGem, 'xcodeproj/plist/plist_gem'
7
+
8
+ # @return [Hash] Returns the native objects loaded from a property list
9
+ # file.
10
+ #
11
+ # @param [#to_s] path
12
+ # The path of the file.
13
+ #
14
+ def self.read_from_path(path)
15
+ path = path.to_s
16
+ unless File.exist?(path)
17
+ raise Informative, "The plist file at path `#{path}` doesn't exist."
18
+ end
19
+ if file_in_conflict?(path)
20
+ raise Informative, "The file `#{path}` is in a merge conflict."
21
+ end
22
+ implementation.read_from_path(path)
23
+ end
24
+
25
+ # Serializes a hash as an XML property list file.
26
+ #
27
+ # @param [#to_hash] hash
28
+ # The hash to store.
29
+ #
30
+ # @param [#to_s] path
31
+ # The path of the file.
32
+ #
33
+ def self.write_to_path(hash, path)
34
+ if hash.respond_to?(:to_hash)
35
+ hash = hash.to_hash
36
+ else
37
+ raise TypeError, "The given `#{hash.inspect}` must respond " \
38
+ "to #to_hash'."
39
+ end
40
+
41
+ unless path.is_a?(String) || path.is_a?(Pathname)
42
+ raise TypeError, "The given `#{path}` must be a string or 'pathname'."
43
+ end
44
+ path = path.to_s
45
+ raise IOError, 'Empty path.' if path.empty?
46
+ implementation.write_to_path(hash, path)
47
+ end
48
+
49
+ # The known modules that can serialize plists.
50
+ #
51
+ KNOWN_IMPLEMENTATIONS = [:FFI, :PlistGem]
52
+
53
+ class << self
54
+ # @return The module used to implement plist serialization.
55
+ #
56
+ attr_accessor :implementation
57
+ def implementation
58
+ @implementation ||= autoload_implementation
59
+ end
60
+ end
61
+
62
+ # Attempts to autoload a known plist implementation.
63
+ #
64
+ # @return a successfully loaded plist serialization implementation.
65
+ #
66
+ def self.autoload_implementation
67
+ failures = KNOWN_IMPLEMENTATIONS.map do |impl|
68
+ begin
69
+ impl = Plist.const_get(impl)
70
+ failure = impl.attempt_to_load!
71
+ return impl if failure.nil?
72
+ failure
73
+ rescue NameError, LoadError => e
74
+ e.message
75
+ end
76
+ end.compact
77
+ raise Informative, "Unable to load a plist implementation:\n\n#{failures.join("\n\n")}"
78
+ end
79
+
80
+ # @return [Bool] Checks whether there are merge conflicts in the file.
81
+ #
82
+ # @param [#to_s] path
83
+ # The path of the file.
84
+ #
85
+ def self.file_in_conflict?(path)
86
+ File.read(path).match(/^(<|=|>){7}/)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,119 @@
1
+ module Xcodeproj
2
+ module Plist
3
+ # Provides support for loading and serializing property list files via
4
+ # Fiddle and CoreFoundation / Xcode.
5
+ #
6
+ module FFI
7
+ autoload :CoreFoundation, 'xcodeproj/plist/ffi/core_foundation'
8
+ autoload :DevToolsCore, 'xcodeproj/plist/ffi/dev_tools_core'
9
+
10
+ class << self
11
+ # Attempts to load the `fiddle` and Xcode based plist serializer.
12
+ #
13
+ # @return [String,Nil] The loading error message, or `nil` if loading
14
+ # was successful.
15
+ #
16
+ def attempt_to_load!
17
+ return @attempt_to_load if defined?(@attempt_to_load)
18
+ @attempt_to_load = begin
19
+ require 'fiddle'
20
+ nil
21
+ rescue LoadError
22
+ 'Xcodeproj relies on a library called `fiddle` to read and write ' \
23
+ 'Xcode project files. Ensure your Ruby installation includes ' \
24
+ '`fiddle` and try again.'
25
+ end
26
+ end
27
+
28
+ # Serializes a hash as an XML property list file.
29
+ #
30
+ # @param [#to_hash] hash
31
+ # The hash to store.
32
+ #
33
+ # @param [#to_s] path
34
+ # The path of the file.
35
+ #
36
+ def write_to_path(hash, path)
37
+ raise ThreadError, 'Can only write plists from the main thread.' unless Thread.current == Thread.main
38
+
39
+ if DevToolsCore.load_xcode_frameworks && path.end_with?('pbxproj')
40
+ ruby_hash_write_xcode(hash, path)
41
+ else
42
+ CoreFoundation.RubyHashPropertyListWrite(hash, path)
43
+ fix_encoding(path)
44
+ end
45
+ end
46
+
47
+ # @return [Hash] Returns the native objects loaded from a property list
48
+ # file.
49
+ #
50
+ # @param [#to_s] path
51
+ # The path of the file.
52
+ #
53
+ def read_from_path(path)
54
+ CoreFoundation.RubyHashPropertyListRead(path)
55
+ end
56
+
57
+ private
58
+
59
+ # Simple workaround to escape characters which are outside of ASCII
60
+ # character-encoding. Relies on the fact that there are no XML characters
61
+ # which would need to be escaped.
62
+ #
63
+ # @note This is necessary because Xcode (4.6 currently) uses the MacRoman
64
+ # encoding unless the `// !$*UTF8*$!` magic comment is present. It
65
+ # is not possible to serialize a plist using the NeXTSTEP format
66
+ # without access to the private classes of Xcode and that comment
67
+ # is not compatible with the XML format. For the complete
68
+ # discussion see CocoaPods/CocoaPods#926.
69
+ #
70
+ #
71
+ # @note Sadly this hack is not sufficient for supporting Emoji.
72
+ #
73
+ # @param [String, Pathname] The path of the file which needs to be fixed.
74
+ #
75
+ # @return [void]
76
+ #
77
+ def fix_encoding(filename)
78
+ output = ''
79
+ input = File.open(filename, 'rb', &:read)
80
+ input.unpack('U*').each do |codepoint|
81
+ if codepoint > 127 # ASCII is 7-bit, so 0-127 are valid characters
82
+ output << "&##{codepoint};"
83
+ else
84
+ output << codepoint.chr
85
+ end
86
+ end
87
+ File.open(filename, 'wb') { |file| file.write(output) }
88
+ end
89
+
90
+ # Serializes a hash as an ASCII plist, using Xcode.
91
+ #
92
+ # @param [Hash] hash
93
+ # The hash to store.
94
+ #
95
+ # @param [String] path
96
+ # The path of the file.
97
+ #
98
+ def ruby_hash_write_xcode(hash, path)
99
+ path = File.expand_path(path)
100
+ success = true
101
+
102
+ begin
103
+ plist = DevToolsCore::CFDictionary.new(CoreFoundation.RubyHashToCFDictionary(hash))
104
+ data = DevToolsCore::NSData.new(plist.plistDescriptionUTF8Data)
105
+ success &= data.writeToFileAtomically(path)
106
+
107
+ project = DevToolsCore::PBXProject.new(path)
108
+ success &= project.writeToFileSystemProjectFile
109
+ project.close
110
+ rescue Fiddle::DLError
111
+ success = false
112
+ end
113
+
114
+ CoreFoundation.RubyHashPropertyListWrite(hash, path) unless success
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end