Skip to content

Commit

Permalink
improve dead code checking
Browse files Browse the repository at this point in the history
  • Loading branch information
porter-stripe committed Sep 27, 2024
1 parent 7c993dc commit a42f3ac
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 36 deletions.
22 changes: 1 addition & 21 deletions .github/workflows/find-dead-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,7 @@ jobs:
- name: Compare Unused Code JSON Files
id: compare-dead-code
run: |
# Compare the keys in the JSON files to find new dead code
ruby -r json -e '
master_file = "unused_code_master.json"
feature_file = "unused_code_feature.json"
output_file = "new_dead_code.json"
master_unused_code = JSON.parse(File.read(master_file))
feature_unused_code = JSON.parse(File.read(feature_file))
new_dead_code = feature_unused_code.reject { |k, _| master_unused_code.key?(k) }
if new_dead_code.size > 200
puts "More than 200 keys present, skipping. This usually happens if a build fails"
elsif new_dead_code.empty?
puts "No new dead code detected."
else
File.write(output_file, JSON.pretty_generate(new_dead_code) + "\n")
end
'
ruby ci_scripts/dead_code/compare_unused_code.rb unused_code_master.json unused_code_feature.json
# Check if new_dead_code.json exists and is not empty
if [ -s new_dead_code.json ]; then
echo "New dead code detected."
Expand Down
5 changes: 1 addition & 4 deletions .periphery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,13 @@ targets:
# - UI Examples

retain_public: true
retain_objc_accessible: true
retain_objc_accessible: false
retain_objc_annotated: true
retain_objc_protocols: true

retain_ibaction: true
retain_iboutlet: true
retain_ibinspectable: true

analyze_tests: true

verbose: true

build_arguments:
Expand Down
44 changes: 44 additions & 0 deletions ci_scripts/dead_code/compare_unused_code.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env ruby
require 'json'

# Check for correct usage
if ARGV.length != 2
puts "Usage: ruby ci_scripts/dead_code/compare_unused_code.rb <master_json_file> <feature_json_file>"
exit 1
end

master_json_file = ARGV[0]
feature_json_file = ARGV[1]
diff_json_file = "new_dead_code.json"

# Load JSON data
begin
master_unused_code = JSON.parse(File.read(master_json_file))
rescue Errno::ENOENT
puts "Master JSON file not found: #{master_json_file}"
master_unused_code = {}
rescue JSON::ParserError => e
puts "Error parsing master JSON file: #{e}"
master_unused_code = {}
end

begin
feature_unused_code = JSON.parse(File.read(feature_json_file))
rescue Errno::ENOENT
puts "Feature JSON file not found: #{feature_json_file}"
feature_unused_code = {}
rescue JSON::ParserError => e
puts "Error parsing feature JSON file: #{e}"
feature_unused_code = {}
end

# Compute the difference: keys present in feature_data but not in master_data
new_dead_code = feature_unused_code.reject { |k, _| master_unused_code.key?(k) }

if new_dead_code.size > 200
puts "More than 200 keys present, skipping. This usually happens if a build fails"
elsif new_dead_code.empty?
puts "No new dead code detected."
else
File.write(diff_json_file, JSON.pretty_generate(new_dead_code) + "\n")
end
51 changes: 40 additions & 11 deletions ci_scripts/dead_code/process_periphery_output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,56 @@
output_json_file = ARGV[1]

unused_code = {}
processed_lines = 0
matched_lines = 0
skipped_lines = 0

File.foreach(periphery_output_file) do |line|
line.chomp!

# Remove full file path and extract relevant information
# Example line:
# /path/to/file/SimpleMandateTextView.swift:29:17: warning: Initializer 'init(mandateText:theme:)' is unused
# Increment the total processed lines
processed_lines += 1

if line =~ %r{^(?:.*/)?(.+?)(?::\d+:\d+)?\s*:?\s*warning:\s*(?:.+?)\s+'(.+?)'\s+is unused$}
filename = $1
identifier = $2
# Process lines that contain ".swift" and either "unused" or "warning" (case-insensitive)
if line.include?('.swift') && (line.downcase.include?('unused') || line.downcase.include?('warning'))
# Split the line into up to 4 parts based on colon
# Example line:
# /path/to/file/SimpleMandateTextView.swift:29:17: warning: Initializer 'init(mandateText:theme:)' is unused

key = "#{filename}_#{identifier}"
parts = line.split(':', 4) # Split into 4 parts at most

unused_code[key] = "#{filename}: warning: #{identifier} is unused"
if parts.length >= 4
file_path = parts[0].strip
# line_num = parts[1].strip # Not needed
# col_num = parts[2].strip # Not needed
warning_message = parts[3].strip

# Extract the filename from the file path
filename = File.basename(file_path)

# Remove 'warning:' from the warning_message if present (case-insensitive)
warning_text = warning_message.sub(/^warning:\s*/i, '')

# Construct the full warning message without line and column numbers
# Format: Filename.swift: warning: Message
full_warning = "#{filename}: warning: #{warning_text}"

# Assign the same string as both key and value
unused_code[full_warning] = full_warning

matched_lines += 1
else
puts "Skipping improperly formatted line: #{line}"
skipped_lines += 1
end
else
# Handle lines that don't match the expected pattern
puts "Skipping unrecognized line: #{line}"
# Handle lines that don't match criteria
skipped_lines += 1
end
end


# Write the unused_code hash to the output JSON file with a newline at the end
File.open(output_json_file, 'w') do |f|
f.write(JSON.pretty_generate(unused_code))
f.write(JSON.pretty_generate(unused_code) + "\n")
end

0 comments on commit a42f3ac

Please sign in to comment.