yjcocoa 18.11.22 → 19.01.05

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0af49e3f3b068c88baee52578bfb9660e1b20c9f
4
- data.tar.gz: bebca944235041e7987d85a3e0a48c02467cdcf1
3
+ metadata.gz: d266e13f581e8b1e706cfae22758563cde9ccf80
4
+ data.tar.gz: a3ceb39237847ad6873865e63beb5c3aa6dfb20c
5
5
  SHA512:
6
- metadata.gz: b35c1026f844255b1c6277bc585e586603af1f74ac18a17204abb4c62e5b76d9c007b722b8022f48564dd86a993bcee0ebcbc105350effc705b4ec1d5a2222ea
7
- data.tar.gz: 27c8d94619fd52b6257b417ba01b3c5584e465aa029d3ab2e9ec6913fdd3b3312f384967b895e3c3237ab4777199f13850a2c8f6eef8eec8914d60f465b1dc15
6
+ metadata.gz: f2c1e1b68c4098051235349c7e49b9c6b64705210b5e9ed1fe53e9640bc66496e415383c3939896e1e5b717b57e9c181279f9517564e3cd44cf4d0538962c89c
7
+ data.tar.gz: c1b7f1068d3f60e22ea160a99fed19b22f795f12c07d4559047f9a964890b5b33bc2ed2e578cdc05fe5f118cd6fe5f2c6ebb6bd9b6cd3136c3d0d1ce122f766c
data/README.md CHANGED
@@ -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
 
@@ -73,6 +73,7 @@ module YJCocoa
73
73
  require 'yjcocoa/git/git'
74
74
  require 'yjcocoa/log/log'
75
75
  require 'yjcocoa/pod/pod'
76
+ require 'yjcocoa/unused/unused'
76
77
 
77
78
  end
78
79
 
@@ -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 和 branchs'
18
+ self.description = 'git pull 当前文件夹下所有 gits'
19
19
 
20
20
  def self.options
21
- [['--current-branch', '只拉取当前分支'],]
21
+ [['--all', 'pull all branch'],]
22
22
  end
23
23
 
24
24
  # property
25
- attr_accessor :currentBranch #是否只拉取当前分支
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.currentBranch = argv.flag?('current-branch', false)
31
+ self.all = argv.flag?('all', false)
32
32
  end
33
33
 
34
34
  # businrss
@@ -57,9 +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
- `git pull -p`
61
- system("git pull")
62
- unless self.currentBranch
60
+ system("git pull -p")
61
+ if self.all
63
62
  list = (`git branch`).split("\n")
64
63
  if list.size >= 2
65
64
  headBranch = "master"
@@ -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 =~ /master/
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,2 +1,7 @@
1
- `git pull -p`
2
- system("git pull")
1
+ gem build yjcocoa.gemspec
2
+
3
+ gem install yjcocoa-18.12.13.gem
4
+
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: 18.11.22
4
+ version: 19.01.05
5
5
  platform: ruby
6
6
  authors:
7
7
  - 阳君
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-22 00:00:00.000000000 Z
11
+ date: 2019-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: claide
@@ -78,6 +78,10 @@ files:
78
78
  - lib/yjcocoa/pod/pod_release.rb
79
79
  - lib/yjcocoa/pod/product_class.rb
80
80
  - lib/yjcocoa/test.rb
81
+ - lib/yjcocoa/unused/unused.rb
82
+ - lib/yjcocoa/unused/unused_class.rb
83
+ - lib/yjcocoa/unused/unused_image.rb
84
+ - lib/yjcocoa/unused/unused_method.rb
81
85
  homepage: https://github.com/937447974/YJCocoaGem
82
86
  licenses:
83
87
  - MIT