xcodeproj 1.16.0 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/xcodeproj/command/sort.rb +12 -1
  4. data/lib/xcodeproj/config.rb +12 -2
  5. data/lib/xcodeproj/config/other_linker_flags_parser.rb +5 -0
  6. data/lib/xcodeproj/constants.rb +62 -49
  7. data/lib/xcodeproj/gem_version.rb +1 -1
  8. data/lib/xcodeproj/project.rb +9 -6
  9. data/lib/xcodeproj/project/object/build_file.rb +3 -1
  10. data/lib/xcodeproj/project/object/build_phase.rb +10 -0
  11. data/lib/xcodeproj/project/object/group.rb +6 -6
  12. data/lib/xcodeproj/project/object/helpers/file_references_factory.rb +8 -6
  13. data/lib/xcodeproj/project/object/helpers/groupable_helper.rb +1 -1
  14. data/lib/xcodeproj/project/object/swift_package_product_dependency.rb +10 -0
  15. data/lib/xcodeproj/project/object/swift_package_remote_reference.rb +14 -0
  16. data/lib/xcodeproj/project/object/target_dependency.rb +1 -0
  17. data/lib/xcodeproj/project/project_helper.rb +6 -6
  18. data/lib/xcodeproj/scheme.rb +5 -1
  19. data/lib/xcodeproj/scheme/abstract_scheme_action.rb +72 -0
  20. data/lib/xcodeproj/scheme/build_action.rb +87 -1
  21. data/lib/xcodeproj/scheme/execution_action.rb +86 -0
  22. data/lib/xcodeproj/scheme/launch_action.rb +17 -2
  23. data/lib/xcodeproj/scheme/location_scenario_reference.rb +49 -0
  24. data/lib/xcodeproj/scheme/profile_action.rb +5 -5
  25. data/lib/xcodeproj/scheme/send_email_action_content.rb +84 -0
  26. data/lib/xcodeproj/scheme/shell_script_action_content.rb +77 -0
  27. data/lib/xcodeproj/scheme/test_action.rb +7 -3
  28. data/lib/xcodeproj/workspace.rb +3 -2
  29. data/lib/xcodeproj/workspace/file_reference.rb +1 -1
  30. metadata +26 -8
@@ -42,17 +42,19 @@ module Xcodeproj
42
42
  # @param [PBXGroup] group
43
43
  # The group to which to add the reference.
44
44
  #
45
- # @param [#to_s] product_name
45
+ # @param [#to_s] product_basename
46
46
  # The name of the static library.
47
47
  #
48
48
  # @return [PBXFileReference] The new file reference.
49
49
  #
50
- def new_product_ref_for_target(group, target_name, product_type)
50
+ def new_product_ref_for_target(group, product_basename, product_type)
51
51
  if product_type == :static_library
52
52
  prefix = 'lib'
53
53
  end
54
54
  extension = Constants::PRODUCT_UTI_EXTENSIONS[product_type]
55
- ref = new_reference(group, "#{prefix}#{target_name}.#{extension}", :built_products)
55
+ path = "#{prefix}#{product_basename}"
56
+ path += ".#{extension}" if extension
57
+ ref = new_reference(group, path, :built_products)
56
58
  ref.include_in_index = '0'
57
59
  ref.set_explicit_file_type
58
60
  ref
@@ -64,13 +66,13 @@ module Xcodeproj
64
66
  # @param [PBXGroup] group
65
67
  # The group to which to add the reference.
66
68
  #
67
- # @param [#to_s] product_name
69
+ # @param [#to_s] product_basename
68
70
  # The name of the bundle.
69
71
  #
70
72
  # @return [PBXFileReference] The new file reference.
71
73
  #
72
- def new_bundle(group, product_name)
73
- ref = new_reference(group, "#{product_name}.bundle", :built_products)
74
+ def new_bundle(group, product_basename)
75
+ ref = new_reference(group, "#{product_basename}.bundle", :built_products)
74
76
  ref.include_in_index = '0'
75
77
  ref.set_explicit_file_type('wrapper.cfbundle')
76
78
  ref
@@ -205,7 +205,7 @@ module Xcodeproj
205
205
  # @return [void]
206
206
  #
207
207
  def set_path_with_source_tree(object, path, source_tree)
208
- path = Pathname.new(path)
208
+ path = Pathname(path)
209
209
  source_tree = normalize_source_tree(source_tree)
210
210
  object.source_tree = source_tree
211
211
 
@@ -13,6 +13,16 @@ module Xcodeproj
13
13
  # @return [String] the product name of this Swift package.
14
14
  #
15
15
  attribute :product_name, String
