class Pod::Command::Diff
This is an example of a cocoapods plugin adding a top-level subcommand to the 'pod' command.
You can also create subcommands of existing or new commands. Say you wanted to add a subcommand to `list` to show newly deprecated pods, (e.g. `pod list deprecated`), there are a few things that would need to change.
-
move this file to `lib/pod/command/list/deprecated.rb` and update the class to exist in the the Pod::Command::List namespace
-
change this class to extend from `List` instead of `Command`. This tells the plugin system that it is a subcommand of `list`.
-
edit `lib/cocoapods_plugins.rb` to require this file
@todo Create a PR to add your plugin to CocoaPods/cocoapods.org
in the `plugins.json` file, once your plugin is released.
Public Class Methods
new(argv)
click to toggle source
Calls superclass method
# File lib/cocoapods-api-diff/command/diff.rb, line 39 def initialize(argv) @name = argv.shift_argument @version_a = Version.new(argv.shift_argument) @version_b = Version.new(argv.shift_argument) @platform = :ios @spec_sources = argv.option('spec-sources', 'master').split(',') repos = Dir["#{ENV['HOME']}/.cocoapods/repos/*"].select do |path| source = Pod::Source.new(path) matches = false @spec_sources.each do |s| if s == source.name || s == source.url matches = true end end matches end @sources = repos.map do |path| source = Pod::Source.new(path) end @sources = @sources || [] super end
options()
click to toggle source
# File lib/cocoapods-api-diff/command/diff.rb, line 33 def self.options [ ['--spec-sources=private,https://github.com/CocoaPods/Specs.git', 'The sources to pull dependent pods from (defaults to https://github.com/CocoaPods/Specs.git)'], ] end
Public Instance Methods
clang_parse_headers(spec, platform)
click to toggle source
# File lib/cocoapods-api-diff/command/diff.rb, line 146 def clang_parse_headers(spec, platform) consumer = spec.consumer(platform) public_header_files = [] (consumer.public_header_files.length > 0 ? consumer.public_header_files : ["**/*.h"]).each do |file| public_header_files += Dir[file] end private_header_files = [] consumer.private_header_files.each do |file| private_header_files += Dir[file] end public_header_files -= private_header_files public_header_files.select! do |file| !File.symlink?(file) end # Remove all import lines to avoid duplicate result and speed up public_header_files.each do |file| data = File.read(file) data.gsub!(/[#@](import|include|class)\s*.*/, '') data.gsub!(/(FOUNDATION_EXTERN|UIKIT_EXTERN)/, '') File.delete(file) File.write(file, data) end # UI.puts "public_header_files: #{public_header_files}" result = `clang \ -Xclang -ast-print \ -ObjC \ -fno-diagnostics-color \ -fsyntax-only \ #{public_header_files.map{ |file| "\"#{file}\""}.join(" ")} \ 2> /dev/null ` # TODO parse & sort return result end
diff_results(result_a, result_b)
click to toggle source
# File lib/cocoapods-api-diff/command/diff.rb, line 190 def diff_results(result_a, result_b) `git init` file = "#{@name}.h" File.write(file, result_a) `git add #{file}` `rm #{file}` File.write(file, result_b) system("git --no-pager diff #{file}") end
get_spec_from_sources(sources, name, version)
click to toggle source
# File lib/cocoapods-api-diff/command/diff.rb, line 109 def get_spec_from_sources(sources, name, version) spec = nil sources.each do |source| if source.versions(name).include?(version) spec = source.specification(name, version) end end return spec end
install_pod(spec, platform_name, sandbox_root)
click to toggle source
# File lib/cocoapods-api-diff/command/diff.rb, line 119 def install_pod(spec, platform_name, sandbox_root) # Remove useless dependencies & platform deployment_target spec.store_attribute(:dependencies, nil) spec.store_attribute(:dependencies, nil, @platform) spec.store_attribute(:platforms, {platform_name => 0}) # Recreate podspec spec_path = "#{spec.name}-#{spec.version}.podspec.json" # UI.puts "podspec: #{spec.to_json}" File.write(spec_path, spec.to_json) podfile = Pod::Podfile.new do install!('cocoapods', :integrate_targets => false) platform(platform_name) target('api-diff') do pod(spec.name, podspec: spec_path) end end sandbox = Sandbox.new(sandbox_root) installer = Installer.new(sandbox, podfile) UI.puts "> Installing #{spec.name} #{spec.version}..." installer.install! end
run()
click to toggle source
# File lib/cocoapods-api-diff/command/diff.rb, line 83 def run Dir.mktmpdir('cocoapods-api-diff-') do |tmpDir| Dir.chdir(tmpDir) do UI.puts "> Create temp dir at: #{tmpDir}" spec_a = get_spec_from_sources(@sources, @name, @version_a) install_pod(spec_a, @platform, spec_a.version.to_s) result_a = nil Dir.chdir(File.join(spec_a.version.to_s, @name)) do result_a = clang_parse_headers(spec_a, @platform.to_s) end spec_b = get_spec_from_sources(@sources, @name, @version_b) sandbox_b = install_pod(spec_b, @platform, spec_b.version.to_s) result_b = nil Dir.chdir(File.join(spec_b.version.to_s, @name)) do result_b = clang_parse_headers(spec_b, @platform.to_s) end UI.puts "> Diff #{@name} #{@version_a} & #{@version_b}" diff_results(result_a, result_b) end end end
validate!()
click to toggle source
Calls superclass method
# File lib/cocoapods-api-diff/command/diff.rb, line 65 def validate! super help! 'A Pod name is required.' unless @name help! 'Version A is required.' unless @version_a help! 'Version B is required.' unless @version_b help! 'Version A and Version B are same.' unless @version_a != @version_b versions = [] @sources.each do |source| versions += source.versions(@name) || [] end help! "#{@name} can not be found in repo #{@spec_sources}." unless versions.length != 0 help! "#{@name} (#{@version_a}) can not be found in repo #{@spec_sources}. Avaliable versions: #{versions.map{|v| v.to_s}}" unless versions.include?(@version_a) help! "#{@name} (#{@version_b}) can not be found in repo #{@spec_sources}. Avaliable versions: #{versions.map{|v| v.to_s}}" unless versions.include?(@version_b) end