Class: Xcodeproj::Workspace

Inherits:
Object
  • Object
show all
Defined in:
lib/xcodeproj/workspace.rb,
lib/xcodeproj/workspace/reference.rb,
lib/xcodeproj/workspace/file_reference.rb,
lib/xcodeproj/workspace/group_reference.rb

Overview

Provides support for generating, reading and serializing Xcode Workspace documents.

Defined Under Namespace

Classes: FileReference, GroupReference, Reference

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document, *file_references) ⇒ Workspace

Note:

The document parameter is passed to the << operator if it is not a valid REXML::Document. It is optional, but may also be passed as nil

Returns a new instance of Workspace.

Parameters:

  • document (REXML::Document)

    @see document

  • file_references (Array<FileReference>)

    additional projects to add


43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/xcodeproj/workspace.rb', line 43

def initialize(document, *file_references)
  @schemes = {}
  if document.nil?
    @document = REXML::Document.new(root_xml(''))
  elsif document.is_a?(REXML::Document)
    @document = document
  else
    @document = REXML::Document.new(root_xml(''))
    self << document
  end
  file_references.each { |ref| self << ref }
end

Instance Attribute Details

#documentREXML::Document (readonly)

Returns the parsed XML model for the workspace contents.

Returns:

  • (REXML::Document)

    the parsed XML model for the workspace contents


12
13
14
# File 'lib/xcodeproj/workspace.rb', line 12

def document
  @document
end

#schemesHash<String => String> (readonly)

Returns a mapping from scheme name to project full path containing the scheme.

Returns:

  • (Hash<String => String>)

    a mapping from scheme name to project full path containing the scheme


16
17
18
# File 'lib/xcodeproj/workspace.rb', line 16

def schemes
  @schemes
end

Class Method Details

.from_s(xml, workspace_path = '') ⇒ Workspace

Returns a workspace generated by reading the contents of the given XML representation.

Parameters:

  • xml (String)

    the XML representation of the workspace.

Returns:


82
83
84
85
86
87
# File 'lib/xcodeproj/workspace.rb', line 82

def self.from_s(xml, workspace_path = '')
  document = REXML::Document.new(xml)
  instance = new(document)
  instance.load_schemes(workspace_path)
  instance
end

.new_from_xcworkspace(path) ⇒ Workspace

Returns a workspace generated by reading the contents of the given path.

Parameters:

  • path (String)

    the path of the `xcworkspace` file.

Returns:


65
66
67
68
69
70
# File 'lib/xcodeproj/workspace.rb', line 65

def self.new_from_xcworkspace(path)
  from_s(File.read(File.join(path, 'contents.xcworkspacedata')),
         File.expand_path(path))
rescue Errno::ENOENT
  new(nil)
end

Instance Method Details

#<<(path_or_reference) ⇒ void

This method returns an undefined value.

Adds a new path to the list of the of projects contained in the workspace.

Parameters:

Raises:

  • (ArgumentError)

    Raised if the input is neither a String nor a FileReference


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/xcodeproj/workspace.rb', line 98

def <<(path_or_reference)
  return unless @document && @document.respond_to?(:root)

  case path_or_reference
  when String
    project_file_reference = Xcodeproj::Workspace::FileReference.new(path_or_reference)
  when Xcodeproj::Workspace::FileReference
    project_file_reference = path_or_reference
    projpath = nil
  else
    raise ArgumentError, "Input to the << operator must be a file path or FileReference, got #{path_or_reference.inspect}"
  end
  unless file_references.any? { |ref| project_file_reference.eql? ref }
    @document.root.add_element(project_file_reference.to_node)
  end
  load_schemes_from_project File.expand_path(projpath || project_file_reference.path)
end

#add_group(name) {|Xcodeproj::Workspace::GroupReference, REXML::Element| ... } ⇒ Xcodeproj::Workspace::GroupReference

Adds a new group container to the workspace workspace.

Parameters:

  • name (String)

    The name of the group

Yields:

Returns:


128
129
130
131
132
133
134
# File 'lib/xcodeproj/workspace.rb', line 128

def add_group(name)
  return nil unless @document
  group = Xcodeproj::Workspace::GroupReference.new(name)
  elem = @document.root.add_element(group.to_node)
  yield group, elem if block_given?
  group
end

#file_referencesArray<FileReference>

Returns the paths of the projects contained in the workspace.

Returns:

  • (Array<FileReference>)

    the paths of the projects contained in the workspace.


21
22
23
24
25
26
# File 'lib/xcodeproj/workspace.rb', line 21

def file_references
  return [] unless @document
  @document.get_elements('/Workspace//FileRef').map do |node|
    FileReference.from_node(node)
  end
end

#group_referencesArray<GroupReference>

Returns the groups contained in the workspace.

Returns:


30
31
32
33
34
35
# File 'lib/xcodeproj/workspace.rb', line 30

def group_references
  return [] unless @document
  @document.get_elements('/Workspace//Group').map do |node|
    GroupReference.from_node(node)
  end
end

#include?(file_reference) ⇒ Boolean

Checks if the workspace contains the project with the given file reference.

Parameters:

  • file_reference (FileReference)

    The file_reference to the project.

Returns:

  • (Boolean)

    whether the project is contained in the workspace.


144
145
146
# File 'lib/xcodeproj/workspace.rb', line 144

def include?(file_reference)
  file_references.include?(file_reference)
end

#load_schemes(workspace_dir_path) ⇒ void

This method returns an undefined value.

Load all schemes from all projects in workspace or in the workspace container itself

Parameters:

  • workspace_dir_path (String)

    path of workspaces dir


196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/xcodeproj/workspace.rb', line 196

def load_schemes(workspace_dir_path)
  # Normalizes path to directory of workspace needed for file_reference.absolute_path
  workspaces_dir = workspace_dir_path
  if File.extname(workspace_dir_path) == '.xcworkspace'
    workspaces_dir = File.expand_path('..', workspaces_dir)
  end

  file_references.each do |file_reference|
    project_full_path = file_reference.absolute_path(workspaces_dir)
    load_schemes_from_project(project_full_path)
  end

  # Load schemes that are in the workspace container.
  workspace_abs_path = File.absolute_path(workspace_dir_path)
  Dir[File.join(workspace_dir_path, 'xcshareddata', 'xcschemes', '*.xcscheme')].each do |scheme|
    scheme_name = File.basename(scheme, '.xcscheme')
    @schemes[scheme_name] = workspace_abs_path
  end
end

#save_as(path) ⇒ void

This method returns an undefined value.

Saves the workspace at the given `xcworkspace` path.

Parameters:

  • path (String)

    the path where to save the project.


180
181
182
183
184
185
# File 'lib/xcodeproj/workspace.rb', line 180

def save_as(path)
  FileUtils.mkdir_p(path)
  File.open(File.join(path, 'contents.xcworkspacedata'), 'w') do |out|
    out << to_s
  end
end

#to_sString

Returns the XML representation of the workspace.

Returns:

  • (String)

    the XML representation of the workspace.


150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/xcodeproj/workspace.rb', line 150

def to_s
  contents = ''
  stack = []
  @document.root.each_recursive do |elem|
    until stack.empty?
      last = stack.last
      break if last == elem.parent
      contents += xcworkspace_element_end_xml(stack.length, last)
      stack.pop
    end

    stack << elem
    contents += xcworkspace_element_start_xml(stack.length, elem)
  end

  until stack.empty?
    contents += xcworkspace_element_end_xml(stack.length, stack.last)
    stack.pop
  end

  root_xml(contents)
end