Created
April 2, 2018 22:15
-
-
Save rnkyr/ecaae345ed223117942717b9dc9b761c to your computer and use it in GitHub Desktop.
An semi-automation script for Carthage dependency manager
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/ruby | |
| # An semi-automation script for Carthage dependency manager | |
| # It performs linking and copy-frameworks phase creation | |
| # Basic usage examples: | |
| # ruby ~/dev/cart.rb -d "~/Desktop/MyProject" -l | |
| # ruby ~/dev/cart.rb -d "~/Desktop/MyProject" -tar "Core" -t "RxSwift, Bolts-Swift" | |
| # ruby ~/dev/cart.rb -d "~/Desktop/MyProject" -s "RxSwift, Bolts-Swift" | |
| # Or you can create a Run Script phase (in dedicated Aggregate Target) which will run carthage as well. | |
| # Run Script Phase: | |
| =begin | |
| if which xcodeproj >/dev/null; then | |
| if which carthage >/dev/null; then | |
| carthage update --platform "iOS" --cache-builds | |
| /usr/bin/ruby ~/dev/cart.rb --dir $PWD --target "Core" -t "APIClient, APIClientAlamofire, APIClientObjectMapper, BoltsSwift, ObjectMapper" -v | |
| /usr/bin/ruby ~/dev/cart.rb --dir $PWD --take "RxSwift, RxCocoa, NSObject_Rx" -v | |
| else | |
| echo "warning: Carthage line tool is required. 'https://github.com/Carthage/Carthage'" | |
| fi | |
| else | |
| echo "warning: xcodeproj gem is required. Please run 'sudo /usr/bin/gem install xcodeproj'" | |
| fi | |
| =end | |
| require 'optparse' | |
| require 'fileutils' | |
| require 'xcodeproj' | |
| def spit(input) | |
| puts "\e[33m#{input}\e[0m" if $v | |
| end | |
| def info(input) | |
| puts "\e[32m#{input}\e[0m" | |
| end | |
| def error(input) | |
| puts "\e[31m#{input}\e[0m" | |
| info 'Interrupting...' | |
| exit | |
| end | |
| options = { | |
| :dir => File.dirname(__FILE__), | |
| :platform => 'iOS', | |
| :verbose => false, | |
| :backup => false, | |
| :skip => [], | |
| :take => [], | |
| :target => nil, | |
| :list => false | |
| } | |
| parser = OptionParser.new do |opts| | |
| opts.banner = 'Usage: cart.rb [options]' | |
| opts.on('-d', '--dir dir', 'Directory of the project') do |dir| | |
| options[:dir] = dir.sub('~', Dir.home) | |
| end | |
| opts.on('-p', '--platform platform', 'Platform') do |platform| | |
| options[:platform] = platform | |
| end | |
| opts.on('-b', '--backup', 'Backups files before modifying') do | |
| options[:backup] = true | |
| end | |
| opts.on('-v', '--verbose', 'Prints debug info') do | |
| options[:verbose] = true | |
| end | |
| opts.on('--target target', 'Target name') do |target| | |
| options[:target] = target | |
| end | |
| opts.on('-s', '--skip f1,f2,f3,...', 'Skip given list of frameworks (comma separated)') do |list| | |
| options[:skip] = list.split(',').map { |f| f.strip + '.framework' } | |
| end | |
| opts.on('-t', '--take f1,f2,...', 'Takes only given list of frameworks (comma separated') do |list| | |
| options[:take] = list.split(',').map { |f| f.strip + '.framework' } | |
| end | |
| opts.on('-l', '--list', 'List frameworks found in Carthage build directory and terminates') do | |
| options[:list] = true | |
| end | |
| opts.on('-h', '--help', 'Displays Help') do | |
| info opts.to_s | |
| info "Example: ruby ~/dev/cart.rb -d \"~/dev/iOS/jet-journal\" -tar \"Core\" -s \"RxTesting,RxBlocking\"" | |
| exit | |
| end | |
| end | |
| parser.parse! | |
| project_name = options[:dir].split('/').last | |
| options[:target] = project_name unless options[:target] | |
| target_name = options[:target] | |
| carthage_build_path = options[:dir] + '/Carthage/Build/' + options[:platform] + '/' | |
| file_path = options[:dir] + '/' + project_name + '.xcodeproj' | |
| $v = options[:verbose] | |
| spit 'Input: ' + options.to_s | |
| frameworks = Dir[carthage_build_path + '/*.framework'].map { |p| p.split('/').last } | |
| if options[:list] | |
| info frameworks.map { |f| f.split('.').first }.to_s | |
| exit | |
| end | |
| spit 'Found: ' + frameworks.map { |f| f.split('.').first }.to_s | |
| error ('No Frameworks found in ' + carthage_build_path) if frameworks.length == 0 | |
| if options[:take].length != 0 | |
| take = options[:take] | |
| frameworks = frameworks.reject { |f| !take.include?(f) } | |
| spit 'Take: ' + frameworks.map { |f| f.split('.').first }.to_s | |
| end | |
| if options[:skip].length != 0 | |
| skip = options[:skip] | |
| frameworks = frameworks.reject { |f| skip.include?(f) } | |
| spit 'Take: ' + frameworks.map { |f| f.split('.').first }.to_s | |
| end | |
| error 'No Frameworks satisfies given criterion' if frameworks.length == 0 | |
| spit "Modifying #{file_path}:" | |
| error('File not found ' + file_path) unless File.directory?(file_path) | |
| # @type [Project] | |
| project = Xcodeproj::Project.open(file_path) | |
| # @type [PBXGroup] | |
| group = project['Frameworks'] | |
| if group.nil? | |
| group = project.new_group('Frameworks') | |
| spit 'Created Frameworks group' | |
| end | |
| # @type [Array<PBXFileReference>] | |
| references = [] | |
| frameworks.each do |f| | |
| path = carthage_build_path + f | |
| ref = group[f] | |
| if ref.nil? | |
| ref = group.new_reference(path) | |
| end | |
| references << ref | |
| end | |
| # @type [AbstractTarget] | |
| target = nil | |
| project.targets.each do |t| | |
| if t.name.eql? target_name | |
| target = t | |
| break | |
| end | |
| end | |
| if target.nil? | |
| error 'Target not found ' + target_name | |
| end | |
| target.build_configurations.each do |config| | |
| setting = config.build_settings['FRAMEWORK_SEARCH_PATHS'] | |
| path = '$(PROJECT_DIR)/Carthage/Build/iOS' | |
| setting << path unless setting.include? path | |
| end | |
| # @type [PBXFrameworksBuildPhase] | |
| frameworks_build_phase = target.frameworks_build_phase | |
| references.each do |ref| | |
| unless frameworks_build_phase.include?(ref) | |
| frameworks_build_phase.add_file_reference(ref) | |
| end | |
| end | |
| # @type [PBXShellScriptBuildPhase] | |
| run_script_phase = nil | |
| target.shell_script_build_phases.each do |scp| | |
| if scp.shell_script == '/usr/local/bin/carthage copy-frameworks' | |
| run_script_phase = scp | |
| break | |
| end | |
| end | |
| if run_script_phase.nil? | |
| run_script_phase = target.new_shell_script_build_phase('carthage copy frameworks') | |
| run_script_phase.shell_script = '/usr/local/bin/carthage copy-frameworks' | |
| spit 'Added Run Script Phase' | |
| end | |
| frameworks.each do |f| | |
| input_path = '$(SRCROOT)/Carthage/Build/iOS/' + f | |
| output_path = '$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/' + f | |
| unless run_script_phase.input_paths.include?(input_path) | |
| run_script_phase.input_paths << input_path | |
| end | |
| unless run_script_phase.output_paths.include?(output_path) | |
| run_script_phase.output_paths << output_path | |
| end | |
| end | |
| if options[:backup] | |
| backup_file = options[:dir] + '/' + options[:dir].split('/').last + '.xcodeproj/project.pbxproj.backup' | |
| spit 'Creating backup file ' + backup_file | |
| FileUtils.cp(file_path, backup_file) | |
| end | |
| project.save | |
| info 'Successfully saved!' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment