Guest User

Untitled

a guest
Oct 15th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.21 KB | None | 0 0
  1. Прописать скрипт в Target -> Build Phases
  2.  
  3.  
  4. file="unused.rb"
  5. if [ -f "$file" ]
  6. then
  7. echo "$file found."
  8. ruby unused.rb xcode
  9. else
  10. echo "unused.rb doesn't exist"
  11. fi
  12.  
  13.  
  14. Добавить файл unused.rb в корневую папку проекта. (Там где лежит .xcworkspace)
  15.  
  16. В файле необходимо прописать следующий код:
  17.  
  18. #!/usr/bin/ruby
  19. #encoding: utf-8
  20. Encoding.default_external = Encoding::UTF_8
  21. Encoding.default_internal = Encoding::UTF_8
  22.  
  23. class Item
  24. def initialize(file, line, at)
  25. @file = file
  26. @line = line
  27. @at = at + 1
  28. if match = line.match(/(func|let|var|class|enum|struct|protocol)\s+(\w+)/)
  29. @type = match.captures[0]
  30. @name = match.captures[1]
  31. end
  32. end
  33.  
  34. def modifiers
  35. return @modifiers if @modifiers
  36. @modifiers = []
  37. if match = @line.match(/(.*?)#{@type}/)
  38. @modifiers = match.captures[0].split(" ")
  39. end
  40. return @modifiers
  41. end
  42.  
  43. def name
  44. @name
  45. end
  46.  
  47. def file
  48. @file
  49. end
  50.  
  51. def to_s
  52. serialize
  53. end
  54. def to_str
  55. serialize
  56. end
  57.  
  58. def full_file_path
  59. Dir.pwd + '/' + @file
  60. end
  61.  
  62. def serialize
  63. "Item< #{@type.to_s.green} #{@name.to_s.yellow} [#{modifiers.join(" ").cyan}] from: #{@file}:#{@at}:0>"
  64. end
  65.  
  66. def to_xcode
  67. "#{full_file_path}:#{@at}:0: warning: #{@type.to_s} #{@name.to_s} is unused"
  68. end
  69.  
  70.  
  71. end
  72. class Unused
  73. def find
  74. items = []
  75. all_files = Dir.glob("**/*.swift").reject do |path|
  76. File.directory?(path)
  77. end
  78.  
  79. all_files.each { |my_text_file|
  80. file_items = grab_items(my_text_file)
  81. file_items = filter_items(file_items)
  82.  
  83. non_private_items, private_items = file_items.partition { |f| !f.modifiers.include?("private") && !f.modifiers.include?("fileprivate") }
  84. items += non_private_items
  85.  
  86. # Usage within the file
  87. if private_items.length > 0
  88. find_usages_in_files([my_text_file], [], private_items)
  89. end
  90.  
  91. }
  92.  
  93. puts "Total items to be checked #{items.length}"
  94.  
  95. items = items.uniq { |f| f.name }
  96. puts "Total unique items to be checked #{items.length}"
  97.  
  98. puts "Starting searching globally it can take a while".green
  99.  
  100. xibs = Dir.glob("**/*.xib")
  101. storyboards = Dir.glob("**/*.storyboard")
  102.  
  103. find_usages_in_files(all_files, xibs + storyboards, items)
  104.  
  105. end
  106.  
  107. def ignore_files_with_regexps(files, regexps)
  108. files.select { |f| regexps.all? { |r| Regexp.new(r).match(f.file).nil? } }
  109. end
  110.  
  111. def ignoring_regexps_from_command_line_args
  112. regexps = []
  113. should_skip_predefined_ignores = false
  114.  
  115. arguments = ARGV.clone
  116. until arguments.empty?
  117. item = arguments.shift
  118. if item == "--ignore"
  119. regex = arguments.shift
  120. regexps += [regex]
  121. end
  122.  
  123. if item == "--skip-predefined-ignores"
  124. should_skip_predefined_ignores = true
  125. end
  126. end
  127.  
  128. if not should_skip_predefined_ignores
  129. regexps += [
  130. "Service/",
  131. "^Pods/",
  132. "Tests.swift$",
  133. "Spec.swift$",
  134. "Tests/"
  135. ]
  136. end
  137.  
  138. regexps
  139. end
  140.  
  141. def find_usages_in_files(files, xibs, items_in)
  142. items = items_in
  143. usages = items.map { |f| 0 }
  144. files.each { |file|
  145. lines = File.readlines(file).map {|line| line.gsub(/^\s*\/\/.*/, "") }
  146. words = lines.join("\n").split(/\W+/)
  147. words_arrray = words.group_by { |w| w }.map { |w, ws| [w, ws.length] }.flatten
  148.  
  149. wf = Hash[*words_arrray]
  150.  
  151. items.each_with_index { |f, i|
  152. usages[i] += (wf[f.name] || 0)
  153. }
  154. # Remove all items which has usage 2+
  155. indexes = usages.each_with_index.select { |u, i| u >= 2 }.map { |f, i| i }
  156.  
  157. # reduce usage array if we found some functions already
  158. indexes.reverse.each { |i| usages.delete_at(i) && items.delete_at(i) }
  159. }
  160.  
  161. xibs.each { |xib|
  162. lines = File.readlines(xib).map {|line| line.gsub(/^\s*\/\/.*/, "") }
  163. full_xml = lines.join(" ")
  164. classes = full_xml.scan(/(class|customClass)="([^"]+)"/).map { |cd| cd[1] }
  165. classes_array = classes.group_by { |w| w }.map { |w, ws| [w, ws.length] }.flatten
  166.  
  167. wf = Hash[*classes_array]
  168.  
  169. items.each_with_index { |f, i|
  170. usages[i] += (wf[f.name] || 0)
  171. }
  172. # Remove all items which has usage 2+
  173. indexes = usages.each_with_index.select { |u, i| u >= 2 }.map { |f, i| i }
  174.  
  175. # reduce usage array if we found some functions already
  176. indexes.reverse.each { |i| usages.delete_at(i) && items.delete_at(i) }
  177.  
  178. }
  179.  
  180. regexps = ignoring_regexps_from_command_line_args()
  181.  
  182. items = ignore_files_with_regexps(items, regexps)
  183.  
  184. if items.length > 0
  185. if ARGV[0] == "xcode"
  186. $stderr.puts "#{items.map { |e| e.to_xcode }.join("\n")}"
  187. else
  188. puts "#{items.map { |e| e.to_s }.join("\n ")}"
  189. end
  190. end
  191. end
  192.  
  193. def grab_items(file)
  194. lines = File.readlines(file).map {|line| line.gsub(/^\s*\/\/.*/, "") }
  195. items = lines.each_with_index.select { |line, i| line[/(func|let|var|class|enum|struct|protocol)\s+\w+/] }.map { |line, i| Item.new(file, line, i)}
  196. end
  197.  
  198. def filter_items(items)
  199. items.select { |f|
  200. !f.name.start_with?("test") && !f.modifiers.include?("@IBAction") && !f.modifiers.include?("override") && !f.modifiers.include?("@objc") && !f.modifiers.include?("@IBInspectable")
  201. }
  202. end
  203.  
  204. end
  205.  
  206. class String
  207. def black; "\e[30m#{self}\e[0m" end
  208. def red; "\e[31m#{self}\e[0m" end
  209. def green; "\e[32m#{self}\e[0m" end
  210. def yellow; "\e[33m#{self}\e[0m" end
  211. def blue; "\e[34m#{self}\e[0m" end
  212. def magenta; "\e[35m#{self}\e[0m" end
  213. def cyan; "\e[36m#{self}\e[0m" end
  214. def gray; "\e[37m#{self}\e[0m" end
  215.  
  216. def bg_black; "\e[40m#{self}\e[0m" end
  217. def bg_red; "\e[41m#{self}\e[0m" end
  218. def bg_green; "\e[42m#{self}\e[0m" end
  219. def bg_brown; "\e[43m#{self}\e[0m" end
  220. def bg_blue; "\e[44m#{self}\e[0m" end
  221. def bg_magenta; "\e[45m#{self}\e[0m" end
  222. def bg_cyan; "\e[46m#{self}\e[0m" end
  223. def bg_gray; "\e[47m#{self}\e[0m" end
  224.  
  225. def bold; "\e[1m#{self}\e[22m" end
  226. def italic; "\e[3m#{self}\e[23m" end
  227. def underline; "\e[4m#{self}\e[24m" end
  228. def blink; "\e[5m#{self}\e[25m" end
  229. def reverse_color; "\e[7m#{self}\e[27m" end
  230. end
  231.  
  232.  
  233. Unused.new.find
Add Comment
Please, Sign In to add comment