16
+
17
+ # @!group AbstractObject Hooks
18
+ #--------------------------------------#
19
+
20
+ # @return [String] the name of the Swift package.
21
+ #
22
+ def display_name
23
+ return product_name if product_name
24
+ super
25
+ end
16
26
  end
17
27
  end
18
28
  end
@@ -13,6 +13,20 @@ module Xcodeproj
13
13
  # @return [Hash] the version requirements for this Swift package.
14
14
  #
15
15
  attribute :requirement, Hash
16
+
17
+ # @!group AbstractObject Hooks
18
+ #--------------------------------------#
19
+
20
+ def ascii_plist_annotation
21
+ " #{isa} \"#{File.basename(display_name)}\" "
22
+ end
23
+
24
+ # @return [String] the name of the Swift package repository.
25
+ #
26
+ def display_name
27
+ return repositoryURL if repositoryURL
28
+ super
29
+ end
16
30
  end
17
31
  end
18
32
  end
@@ -73,6 +73,7 @@ module Xcodeproj
73
73
  hash = {}
74
74
  hash['displayName'] = display_name
75
75
  hash['isa'] = isa
76
+ hash['targetProxy'] = target_proxy.to_tree_hash
76
77
  hash
77
78
  end
78
79
 
@@ -41,17 +41,17 @@ module Xcodeproj
41
41
  #
42
42
  # @return [PBXNativeTarget] the target.
43
43
  #
44
- def self.new_target(project, type, name, platform, deployment_target, product_group, language)
44
+ def self.new_target(project, type, name, platform, deployment_target, product_group, language, product_basename)
45
45
  # Target
46
46
  target = project.new(PBXNativeTarget)
47
47
  project.targets << target
48
48
  target.name = name
49
- target.product_name = name
49
+ target.product_name = product_basename
50
50
  target.product_type = Constants::PRODUCT_TYPE_UTI[type]
51
51
  target.build_configuration_list = configuration_list(project, platform, deployment_target, type, language)
52
52
 
53
53
  # Product
54
- product = product_group.new_product_ref_for_target(name, type)
54
+ product = product_group.new_product_ref_for_target(target.product_name, type)
55
55
  target.product_reference = product
56
56
 
57
57
  # Build phases
@@ -88,12 +88,12 @@ module Xcodeproj
88
88
  #
89
89
  # @return [PBXNativeTarget] the target.
90
90
  #
91
- def self.new_resources_bundle(project, name, platform, product_group)
91
+ def self.new_resources_bundle(project, name, platform, product_group, product_basename)
92
92
  # Target
93
93
  target = project.new(PBXNativeTarget)
94
94
  project.targets << target
95
95
  target.name = name
96
- target.product_name = name
96
+ target.product_name = product_basename
97
97
  target.product_type = Constants::PRODUCT_TYPE_UTI[:bundle]
98
98
 
99
99
  # Configuration List
@@ -111,7 +111,7 @@ module Xcodeproj
111
111
  target.build_configuration_list = cl
112
112
 
113
113
  # Product
114
- product = product_group.new_bundle(name)
114
+ product = product_group.new_bundle(target.product_name)
115
115
  target.product_reference = product
116
116
 
117
117
  # Build phases
@@ -9,8 +9,12 @@ require 'xcodeproj/scheme/archive_action'
9
9
 
10
10
  require 'xcodeproj/scheme/buildable_product_runnable'
11
11
  require 'xcodeproj/scheme/buildable_reference'
12
+ require 'xcodeproj/scheme/location_scenario_reference'
13
+ require 'xcodeproj/scheme/execution_action'
12
14
  require 'xcodeproj/scheme/macro_expansion'
13
15
  require 'xcodeproj/scheme/remote_runnable'
16
+ require 'xcodeproj/scheme/send_email_action_content'
17
+ require 'xcodeproj/scheme/shell_script_action_content'
14
18
 
15
19
  module Xcodeproj
16
20
  # This class represents a Scheme document represented by a ".xcscheme" file
@@ -221,7 +225,7 @@ module Xcodeproj
221
225
  launch_runnable = BuildableProductRunnable.new(build_target, 0)
222
226
  launch_action.buildable_product_runnable = launch_runnable
223
227
 
224
- profile_runnable = BuildableProductRunnable.new(build_target)
228
+ profile_runnable = BuildableProductRunnable.new(build_target, 0)
225
229
  profile_action.buildable_product_runnable = profile_runnable
226
230
 
227
231
  macro_exp = MacroExpansion.new(build_target)
@@ -23,6 +23,78 @@ module Xcodeproj
23
23
  def build_configuration=(config_name)
