Class: Fastlane::SwiftRunnerUpgrader
- Inherits:
-
Object
- Object
- Fastlane::SwiftRunnerUpgrader
- Defined in:
- fastlane/lib/fastlane/swift_runner_upgrader.rb
Overview
build project
Constant Summary collapse
- API_VERSION_REGEX =
also used by SwiftFastlaneAPIGenerator
/FastlaneRunnerAPIVersion\s*\[\s*([0-9]+.[0-9]+.[0-9]+)\s*\]/
- RELATIVE_SOURCE_FILE_PATH =
"../"
Instance Attribute Summary collapse
-
#fastlane_runner_target ⇒ Object
FastlaneRunner xcodeproj target.
-
#manifest_groups ⇒ Object
unique list of group names that came from the manifest.
-
#manifest_hash ⇒ Object
hash of file names to group names they belong to.
-
#source_swift_code_file_folder_path ⇒ Object
source location of where we’re copying file from during the upgrade process.
-
#target_project ⇒ Object
project we’ll be updating.
-
#target_swift_code_file_folder_path ⇒ Object
location in filesystem where all swift files should exist when we’re done.
Instance Method Summary collapse
-
#add_missing_copy_phase!(dry_run: false) ⇒ Object
adds new copy files build phase to fastlane_runner_target.
-
#add_missing_flags!(dry_run: false) ⇒ Object
adds build_settings flags to fastlane_runner_target.
-
#add_missing_groups_and_files!(dry_run: false) ⇒ Object
adds new groups, and the files inside those groups Note: this does not add new files to existing groups, that is in add_new_files_to_groups!.
- #add_new_files_to_groups! ⇒ Object
-
#copy_file_if_needed!(filename: nil, dry_run: false) ⇒ Object
currently just copies file, even if not needed.
-
#file_needs_update?(filename: nil) ⇒ Boolean
compares source file against the target file’s FastlaneRunnerAPIVersion and returned ‘true` if there is a difference.
- #find_missing_groups ⇒ Object
-
#initialize ⇒ SwiftRunnerUpgrader
constructor
A new instance of SwiftRunnerUpgrader.
- #upgrade_files!(dry_run: false) ⇒ Object
- #upgrade_if_needed!(dry_run: false) ⇒ Object
Constructor Details
#initialize ⇒ SwiftRunnerUpgrader
Returns a new instance of SwiftRunnerUpgrader.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 28 def initialize @source_swift_code_file_folder_path = File.(File.join(Fastlane::ROOT, "/swift")) @target_swift_code_file_folder_path = FastlaneCore::FastlaneFolder.swift_folder_path Fastlane::Setup.setup_swift_support manifest_file = File.join(@source_swift_code_file_folder_path, "/upgrade_manifest.json") UI.success("loading manifest: #{manifest_file}") @manifest_hash = JSON.parse(File.read(manifest_file)) @manifest_groups = @manifest_hash.values.uniq runner_project_path = FastlaneCore::FastlaneFolder.swift_runner_project_path @target_project = Xcodeproj::Project.open(runner_project_path) @root_group = @target_project.groups.select { |group| group.name == "Fastlane Runner" }.first @fastlane_runner_target = @target_project.targets.select { |target| target.name == "FastlaneRunner" }.first end |
Instance Attribute Details
#fastlane_runner_target ⇒ Object
FastlaneRunner xcodeproj target
20 21 22 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 20 def fastlane_runner_target @fastlane_runner_target end |
#manifest_groups ⇒ Object
unique list of group names that came from the manifest
22 23 24 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 22 def manifest_groups @manifest_groups end |
#manifest_hash ⇒ Object
hash of file names to group names they belong to
21 22 23 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 21 def manifest_hash @manifest_hash end |
#source_swift_code_file_folder_path ⇒ Object
source location of where we’re copying file from during the upgrade process
24 25 26 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 24 def source_swift_code_file_folder_path @source_swift_code_file_folder_path end |
#target_project ⇒ Object
project we’ll be updating
19 20 21 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 19 def target_project @target_project end |
#target_swift_code_file_folder_path ⇒ Object
location in filesystem where all swift files should exist when we’re done
23 24 25 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 23 def target_swift_code_file_folder_path @target_swift_code_file_folder_path end |
Instance Method Details
#add_missing_copy_phase!(dry_run: false) ⇒ Object
adds new copy files build phase to fastlane_runner_target
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 233 def add_missing_copy_phase!(dry_run: false) # Check if upgrade is needed # If fastlane copy files build phase exists already, we don't need any more changes to the Xcode project phase_copy_sign = self.fastlane_runner_target.copy_files_build_phases.select { |phase_copy| phase_copy.name == "FastlaneRunnerCopySigned" }.first old_phase_copy_sign = self.fastlane_runner_target.shell_script_build_phases.select { |phase_copy| phase_copy.shell_script == "cd \"${SRCROOT}\"\ncd ../..\ncp \"${TARGET_BUILD_DIR}/${EXECUTABLE_PATH}\" .\n" }.first return true if dry_run && phase_copy_sign.nil? return false if dry_run # Proceed to upgrade old_phase_copy_sign.remove_from_project unless old_phase_copy_sign.nil? unless phase_copy_sign # Create a copy files build phase phase_copy_sign = self.fastlane_runner_target.new_copy_files_build_phase("FastlaneRunnerCopySigned") phase_copy_sign.dst_path = "$SRCROOT/../.." phase_copy_sign.dst_subfolder_spec = "0" phase_copy_sign.run_only_for_deployment_postprocessing = "0" targetBinaryReference = self.fastlane_runner_target.product_reference phase_copy_sign.add_file_reference(targetBinaryReference) # Set "Code sign on copy" flag on Xcode for fastlane_runner_target targetBinaryReference.build_files.each { |target_binary_build_file_reference| target_binary_build_file_reference.settings = { "ATTRIBUTES": ["CodeSignOnCopy"] } } end target_project.save end |
#add_missing_flags!(dry_run: false) ⇒ Object
adds build_settings flags to fastlane_runner_target
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 215 def add_missing_flags!(dry_run: false) # Check if upgrade is needed # If fastlane build settings exists already, we don't need any more changes to the Xcode project self.fastlane_runner_target.build_configurations.each { |config| return true if dry_run && config.build_settings["CODE_SIGN_IDENTITY"].nil? return true if dry_run && config.build_settings["MACOSX_DEPLOYMENT_TARGET"].nil? } return false if dry_run # Proceed to upgrade self.fastlane_runner_target.build_configurations.each { |config| config.build_settings["CODE_SIGN_IDENTITY"] = "-" config.build_settings["MACOSX_DEPLOYMENT_TARGET"] = "10.12" } target_project.save end |
#add_missing_groups_and_files!(dry_run: false) ⇒ Object
adds new groups, and the files inside those groups Note: this does not add new files to existing groups, that is in add_new_files_to_groups!
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 186 def add_missing_groups_and_files!(dry_run: false) missing_groups = self.find_missing_groups.to_set unless missing_groups.length > 0 UI.verbose("No missing groups found, so we don't need to worry about adding new groups") return false end # well, we know we have some changes to make, so if this is a dry run, # don't bother doing anything and just return true return true if dry_run missing_groups.each do |missing_group_name| new_group = @root_group.new_group(missing_group_name) # find every file in the manifest that belongs to the new group, and add it to the new group self.manifest_hash.each do |filename, group| next unless group.casecmp(missing_group_name.downcase).zero? # assumes this is a new file, we don't handle moving files between groups new_file_reference = new_group.new_file("#{RELATIVE_SOURCE_FILE_PATH}#{filename}") # add references to the target, and make sure they are added to the build phase to self.fastlane_runner_target.source_build_phase.add_file_reference(new_file_reference) end end return true # yup, we definitely updated groups end |
#add_new_files_to_groups! ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 138 def add_new_files_to_groups! inverted_hash = {} # need {group => [file1, file2, etc..]} instead of: {file1 => group, file2 => group, etc...} self.manifest_hash.each do |filename, group_name| group_name = group_name.downcase files_in_group = inverted_hash[group_name] if files_in_group.nil? files_in_group = [] inverted_hash[group_name] = files_in_group end files_in_group << filename end # this helps us signal to the user that we made changes updated_project = false # iterate through the groups and collect all the swift files in each @root_group.groups.each do |group| # current group's filenames existing_group_files_set = group.files .select { |file| !file.name.nil? && file.name.end_with?(".swift") } .map(&:name) .to_set group_name = group.name.downcase manifest_group_filenames = inverted_hash[group_name] # compare the current group files to what the manifest says should minially be there manifest_group_filenames.each do |filename| # current group is missing a file from the manifest, need to add it next if existing_group_files_set.include?(filename) UI.verbose("Adding new file #{filename} to group: `#{group.name}`") new_file_reference = group.new_file("#{RELATIVE_SOURCE_FILE_PATH}#{filename}") # add references to the target, and make sure they are added to the build phase to self.fastlane_runner_target.source_build_phase.add_file_reference(new_file_reference) updated_project = true end end return updated_project end |
#copy_file_if_needed!(filename: nil, dry_run: false) ⇒ Object
currently just copies file, even if not needed.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 118 def copy_file_if_needed!(filename: nil, dry_run: false) needs_update = file_needs_update?(filename: filename) UI.verbose("file #{filename} needs an update") if needs_update # Ok, we know if this file needs an update, can return now if it's a dry run return needs_update if dry_run unless needs_update # no work needed, just return return false end source = File.join(self.source_swift_code_file_folder_path, "/#{filename}") target = File.join(self.target_swift_code_file_folder_path, "/#{filename}") FileUtils.cp(source, target) UI.verbose("Copied #{source} to #{target}") return true end |
#file_needs_update?(filename: nil) ⇒ Boolean
compares source file against the target file’s FastlaneRunnerAPIVersion and returned ‘true` if there is a difference
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 84 def file_needs_update?(filename: nil) # looking for something like: FastlaneRunnerAPIVersion [0.9.1] regex_to_use = API_VERSION_REGEX source = File.join(self.source_swift_code_file_folder_path, "/#{filename}") target = File.join(self.target_swift_code_file_folder_path, "/#{filename}") # target doesn't have the file yet, so ya, I'd say it needs to be updated return true unless File.exist?(target) source_file_content = File.read(source) target_file_content = File.read(target) # ignore if files don't contain FastlaneRunnerAPIVersion return false unless source_file_content.include?("FastlaneRunnerAPIVersion") return false unless target_file_content.include?("FastlaneRunnerAPIVersion") bundled_version = source_file_content.match(regex_to_use)[1] target_version = target_file_content.match(regex_to_use)[1] file_versions_are_different = bundled_version != target_version UI.verbose("#{filename} FastlaneRunnerAPIVersion (bundled/target): #{bundled_version}/#{target_version}") files_are_different = source_file_content != target_file_content if files_are_different && !file_versions_are_different UI.verbose("File versions are the same, but the two files are not equal, so that's a problem, setting needs update to 'true'") end needs_update = file_versions_are_different || files_are_different return needs_update end |
#find_missing_groups ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 71 def find_missing_groups missing_groups = [] existing_group_names_set = @root_group.groups.map { |group| group.name.downcase }.to_set self.manifest_groups.each do |group_name| unless existing_group_names_set.include?(group_name.downcase) missing_groups << group_name end end return missing_groups end |
#upgrade_files!(dry_run: false) ⇒ Object
63 64 65 66 67 68 69 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 63 def upgrade_files!(dry_run: false) upgraded_anything = false self.manifest_hash.each do |filename, group| upgraded_anything = copy_file_if_needed!(filename: filename, dry_run: dry_run) || upgraded_anything end return upgraded_anything end |
#upgrade_if_needed!(dry_run: false) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'fastlane/lib/fastlane/swift_runner_upgrader.rb', line 47 def upgrade_if_needed!(dry_run: false) upgraded = add_missing_flags!(dry_run: dry_run) upgraded = add_missing_copy_phase!(dry_run: dry_run) || upgraded upgraded = add_missing_groups_and_files!(dry_run: dry_run) || upgraded upgraded = upgrade_files!(dry_run: dry_run) || upgraded upgraded = add_new_files_to_groups! || upgraded UI.verbose("FastlaneRunner project has been updated and can be written back to disk") if upgraded unless dry_run UI.verbose("FastlaneRunner project changes have been stored") if upgraded target_project.save if upgraded end return upgraded end |