class Stronglyboards::Stronglyboards
Constants
- BUILD_SCRIPT_NAME
Public Instance Methods
install(project_file)
click to toggle source
# File lib/stronglyboards.rb, line 24 def install(project_file) lock_file = LockFile.new(project_file) if lock_file.exists? puts 'It appears that Stronglyboards has already been installed on this project.' exit end puts "Installing Stronglyboards into #{project_file}" # Open the existing Xcode project project = Xcodeproj::Project.open(project_file) # Do main processing process(project, options) # Finalise installation lock_file.update(options) project.save end
uninstall(project_file)
click to toggle source
# File lib/stronglyboards.rb, line 57 def uninstall(project_file) lock_file = require_lock_file(project_file) configuration = lock_file.contents base_output_file = configuration[:output] language = configuration[:language] prefix = configuration[:prefix] puts "Uninstalling Stronglyboards from #{project_file}" files_to_delete = Array.new # Open the Xcode project project = Xcodeproj::Project.open(project_file) project_root = project.path.dirname # Gather the targets that we're interested in targets = interesting_targets(project) targets.each do |target| # Find and delete the build script phase for this target target.build_phases.select { |phase| phase.is_a? Xcodeproj::Project::PBXShellScriptBuildPhase and phase.name == BUILD_SCRIPT_NAME }.each { |phase| target.build_phases.delete(phase) } # Get a source generator for this target output_file = base_output_file_for_target(base_output_file, target, prefix) source_generator = source_generator(language, prefix, output_file) # Gather the files that would have been generated for this target. # Bare in mind that this target may have been created since the # last time the install or update command ran, so there may be # files in this list that don't actually exist. files_to_delete << source_generator.output_files end # Expand the paths of the files to be deleted to be absolute files_to_delete.flatten!.uniq! paths_to_delete = files_to_delete.collect do |file| project_root + file.file.path end # Look through each target to see if this file is a member, # removing it from the source build phase if necessary. # TODO: There's got to be a better way, question asked. # http://stackoverflow.com/questions/32908231/how-to-get-the-targets-for-a-pbxfilereference-in-xcodeproj targets.each do |target| target.source_build_phase.files.each do |build_file| full_path = build_file.file_ref.real_path if paths_to_delete.include?(full_path) # Need to get a reference to the underlying file reference # as it will be removed when the build file is removed # from the target's build phase. file = build_file.file_ref # Remove the file from the build phase, project, and file system target.source_build_phase.remove_build_file(build_file) file.remove_from_project File.delete(full_path) end end end # Iterate through the files to delete to get rid of any non-source files files_to_delete.each do |file| unless file.is_source full_path = File.realpath(file.file) file_ref = project.reference_for_path(full_path) file_ref.remove_from_project File.delete(full_path) end end project.save # Finally delete the lock file lock_file.delete end
update(project_file)
click to toggle source
# File lib/stronglyboards.rb, line 45 def update(project_file) configuration = require_lock_file(project_file).contents puts "Updating Stronglyboards in #{project_file}" # Open the Xcode project project = Xcodeproj::Project.open(project_file) process(project, configuration) end
Private Instance Methods
add_build_script(project, target)
click to toggle source
# File lib/stronglyboards.rb, line 217 def add_build_script(project, target) puts 'Adding build script' phase = project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase) phase.name = BUILD_SCRIPT_NAME phase.shell_script = 'stronglyboards update ${PROJECT_NAME}' target.build_phases.insert(0, phase) end
add_files_to_target(project, target, output_files)
click to toggle source
# File lib/stronglyboards.rb, line 203 def add_files_to_target(project, target, output_files) puts "Adding files to target \"#{target}\"" output_files.each do |output_file| # Insert the file into the root group in the project file_reference = project.new_file(output_file.file) # Add the file to the target to ensure it is compiled target.source_build_phase.add_file_reference(file_reference) if output_file.is_source end end
base_output_file_for_target(base_file, target, prefix)
click to toggle source
# File lib/stronglyboards.rb, line 195 def base_output_file_for_target(base_file, target, prefix) if base_file == nil base_file = prefix + 'Stronglyboards' end base_file + "_#{target.name}" end
interesting_targets(project)
click to toggle source
# File lib/stronglyboards.rb, line 190 def interesting_targets(project) project.native_targets.select { |target| target.product_type == 'com.apple.product-type.application' } end
process(project, options)
click to toggle source
—- End external interface —-
# File lib/stronglyboards.rb, line 142 def process(project, options) base_output_file = options[:output] language = options[:language] prefix = options[:prefix] interesting_targets(project).each do |target| # Provide a default output filename output_file = base_output_file_for_target(base_output_file, target, prefix) # Instantiate a source generator appropriate for the selected language source_generator = source_generator(language, prefix, output_file) # Iterate the target's resource files looking for storyboards target.resources_build_phase.files.each do |build_file| next unless build_file.display_name.end_with? Storyboard::EXTENSION file_or_group = build_file.file_ref if file_or_group.is_a? Xcodeproj::Project::Object::PBXFileReference # Getting the real path is sufficient for non-localized storyboards # as it will return the absolute path to the .storyboard path = file_or_group.real_path elsif file_or_group.is_a? Xcodeproj::Project::Object::PBXVariantGroup # Localized storyboards will be a group and will # need the path constructing from the Base storyboard. base_storyboard_file = file_or_group.children.find { |f| f.name == 'Base' } if base_storyboard_file == nil puts "No Base storyboard found for #{file_or_group}!!!" next end path = base_storyboard_file.real_path end storyboard = Storyboard.new(path) source_generator.add_storyboard(storyboard) end # end project file iterator output_files = source_generator.parse_storyboards # Add the output files to the target add_files_to_target(project, target, output_files) add_build_script(project, target) end end
require_lock_file(project_file)
click to toggle source
# File lib/stronglyboards.rb, line 240 def require_lock_file(project_file) lock_file = LockFile.new(project_file) unless lock_file.exists? puts 'Stronglyboards must first be installed using the install command.' exit end lock_file end
source_generator(language, prefix, output_file)
click to toggle source
# File lib/stronglyboards.rb, line 227 def source_generator(language, prefix, output_file) case language when 'objc' SourceGeneratorObjC.new(prefix, output_file) when 'swift' SourceGeneratorSwift.new(prefix, output_file) else puts 'Language must be objc or swift.' exit end end