24
24
  @xml_element.attributes['buildConfiguration'] = config_name
25
25
  end
26
+
27
+ # @return [Array<ExecutionAction>]
28
+ # The list of actions to run before this scheme action.
29
+ # Each entry can be either a 'Run Script' or a 'Send Email' action.
30
+ #
31
+ def pre_actions
32
+ pre_actions = @xml_element.elements['PreActions']
33
+ return nil unless pre_actions
34
+ pre_actions.get_elements('ExecutionAction').map do |entry_node|
35
+ ExecutionAction.new(entry_node)
36
+ end
37
+ end
38
+
39
+ # @param [Array<ExecutionAction>] pre_actions
40
+ # Set the list of actions to run before this scheme action.
41
+ # Each entry can be either a 'Run Script' or a 'Send Email' action.
42
+ #
43
+ def pre_actions=(pre_actions)
44
+ @xml_element.delete_element('PreActions')
45
+ unless pre_actions.empty?
46
+ pre_actions_element = @xml_element.add_element('PreActions')
47
+ pre_actions.each do |entry_node|
48
+ pre_actions_element.add_element(entry_node.xml_element)
49
+ end
50
+ end
51
+ pre_actions
52
+ end
53
+
54
+ # @param [ExecutionAction] pre_action
55
+ # Add an action to the list of actions to run before this scheme action.
56
+ # It can be either a 'Run Script' or a 'Send Email' action.
57
+ #
58
+ def add_pre_action(pre_action)
59
+ pre_actions = @xml_element.elements['PreActions'] || @xml_element.add_element('PreActions')
60
+ pre_actions.add_element(pre_action.xml_element)
61
+ end
62
+
63
+ # @return [Array<ExecutionAction>]
64
+ # The list of actions to run after this scheme action.
65
+ # Each entry can be either a 'Run Script' or a 'Send Email' action.
66
+ #
67
+ def post_actions
68
+ post_actions = @xml_element.elements['PostActions']
69
+ return nil unless post_actions
70
+ post_actions.get_elements('ExecutionAction').map do |entry_node|
71
+ ExecutionAction.new(entry_node)
72
+ end
73
+ end
74
+
75
+ # @param [Array<ExecutionAction>] post_actions
76
+ # Set the list of actions to run after this scheme action.
77
+ # Each entry can be either a 'Run Script' or a 'Send Email' action.
78
+ #
79
+ def post_actions=(post_actions)
80
+ @xml_element.delete_element('PostActions')
81
+ unless post_actions.empty?
82
+ post_actions_element = @xml_element.add_element('PostActions')
83
+ post_actions.each do |entry_node|
84
+ post_actions_element.add_element(entry_node.xml_element)
85
+ end
86
+ end
87
+ post_actions
88
+ end
89
+
90
+ # @param [ExecutionAction] post_action
91
+ # Add an action to the list of actions to run after this scheme action.
92
+ # It can be either a 'Run Script' or a 'Send Email' action.
93
+ #
94
+ def add_post_action(post_action)
95
+ post_actions = @xml_element.elements['PostActions'] || @xml_element.add_element('PostActions')
96
+ post_actions.add_element(post_action.xml_element)
97
+ end
26
98
  end
27
99
  end
28
100
  end
@@ -19,6 +19,20 @@ module Xcodeproj
19
19
  end
20
20
  end
21
21
 
22
+ # @return [Bool]
23
+ # Whether or not to run post actions on build failure
24
+ #
25
+ def run_post_actions_on_failure?
26
+ string_to_bool(@xml_element.attributes['runPostActionsOnFailure'])
27
+ end
28
+
29
+ # @param [Bool] flag
30
+ # Set whether or not to run post actions on build failure
31
+ #
32
+ def run_post_actions_on_failure=(flag)
33
+ @xml_element.attributes['runPostActionsOnFailure'] = bool_to_string(flag)
34
+ end
35
+
22
36
  # @return [Bool]
23
37
  # Whether or not to build the various targets in parallel
24
38
  #
@@ -47,6 +61,78 @@ module Xcodeproj
47
61
  @xml_element.attributes['buildImplicitDependencies'] = bool_to_string(flag)
48
62
  end
49
63
 
