module Fastlane::Helper::AndroidChannelsHelper
Constants
- APKSIGNER_COMMAND_KEYS
Public Class Methods
apksigner_args(params)
click to toggle source
解析并合并 apksigner 的参数, 额外的参数会覆盖之前设置过的值
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 94 def self.apksigner_args(params) command = {} params.all_keys.each do |key| if APKSIGNER_COMMAND_KEYS.has_key?(key) if command_value = params[key] command_key = APKSIGNER_COMMAND_KEYS[key].to_s command_value = "pass:#{command_value}" if command_key.end_with?("pass") command[command_key] = command_value.shellescape end end end if extra_args = params[:apksigner_extra_args] extra_args.split(" ").each_slice(2) do |part| key = part[0].to_s.strip.shellescape if value = part[1] command[key.to_s] = value.strip.shellescape end end end command.flatten.join(" ") end
apksigner_path(build_tools_path)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 198 def self.apksigner_path(build_tools_path) file = File.join(build_tools_path, "apksigner") UI.user_error!("Not found apksigner: #{params[:android_sdk_path]}") unless file && File.file?(file) file end
build_tools_path(android_sdk_path, version = nil)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 186 def self.build_tools_path(android_sdk_path, version = nil) build_tools_path = File.join(android_sdk_path, "build-tools") unless version latest_path = Dir.glob("#{build_tools_path}/*").inject {|latest, current| File.basename(latest) > File.basename(current) ? latest : current } version = File.basename(latest_path) end path = File.join(build_tools_path, version) UI.user_error!("Not found build tools path: #{build_tools_path}") unless path && Dir.exist?(path) path end
determine_apk_file!(params)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 118 def self.determine_apk_file!(params) apk_file = find_file(params[:apk_file]) UI.user_error!("Not found apk file: #{params[:apk_file]}") unless apk_file apk_file end
determine_apksigner!(params)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 154 def self.determine_apksigner!(params) android_sdk_path = params[:android_sdk_path] build_tools_version = params[:build_tools_version] UI.user_error!("Not found android SDK path: #{android_sdk_path}") unless android_sdk_path build_tools_path = build_tools_path(android_sdk_path, build_tools_version) apksigner_path(build_tools_path) end
determine_channels!(params)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 124 def self.determine_channels!(params) channels = params[:channels] if (file = params[:channel_file]) && File.exist?(file) channels.concat(load_channel_file(file)) end UI.user_error!("Empty channels") if channels.size.zero? channels.map{|n| n.strip}.uniq end
determine_keystore!(params)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 134 def self.determine_keystore!(params) keystore = find_file(params[:keystore]) UI.user_error!("Not found keystore file: #{params[:keystore]}") unless keystore keystore end
determine_output_path!(params)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 140 def self.determine_output_path!(params) output_path = params[:output_path] if Dir.exist?(output_path) if params[:clean] FileUtils.rm_rf(output_path) else UI.user_error!("output path was exists: #{File.expand_path(output_path)}。 \nyou can use `clean:true` to force clean.") end end FileUtils.mkdir_p(output_path) output_path end
find_file(default_file)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 163 def self.find_file(default_file) return default_file if File.file?(default_file) Dir['**/*'].each do |file| return file if File.basename(file) == default_file end nil end
is_signed?(apk_file)
click to toggle source
验证 apk 是否签名
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 71 def self.is_signed?(apk_file) Zip.warn_invalid_date = false Zip::File.open(apk_file, Zip::File::CREATE) do |zip_file| file = zip_file.find_entry("META-INF/MANIFEST.MF") if file encrypt_keys = 0 file.get_input_stream do |io| io.each_line do |line| return true if encrypt_keys >= 2 encrypt_keys += 1 if line.start_with?("Name:") end end end end false end
load_channel_file(file)
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 173 def self.load_channel_file(file) content = File.read(file) case File.extname(file) when ".json" JSON.load(content).to_a when ".yaml", ".yml" YAML.load(content).to_a else # 安装纯文本解析 content.gsub(/(\s|\n)+/, ",").split(",").select {|n| n && !n.empty?} end end
packing_apk(apk_file, channels, output_path, options = {})
click to toggle source
签名接收的各渠道包
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 21 def self.packing_apk(apk_file, channels, output_path, options = {}) Zip.warn_invalid_date = false UI.message "Packaing apk ..." Tempfile.open("android_channel_name_file") do |empty_channel_file| channels.each do |channel_name| signed_and_write_channel_to_apk(apk_file, channel_name, output_path, empty_channel_file.path, options) end end end
sign_apk(apk_file, options = {})
click to toggle source
签名 apk 文件
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 54 def self.sign_apk(apk_file, options = {}) command = "#{options[:apksigner].shellescape} sign #{options[:apksigner_args]} #{apk_file}" Action.sh(command, print_command: false, print_command_output: verbose?) end
signed_and_write_channel_to_apk(apk_file, channel_name, output_path, write_file, options)
click to toggle source
写入渠道并签名 apk 文件
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 33 def self.signed_and_write_channel_to_apk(apk_file, channel_name, output_path, write_file, options) output_file = File.join(output_path, "#{channel_name}.apk") Action.sh("cp #{apk_file} #{output_file}", print_command: false) channel_filename = [options[:prefix], channel_name, options[:suffix]].compact.join("") UI.verbose "Writing 'META-INF/#{channel_filename}' file to #{output_file}" Zip::File.open(output_file, Zip::File::CREATE) do |zip_file| zip_file.add("META-INF/#{channel_filename}", write_file) end UI.verbose "Signing ..." sign_apk(output_file, options) if options[:verify] && !verify_apk(output_file, options[:apksigner]) UI.build_failure! "Verify failure apk file: #{output_file}" end rescue Zip::EntryExistsError => ex UI.build_failure!([ex.message].concat(ex.backtrace).join("\n")) end
verbose?()
click to toggle source
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 89 def self.verbose? FastlaneCore::Globals.verbose? end
verify_apk(apk_file, apksigner)
click to toggle source
验证 apk 签名是否正确
# File lib/fastlane/plugin/android_channels/helper/android_channels_helper.rb, line 60 def self.verify_apk(apk_file, apksigner) command_args = [apksigner.shellescape, "verify"] command_args << "--verbose" if verbose? command_args << apk_file UI.verbose "Verifing ..." result = Action.sh(command_args.join(" "), print_command: false, print_command_output: verbose?) !result.include?("DOES NOT VERIFY") end