Skip to content

Commit 6bd65ce

Browse files
jeffctowndblock
authored andcommitted
Adding a global switch that will check for global header imports (dblock#28)
1 parent 7ecc03a commit 6bd65ce

File tree

10 files changed

+110
-7
lines changed

10 files changed

+110
-7
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
* Your contribution here.
44

5+
* [#28](https://github.com/dblock/fui/pull/28): Added support for finding global imports (bracket notation). Added ability to turn off global or local import checks through `-g`, `--ignore-global-imports` or `-l`, `--ignore-local-imports`.- [@jeffctown](https://github.com/jeffctown).
6+
57
### 0.4.1 (8/16/2017)
68

79
* [#24](https://github.com/dblock/fui/pull/24): Support .mm files - [@shachlan](https://github.com/Shachlan).

README.md

+20-1
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,31 @@ fui --path=~/source/project/Name find
3434

3535
#### Find Unused Classes in a Path Skipping Interface Builder (.xib) Files
3636

37-
ForRunning `fui` with `-x` (or `--ignorexib`) will, for example, mark `Foo.h` as unused when `Foo.xib` holds a reference to the `Foo` class and no other references to Foo.h exist.
37+
ForRunning `fui` with `-x` (or `--ignore-xib-files`) will, for example, mark `Foo.h` as unused when `Foo.xib` holds a reference to the `Foo` class and no other references to Foo.h exist.
3838

3939
```
4040
fui -x --path=~/source/project/Name find
4141
```
4242

43+
#### Find Unused Classes in a Path Ignoring Local (quotation syntax) Imports
44+
45+
For Running `fui` with `-l` (or `--ignore-local-imports`) will, for example, mark `Foo.h` as unused when `Bar.h` contains a local import of `Foo.h` (`#import Foo.h`)
46+
47+
```
48+
fui -l --path=~/source/project/Name find
49+
50+
```
51+
52+
#### Find Unused Classes in a Path Ignoring Global (bracket syntax) Imports
53+
54+
For Running `fui` with `-g` (or `--ignore-global-imports`) will, for example, mark `Foo.h` as unused when `Bar.h` contains a global import of `Foo.h` (`#import <Framework/Foo.h>`)
55+
56+
```
57+
fui -g --path=~/source/project/Name find
58+
59+
```
60+
61+
4362
#### Delete All Unused Class Files w/ Prompt
4463

4564
```

bin/fui

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ program_desc 'Find unused imports in an Objective-C codebase.'
88

99
flag [:p, :path], desc: 'Path to search.', default_value: Dir.pwd
1010
switch [:v, :verbose], desc: 'Produce verbose output.', default_value: false
11-
switch [:x, :ignorexib], desc: 'Ignore interface builder (.xib) files.', default_value: false
11+
switch [:x, :'ignore-xib-files'], desc: 'Ignore interface builder (.xib) files.', default_value: false
12+
switch [:g, :'ignore-global-imports'], desc: 'Ignores imports using a global (angle bracket) format.', default_value: false
13+
switch [:l, :'ignore-local-imports'], desc: 'Ignores imports using a local (quote) format.', default_value: false
1214

1315
default_command :find
1416

lib/fui/finder.rb

+18-2
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,33 @@ def process_code(references, path)
5151
filename = File.basename(path)
5252
headers.each do |header|
5353
filename_without_extension = File.basename(path, File.extname(path))
54-
references[header] << path if filename_without_extension != header.filename_without_extension && File.read(file).include?("#import \"#{header.filename}\"")
54+
file_contents = File.read(file)
55+
global_import_exists = global_imported(file_contents, header)
56+
local_import_exists = local_imported(file_contents, header)
57+
references[header] << path if filename_without_extension != header.filename_without_extension && (local_import_exists || global_import_exists)
5558
end
5659
end
5760
end
5861

62+
def local_imported(file_contents, header)
63+
return false if options['ignore-local-imports']
64+
file_contents.include?("#import \"#{header.filename}\"")
65+
end
66+
67+
def global_imported(file_contents, header)
68+
return false if options['ignore-global-imports']
69+
escaped_header = Regexp.quote(header.filename)
70+
regex = '(#import\s{1}<.+\/' + escaped_header + '>)'
71+
file_contents.match(regex)
72+
end
73+
5974
def process_xml(references, path)
6075
File.open(path) do |file|
6176
yield path if block_given?
6277
headers.each do |header|
6378
filename_without_extension = File.basename(path, File.extname(path))
64-
references[header] << path if (!options['ignorexib'] || filename_without_extension != header.filename_without_extension) && File.read(file).include?("customClass=\"#{header.filename_without_extension}\"")
79+
check_xibs = !options['ignore-xib-files']
80+
references[header] << path if (check_xibs || filename_without_extension != header.filename_without_extension) && File.read(file).include?("customClass=\"#{header.filename_without_extension}\"")
6581
end
6682
end
6783
end

spec/fixtures/global_import/header.h

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#import <framework/used_class.h>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//
2+
// UnusedClass.h
3+
// FUI
4+
//
5+
6+
@interface UnusedClass
7+
8+
@end
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//
2+
// UnusedClass.m
3+
// FUI
4+
//
5+
6+
#import "unused_class.h"
7+
8+
@implementation UnusedClass
9+
10+
@end
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//
2+
// ImageView.h
3+
// FUI
4+
//
5+
6+
#import <UIKit/UIKit.h>
7+
8+
@interface ImageView
9+
- (NSString *)fooForBar;
10+
@end
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// UsedClass.m
3+
// FUI
4+
//
5+
6+
#import "used_class.h"
7+
8+
@implementation UsedClass
9+
- (NSString *)fooForBar
10+
{
11+
12+
}
13+
@end

spec/fui/finder_spec.rb

+25-3
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
end
102102
end
103103
end
104-
context 'ignorexib option set to false' do
104+
context 'ignore-xib-files option set to false' do
105105
before :each do
106106
@fixtures_dir = File.expand_path(File.join(__FILE__, '../../fixtures/nibself'))
107107
end
@@ -112,15 +112,37 @@
112112
end
113113
end
114114
end
115-
context 'ignorexib option set to true' do
115+
context 'ignore-xib-files option set to true' do
116116
before :each do
117117
@fixtures_dir = File.expand_path(File.join(__FILE__, '../../fixtures/nibself'))
118118
end
119119
describe '#unsed_references' do
120120
it 'finds one unused references' do
121-
finder = Fui::Finder.new(@fixtures_dir, 'ignorexib' => true)
121+
finder = Fui::Finder.new(@fixtures_dir, 'ignore-xib-files' => true)
122122
expect(finder.unused_references.count).to eq(1)
123123
end
124124
end
125125
end
126+
context 'ignore global imports option set to true' do
127+
before :each do
128+
@fixtures_dir = File.expand_path(File.join(__FILE__, '../../fixtures/global_import'))
129+
end
130+
describe '#unused_references' do
131+
it 'finds one unused global reference' do
132+
finder = Fui::Finder.new(@fixtures_dir, 'ignore-global-imports' => false)
133+
expect(Hash[finder.unused_references.map { |k, v| [k.filename, v.count] }]).to eq('header.h' => 0, 'unused_class.h' => 0)
134+
end
135+
end
136+
end
137+
context 'ignore global imports option set to false' do
138+
before :each do
139+
@fixtures_dir = File.expand_path(File.join(__FILE__, '../../fixtures/global_import'))
140+
end
141+
describe '#unused_references' do
142+
it 'finds no unused global references' do
143+
finder = Fui::Finder.new(@fixtures_dir, 'ignore-global-imports' => true)
144+
expect(Hash[finder.unused_references.map { |k, v| [k.filename, v.count] }]).to eq('header.h' => 0, 'unused_class.h' => 0, 'used_class.h' => 0)
145+
end
146+
end
147+
end
126148
end

0 commit comments

Comments
 (0)