64
+ # @return [Array<ExecutionAction>]
65
+ # The list of actions to run before this scheme action.
66
+ # Each entry can be either a 'Run Script' or a 'Send Email' action.
67
+ #
68
+ def pre_actions
69
+ pre_actions = @xml_element.elements['PreActions']
70
+ return nil unless pre_actions
71
+ pre_actions.get_elements('ExecutionAction').map do |entry_node|
72
+ ExecutionAction.new(entry_node)
73
+ end
74
+ end
75
+
76
+ # @param [Array<ExecutionAction>] pre_actions
77
+ # Set the list of actions to run before this scheme action.
78
+ # Each entry can be either a 'Run Script' or a 'Send Email' action.
79
+ #
80
+ def pre_actions=(pre_actions)
81
+ @xml_element.delete_element('PreActions')
82
+ unless pre_actions.empty?
83
+ pre_actions_element = @xml_element.add_element('PreActions')
84
+ pre_actions.each do |entry_node|
85
+ pre_actions_element.add_element(entry_node.xml_element)
86
+ end
87
+ end
88
+ pre_actions
89
+ end
90
+
91
+ # @param [ExecutionAction] pre_action
92
+ # Add an action to the list of actions to run before this scheme action.
93
+ # It can be either a 'Run Script' or a 'Send Email' action.
94
+ #
95
+ def add_pre_action(pre_action)
96
+ pre_actions = @xml_element.elements['PreActions'] || @xml_element.add_element('PreActions')
97
+ pre_actions.add_element(pre_action.xml_element)
98
+ end
99
+
100
+ # @return [Array<ExecutionAction>]
101
+ # The list of actions to run after this scheme action.
102
+ # Each entry can be either a 'Run Script' or a 'Send Email' action.
103
+ #
104
+ def post_actions
105
+ post_actions = @xml_element.elements['PostActions']
106
+ return nil unless post_actions
107
+ post_actions.get_elements('ExecutionAction').map do |entry_node|
108
+ ExecutionAction.new(entry_node)
109
+ end
110
+ end
111
+
112
+ # @param [Array<ExecutionAction>] post_actions
113
+ # Set the list of actions to run after this scheme action.
114
+ # Each entry can be either a 'Run Script' or a 'Send Email' action.
115
+ #
116
+ def post_actions=(post_actions)
117
+ @xml_element.delete_element('PostActions')
118
+ unless post_actions.empty?
119
+ post_actions_element = @xml_element.add_element('PostActions')
120
+ post_actions.each do |entry_node|
121
+ post_actions_element.add_element(entry_node.xml_element)
122
+ end
123
+ end
124
+ post_actions
125
+ end
126
+
127
+ # @param [ExecutionAction] post_action
128
+ # Add an action to the list of actions to run after this scheme action.
129
+ # It can be either a 'Run Script' or a 'Send Email' action.
130
+ #
131
+ def add_post_action(post_action)
132
+ post_actions = @xml_element.elements['PostActions'] || @xml_element.add_element('PostActions')
133
+ post_actions.add_element(post_action.xml_element)
134
+ end
135
+
50
136
  # @return [Array<BuildAction::Entry>]
51
137
  # The list of BuildActionEntry nodes associated with this Build Action.
52
138
  # Each entry represent a target to build and tells for which action it's needed to be built.
@@ -103,11 +189,11 @@ module Xcodeproj
103
189
  is_app_target = app_types.include?(target_or_node.product_type)
104
190
  end
105
191
 
106
- self.build_for_analyzing = true
107
192
  self.build_for_testing = is_test_target
108
193
  self.build_for_running = is_app_target
109
194
  self.build_for_profiling = is_app_target
110
195
  self.build_for_archiving = is_app_target
196
+ self.build_for_analyzing = true
111
197
 
112
198
  add_buildable_reference BuildableReference.new(target_or_node) if target_or_node
113
199
  end
