fui 0.4.1 → 0.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3004280a95452a6d9d564a749e4e4401d141018b
4
- data.tar.gz: 7833b104af4e870cb65df25671a0dc11f3985f1c
2
+ SHA256:
3
+ metadata.gz: ca2369b75631de675a012aa298db4edc1976fba82ca689411be60347be016525
4
+ data.tar.gz: 179e9195e0ededab573b0dee845cb4c60b766ce3e64cf001bf86d6be8a937c8e
5
5
  SHA512:
6
- metadata.gz: 348e74f6fe709c2eb3cf15c50f4665431b5a39654c4daea299461329c22b696cff75dfd62c0d3a8374bcbe68d0cec06f2075bd3585b377ad8de3988872186695
7
- data.tar.gz: 1193c75c6bb5cd05f82732179f6e3cc6b5bbcd9a5fd654e65174e3be10efb15edcc0a9837b8f0967feb1719e1a39e63db9a3bc5801336a695dce35a426b976ac
6
+ metadata.gz: 8f2b6927e03089fee397a11ea73ce511c88ddbbe15652e106e4f1801fc677351f10f90cb39734bb2279cdda003e8c577108c9efab324a3dfe848b90c01133745
7
+ data.tar.gz: 2039608e5a2394039f3d576838da7e7324cdd8588bdca12cb15570a3d729446885568d2e1e3d05fd7777a9e9313d3f500c775368eb77a667a3495c470e5928cf
@@ -1,29 +1,35 @@
1
- ### 0.4.2 (Next)
1
+ ### 0.5.0 (2018/12/19)
2
2
 
