class Viperaptor::XcodeprojHelper
Provides a number of helper methods for working with xcodeproj gem
Public Class Methods
Adds a provided file to a specific Project and Target @param project [Xcodeproj::Project] The target xcodeproj file @param targets_name [String] Array of targets name @param group_path [Pathname] The Xcode group path for current file @param dir_path [Pathname] The directory path for current file @param file_group_path [String] Directory path @param file_name [String] Current file name @param file_is_resource [TrueClass or FalseClass] If true then file is resource
@return [void]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 22 def self.add_file_to_project_and_targets(project, targets_name, group_path, dir_path, file_group_path, file_name, file_is_resource = false) file_path = dir_path file_path = file_path.join(file_group_path) if file_group_path file_path = file_path.join(file_name) if file_name module_group = self.retrieve_group_or_create_if_needed(group_path, dir_path, file_group_path, project, true) xcode_file = module_group.new_file(File.absolute_path(file_path)) targets_name.each do |target| xcode_target = obtain_target(target, project) if file_is_resource || self.is_bundle_resource?(file_name) xcode_target.add_resources([xcode_file]) elsif self.is_compile_source?(file_name) xcode_target.add_file_references([xcode_file]) end end end
Adds a provided directory to a specific Project @param project [Xcodeproj::Project] The target xcodeproj file @param group_path [Pathname] The Xcode group path for current directory @param dir_path [Pathname] The directory path for current directory @param directory_name [String] Current directory name
@return [void]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 48 def self.add_group_to_project(project, group_path, dir_path, directory_name) self.retrieve_group_or_create_if_needed(group_path, dir_path, directory_name, project, true) end
Recursively clears children of the given group @param project [Xcodeproj::Project] The working Xcode project file @param group_path [Pathname] The full group path
@return [Void]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 73 def self.clear_group(project, targets_name, group_path) module_group = self.retrieve_group_or_create_if_needed(group_path, nil, nil, project, false) return unless module_group files_path = self.files_path_from_group(module_group, project) return unless files_path files_path.each do |file_path| self.remove_file_by_file_path(file_path, targets_name, project) end module_group.clear end
File is a resource @param resource_name [String] String
of resource name
@return [TrueClass or FalseClass]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 64 def self.is_bundle_resource?(resource_name) File.extname(resource_name) == '.xib' || File.extname(resource_name) == '.storyboard' end
File is a compiled source @param file_name [String] String
of file name
@return [TrueClass or FalseClass]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 56 def self.is_compile_source?(file_name) File.extname(file_name) == '.m' || File.extname(file_name) == '.swift' || File.extname(file_name) == '.mm' end
Finds a group in a xcodeproj file with a given path @param project [Xcodeproj::Project] The working Xcode project file @param group_path [Pathname] The full group path
@return [TrueClass or FalseClass]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 92 def self.module_with_group_path_already_exists(project, group_path) module_group = self.retrieve_group_or_create_if_needed(group_path, nil, nil, project, false) module_group.nil? ? false : true end
Returns a PBXProject class for a given name @param project_name [String] The name of the project file
@return [Xcodeproj::Project]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 8 def self.obtain_project(project_name) Xcodeproj::Project.open(project_name) end
Private Class Methods
Find and return target build phases @param targets_name [String] Array of targets @param project [Xcodeproj::Project] The target xcodeproj file
@return [[PBXSourcesBuildPhase]]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 196 def self.build_phases_from_targets(targets_name, project) build_phases = [] targets_name.each do |target_name| xcode_target = self.obtain_target(target_name, project) xcode_target.build_phases.each do |build_phase| if build_phase.isa == 'PBXSourcesBuildPhase' build_phases.push(build_phase) end end end build_phases end
Get configure file full path @param file_ref [PBXFileReference] Build file
@return [String]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 231 def self.configure_file_ref_path(file_ref) build_file_ref_path = file_ref.hierarchy_path.to_s build_file_ref_path[0] = '' build_file_ref_path end
Get all files path from group path @param module_group [PBXGroup] The module group @param project [Xcodeproj::Project] The target xcodeproj file
@return [[String]]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 243 def self.files_path_from_group(module_group, _project) files_path = [] module_group.recursive_children.each do |file_ref| if file_ref.isa == 'PBXFileReference' file_ref_path = configure_file_ref_path(file_ref) files_path.push(file_ref_path) end end files_path end
Returns an AbstractTarget class for a given name @param target_name [String] The name of the target @param project [Xcodeproj::Project] The target xcodeproj file
@return [Xcodeproj::AbstractTarget]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 138 def self.obtain_target(target_name, project) project.targets.each do |target| return target if target.name == target_name end error_description = "Cannot find a target with name #{target_name} in Xcode project".red raise StandardError, error_description end
Splits the provided Xcode path to an array of separate paths @param path The full group or file path
@return [[String]]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 151 def self.path_names_from_path(path) path.to_s.split('/') end
Remove build file from target build phase @param file_path [String] The path of the file @param targets_name [String] Array of targets @param project [Xcodeproj::Project] The target xcodeproj file
@return [Void]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 161 def self.remove_file_by_file_path(file_path, targets_name, project) file_names = path_names_from_path(file_path) build_phases = nil if self.is_compile_source?(file_names.last) build_phases = self.build_phases_from_targets(targets_name, project) elsif self.is_bundle_resource?(file_names.last) build_phases = self.resources_build_phase_from_targets(targets_name, project) end self.remove_file_from_build_phases(file_path, build_phases) end
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 175 def self.remove_file_from_build_phases(file_path, build_phases) return if build_phases.nil? build_phases.each do |build_phase| build_phase.files.each do |build_file| next if build_file.nil? || build_file.file_ref.nil? build_file_path = self.configure_file_ref_path(build_file.file_ref) if build_file_path == file_path build_phase.remove_build_file(build_file) end end end end
Find and return target resources build phase @param targets_name [String] Array of targets @param project [Xcodeproj::Project] The target xcodeproj file
@return [[PBXResourcesBuildPhase]]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 216 def self.resources_build_phase_from_targets(targets_name, project) resource_build_phase = [] targets_name.each do |target_name| xcode_target = self.obtain_target(target_name, project) resource_build_phase.push(xcode_target.resources_build_phase) end resource_build_phase end
Finds or creates a group in a xcodeproj file with a given path @param group_path [Pathname] The Xcode group path for module @param dir_path [Pathname] The directory path for module @param file_group_path [String] Directory path @param project [Xcodeproj::Project] The working Xcode project file @param create_group_if_not_exists [TrueClass or FalseClass] If true nonexistent group will be created
@return [PBXGroup]
# File lib/viperaptor/helpers/xcodeproj_helper.rb, line 107 def self.retrieve_group_or_create_if_needed(group_path, dir_path, file_group_path, project, create_group_if_not_exists) group_names = path_names_from_path(group_path) group_components_count = group_names.count group_names += path_names_from_path(file_group_path) if file_group_path final_group = project group_names.each_with_index do |group_name, index| next_group = final_group[group_name] unless next_group return nil unless create_group_if_not_exists if group_path != dir_path && index == group_components_count-1 next_group = final_group.new_group(group_name, dir_path, :project) else next_group = final_group.new_group(group_name, group_name) end end final_group = next_group end final_group end