@@ -0,0 +1,86 @@
1
+ module Xcodeproj
2
+ class XCScheme
3
+ # This class wraps the ExecutionAction node of a .xcscheme XML file
4
+ #
5
+ class ExecutionAction < XMLElementWrapper
6
+ # @param [REXML::Element] node
7
+ # The 'ExecutionAction' XML node that this object will wrap.
8
+ # If nil, will create an empty one
9
+ #
10
+ # @param [Symbol] action_type
11
+ # One of `EXECUTION_ACTION_TYPE.keys`
12
+ #
13
+ def initialize(node = nil, action_type = nil)
14
+ create_xml_element_with_fallback(node, 'ExecutionAction') do
15
+ type = action_type || node.action_type
16
+ raise "[Xcodeproj] Invalid ActionType `#{type}`" unless Constants::EXECUTION_ACTION_TYPE.keys.include?(type)
17
+ @xml_element.attributes['ActionType'] = Constants::EXECUTION_ACTION_TYPE[type]
18
+ end
19
+ end
20
+
21
+ # @return [String]
22
+ # The ActionType of this ExecutionAction. One of two values:
23
+ #
24
+ # Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction,
25
+ # Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.SendEmailAction
26
+ #
27
+ def action_type
28
+ @xml_element.attributes['ActionType']
29
+ end
30
+
31
+ # @return [ShellScriptActionContent]
32
+ # If action_type is 'Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction'
33
+ # returns the contents of the shell script to run pre/post action.
34
+ #
35
+ # @return [SendEmailActionContent]
36
+ # If action_type is 'Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.SendEmailAction'
37
+ # returns the contents of the email to send pre/post action.
38
+ #
39
+ def action_content
40
+ case action_type
41
+ when Constants::EXECUTION_ACTION_TYPE[:shell_script]
42
+ ShellScriptActionContent.new(@xml_element.elements['ActionContent'])
43
+ when Constants::EXECUTION_ACTION_TYPE[:send_email]
44
+ SendEmailActionContent.new(@xml_element.elements['ActionContent'])
45
+ else
46
+ raise "[Xcodeproj] Invalid ActionType `#{action_type}`"
47
+ end
48
+ end
49
+
50
+ # @param [ShellScriptActionContent, SendEmailActionContent] value
51
+ # Set either the contents of the shell script to run pre/post action
52
+ # or the contents of the email to send pre/post action.
53
+ #
54
+ def action_content=(value)
55
+ raise "[Xcodeproj] Invalid ActionContent `#{value.class}` for " \
56
+ "ActionType `#{action_type}`" unless valid_action_content?(value)
57
+
58
+ @xml_element.delete_element('ActionContent')
59
+ @xml_element.add_element(value.xml_element)
60
+ end
61
+
62
+ #-------------------------------------------------------------------------#
63
+
64
+ private
65
+
66
+ # @!group Private helpers
67
+
68
+ # @return [Bool]
69
+ # True if value (ActionContent) is valid for current action_type
70
+ #
71
+ # @param [ShellScriptActionContent, SendEmailActionContent] value
72
+ # Checks if value matches the expected action_type if present.
73
+ #
74
+ def valid_action_content?(value)
75
+ case action_type
76
+ when Constants::EXECUTION_ACTION_TYPE[:shell_script]
77
+ value.is_a?(ShellScriptActionContent)
78
+ when Constants::EXECUTION_ACTION_TYPE[:send_email]
79
+ value.is_a?(SendEmailActionContent)
80
+ else
81
+ false
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -11,6 +11,8 @@ module Xcodeproj
11
11
  #
12
12
  def initialize(node = nil)
13
13
  create_xml_element_with_fallback(node, 'LaunchAction') do
14
+ self.build_configuration = 'Debug'
15
+
14
16
  # Add some attributes (that are not handled by this wrapper class yet but expected in the XML)
15
17
  @xml_element.attributes['selectedDebuggerIdentifier'] = 'Xcode.DebuggerFoundation.Debugger.LLDB'
16
18
  @xml_element.attributes['selectedLauncherIdentifier'] = 'Xcode.DebuggerFoundation.Launcher.LLDB'
@@ -19,10 +21,8 @@ module Xcodeproj
19
21
  @xml_element.attributes['ignoresPersistentStateOnLaunch'] = bool_to_string(false)
20
22
  @xml_element.attributes['debugDocumentVersioning'] = bool_to_string(true)
21
23
  @xml_element.attributes['debugServiceExtension'] = 'internal'
22
- @xml_element.add_element('AdditionalOptions')
23
24
 
24
25
  # Setup default values for other (handled) attributes
25
- self.build_configuration = 'Debug'
26
26
  self.allow_location_simulation = true
27
27
  end
28
28
  end
@@ -47,6 +47,21 @@ module Xcodeproj
47
47
  @xml_element.attributes['allowLocationSimulation'] = bool_to_string(flag)
48
48
  end
49
49
 
50
+ # @return [LocationScenarioReference]
51
+ # The LocationScenarioReference to simulate a GPS location when executing the Launch Action
52
+ #
53
+ def location_scenario_reference?
54
+ LocationScenarioReference.new(@xml_element.elements['LocationScenarioReference'])
55
+ end
56
+
57
+ # @return [LocationScenarioReference]
58
+ # Set the LocationScenarioReference which simulates a GPS location when executing the Launch Action
59
+ #
60
+ def location_scenario_reference=(reference)
61
+ @xml_element.delete_element('LocationScenarioReference')
62
+ @xml_element.add_element(reference.xml_element) if reference
63
+ end
64
+
50
65
  # @return [Bool]
51
66
  # Whether this Build Action should disable detection of UI API misuse
52
67
  # from background threads