xcodeproj 1.8.0 → 1.8.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dd5a8807aed9829a9a1e355790100434f4df1fd7
4
- data.tar.gz: 15e7c38281fb55f32e2a473e1badf6d806d9063e
3
+ metadata.gz: 160de31d624d01bb10824d3d9b06f0154828e769
4
+ data.tar.gz: f692cb98d2e7ad4b34e344c2c8b4f995c5843bf4
5
5
  SHA512:
6
- metadata.gz: ae80f793ecc1635660a7802304547540c9a1e3eb2e8b54a0572acfa8eb3c3069edd3c0302360393041da28026eb77bbf3a5f3e263f72c040ce0c149fb621c2c4
7
- data.tar.gz: 531fa9d52e9be2918b113f6603f7d5382ff00eb707de7cc34b70ed956c65f759420292cb4552611d839ad8bb6031d028c4bc91fc1ac3894ee46e40bf6b3a86fb
6
+ metadata.gz: c85b6c33b61408e2597410292b3fcc3591b7feb6061c5cd3dcf3b950ca8e54d9ca936e1e633b4bd028dd289c9ec5b64f2a9a4c34a21dce299d9dd1e9fcd7dcd3
7
+ data.tar.gz: 4bae982841ee95c3a2de0200210c46c9226d54f999e1a21366701fe19176ceca450c269548cd7c386642ef8581473005aff617171c7f86faf02ba8b26f5d252d
@@ -1,5 +1,5 @@
1
1
  module Xcodeproj
2
2
  # The version of the xcodeproj gem.
3
3
  #
4
- VERSION = '1.8.0'.freeze unless defined? Xcodeproj::VERSION
4
+ VERSION = '1.8.1'.freeze unless defined? Xcodeproj::VERSION
5
5
  end
@@ -85,15 +85,21 @@ module Xcodeproj
85
85
  #
86
86
  def resolve_build_setting(key, root_target = nil)
87
87
  setting = build_settings[key]
88
- setting = resolve_variable_substitution(key, setting, root_target) if setting.is_a?(String)
88
+ setting = resolve_variable_substitution(key, setting, root_target)
89
+
89
90
  config_setting = base_configuration_reference && config[key]
90
- config_setting = resolve_variable_substitution(key, config_setting, root_target) if config_setting.is_a?(String)
91
+ config_setting = resolve_variable_substitution(key, config_setting, root_target)
91
92
 
92
93
  project_setting = project.build_configuration_list[name]
93
- project_setting = nil if project_setting == self
94
+ project_setting = nil if equal?(project_setting)
94
95
  project_setting &&= project_setting.resolve_build_setting(key, root_target)
95
96
 
96
- [project_setting, config_setting, setting, ENV[key]].compact.reduce do |inherited, value|
97
+ defaults = {
98
+ 'CONFIGURATION' => name,
99
+ 'SRCROOT' => project.project_dir.to_s,
100
+ }
101
+
102
+ [defaults[key], project_setting, config_setting, setting, ENV[key]].compact.reduce(nil) do |inherited, value|
97
103
  expand_build_setting(value, inherited)
98
104
  end
99
105
  end
@@ -102,15 +108,25 @@ module Xcodeproj
102
108
 
103
109
  private
104
110
 
111
+ VARIABLE_NAME_PATTERN =
112
+ '( # capture block
113
+ [_a-zA-Z0-9]+? # non-greedy lookup for everything contained in this list
114
+ )'.freeze
115
+ private_constant :VARIABLE_NAME_PATTERN
116
+
105
117
  CAPTURE_VARIABLE_IN_BUILD_CONFIG = /
106
118
  \$ # matches dollar sign literally
