fui 0.4.1 → 0.5.0

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
- 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.