모든 xcodeproj
및 Pods.xcodeproj
의 모든 대상을 수정하기 위해 사용자 지정 ruby
스크립트를 작성했습니다. 이 스크립트는 대상 이름과 현재 시간 소인을 출력 파일에 기록하는 두 개의 build phase
을 추가합니다. 하나는 build phase
이고 다른 하나는 마지막으로 실행됩니다. 나중에 나는 별도의 스크립트로 다른 타임 스탬프를 빼기 만하면된다.

출력 파일 (정렬 후)과 같이 표시됩니다 출력 파일에
Alamofire end: 1510929112.3409
Alamofire start: 1510929110.2161
AlamofireImage end: 1510929113.6925
AlamofireImage start: 1510929112.5205
경로 (/a/ci_automation/metrics/performance-metrics/a.txt
에 : 여기
스크립트의 결과입니다 스크린 샷)은 아무렇게나 하드 코드되지 않습니다. 대신,이 같은
ruby
스크립트의 매개 변수로 전달합니다
$ruby prepare-for-target-build-time-profiling.rb ${PWD}/output.txt
참고,이 스크립트는 cocoapods 1.3.1
(아마도 1.3
)을 필요로. ruby prepare-for-target-build-time-profiling.rb
#!/usr/bin/env ruby
require 'xcodeproj'
require 'cocoapods'
require 'fileutils'
def inject_build_time_profiling_build_phases(project_path)
project = Xcodeproj::Project.open(project_path)
log_time_before_build_phase_name = '[Prefix placeholder] Log time before build'.freeze
log_time_after_build_phase_name = '[Prefix placeholder] Log time after build'.freeze
puts "Patching project at path: #{project_path}"
puts
project.targets.each do |target|
puts "Target: #{target.name}"
first_build_phase = create_leading_build_phase(target, log_time_before_build_phase_name)
last_build_phase = create_trailing_build_phase(target, log_time_after_build_phase_name)
puts
end
project.save
puts "Finished patching project at path: #{project_path}"
puts
end
def create_leading_build_phase(target, build_phase_name)
remove_existing_build_phase(target, build_phase_name)
build_phase = create_build_phase(target, build_phase_name)
shift_build_phase_leftwards(target, build_phase)
is_build_phase_leading = true
inject_shell_code_into_build_phase(target, build_phase, is_build_phase_leading)
return build_phase
end
def create_trailing_build_phase(target, build_phase_name)
remove_existing_build_phase(target, build_phase_name)
build_phase = create_build_phase(target, build_phase_name)
is_build_phase_leading = false
inject_shell_code_into_build_phase(target, build_phase, is_build_phase_leading)
return build_phase
end
def remove_existing_build_phase(target, build_phase_name)
existing_build_phase = target.shell_script_build_phases.find do |build_phase|
build_phase.name.end_with?(build_phase_name)
# We use `end_with` instead of `==`, because `cocoapods` adds its `[CP]` prefix to a `build_phase_name`
end
if !existing_build_phase.nil?
puts "deleting build phase #{existing_build_phase.name}"
target.build_phases.delete(existing_build_phase)
end
end
def create_build_phase(target, build_phase_name)
puts "creating build phase: #{build_phase_name}"
build_phase = Pod::Installer::UserProjectIntegrator::TargetIntegrator
.create_or_update_build_phase(target, build_phase_name)
return build_phase
end
def shift_build_phase_leftwards(target, build_phase)
puts "moving build phase leftwards: #{build_phase.name}"
target.build_phases.unshift(build_phase).uniq! unless target.build_phases.first == build_phase
end
def inject_shell_code_into_build_phase(target, build_phase, is_build_phase_leading)
start_or_end = is_build_phase_leading ? "start" : "end"
build_phase.shell_script = <<-SH.strip_heredoc
timestamp=`echo "scale=4; $(gdate +%s%N/1000000000)" | bc`
echo "#{target.name} #{start_or_end}: ${timestamp}" >> #{$build_time_logs_output_file}
SH
end
def parse_arguments
$build_time_logs_output_file = ARGV[0]
if $build_time_logs_output_file.to_s.empty? || ! $build_time_logs_output_file.start_with?("/")
puts "Error: you should pass a full path to a output file as an script's argument. Example:"
puts "$ruby prepare-for-target-build-time-profiling.rb /path/to/script/output.txt"
puts
exit 1
end
end
def print_arguments
puts "Arguments:"
puts "Output path: #{$build_time_logs_output_file}"
puts
end
def clean_up_before_script
if File.exist?($build_time_logs_output_file)
FileUtils.rm($build_time_logs_output_file)
end
build_time_logs_output_folder = File.dirname($build_time_logs_output_file)
unless File.directory?(build_time_logs_output_folder)
FileUtils.mkdir_p(build_time_logs_output_folder)
end
end
def main
parse_arguments
print_arguments
clean_up_before_script
inject_build_time_profiling_build_phases("path/to/project.xcodeproj")
inject_build_time_profiling_build_phases("path/to/pods/project.xcodeproj")
end
# arguments:
$build_time_logs_output_file
main
: 여기
는
ruby
스크립트입니다
출처
2017-11-17 15:37:19
Tim