107
- [{(] # matches a single caracter on this list
108
- ( # capture block
109
- [^inherited] # ignore if match characters in this list
110
- [$(){}_a-zA-Z0-9]*? # non-greedy lookup for everything that contains this list
111
- )
112
- [})] # matches a single caracter on this list
119
+ (?: # non-capturing group
120
+ [{] # matches a single character on this list
121
+ #{VARIABLE_NAME_PATTERN}
122
+ [}] # matches a single character on this list
123
+ | # or
124
+ [(] # matches a single character on this list
125
+ #{VARIABLE_NAME_PATTERN}
126
+ [)] # matches a single character on this list
127
+ )
113
128
  /x
129
+ private_constant :CAPTURE_VARIABLE_IN_BUILD_CONFIG
114
130
 
115
131
  def expand_build_setting(build_setting_value, config_value)
116
132
  if build_setting_value.is_a?(Array) && config_value.is_a?(String)
@@ -127,23 +143,37 @@ module Xcodeproj
127
143
  end
128
144
 
129
145
  def resolve_variable_substitution(key, value, root_target)
130
- variable = match_variable(value)
131
- return nil if key.eql?(variable)
132
- if variable.nil?
133
- return name if value.eql?('CONFIGURATION')
134
- if root_target
135
- return root_target.build_configuration_list[name].resolve_build_setting(value, root_target) || value
136
- else
137
- return resolve_build_setting(value, root_target) || value
138
- end
146
+ case value
147
+ when Array
148
+ return value.map { |v| resolve_variable_substitution(key, v, root_target) }
149
+ when nil
150
+ return
151
+ when String
152
+ # we know how to resolve strings!
153
+ nil
154
+ else
155
+ raise ArgumentError, "Settings values can only be nil, string, or array, got #{value.inspect} for #{key}"
139
156
  end
140
- resolve_variable_substitution(key, value.sub(CAPTURE_VARIABLE_IN_BUILD_CONFIG, resolve_variable_substitution(key, variable, root_target)), root_target)
141
- end
142
157
 
143
- def match_variable(config_setting)
144
- match_data = config_setting.match(CAPTURE_VARIABLE_IN_BUILD_CONFIG)
145
- return match_data.captures.first unless match_data.nil?
146
- match_data
158
+ unless variable_match_data = value.match(CAPTURE_VARIABLE_IN_BUILD_CONFIG)
159
+ # no variables left, return the value unchanged
160
+ return value
161
+ end
162
+ variable_reference, variable = *variable_match_data.values_at(0, 1, 2).compact
163
+
164
+ case variable
165
+ when 'inherited'
166
+ # this is handled separately, after resolving all other variable references
167
+ value
168
+ when key
169
+ # to prevent infinite recursion
170
+ nil
171
+ else
172
+ configuration_to_resolve_against = root_target ? root_target.build_configuration_list[name] : self
173
+ resolved_value_for_variable = configuration_to_resolve_against.resolve_build_setting(variable, root_target) || ''
174
+ value = value.gsub(variable_reference, resolved_value_for_variable)
175
+ resolve_variable_substitution(key, value, root_target)
176
+ end
147
177
  end
148
178
 
149
179
  def sorted_build_settings
@@ -98,7 +98,7 @@ module Xcodeproj
98
98
  #
99
99
  def real_path(object)
100
100
  source_tree = source_tree_real_path(object)
101
- path = object.path || ''
101
+ path = object.path || ''.freeze
102
102
  if source_tree
103
103
  source_tree + path
104
104
  else
@@ -115,11 +115,16 @@ module Xcodeproj
115
115
  def full_path(object)
116
116
  folder = case object.source_tree
117
117
  when '<group>'
118
- parent(object).isa != 'PBXProject' ? full_path(parent(object)) : nil
118
+ object_parent = parent(object)
119
+ if object_parent.isa == 'PBXProject'.freeze
120
+ nil
121
+ else
122
+ full_path(object_parent)
123
+ end
119
124
  when 'SOURCE_ROOT'
120
125
  nil
121
126
  when '<absolute>'
122
- Pathname.new('/')
127
+ Pathname.new('/'.freeze)
123
128
  else