3
- * Your contribution here.
3
+ * [#29](https://github.com/dblock/fui/pull/29): Added support for ignoring paths through `-i`, `--ignore-path` - [@jeffctown](https://github.com/jeffctown).
4
+ * [#28](https://github.com/dblock/fui/pull/28): Added support for finding global imports (bracket notation) - [@jeffctown](https://github.com/jeffctown).
5
+ * [#28](https://github.com/dblock/fui/pull/28): 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
+ * [#28](https://github.com/dblock/fui/pull/28): The `--ignorexib` option has been renamed to `--ignore-xib-files` - [@jeffctown](https://github.com/jeffctown).
7
+ * [#31](https://github.com/dblock/fui/pull/31): Added Danger, PR linter and a README TOC - [@jeffctown](https://github.com/jeffctown).
8
+ * [#32](https://github.com/dblock/fui/pull/32): Added support for ignoring bridging headers - [@jeffctown](https://github.com/jeffctown).
9
+ * [#33](https://github.com/dblock/fui/pull/33): Added RELEASING.md to document release process - [@jeffctown](https://github.com/jeffctown).
4
10
 
5
- ### 0.4.1 (8/16/2017)
11
+ ### 0.4.1 (2017/8/16)
6
12
 
7
13
  * [#24](https://github.com/dblock/fui/pull/24): Support .mm files - [@shachlan](https://github.com/Shachlan).
8
14
 
9
- ### 0.4.0 (5/14/2016)
15
+ ### 0.4.0 (2016/5/14)
10
16
 
11
17
  * [#20](https://github.com/dblock/fui/pull/20): Added `-x`, `--ignorexib`, find unused classes referenced from its own XIB - [@Ezor](https://github.com/Ezor).
12
18
 
13
- ### 0.3.0 (2/7/2014)
19
+ ### 0.3.0 (2014/2/7)
14
20
 
15
21
  * [#5](https://github.com/dblock/fui/issues/5): Explicitly require Ruby 1.9.3 or later in .gemspec - [@paulyoung](https://github.com/paulyoung).
16
22
  * [#4](https://github.com/dblock/fui/issues/4): Added support for .storyboard and .xib `customClass` references - [@dblock](https://github.com/dblock).
17
23
 
18
- ### 0.2.0 (1/23/2014)
24
+ ### 0.2.0 (2014/1/23)
19
25
 
20
26
  * By default will display "(simulation)" because no actual files are being deleted - [@dblock](https://github.com/dblock).
21
27
  * Fui's exit code with `find` will be the number of unused references found - [@dblock](https://github.com/dblock).
22
28
 
23
- ### 0.1.1 (1/22/2014)
29
+ ### 0.1.1 (2014/1/22)
24
30
 
25
31
  * Fix: properly handle .pch includes - [@dblock](https://github.com/dblock).
26
32
 
27
- ### 0.1.0 (1/22/2014)
33
+ ### 0.1.0 (2014/1/22)
28
34
 
29
35
  * Initial public release, based on code by [@dstnbrkr](https://github.com/dstnbrkr) - [@dblock](https://github.com/dblock).
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2013 Daniel Doubrovkine.
3
+ Copyright (c) 2014-2018 Daniel Doubrovkine.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -6,19 +6,35 @@ Fui
6
6
 
7
7
  Find unused Objective-C imports.
8
8
 
9
+ # Table of Contents
10
+
11
+ - [Usage](#usage)
12
+ - [Get Help](#get-help)
13
+ - [Find Unused Classes in the Current Directory](#find-unused-classes-in-the-current-directory)
14
+ - [Find Unused Classes in any Path](#find-unused-classes-in-any-path)
15
+ - [Skip Interface Builder (.xib) Files](#skip-interface-builder-xib-files)
16
+ - [Ignore Local Imports](#ignore-local-imports)
17
+ - [Ignore Global Imports](#ignore-global-imports)
18
+ - [Ignore a Path](#ignore-a-path)
19
+ - [Ignore Multiple Paths](#ignore-multiple-paths)
20
+ - [Delete All Unused Class Files with Prompt](#delete-all-unused-class-files-with-prompt)
21
+ - [Xcode Plugin](#xcode-plugin)
22
+ - [Contributing](#contributing)
23
+ - [Copyright and License](#copyright-and-license)
24
+
9
25
  ## Usage
10
26
 
11
27
  ```
12
28
  gem install fui
13
29
  ```
14
30
 
15
- #### Get Help
31
+ ### Get Help
16
32
 
17
33
  ```
18
34
  fui help
19
35
  ```
20
36
 
21
- #### Find Unused Classes in the Current Directory
37
+ ### Find Unused Classes in the Current Directory
22
38
 
23
39
  ```
24
40
  fui find
@@ -26,27 +42,59 @@ fui find
26
42
 
27
43
  The `find` command lists all the files that contain unused imports and exits with the number of files found.
28
44
 
29
- #### Find Unused Classes in a Path
45
+ ### Find Unused Classes in any Path
30
46
 
31
47
  ```
32
48
  fui --path=~/source/project/Name find
33
49
  ```
34
50
 
35
- #### Find Unused Classes in a Path Skipping Interface Builder (.xib) Files
51
+ ### Skip Interface Builder (.xib) Files
36
52
 
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.
53
+ Running `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.
38
54
 
39
55
  ```
40
56
  fui -x --path=~/source/project/Name find
41
57
  ```
42
58
 
43
- #### Delete All Unused Class Files w/ Prompt
59
+ ### Ignore Local Imports
60
+
61
+ Running `fui` with `-l` (or `--ignore-local-imports`) will, for example, mark `Foo.h` as unused when `Bar.h` contains a local (quotation syntax) import of `Foo.h` (eg. `#import Foo.h`).
62
+
63
+ ```
64
+ fui -l --path=~/source/project/Name find
65
+ ```
66
+
67
+ ### Ignore Global Imports
68
+
69
+ Running `fui` with `-g` (or `--ignore-global-imports`) will, for example, mark `Foo.h` as unused when `Bar.h` contains a global (bracket syntax) import of `Foo.h` (eg. `#import <Framework/Foo.h>`).
70
+
71
+ ```
72
+ fui -g --path=~/source/project/Name find
73
+ ```
74
+
75
+ ### Ignore a Path
76
+
77
+ Running `fui` with `-i` (or `--ignore-path`) will, for example, ignore a `Pods` folder when searching for headers or referencing files.
78
+
79
+ ```
80
+ fui --path=~/source/project/Name --ignore-path=Pods find
81
+ ```
82
+
83
+ ### Ignore Multiple Paths
84
+
85
+ Running `fui` with `-i` (or `--ignore-path`) can ignore multiple folders when searching for headers or referencing files.
86
+
87
+ ```
88
+ fui --path=~/source/project/Name --ignore-path=Pods --ignore-path=Libraries find
89
+ ```
90
+
91
+ ### Delete All Unused Class Files with Prompt
44
92
 
45
93
  ```
46
94
  fui --path=~/source/project/Name delete --perform --prompt
47
95
  ```
48
96
 
49
- #### Xcode Plugin
97
+ ## Xcode Plugin
50
98
 
51
99
  Use [xcfui](https://github.com/jcavar/xcfui) for integration with Xcode.
52
100
 
@@ -56,6 +104,6 @@ There're [a few feature requests and known issues](https://github.com/dblock/fui
56
104
 
57
105
  ## Copyright and License
58
106
 
59
- Copyright (c) 2014, Daniel Doubrovkine, [Artsy](http://artsy.github.io), based on code by [Dustin Barker](https://github.com/dstnbrkr).
107
+ Copyright (c) 2014-2018, Daniel Doubrovkine, [Artsy](http://artsy.github.io), based on code by [Dustin Barker](https://github.com/dstnbrkr).
60
108
 
61
109
  This project is licensed under the [MIT License](LICENSE.md).
@@ -0,0 +1,61 @@
1
+ # Releasing fui
2
+
3
+ There are no hard rules about when to release fui. Release bug fixes frequently, features not so frequently, and breaking changes rarely.
4
+
5
+ ### Release
6
+
7
+ Run tests, check that all tests succeed locally.
8
+
9
+ ```
10
+ bundle install
11
+ rake
12
+ ```
13
+
14
+ Check that the last build succeeded in [Travis CI](https://travis-ci.org/dblock/fui).
15
+
16
+ Change "Next" in [CHANGELOG.md](CHANGELOG.md) to the current date.
17
+
18
+ ```
19
+ ### 0.4.0 (2016/5/14)
20
+ ```
21
+
22
+ Remove the line with "Your contribution here.", since there will be no more contributions to this release.
23
+
24
+ Commit your changes.
25
+
26
+ ```
27
+ git add CHANGELOG.md
28
+ git commit -m "Preparing for release, 0.4.0."
29
+ git push origin master
30
+ ```
31
+
32
+ Release.
33
+
34
+ ```
35
+ $ rake release
36
+
37
+ fui 0.4.0 built to pkg/fui-0.4.0.gem.
38
+ Tagged v0.4.0.
39
+ Pushed git commits and tags.
40
+ Pushed fui 0.4.0 to rubygems.org.
41
+ ```
42
+
43
+ ### Prepare for the Next Version
44
+
45
+ Add the next release to [CHANGELOG.md](CHANGELOG.md).
46
+
47
+ ```
48
+ ### 0.4.1 (Next)
49
+
50
+ * Your contribution here.
51
+ ```
52
+
53
+ Increment the third version number in [lib/fui/version.rb](lib/fui/version.rb).
54
+
55
+ Commit your changes.
56
+
57
+ ```
58
+ git add CHANGELOG.md lib/fui/version.rb
59
+ git commit -m "Preparing for next development iteration, 0.4.1."
60
+ git push origin master
61
+ ```
data/bin/fui CHANGED
@@ -6,13 +6,16 @@ include GLI::App
6
6
 
7
7
  program_desc 'Find unused imports in an Objective-C codebase.'
8
8
 
9
- flag [:p, :path], desc: 'Path to search.', default_value: Dir.pwd
10
- switch [:v, :verbose], desc: 'Produce verbose output.', default_value: false
11
- switch [:x, :ignorexib], desc: 'Ignore interface builder (.xib) files.', default_value: false
9
+ flag %i[p path], desc: 'Path to search.', default_value: Dir.pwd
10
+ flag %i[i ignore-path], desc: 'Path to ignore.', default_value: nil, multiple: true
11
+ switch %i[v verbose], desc: 'Produce verbose output.', default_value: false
12
+ switch %i[x ignore-xib-files], desc: 'Ignore interface builder (.xib) files.', default_value: false
13
+ switch %i[g ignore-global-imports], desc: 'Ignores imports using a global (angle bracket) format.', default_value: false
14
+ switch %i[l ignore-local-imports], desc: 'Ignores imports using a local (quote) format.', default_value: false
12
15
 
13
16
  default_command :find
14
17
 
15
- pre do |global_options, _command, options, _args|
18
+ pre do |global_options, _command, _options, _args|
16
19
  options = global_options.dup
17
20
  path = options.delete(:path)
18
21
  $fui = Fui::Finder.new(path, options)
@@ -40,8 +43,8 @@ end
40
43
 
41
44
  desc 'Delete header and implementation files of unused classes'
42
45
  command :delete do |c|
43
- c.switch [:t, :prompt], desc: 'Prompt on delete', default_value: true
44
- c.switch [:f, :perform], desc: 'Actually perform deletion', default_value: false, negatable: false
46
+ c.switch %i[t prompt], desc: 'Prompt on delete', default_value: true
47
+ c.switch %i[f perform], desc: 'Actually perform deletion', default_value: false, negatable: false
45
48
 
46
49
  c.action do |global_options, options, _args|
47
50
  begin
@@ -67,6 +70,7 @@ command :delete do |c|
67
70
  File.delete(k.path) if options[:perform]
68
71
  impl_path = k.path.gsub(/\.h$/, '.m')
69
72
  next unless File.exist?(impl_path)
73
+
70
74
  relative_path = Pathname.new(impl_path).relative_path_from(root).to_s
71
75
  if global_options[:verbose]
72
76
  puts "Removing #{relative_path}#{options[:perform] ? '' : ' (simulation)'}\r\n"
data/lib/fui.rb CHANGED
@@ -4,3 +4,4 @@ require 'pathname'
4
4
  require 'fui/version'
5
5
  require 'fui/header'
6
6
  require 'fui/finder'
7
+ require 'fui/project'
@@ -1,4 +1,5 @@
1
1
  module Fui
2
+ # A class to find various things in an Objective C project.
2
3
  class Finder
3
4
  attr_reader :path, :options
4
5
 
@@ -9,7 +10,21 @@ module Fui
9
10
  end
10
11
 
11
12
  def headers
12
- @headers ||= Finder.find(path) { |path| Header.header?(path) }.collect { |path| Header.new(path) }
13
+ @headers ||= find(path) { |path| Header.header?(path) }.collect { |path| Header.new(path) }
14
+ end
15
+
16
+ def bridging_headers
17
+ @bridging_headers ||= find(path) { |path| Project.project?(path) }.collect { |path| Project.new(path).bridging_headers(options[:verbose]) }
18
+ end
19
+
20
+ def ignores
21
+ return unless options['ignore-path']
22
+
23
+ @ignores ||= options['ignore-path'].map do |i|
24
+ raise Errno::ENOENT, i unless Dir.exist?(i)
25
+
26
+ Pathname(i)
27
+ end
13
28
  end
14
29
 
15
30
  def references(&block)
@@ -19,7 +34,6 @@ module Fui
19
34
  references[header] = []
20
35
  end
21
36
  Find.find(path) do |path|
22
- next unless File.ftype(path) == 'file'
23
37
  if ['.m', '.mm', '.h', '.pch'].include?(File.extname(path))
24
38
  process_code references, path, &block
25
39
  elsif ['.storyboard', '.xib'].include?(File.extname(path))
@@ -31,27 +45,53 @@ module Fui
31
45
  end
32
46
 
33
47
  def unused_references(&block)
34
- @unused_references ||= references(&block).select { |_k, v| v.count == 0 }
48
+ @unused_references ||= references(&block).select { |k, v| v.count.zero? && !bridging_headers.include?(k.filename) }
35
49
  end
36
50
 
37
51
  private
38
52
 
39
53
  # Find all files for which the block yields.
40
- def self.find(path)
54
+ def find(path)
41
55
  results = []
42
56
  Find.find(path) do |fpath|
57
+ if FileTest.directory?(fpath)
58
+ next unless ignores
59
+
60
+ ignores.each do |ignore|
61
+ next unless fpath.include?(ignore.realpath.to_s)
62
+
63
+ puts "Ignoring Directory: #{fpath}" if options[:verbose]
64
+ Find.prune
65
+ end
66
+ end
43
67
  results << fpath if yield fpath
44
68
  end
45
69
  results
46
70
  end
47
71
 
72
+ def local_imported(file_contents, header)
73
+ return false if options['ignore-local-imports']
74
+
75
+ file_contents.include?("#import \"#{header.filename}\"")
76
+ end
77
+
78
+ def global_imported(file_contents, header)
79
+ return false if options['ignore-global-imports']
80
+
81
+ escaped_header = Regexp.quote(header.filename)
82
+ regex = '(#import\s{1}<.+\/' + escaped_header + '>)'
83
+ file_contents.match(regex)
84
+ end
85
+
48
86
  def process_code(references, path)
49
87
  File.open(path) do |file|
50
88
  yield path if block_given?
51
- filename = File.basename(path)
52
89
  headers.each do |header|
53
90
  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}\"")
91
+ file_contents = File.read(file)
92
+ global_import_exists = global_imported(file_contents, header)
93
+ local_import_exists = local_imported(file_contents, header)
94
+ references[header] << path if filename_without_extension != header.filename_without_extension && (local_import_exists || global_import_exists)
55
95
  end
56
96
  end
57
97
  end
@@ -61,7 +101,8 @@ module Fui
61
101
  yield path if block_given?
62
102
  headers.each do |header|
63
103
  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}\"")
104
+ check_xibs = !options['ignore-xib-files']
105
+ references[header] << path if (check_xibs || filename_without_extension != header.filename_without_extension) && File.read(file).include?("customClass=\"#{header.filename_without_extension}\"")
65
106
  end
66
107
  end
67
108
  end
@@ -1,4 +1,5 @@
1
1
  module Fui
2
+ # Represents a Header (.h) file
2
3
  class Header
3
4
  attr_accessor :filename, :filename_without_extension, :path
4
5
 
@@ -0,0 +1,32 @@
1
+ module Fui
2
+ # Represents an Xcode Project pbxproj file
3
+ class Project
4
+ attr_accessor :filename, :bridging_header, :path
5
+
6
+ def self.project?(path)
7
+ File.extname(path) == '.pbxproj'
8
+ end
9
+
10
+ def initialize(path)
11
+ @path = path
12
+ @filename = File.basename(path)
13
+ end
14
+
15
+ def bridging_headers(verbose)
16
+ @bridging_headers ||= begin
17
+ regex = /(SWIFT_OBJC_BRIDGING_HEADER) = \".+\"/
18
+ bridging_headers = []
19
+ File.new(path).grep regex do |result|
20
+ tokens = result.split('"')
21
+ next if tokens.length < 2
22
+
23
+ path_tokens = tokens[1].split('/')
24
+ bridging_header = path_tokens[path_tokens.length - 1]
25
+ puts "Bridging Header Found: #{bridging_header} in #{project_path}." if verbose
26
+ bridging_headers << bridging_header
27
+ end
28
+ bridging_headers.uniq
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,3 @@
1
1
  module Fui
2
- VERSION = '0.4.1'.freeze
2
+ VERSION = '0.5.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Doubrovkine
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-17 00:00:00.000000000 Z
11
+ date: 2018-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  description:
@@ -35,10 +35,12 @@ files:
35
35
  - CONTRIBUTING.md
36
36
  - LICENSE.md
37
37
  - README.md
38
+ - RELEASING.md
38
39
  - bin/fui
39
40
  - lib/fui.rb
40
41
  - lib/fui/finder.rb
41
42
  - lib/fui/header.rb
43
+ - lib/fui/project.rb
42
44
  - lib/fui/version.rb
43
45
  homepage: http://github.com/dblock/fui
44
46
  licenses:
@@ -50,17 +52,17 @@ require_paths:
50
52
  - lib
51
53
  required_ruby_version: !ruby/object:Gem::Requirement
52
54
  requirements:
53
- - - '>='
55
+ - - ">="
54
56
  - !ruby/object:Gem::Version
55
57
  version: 1.9.3
56
58
  required_rubygems_version: !ruby/object:Gem::Requirement
57
59
  requirements:
58
- - - '>='
60
+ - - ">="
59
61
  - !ruby/object:Gem::Version
60
62
  version: 1.3.6
61
63
  requirements: []
62
64
  rubyforge_project:
63
- rubygems_version: 2.6.12
65
+ rubygems_version: 2.7.8
64
66
  signing_key:
65
67
  specification_version: 4
66
68
  summary: Find unused Objective-C imports.