class CocoapodsPruneLocalizations::Pruner
Public Class Methods
new(context, user_options)
click to toggle source
# File lib/pruner.rb, line 5 def initialize(context, user_options) @user_options = self.class.user_options(context, user_options) @pruned_bundles_path = File.join(context.sandbox_root, "Pruned Localized Bundles") FileUtils.mkdir @pruned_bundles_path unless Dir.exist? @pruned_bundles_path inject_podfile_post_install_hook(context) end
user_options(context, orig_user_opts = {})
click to toggle source
# File lib/pruner.rb, line 13 def self.user_options(context, orig_user_opts = {}) user_options = {} if orig_user_opts["localizations"] user_options["localizations"] = orig_user_opts["localizations"].map do |loc| loc = loc + ".lproj" unless loc.end_with? ".lproj" loc end else user_options["localizations"] = Utils.user_project_localizations(context.podfile.target_definition_list) end user_options end
Public Instance Methods
inject_podfile_post_install_hook(context)
click to toggle source
Because the pre_install hook is executed before anything at all is generated The plugin hooks to the Podfile's post_install hook, which (as documented) happens after the Project is generated but before is saved, a perfect spot for this
# File lib/pruner.rb, line 29 def inject_podfile_post_install_hook(context) podfile = context.podfile previous_block = podfile.instance_variable_get(:@post_install_callback) new_callback = lambda do |installer| @pod_project = installer.pods_project @sandbox_root = installer.sandbox.root prune! previous_block.call(installer) if previous_block end if previous_block podfile.instance_variable_set(:@post_install_callback, new_callback) else podfile.post_install do |installer| new_callback.call(installer) end end end
prune!()
click to toggle source
# File lib/pruner.rb, line 61 def prune! rsrc_scripts_files = Hash.new self.resources_scripts(@pod_project["Targets Support Files"]).each do |file| rsrc_scripts_files[file] = File.readlines(file.real_path) end langs_to_keep = @user_options["localizations"] || [] Pod::UI.title 'Pruning unused localizations' do #Group all the Pods pod_groups = [] pod_items = @pod_project.pods dev_pod_items = @pod_project.development_pods pod_groups += pod_items.children.objects if pod_items pod_groups += dev_pod_items.children.objects if dev_pod_items pod_groups.each do |group| #Gather all Resources groups resGroups = group.recursive_children_groups.select do |group| group.name == "Resources" end next unless resGroups.length > 0 markForRemoval = [] trimmedBundlesToAdd = Hash.new resGroups.each do |resGroup| subTrimmedBundlesToAdd = Hash.new resGroup.files.each do |file| keep = true if file.path.end_with? ".lproj" keep = langs_to_keep.include?(File.basename(file.path)) elsif file.path.end_with? ".bundle" trimmed_bundle = self.trimmed_bundle(file.real_path) if trimmed_bundle subTrimmedBundlesToAdd[file.real_path] = [trimmed_bundle, file] keep = true end end if !keep markForRemoval << file end end trimmedBundlesToAdd[resGroup] = subTrimmedBundlesToAdd unless subTrimmedBundlesToAdd.length == 0 end #Remove file references indentified for removal if markForRemoval.length > 0 Pod::UI.section "Pruning in #{group.path}" do markForRemoval.each do |file| Pod::UI.message "- Pruning #{file}" relative_path = file.real_path.relative_path_from @sandbox_root rsrc_scripts_files.each_value do |lines| for i in 0...lines.length line = lines[i] if line.include?(relative_path.to_s) lines[i] = "" end end end file.remove_from_project end end end if trimmedBundlesToAdd.length > 0 Pod::UI.section "Adding trimmed bundles to #{group.path}" do group_path = File.join(@pruned_bundles_path, group.path) FileUtils.mkdir group_path unless Dir.exist? group_path trimmedBundlesToAdd.each_pair do |resGroup, bundleArray| bundleArray.each_pair do |original_bundle_path, bundle_arr| bundle_path = bundle_arr[0] original_file = bundle_arr[1] bundle_name = File.basename(original_bundle_path) new_bundle_path = File.join(group_path, bundle_name) FileUtils.rm_r(new_bundle_path) if File.exist? new_bundle_path FileUtils.mv(bundle_path, new_bundle_path) # Update Project path original_file.set_path(new_bundle_path) # Update Resource Scripts path relative_path = original_bundle_path.relative_path_from(@sandbox_root).to_s new_relative_path = Pathname.new(new_bundle_path).relative_path_from(@sandbox_root).to_s rsrc_scripts_files.each_value do |lines| for i in 0...lines.length lines[i] = lines[i].gsub(relative_path, new_relative_path) end end end end end end end rsrc_scripts_files.each_pair do |file, lines| fd = File.open(file.real_path, "w") lines.each do |line| fd.puts line unless (line == "") end fd.close end end end
resources_scripts(group)
click to toggle source
# File lib/pruner.rb, line 49 def resources_scripts(group) file_references = [] group.children.objects.each do |children| if children.class == Xcodeproj::Project::Object::PBXFileReference && children.path.end_with?("resources.sh") file_references << children elsif children.class == Xcodeproj::Project::Object::PBXGroup file_references.concat(self.resources_scripts(children)) end end file_references end
trimmed_bundle(bundle_path)
click to toggle source
# File lib/pruner.rb, line 168 def trimmed_bundle(bundle_path) langs_to_keep = @user_options["localizations"] || [] return unless Dir.exist? bundle_path tmp_dir = Dir.mktmpdir changed_bundle = false Dir.foreach(bundle_path) do |file_name| if (file_name == "." || file_name == "..") next end absolute_file_path = File.join(bundle_path, file_name) if file_name.end_with? ".lproj" if langs_to_keep.include?(file_name) FileUtils.cp_r(absolute_file_path, tmp_dir) else changed_bundle = true end elsif file_name.end_with? ".bundle" sub_trimmed_bundle = self.trimmed_bundle(absolute_file_path) if sub_trimmed_bundle sub_bundle_path = File.join(tmp_dir, file_name) FileUtils.mv(sub_trimmed_bundle, sub_bundle_path) changed_bundle = true else FileUtils.cp_r(absolute_file_path, tmp_dir) end else FileUtils.cp_r(absolute_file_path, tmp_dir) end end tmp_dir if changed_bundle end