124
129
  Pathname.new("${#{object.source_tree}}")
125
130
  end
@@ -140,10 +145,11 @@ module Xcodeproj
140
145
  def source_tree_real_path(object)
141
146
  case object.source_tree
142
147
  when '<group>'
143
- if parent(object).isa == 'PBXProject'
148
+ object_parent = parent(object)
149
+ if object_parent.isa == 'PBXProject'.freeze
144
150
  object.project.project_dir
145
151
  else
146
- real_path(parent(object))
152
+ real_path(object_parent)
147
153
  end
148
154
  when 'SOURCE_ROOT'
149
155
  object.project.project_dir
@@ -31,7 +31,9 @@ module Xcodeproj
31
31
  def initialize(file_path = nil)
32
32
  if file_path
33
33
  @file_path = file_path
34
- @doc = REXML::Document.new(File.new(file_path))
34
+ @doc = File.open(file_path, 'r') do |f|
35
+ REXML::Document.new(f)
36
+ end
35
37
  @doc.context[:attribute_quote] = :quote
36
38
 
37
39
  @scheme = @doc.elements['Scheme']
@@ -59,10 +59,12 @@ module Xcodeproj
59
59
  # If true, buildable_name will also be updated by computing a name from the target
60
60
  #
61
61
  def set_reference_target(target, override_buildable_name = false, root_project = nil)
62
+ # note, the order of assignment here is important, it determines the order of serialization in the xml
63
+ # this matches the order that Xcode generates
62
64
  @xml_element.attributes['BlueprintIdentifier'] = target.uuid
65
+ self.buildable_name = construct_buildable_name(target) if override_buildable_name
63
66
  @xml_element.attributes['BlueprintName'] = target.name
64
67
  @xml_element.attributes['ReferencedContainer'] = construct_referenced_container_uri(target, root_project)
65
- self.buildable_name = construct_buildable_name(target) if override_buildable_name
66
68
  end
67
69
 
68
70
  # @return [String]
@@ -64,7 +64,7 @@ module Xcodeproj
64
64
  #
65
65
  def self.new_from_xcworkspace(path)
66
66
  from_s(File.read(File.join(path, 'contents.xcworkspacedata')),
67
- File.expand_path(File.dirname(path)))
67
+ File.expand_path(path))
68
68
  rescue Errno::ENOENT
69
69
  new(nil)
70
70
  end
@@ -191,8 +191,14 @@ module Xcodeproj
191
191
  # @return [void]
192
192
  #
193
193
  def load_schemes(workspace_dir_path)
194
+ # Normalizes path to directory of workspace needed for file_reference.absolute_path
195
+ workspaces_dir = workspace_dir_path
196
+ if File.extname(workspace_dir_path) == '.xcworkspace'
197
+ workspaces_dir = File.expand_path('..', workspaces_dir)
198
+ end
199
+
194
200
  file_references.each do |file_reference|
195
- project_full_path = file_reference.absolute_path(workspace_dir_path)
201
+ project_full_path = file_reference.absolute_path(workspaces_dir)
196
202
  load_schemes_from_project(project_full_path)
197
203
  end
198
204
 
@@ -1,22 +1,14 @@
1
+ require 'xcodeproj/workspace/reference'
2
+
1
3
  module Xcodeproj
2
4
  class Workspace
3
5
  # Describes a file reference of a Workspace.
4
6
  #
5
- class FileReference
7
+ class FileReference < Reference
6
8
  # @return [String] the path to the project
7
9
  #
8
10
  attr_reader :path
9
11
 
10
- # @return [String] the type of reference to the project
11
- #
12
- # This can be of the following values:
13
- # - absolute
14
- # - group
15
- # - container
16
- # - developer (unsupported)
17
- #
18
- attr_reader :type
19
-
20
12
  # @param [#to_s] path @see path
21
13
  # @param [#to_s] type @see type
22
14
  #
