cocoapods-api-diff 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dcfcfee72ab20b2af4e8b62f3c1006f98cc06bf8de51f8f2f3ec272052d111c9
4
+ data.tar.gz: a13f0786a173759ed8ebe4468b8b7ffacff8fe941c12d618c0e1ab8a0460f870
5
+ SHA512:
6
+ metadata.gz: 43da02b004f8db558959ef26b57730ccd12ecf3233e3cc9c10445f9c54bf77b307e9f3e610cedfb11f9bc589418f2ac9a8182a54623fe10a20212dbec3317597
7
+ data.tar.gz: 2002a2ba669eaa96233181866b49587bc8693bad23f14604f4ce2f060cd40d59b14e5bae8e28c2b209a595aa30c4e72da5909345eeddc68fdfa7f75a9bf5c596
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ pkg
3
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # source 'https://rubygems.org'
2
+ source 'https://gems.ruby-china.com/'
3
+
4
+ # Specify your gem's dependencies in cocoapods-api-diff.gemspec
5
+ gemspec
6
+
7
+ group :development do
8
+ gem 'cocoapods'
9
+
10
+ gem 'mocha'
11
+ gem 'bacon'
12
+ gem 'mocha-on-bacon'
13
+ gem 'prettybacon'
14
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2019 高森 <gaosen@tuya.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,11 @@
1
+ # cocoapods-api-diff
2
+
3
+ A description of cocoapods-api-diff.
4
+
5
+ ## Installation
6
+
7
+ $ gem install cocoapods-api-diff
8
+
9
+ ## Usage
10
+
11
+ $ pod spec diff POD_NAME
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ def specs(dir)
4
+ FileList["spec/#{dir}/*_spec.rb"].shuffle.join(' ')
5
+ end
6
+
7
+ desc 'Runs all the specs'
8
+ task :specs do
9
+ sh "bundle exec bacon #{specs('**')}"
10
+ end
11
+
12
+ task :default => :specs
13
+
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cocoapods-api-diff/gem_version.rb'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cocoapods-api-diff'
8
+ spec.version = CocoapodsApiDiff::VERSION
9
+ spec.authors = ['高森']
10
+ spec.email = ['gaosen@tuya.com']
11
+ spec.description = %q{A short description of cocoapods-api-diff.}
12
+ spec.summary = %q{A longer description of cocoapods-api-diff.}
13
+ spec.homepage = 'https://registry.code.tuya-inc.top/tuyaIOSSDK/cocoapods-api-diff'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'rake'
23
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-api-diff/gem_version'
@@ -0,0 +1 @@
1
+ require 'cocoapods-api-diff/command/diff'
@@ -0,0 +1,204 @@
1
+ module Pod
2
+ class Command
3
+ # This is an example of a cocoapods plugin adding a top-level subcommand
4
+ # to the 'pod' command.
5
+ #
6
+ # You can also create subcommands of existing or new commands. Say you
7
+ # wanted to add a subcommand to `list` to show newly deprecated pods,
8
+ # (e.g. `pod list deprecated`), there are a few things that would need
9
+ # to change.
10
+ #
11
+ # - move this file to `lib/pod/command/list/deprecated.rb` and update
12
+ # the class to exist in the the Pod::Command::List namespace
13
+ # - change this class to extend from `List` instead of `Command`. This
14
+ # tells the plugin system that it is a subcommand of `list`.
15
+ # - edit `lib/cocoapods_plugins.rb` to require this file
16
+ #
17
+ # @todo Create a PR to add your plugin to CocoaPods/cocoapods.org
18
+ # in the `plugins.json` file, once your plugin is released.
19
+ #
20
+ class Diff < Command
21
+ self.summary = 'Simply review the api change of a pod between two versions.'
22
+
23
+ self.description = <<-DESC
24
+ cocoapods-api-diff will compare two versions of the pod, preprocessing the public headers with `clang` command line tool, and diff. Then show you the changes.
25
+ DESC
26
+
27
+ self.arguments = [
28
+ CLAide::Argument.new('NAME', true),
29
+ CLAide::Argument.new('[VERSION_A]', true),
30
+ CLAide::Argument.new('[VERSION_B]', true),
31
+ ]
32
+
33
+ def self.options
34
+ [
35
+ ['--spec-sources=private,https://github.com/CocoaPods/Specs.git', 'The sources to pull dependent pods from (defaults to https://github.com/CocoaPods/Specs.git)'],
36
+ ]
37
+ end
38
+
39
+ def initialize(argv)
40
+ @name = argv.shift_argument
41
+ @version_a = Version.new(argv.shift_argument)
42
+ @version_b = Version.new(argv.shift_argument)
43
+ @platform = :ios
44
+
45
+ @spec_sources = argv.option('spec-sources', 'master').split(',')
46
+ repos = Dir["#{ENV['HOME']}/.cocoapods/repos/*"].select do |path|
47
+ source = Pod::Source.new(path)
48
+ matches = false
49
+ @spec_sources.each do |s|
50
+ if s == source.name || s == source.url
51
+ matches = true
52
+ end
53
+ end
54
+ matches
55
+ end
56
+
57
+ @sources = repos.map do |path|
58
+ source = Pod::Source.new(path)
59
+ end
60
+ @sources = @sources || []
61
+
62
+ super
63
+ end
64
+
65
+ def validate!
66
+ super
67
+ help! 'A Pod name is required.' unless @name
68
+ help! 'Version A is required.' unless @version_a
69
+ help! 'Version B is required.' unless @version_b
70
+ help! 'Version A and Version B are same.' unless @version_a != @version_b
71
+
72
+ versions = []
73
+ @sources.each do |source|
74
+ versions += source.versions(@name) || []
75
+ end
76
+
77
+ help! "#{@name} can not be found in repo #{@spec_sources}." unless versions.length != 0
78
+ 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)
79
+ 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)
80
+
81
+ end
82
+
83
+ def run
84
+ Dir.mktmpdir('cocoapods-api-diff-') do |tmpDir|
85
+ Dir.chdir(tmpDir) do
86
+ UI.puts "> Create temp dir at: #{tmpDir}"
87
+
88
+ spec_a = get_spec_from_sources(@sources, @name, @version_a)
89
+ install_pod(spec_a, @platform, spec_a.version.to_s)
90
+ result_a = nil
91
+ Dir.chdir(File.join(spec_a.version.to_s, @name)) do
92
+ result_a = clang_parse_headers(spec_a, @platform.to_s)
93
+ end
94
+
95
+ spec_b = get_spec_from_sources(@sources, @name, @version_b)
96
+ sandbox_b = install_pod(spec_b, @platform, spec_b.version.to_s)
97
+ result_b = nil
98
+ Dir.chdir(File.join(spec_b.version.to_s, @name)) do
99
+ result_b = clang_parse_headers(spec_b, @platform.to_s)
100
+ end
101
+
102
+ UI.puts "> Diff #{@name} #{@version_a} & #{@version_b}"
103
+ diff_results(result_a, result_b)
104
+
105
+ end
106
+ end
107
+ end
108
+
109
+ def get_spec_from_sources(sources, name, version)
110
+ spec = nil
111
+ sources.each do |source|
112
+ if source.versions(name).include?(version)
113
+ spec = source.specification(name, version)
114
+ end
115
+ end
116
+ return spec
117
+ end
118
+
119
+ def install_pod(spec, platform_name, sandbox_root)
120
+ # Remove useless dependencies & platform deployment_target
121
+ spec.store_attribute(:dependencies, nil)
122
+ spec.store_attribute(:dependencies, nil, @platform)
123
+ spec.store_attribute(:platforms, {platform_name => 0})
124
+
125
+ # Recreate podspec
126
+ spec_path = "#{spec.name}-#{spec.version}.podspec.json"
127
+ # UI.puts "podspec: #{spec.to_json}"
128
+ File.write(spec_path, spec.to_json)
129
+
130
+ podfile = Pod::Podfile.new do
131
+ install!('cocoapods', :integrate_targets => false)
132
+ platform(platform_name)
133
+ target('api-diff') do
134
+ pod(spec.name, podspec: spec_path)
135
+ end
136
+ end
137
+
138
+ sandbox = Sandbox.new(sandbox_root)
139
+ installer = Installer.new(sandbox, podfile)
140
+
141
+ UI.puts "> Installing #{spec.name} #{spec.version}..."
142
+ installer.install!
143
+
144
+ end
145
+
146
+ def clang_parse_headers(spec, platform)
147
+
148
+ consumer = spec.consumer(platform)
149
+
150
+ public_header_files = []
151
+ (consumer.public_header_files.length > 0 ? consumer.public_header_files : ["**/*.h"]).each do |file|
152
+ public_header_files += Dir[file]
153
+ end
154
+
155
+ private_header_files = []
156
+ consumer.private_header_files.each do |file|
157
+ private_header_files += Dir[file]
158
+ end
159
+
160
+ public_header_files -= private_header_files
161
+ public_header_files.select! do |file|
162
+ !File.symlink?(file)
163
+ end
164
+
165
+ # Remove all import lines to avoid duplicate result and speed up
166
+ public_header_files.each do |file|
167
+ data = File.read(file)
168
+ data.gsub!(/[#@](import|include|class)\s*.*/, '')
169
+ data.gsub!(/(FOUNDATION_EXTERN|UIKIT_EXTERN)/, '')
170
+ File.delete(file)
171
+ File.write(file, data)
172
+ end
173
+
174
+ # UI.puts "public_header_files: #{public_header_files}"
175
+
176
+ result = `clang \
177
+ -Xclang -ast-print \
178
+ -ObjC \
179
+ -fno-diagnostics-color \
180
+ -fsyntax-only \
181
+ #{public_header_files.map{ |file| "\"#{file}\""}.join(" ")} \
182
+ 2> /dev/null
183
+ `
184
+
185
+ # TODO parse & sort
186
+
187
+ return result
188
+ end
189
+
190
+ def diff_results(result_a, result_b)
191
+ `git init`
192
+ file = "#{@name}.h"
193
+ File.write(file, result_a)
194
+ `git add #{file}`
195
+ `rm #{file}`
196
+ File.write(file, result_b)
197
+
198
+ system("git --no-pager diff #{file}")
199
+
200
+ end
201
+
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,3 @@
1
+ module CocoapodsApiDiff
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1 @@
1
+ require 'cocoapods-api-diff/command'
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ module Pod
4
+ describe Command::Diff do
5
+ describe 'CLAide' do
6
+ it 'registers it self' do
7
+ Command.parse(%w{ diff }).should.be.instance_of Command::Diff
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,50 @@
1
+ require 'pathname'
2
+ ROOT = Pathname.new(File.expand_path('../../', __FILE__))
3
+ $:.unshift((ROOT + 'lib').to_s)
4
+ $:.unshift((ROOT + 'spec').to_s)
5
+
6
+ require 'bundler/setup'
7
+ require 'bacon'
8
+ require 'mocha-on-bacon'
9
+ require 'pretty_bacon'
10
+ require 'pathname'
11
+ require 'cocoapods'
12
+
13
+ Mocha::Configuration.prevent(:stubbing_non_existent_method)
14
+
15
+ require 'cocoapods_plugin'
16
+
17
+ #-----------------------------------------------------------------------------#
18
+
19
+ module Pod
20
+
21
+ # Disable the wrapping so the output is deterministic in the tests.
22
+ #
23
+ UI.disable_wrap = true
24
+
25
+ # Redirects the messages to an internal store.
26
+ #
27
+ module UI
28
+ @output = ''
29
+ @warnings = ''
30
+
31
+ class << self
32
+ attr_accessor :output
33
+ attr_accessor :warnings
34
+
35
+ def puts(message = '')
36
+ @output << "#{message}\n"
37
+ end
38
+
39
+ def warn(message = '', actions = [])
40
+ @warnings << "#{message}\n"
41
+ end
42
+
43
+ def print(message)
44
+ @output << message
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ #-----------------------------------------------------------------------------#
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cocoapods-api-diff
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - 高森
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-06-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A short description of cocoapods-api-diff.
42
+ email:
43
+ - gaosen@tuya.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - cocoapods-api-diff.gemspec
54
+ - lib/cocoapods-api-diff.rb
55
+ - lib/cocoapods-api-diff/command.rb
56
+ - lib/cocoapods-api-diff/command/diff.rb
57
+ - lib/cocoapods-api-diff/gem_version.rb
58
+ - lib/cocoapods_plugin.rb
59
+ - spec/command/diff_spec.rb
60
+ - spec/spec_helper.rb
61
+ homepage: https://registry.code.tuya-inc.top/tuyaIOSSDK/cocoapods-api-diff
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubygems_version: 3.0.3
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: A longer description of cocoapods-api-diff.
84
+ test_files:
85
+ - spec/command/diff_spec.rb
86
+ - spec/spec_helper.rb