yjcocoa 18.07.31 → 20.07.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +4 -2
- data/lib/yjcocoa/command.rb +1 -0
- data/lib/yjcocoa/git/git.rb +1 -0
- data/lib/yjcocoa/git/git_branch.rb +33 -6
- data/lib/yjcocoa/git/git_checkout.rb +71 -0
- data/lib/yjcocoa/git/git_pull.rb +6 -6
- data/lib/yjcocoa/git/git_tag.rb +3 -3
- data/lib/yjcocoa/git/git_tag_add.rb +1 -1
- data/lib/yjcocoa/pod/pod_release.rb +2 -10
- data/lib/yjcocoa/test.rb +5 -12
- data/lib/yjcocoa/unused/unused.rb +63 -0
- data/lib/yjcocoa/unused/unused_class.rb +107 -0
- data/lib/yjcocoa/unused/unused_image.rb +98 -0
- data/lib/yjcocoa/unused/unused_method.rb +91 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 40d37f6010c02d5bc410ed53af79da394e7ba2a3c851863b234876545d3fe5be
|
4
|
+
data.tar.gz: a396593d587cde35a650f8c34f0abf1d26f027e8e92872cc8475f7bf9b7304a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 067a7461030bec8e1d45aec69317006037491f3b64f968bda50f9fa614e6155ae9126b8e1e01dbb07cb2e1ed296f7c02d73a27d965bae4a2e5349065972b7c3d
|
7
|
+
data.tar.gz: d10af319ad7d5665e861e6e3d3d9833ce45ff92b51a9bb5aeebd431c7a0d9c51018ed355dc46f3266d6379803adae480ebd7c267d68a41a86a637fc86326fa24
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://www.ruby-lang.org/zh_cn/)
|
4
4
|
[](https://github.com/937447974/YJCocoaGem/blob/master/LICENSE)
|
5
|
-
[](https://rubygems.org/gems/yjcocoa)
|
6
6
|

|
7
7
|
|
8
8
|
# YJCocoaGem
|
@@ -23,6 +23,7 @@ Commands:
|
|
23
23
|
+ git Git commands
|
24
24
|
+ log log 日志解析
|
25
25
|
+ pod Pod commands
|
26
|
+
+ unused OC 项目未使用资源查找
|
26
27
|
|
27
28
|
Options:
|
28
29
|
|
@@ -48,4 +49,5 @@ YJ技术支持群:557445088
|
|
48
49
|
|
49
50
|
CSDN:http://blog.csdn.net/y550918116j
|
50
51
|
|
51
|
-
GitHub:https://github.com/937447974
|
52
|
+
GitHub:https://github.com/937447974
|
53
|
+
|
data/lib/yjcocoa/command.rb
CHANGED
data/lib/yjcocoa/git/git.rb
CHANGED
@@ -31,6 +31,7 @@ module YJCocoa
|
|
31
31
|
# property
|
32
32
|
attr_accessor :addBranch
|
33
33
|
attr_accessor :deleteBranchs
|
34
|
+
attr_accessor :gits # git array
|
34
35
|
|
35
36
|
# 初始化
|
36
37
|
def initialize(argv)
|
@@ -42,18 +43,44 @@ module YJCocoa
|
|
42
43
|
|
43
44
|
# businrss
|
44
45
|
def validate!
|
45
|
-
|
46
|
+
super
|
46
47
|
self.banner! unless self.addBranch || self.deleteBranchs
|
47
48
|
end
|
48
49
|
|
49
|
-
def run
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
def run
|
51
|
+
self.buildGitPaths
|
52
|
+
if self.gits.empty?
|
53
|
+
if self.gitExist?
|
54
|
+
self.gitRun
|
55
|
+
end
|
56
|
+
else
|
57
|
+
self.gits.each { |path|
|
58
|
+
self.gitRun(path)
|
59
|
+
}
|
53
60
|
end
|
54
|
-
|
61
|
+
end
|
62
|
+
|
63
|
+
def buildGitPaths
|
64
|
+
self.gits = Dir["**/.git"]
|
65
|
+
self.gits.map! { |path|
|
66
|
+
File.dirname(path)
|
67
|
+
}
|
55
68
|
end
|
56
69
|
|
70
|
+
def gitRun(path=".")
|
71
|
+
thread = Thread.new {
|
72
|
+
Dir.chdir(path) {
|
73
|
+
puts "YJCocoa git #{path}/.git".green
|
74
|
+
self.gitBranchDelete if self.deleteBranchs && !self.deleteBranchs.empty?
|
75
|
+
if self.addBranch
|
76
|
+
self.gitBranchAdd
|
77
|
+
puts
|
78
|
+
end
|
79
|
+
}
|
80
|
+
}
|
81
|
+
thread.join
|
82
|
+
end
|
83
|
+
|
57
84
|
def gitBranchAdd
|
58
85
|
puts "YJCocoa git add branch #{self.addBranch}".green
|
59
86
|
system("git push --set-upstream origin #{self.addBranch}") if system("git checkout -b #{self.addBranch}")
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#
|
2
|
+
# git_checkout.rb
|
3
|
+
# YJCocoa
|
4
|
+
#
|
5
|
+
# https://github.com/937447974
|
6
|
+
# YJ技术支持群:557445088
|
7
|
+
#
|
8
|
+
# Created by 阳君 on 2019/03/18.
|
9
|
+
# Copyright © 2017年 YJCocoa. All rights reserved.
|
10
|
+
#
|
11
|
+
|
12
|
+
module YJCocoa
|
13
|
+
|
14
|
+
class GitCheckout < Git
|
15
|
+
|
16
|
+
self.command = 'checkout'
|
17
|
+
self.summary = 'git checkout'
|
18
|
+
self.description = 'git checkout 当前文件夹下所有 gits'
|
19
|
+
|
20
|
+
def self.options
|
21
|
+
[['--branch', '切换 branch'],]
|
22
|
+
end
|
23
|
+
|
24
|
+
# property
|
25
|
+
attr_accessor :branch
|
26
|
+
attr_accessor :gits
|
27
|
+
|
28
|
+
# 初始化
|
29
|
+
def initialize(argv)
|
30
|
+
super
|
31
|
+
self.branch = argv.option('branch')
|
32
|
+
end
|
33
|
+
|
34
|
+
# businrss
|
35
|
+
def validate!
|
36
|
+
self.banner! unless self.branch
|
37
|
+
end
|
38
|
+
|
39
|
+
def run
|
40
|
+
self.buildGitPaths
|
41
|
+
if self.gits.empty?
|
42
|
+
if self.gitExist?
|
43
|
+
self.gitCheckout
|
44
|
+
end
|
45
|
+
else
|
46
|
+
self.gits.each { |path|
|
47
|
+
self.gitCheckout(path)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def buildGitPaths
|
53
|
+
self.gits = Dir["**/.git"]
|
54
|
+
self.gits.map! { |path|
|
55
|
+
File.dirname(path)
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def gitCheckout(path=".")
|
60
|
+
Dir.chdir(path) {
|
61
|
+
puts "YJCocoa git checkout #{path}/.git".green
|
62
|
+
localChanges = !(`git stash` =~ /No local changes to save/)
|
63
|
+
system("git checkout -b #{self.branch}") unless system("git checkout #{self.branch}")
|
64
|
+
`git stash pop` if localChanges
|
65
|
+
puts
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
data/lib/yjcocoa/git/git_pull.rb
CHANGED
@@ -15,20 +15,20 @@ module YJCocoa
|
|
15
15
|
|
16
16
|
self.command = 'pull'
|
17
17
|
self.summary = 'git pull'
|
18
|
-
self.description = 'git pull 当前文件夹下所有 gits
|
18
|
+
self.description = 'git pull 当前文件夹下所有 gits'
|
19
19
|
|
20
20
|
def self.options
|
21
|
-
[['--
|
21
|
+
[['--all', 'pull all branch'],]
|
22
22
|
end
|
23
23
|
|
24
24
|
# property
|
25
|
-
attr_accessor :
|
25
|
+
attr_accessor :all #是否拉取所有分支
|
26
26
|
attr_accessor :gits # git array
|
27
27
|
|
28
28
|
# 初始化
|
29
29
|
def initialize(argv)
|
30
30
|
super
|
31
|
-
self.
|
31
|
+
self.all = argv.flag?('all', false)
|
32
32
|
end
|
33
33
|
|
34
34
|
# businrss
|
@@ -57,8 +57,8 @@ module YJCocoa
|
|
57
57
|
Dir.chdir(path) {
|
58
58
|
puts "YJCocoa git pull #{path}/.git".green
|
59
59
|
localChanges = !(`git stash` =~ /No local changes to save/)
|
60
|
-
system("git pull")
|
61
|
-
|
60
|
+
system("git pull -p")
|
61
|
+
if self.all
|
62
62
|
list = (`git branch`).split("\n")
|
63
63
|
if list.size >= 2
|
64
64
|
headBranch = "master"
|
data/lib/yjcocoa/git/git_tag.rb
CHANGED
@@ -51,11 +51,11 @@ module YJCocoa
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def run
|
54
|
-
if self.
|
55
|
-
self.
|
54
|
+
if self.deleteTags && !self.deleteTags.empty?
|
55
|
+
self.gitTagDelete
|
56
56
|
puts
|
57
57
|
end
|
58
|
-
self.
|
58
|
+
self.gitTagAdd if self.addTag
|
59
59
|
end
|
60
60
|
|
61
61
|
def gitTagAdd
|
@@ -23,7 +23,7 @@ module YJCocoa
|
|
23
23
|
if File.exist?(".git")
|
24
24
|
current_branch = self.current_branch
|
25
25
|
tag = File.basename(Dir.pwd)
|
26
|
-
tag << "-#{current_branch}" unless current_branch
|
26
|
+
tag << "-#{current_branch}" unless current_branch == "master"
|
27
27
|
tag << "-#{Time.now.strftime('%Y%m%d%H%M')}"
|
28
28
|
puts "YJCocoa build tag #{tag}".green
|
29
29
|
system("yjcocoa git tag --add=#{tag}")
|
@@ -52,7 +52,6 @@ module YJCocoa
|
|
52
52
|
|
53
53
|
# businrss
|
54
54
|
def run
|
55
|
-
self.gitPull
|
56
55
|
content = []
|
57
56
|
File.open(self.podfile, "r") { |file|
|
58
57
|
while line = file.gets #标准输入流
|
@@ -63,20 +62,13 @@ module YJCocoa
|
|
63
62
|
puts "YJCocoa Pod Release".green
|
64
63
|
puts content.sort * "\n"
|
65
64
|
end
|
66
|
-
|
67
|
-
def gitPull
|
68
|
-
puts "#{self.podfile} git pull".green
|
69
|
-
Dir.chdir(File.dirname(self.podfile)) {| path |
|
70
|
-
system("yjcocoa git pull")
|
71
|
-
}
|
72
|
-
end
|
73
|
-
|
65
|
+
|
74
66
|
private def check (pods, line)
|
75
67
|
pods.each { |pod|
|
76
68
|
if line.include?(pod)
|
77
|
-
pods.delete(pod)
|
78
69
|
line.split(',').each { |item|
|
79
70
|
if item.include?("tag") || item.include?("branch")
|
71
|
+
pods.delete(pod)
|
80
72
|
return "#{pod}, #{item.chomp}"
|
81
73
|
end
|
82
74
|
}
|
data/lib/yjcocoa/test.rb
CHANGED
@@ -1,14 +1,7 @@
|
|
1
|
-
|
2
|
-
list = (`git branch`).split("\n")
|
3
|
-
for item in list
|
4
|
-
if item =~ /\* /
|
5
|
-
return item.gsub(/\* /, "")
|
6
|
-
end
|
7
|
-
end
|
8
|
-
end
|
1
|
+
gem build yjcocoa.gemspec
|
9
2
|
|
10
|
-
|
11
|
-
puts "current_branch1"
|
12
|
-
end
|
3
|
+
gem install yjcocoa-18.12.13.gem
|
13
4
|
|
14
|
-
|
5
|
+
yjcocoa unused image --dir=/Users/cisdi/Desktop/QingTui/master --ignore=QTComm,Pods,LaunchImage,Emoji,AppIcon
|
6
|
+
|
7
|
+
otool -oV /Users/cisdi/Desktop/QingTui_Developer
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#
|
2
|
+
# unused.rb
|
3
|
+
# YJCocoaGem
|
4
|
+
#
|
5
|
+
# https://github.com/937447974
|
6
|
+
# YJ技术支持群:557445088
|
7
|
+
#
|
8
|
+
# Created by 阳君 on 2018/12/8.
|
9
|
+
# Copyright © 2018年 YJCocoa. All rights reserved.
|
10
|
+
#
|
11
|
+
|
12
|
+
module YJCocoa
|
13
|
+
|
14
|
+
# Usage
|
15
|
+
class Unused < Command
|
16
|
+
|
17
|
+
self.abstract_command = true
|
18
|
+
self.command = 'unused'
|
19
|
+
self.summary = 'OC 项目未使用资源查找'
|
20
|
+
self.description = 'These are common unused commands used in YJCocoa.'
|
21
|
+
|
22
|
+
# property
|
23
|
+
attr_accessor :matcho
|
24
|
+
attr_accessor :match
|
25
|
+
attr_accessor :ignore
|
26
|
+
attr_accessor :output
|
27
|
+
|
28
|
+
# 初始化
|
29
|
+
def initialize(argv)
|
30
|
+
super
|
31
|
+
self.matcho = argv.option('match-o')
|
32
|
+
self.match = argv.option('match')
|
33
|
+
self.match = self.match.split(",").reject {|i| i.empty? } if self.match
|
34
|
+
self.ignore = argv.option('ignore')
|
35
|
+
self.ignore = self.ignore.split(",").reject {|i| i.empty? } if self.ignore
|
36
|
+
self.output = argv.option('output')
|
37
|
+
self.output = Dir.pwd + "/YJCocoa.h" unless self.output
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_match(item)
|
41
|
+
return true unless self.match
|
42
|
+
self.match.each { |m|
|
43
|
+
return true if item.include?(m)
|
44
|
+
}
|
45
|
+
return false
|
46
|
+
end
|
47
|
+
|
48
|
+
def check_ignore(item)
|
49
|
+
return false unless self.ignore
|
50
|
+
self.ignore.each { |i|
|
51
|
+
return true if item.include?(i)
|
52
|
+
}
|
53
|
+
return false
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
# Commands
|
59
|
+
require 'yjcocoa/unused/unused_class'
|
60
|
+
require 'yjcocoa/unused/unused_image'
|
61
|
+
require 'yjcocoa/unused/unused_method'
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#
|
2
|
+
# unused_class.rb
|
3
|
+
# YJCocoaGem
|
4
|
+
#
|
5
|
+
# https://github.com/937447974
|
6
|
+
# YJ技术支持群:557445088
|
7
|
+
#
|
8
|
+
# Created by 阳君 on 2018/12/8.
|
9
|
+
# Copyright © 2018年 YJCocoa. All rights reserved.
|
10
|
+
#
|
11
|
+
|
12
|
+
module YJCocoa
|
13
|
+
|
14
|
+
# Usage
|
15
|
+
class UnusedClass < Unused
|
16
|
+
|
17
|
+
self.command = 'class'
|
18
|
+
self.summary = 'unused class commands'
|
19
|
+
self.description = '查找 OC 项目中未使用的 class'
|
20
|
+
|
21
|
+
def self.options
|
22
|
+
[['--match-o', 'Match O 文件地址'],
|
23
|
+
['--match', '指定的字符串匹配,多字符串用 "," 分隔'],
|
24
|
+
['--ignore', '忽略的字符串匹配, 多字符串用 "," 分隔'],
|
25
|
+
['--output', '日志存放路径,默认当前路径']] + super
|
26
|
+
end
|
27
|
+
|
28
|
+
# businrss
|
29
|
+
def validate!
|
30
|
+
super
|
31
|
+
unless self.matcho && self.matcho.length > 0
|
32
|
+
puts "Match O 文件地址为空".red
|
33
|
+
self.banner!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def run
|
38
|
+
unused_class = self.unreferenced_class
|
39
|
+
fetch_class = unused_class.reject {|m| !(check_match(m) && !check_ignore(m))}
|
40
|
+
puts "分析完毕,打开日志:#{self.output}".green
|
41
|
+
File.write(self.output, fetch_class.join("\n"))
|
42
|
+
`open #{self.output}`
|
43
|
+
end
|
44
|
+
|
45
|
+
def unreferenced_class
|
46
|
+
section = match_o_section
|
47
|
+
unless section.count
|
48
|
+
puts "#{self.matcho} can't find classlist".red
|
49
|
+
self.banner!
|
50
|
+
end
|
51
|
+
classlist = section["Contents of (__DATA,__objc_classlist) section"]
|
52
|
+
classrefs = section["Contents of (__DATA,__objc_classrefs) section"]
|
53
|
+
superrefs = section["Contents of (__DATA,__objc_superrefs) section"]
|
54
|
+
all_classlist = objc_classlist(classlist)
|
55
|
+
used_classlist = objc_super_classlist(classlist) + objc_classlist(classrefs) + objc_classlist(superrefs)
|
56
|
+
unused_classlist = []
|
57
|
+
all_classlist.each {|item|
|
58
|
+
unused_classlist << item unless used_classlist.include?(item)
|
59
|
+
}
|
60
|
+
return unused_classlist.sort
|
61
|
+
end
|
62
|
+
|
63
|
+
def match_o_section
|
64
|
+
lines = `otool -oV #{self.matcho}`.split("\n")
|
65
|
+
section = Hash.new
|
66
|
+
key = nil
|
67
|
+
lines.each {|line|
|
68
|
+
line = line#.strip
|
69
|
+
if line.include?("Contents of (__DATA,")
|
70
|
+
key = line
|
71
|
+
elsif (key)
|
72
|
+
if section.include?(key)
|
73
|
+
section[key] << line
|
74
|
+
else
|
75
|
+
section[key] = [line]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
}
|
79
|
+
return section
|
80
|
+
end
|
81
|
+
|
82
|
+
def objc_super_classlist(classlist)
|
83
|
+
result = []
|
84
|
+
classlist.each { |line|
|
85
|
+
line_scan = line.scan(/_OBJC_CLASS_\$_(.+)/)
|
86
|
+
if line_scan.count > 0 && line.include?("superclass")
|
87
|
+
result << line_scan[0][0]
|
88
|
+
end
|
89
|
+
}
|
90
|
+
return result
|
91
|
+
end
|
92
|
+
|
93
|
+
def objc_classlist(classlist)
|
94
|
+
result = []
|
95
|
+
classlist.each { |line|
|
96
|
+
line_scan = line.scan(/_OBJC_CLASS_\$_(.+)/)
|
97
|
+
if line_scan.count > 0 && !line.include?("superclass")
|
98
|
+
result << line_scan[0][0]
|
99
|
+
end
|
100
|
+
}
|
101
|
+
return result
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#
|
2
|
+
# unused_image.rb
|
3
|
+
# YJCocoaGem
|
4
|
+
#
|
5
|
+
# https://github.com/937447974
|
6
|
+
# YJ技术支持群:557445088
|
7
|
+
#
|
8
|
+
# Created by 阳君 on 2018/12/8.
|
9
|
+
# Copyright © 2018年 YJCocoa. All rights reserved.
|
10
|
+
#
|
11
|
+
|
12
|
+
module YJCocoa
|
13
|
+
|
14
|
+
# Usage
|
15
|
+
class UnusedImage < Unused
|
16
|
+
|
17
|
+
self.command = 'image'
|
18
|
+
self.summary = 'unused image commands'
|
19
|
+
self.description = '查找 OC 项目中未使用的 image'
|
20
|
+
|
21
|
+
def self.options
|
22
|
+
[['--dir', '项目文件夹'],
|
23
|
+
['--ignore', '忽略的字符串匹配, 多字符串用 "," 分隔'],
|
24
|
+
['--output', '日志存放路径,默认当前路径']] + super
|
25
|
+
end
|
26
|
+
|
27
|
+
# property
|
28
|
+
attr_accessor :dir
|
29
|
+
attr_accessor :image_hash
|
30
|
+
attr_accessor :class_content
|
31
|
+
|
32
|
+
# 初始化
|
33
|
+
def initialize(argv)
|
34
|
+
super
|
35
|
+
self.dir = argv.option('dir')
|
36
|
+
self.image_hash = Hash.new
|
37
|
+
self.class_content = ""
|
38
|
+
end
|
39
|
+
|
40
|
+
# businrss
|
41
|
+
def validate!
|
42
|
+
super
|
43
|
+
unless self.dir && self.dir.length > 0
|
44
|
+
puts "dir 文件地址为空".red
|
45
|
+
self.banner!
|
46
|
+
end
|
47
|
+
unless Dir.exist?(self.dir)
|
48
|
+
puts "dir 文件路径 #{self.dir} 不是文件夹".red
|
49
|
+
self.banner!
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def run
|
54
|
+
unused_image = self.unreferenced_image
|
55
|
+
puts "分析完毕,打开日志:#{self.output}".green
|
56
|
+
File.write(self.output, unused_image.join("\n"))
|
57
|
+
`open #{self.output}`
|
58
|
+
end
|
59
|
+
|
60
|
+
def unreferenced_image
|
61
|
+
self.deal_with_path(self.dir)
|
62
|
+
puts "分析图片资源".green
|
63
|
+
result = []
|
64
|
+
self.image_hash.each {|key, value|
|
65
|
+
puts key
|
66
|
+
result += value unless self.class_content.include?(key)
|
67
|
+
}
|
68
|
+
return result.sort
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def deal_with_path(path)
|
73
|
+
Dir.chdir(path) {
|
74
|
+
Dir["**/*.{png,jpg}"].each {|filename| self.deal_with_image(filename)}
|
75
|
+
Dir["**/*.{h,m,mm,swift,xib,storyboard,plist}"].each {|filename| self.deal_with_file(filename)}
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def deal_with_image(filename)
|
80
|
+
return if self.check_ignore(filename)
|
81
|
+
basename = File.basename(filename)
|
82
|
+
image_gsub = [".png", ".jpg", "@1x", "@2x", "@3x", "@1X", "@2X", "@3X"]
|
83
|
+
image_gsub.each {|gsub| basename.gsub!(gsub, "")}
|
84
|
+
if self.image_hash.include?(basename)
|
85
|
+
self.image_hash[basename] << filename
|
86
|
+
else
|
87
|
+
self.image_hash[basename] = [filename]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def deal_with_file(filename)
|
92
|
+
self.class_content << File.read(filename) unless File.symlink?(filename)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
#
|
2
|
+
# unused_method.rb
|
3
|
+
# YJCocoaGem
|
4
|
+
#
|
5
|
+
# https://github.com/937447974
|
6
|
+
# YJ技术支持群:557445088
|
7
|
+
#
|
8
|
+
# Created by 阳君 on 2018/12/8.
|
9
|
+
# Copyright © 2018年 YJCocoa. All rights reserved.
|
10
|
+
#
|
11
|
+
|
12
|
+
module YJCocoa
|
13
|
+
|
14
|
+
# Usage
|
15
|
+
class UnusedMethod < Unused
|
16
|
+
|
17
|
+
self.command = 'method'
|
18
|
+
self.summary = 'unused method commands'
|
19
|
+
self.description = '查找 OC 项目中未使用的 method'
|
20
|
+
|
21
|
+
def self.options
|
22
|
+
[['--match-o', 'Match O 文件地址'],
|
23
|
+
['--match', '指定的字符串匹配,多字符串用 "," 分隔'],
|
24
|
+
['--ignore', '忽略的字符串匹配, 多字符串用 "," 分隔'],
|
25
|
+
['--output', '日志存放路径,默认当前路径']] + super
|
26
|
+
end
|
27
|
+
|
28
|
+
# businrss
|
29
|
+
def validate!
|
30
|
+
super
|
31
|
+
unless self.matcho && self.matcho.length > 0
|
32
|
+
puts "Match O 文件地址为空".red
|
33
|
+
self.banner!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def run
|
38
|
+
unused_methods = self.unreferenced_methods
|
39
|
+
fetch_methods = unused_methods.reject {|m| !(check_match(m) && !check_ignore(m))}
|
40
|
+
puts "分析完毕,打开日志:#{self.output}".green
|
41
|
+
File.write(self.output, fetch_methods.join("\n"))
|
42
|
+
`open #{self.output}`
|
43
|
+
end
|
44
|
+
|
45
|
+
def unreferenced_methods
|
46
|
+
methods = self.implemented_methods
|
47
|
+
unless methods.count
|
48
|
+
puts "#{self.matcho} can't find implemented methods".red
|
49
|
+
self.banner!
|
50
|
+
end
|
51
|
+
sels = self.referenced_selectors
|
52
|
+
sels.each {|sel| methods.delete(sel)}
|
53
|
+
result = []
|
54
|
+
methods.values.each {|value| result += value}
|
55
|
+
return result.sort
|
56
|
+
end
|
57
|
+
|
58
|
+
def implemented_methods
|
59
|
+
lines = `otool -oV #{self.matcho}`.split("\n")
|
60
|
+
methods = Hash.new
|
61
|
+
lines.each {|line|
|
62
|
+
line_scan = line.scan(/\s*imp 0x\w+ ([+|-]\[.+\s(.+)\])/)
|
63
|
+
if line_scan.count > 0
|
64
|
+
imp = line_scan[0][0]
|
65
|
+
sel = line_scan[0][1]
|
66
|
+
if methods.include?(sel)
|
67
|
+
methods[sel] << imp
|
68
|
+
else
|
69
|
+
methods[sel] = [imp]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
}
|
73
|
+
return methods
|
74
|
+
end
|
75
|
+
|
76
|
+
def referenced_selectors
|
77
|
+
lines = `otool -v -s __DATA __objc_selrefs #{self.matcho}`.split("\n")
|
78
|
+
refs = []
|
79
|
+
lines.each { |line|
|
80
|
+
line_scan = line.scan(/__TEXT:__objc_methname:(.+)/)
|
81
|
+
if line_scan.count > 0
|
82
|
+
refs << line_scan[0][0]
|
83
|
+
end
|
84
|
+
}
|
85
|
+
return refs
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yjcocoa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 20.07.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 阳君
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: claide
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/yjcocoa/git/git.rb
|
68
68
|
- lib/yjcocoa/git/git_branch.rb
|
69
69
|
- lib/yjcocoa/git/git_cache.rb
|
70
|
+
- lib/yjcocoa/git/git_checkout.rb
|
70
71
|
- lib/yjcocoa/git/git_pull.rb
|
71
72
|
- lib/yjcocoa/git/git_tag.rb
|
72
73
|
- lib/yjcocoa/git/git_tag_add.rb
|
@@ -78,6 +79,10 @@ files:
|
|
78
79
|
- lib/yjcocoa/pod/pod_release.rb
|
79
80
|
- lib/yjcocoa/pod/product_class.rb
|
80
81
|
- lib/yjcocoa/test.rb
|
82
|
+
- lib/yjcocoa/unused/unused.rb
|
83
|
+
- lib/yjcocoa/unused/unused_class.rb
|
84
|
+
- lib/yjcocoa/unused/unused_image.rb
|
85
|
+
- lib/yjcocoa/unused/unused_method.rb
|
81
86
|
homepage: https://github.com/937447974/YJCocoaGem
|
82
87
|
licenses:
|
83
88
|
- MIT
|
@@ -98,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
103
|
version: '0'
|
99
104
|
requirements: []
|
100
105
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.
|
106
|
+
rubygems_version: 2.7.8
|
102
107
|
signing_key:
|
103
108
|
specification_version: 3
|
104
109
|
summary: YJCocoa, the Cocoa library package manager.
|