@@ -47,20 +39,10 @@ module Xcodeproj
47
39
  #
48
40
  def self.from_node(xml_node)
49
41
  type, path = xml_node.attribute('location').value.split(':', 2)
50
- path = prepend_parent_path(xml_node, path)
51
- new(path, type)
52
- end
53
-
54
- def self.prepend_parent_path(xml_node, path)
55
- if !xml_node.parent.nil? && (xml_node.parent.name == 'Group')
56
- group = GroupReference.from_node(xml_node.parent)
57
- if !group.location.nil? && !group.location.empty?
58
- path = '' if path.nil?
59
- path = File.join(group.location, path)
60
- end
42
+ if type == 'group'
43
+ path = prepend_parent_path(xml_node, path)
61
44
  end
62
-
63
- path
45
+ new(path, type)
64
46
  end
65
47
 
66
48
  # @return [REXML::Element] the XML representation of the file reference.
@@ -1,22 +1,14 @@
1
+ require 'xcodeproj/workspace/reference'
2
+
1
3
  module Xcodeproj
2
4
  class Workspace
3
5
  # Describes a group reference of a Workspace.
4
6
  #
5
- class GroupReference
7
+ class GroupReference < Reference
6
8
  # @return [String] the name of the group
7
9
  #
8
10
  attr_reader :name
9
11
 
10
- # @return [String] the type of reference to the project
11
- #
12
- # This can be of the following values:
13
- # - absolute
14
- # - group
15
- # - container (only supported value)
16
- # - developer
17
- #
18
- attr_reader :type
19
-
20
12
  # @return [String] the location of the group on disk
21
13
  #
22
14
  attr_reader :location
@@ -55,6 +47,9 @@ module Xcodeproj
55
47
  location_array = xml_node.attribute('location').value.split(':', 2)
56
48
  type = location_array.first
57
49
  location = location_array[1] || ''
50
+ if type == 'group'
51
+ location = prepend_parent_path(xml_node, location)
52
+ end
58
53
  name = xml_node.attribute('name').value
59
54
  new(name, type, location)
60
55
  end
@@ -0,0 +1,40 @@
1
+ module Xcodeproj
2
+ class Workspace
3
+ # Describes a file/group reference of a Workspace.
4
+ #
5
+ class Reference
6
+ # @return [String] the type of reference to the project
7
+ #
8
+ # This can be of the following values:
9
+ # - absolute
10
+ # - group
11
+ # - container
12
+ # - developer (unsupported)
13
+ #
14
+ attr_reader :type
15
+
16
+ # Returns the relative path to the parent group reference (if one exists)
17
+ # prepended to the passed in path.
18
+ #
19
+ # @param [REXML::Element] xml_node
20
+ # the XML representation.
21
+ #
22
+ # @param [String] path
23
+ # the path that will be prepended to.
24
+ #
25
+ # @return [String] the extended path including the parent node's path.
26
+ #
27
+ def self.prepend_parent_path(xml_node, path)
28
+ if !xml_node.parent.nil? && (xml_node.parent.name == 'Group')
29
+ group = GroupReference.from_node(xml_node.parent)
30
+ if !group.location.nil? && !group.location.empty?
31
+ path = '' if path.nil?
32
+ path = File.join(group.location, path)
33
+ end
34
+ end
35
+
36
+ path
37
+ end
38
+ end
39
+ end
40
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcodeproj
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eloy Duran
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-25 00:00:00.000000000 Z
11
+ date: 2019-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: atomos
@@ -160,6 +160,7 @@ files:
160
160
  - lib/xcodeproj/workspace.rb
161
161
  - lib/xcodeproj/workspace/file_reference.rb
162
162
  - lib/xcodeproj/workspace/group_reference.rb
163
+ - lib/xcodeproj/workspace/reference.rb
163
164
  - lib/xcodeproj/xcodebuild_helper.rb
164
165
  homepage: https://github.com/cocoapods/xcodeproj
165
166
  licenses: