danger-periphery 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8478fb86f4d5952f88ee7772f352049288bbc5c21f2f5d452ab7b37389b561ec
4
+ data.tar.gz: 63c976e46da5ad41bd5797adb3f1ddc83edd5c09f8d607c043757924b3b32cad
5
+ SHA512:
6
+ metadata.gz: aeae221bc8e42918a500eb3050b3bd44451a4fa4af5e2e42a77e252a64cfc17ca7213b455af830d26c1c001a0250a2af4e532303b1bce8c5e45dd2b02c817dfb
7
+ data.tar.gz: d07fd15ea7105b6fbb875d628771a70c557bbd4066246712e26e5f1599d80d6d42e078d61b22e3c0c30c677105c0da317596a2d3a60595b3f16355193a8bed48
@@ -0,0 +1,12 @@
1
+ name: Lint
2
+ on: [pull_request]
3
+ jobs:
4
+ lint:
5
+ runs-on: macOS-11
6
+ env:
7
+ DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
8
+ steps:
9
+ - uses: actions/checkout@v2
10
+ - run: bin/download_periphery
11
+ - run: bundle install
12
+ - run: bundle exec danger
@@ -0,0 +1,10 @@
1
+ name: Test
2
+ on: [push]
3
+ jobs:
4
+ unit-test:
5
+ runs-on: macOS-11
6
+ steps:
7
+ - uses: actions/checkout@v2
8
+ - run: bin/download_periphery
9
+ - run: bundle install
10
+ - run: bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ .DS_Store
2
+ .idea/
3
+ .yardoc
4
+ /tmp
5
+ Gemfile.lock
6
+ bin/lib_InternalSwiftSyntaxParser.dylib
7
+ bin/periphery
8
+ pkg
9
+ project.xcworkspace
10
+ xcuserdata
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/.rubocop.yml ADDED
@@ -0,0 +1,281 @@
1
+ # Defaults can be found here: https://github.com/bbatsov/rubocop/blob/master/config/default.yml
2
+
3
+ # If you don't like these settings, just delete this file :)
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.6
7
+ SuggestExtensions: false
8
+
9
+ Style/StringLiterals:
10
+ EnforcedStyle: double_quotes
11
+ Enabled: true
12
+
13
+ # kind_of? is a good way to check a type
14
+ Style/ClassCheck:
15
+ EnforcedStyle: kind_of?
16
+
17
+ # specs sometimes have useless assignments, which is fine
18
+ Lint/UselessAssignment:
19
+ Exclude:
20
+ - '**/spec/**/*'
21
+
22
+ # We could potentially enable the 2 below:
23
+ Layout/FirstHashElementIndentation:
24
+ Enabled: false
25
+
26
+ Layout/HashAlignment:
27
+ Enabled: false
28
+
29
+ # HoundCI doesn't like this rule
30
+ Layout/DotPosition:
31
+ Enabled: false
32
+
33
+ # We allow !! as it's an easy way to convert ot boolean
34
+ Style/DoubleNegation:
35
+ Enabled: false
36
+
37
+ # Cop supports --auto-correct.
38
+ Lint/UnusedBlockArgument:
39
+ Enabled: false
40
+
41
+ # We want to allow class Fastlane::Class
42
+ Style/ClassAndModuleChildren:
43
+ Enabled: false
44
+
45
+ Metrics/AbcSize:
46
+ Max: 60
47
+
48
+ # The %w might be confusing for new users
49
+ Style/WordArray:
50
+ MinSize: 19
51
+
52
+ # raise and fail are both okay
53
+ Style/SignalException:
54
+ Enabled: false
55
+
56
+ # Better too much 'return' than one missing
57
+ Style/RedundantReturn:
58
+ Enabled: false
59
+
60
+ # Having if in the same line might not always be good
61
+ Style/IfUnlessModifier:
62
+ Enabled: false
63
+
64
+ # and and or is okay
65
+ Style/AndOr:
66
+ Enabled: false
67
+
68
+ # Configuration parameters: CountComments.
69
+ Metrics/ClassLength:
70
+ Max: 350
71
+
72
+ Metrics/CyclomaticComplexity:
73
+ Max: 17
74
+
75
+ # Configuration parameters: AllowURI, URISchemes.
76
+ Layout/LineLength:
77
+ Max: 370
78
+
79
+ # Configuration parameters: CountKeywordArgs.
80
+ Metrics/ParameterLists:
81
+ Max: 10
82
+
83
+ Metrics/PerceivedComplexity:
84
+ Max: 18
85
+
86
+ # Sometimes it's easier to read without guards
87
+ Style/GuardClause:
88
+ Enabled: false
89
+
90
+ # something = if something_else
91
+ # that's confusing
92
+ Style/ConditionalAssignment:
93
+ Enabled: false
94
+
95
+ # Better to have too much self than missing a self
96
+ Style/RedundantSelf:
97
+ Enabled: false
98
+
99
+ Metrics/MethodLength:
100
+ Max: 60
101
+
102
+ # We're not there yet
103
+ Style/Documentation:
104
+ Enabled: false
105
+
106
+ # Adds complexity
107
+ Style/IfInsideElse:
108
+ Enabled: false
109
+
110
+ # danger specific
111
+
112
+ Style/BlockComments:
113
+ Enabled: false
114
+
115
+ Layout/MultilineMethodCallIndentation:
116
+ EnforcedStyle: indented
117
+
118
+ # FIXME: 25
119
+ Metrics/BlockLength:
120
+ Max: 345
121
+ Exclude:
122
+ - "**/*_spec.rb"
123
+
124
+ Style/MixinGrouping:
125
+ Enabled: false
126
+
127
+ Naming/FileName:
128
+ Enabled: false
129
+
130
+ Layout/HeredocIndentation:
131
+ Enabled: false
132
+
133
+ Style/SpecialGlobalVars:
134
+ Enabled: false
135
+
136
+ Style/PercentLiteralDelimiters:
137
+ PreferredDelimiters:
138
+ "%": ()
139
+ "%i": ()
140
+ "%q": ()
141
+ "%Q": ()
142
+ "%r": "{}"
143
+ "%s": ()
144
+ "%w": ()
145
+ "%W": ()
146
+ "%x": ()
147
+
148
+ Security/YAMLLoad:
149
+ Enabled: false
150
+
151
+ Gemspec/DateAssignment:
152
+ Enabled: true
153
+
154
+ Layout/LineEndStringConcatenationIndentation:
155
+ Enabled: true
156
+
157
+ Layout/SpaceBeforeBrackets:
158
+ Enabled: true
159
+
160
+ Lint/AmbiguousAssignment:
161
+ Enabled: true
162
+
163
+ Lint/AmbiguousOperatorPrecedence:
164
+ Enabled: true
165
+
166
+ Lint/AmbiguousRange:
167
+ Enabled: true
168
+
169
+ Lint/DeprecatedConstants:
170
+ Enabled: true
171
+
172
+ Lint/DuplicateBranch:
173
+ Enabled: true
174
+
175
+ Lint/DuplicateRegexpCharacterClassElement:
176
+ Enabled: true
177
+
178
+ Lint/EmptyBlock:
179
+ Enabled: true
180
+
181
+ Lint/EmptyClass:
182
+ Enabled: true
183
+
184
+ Lint/EmptyInPattern:
185
+ Enabled: true
186
+
187
+ Lint/IncompatibleIoSelectWithFiberScheduler:
188
+ Enabled: true
189
+
190
+ Lint/LambdaWithoutLiteralBlock:
191
+ Enabled: true
192
+
193
+ Lint/NoReturnInBeginEndBlocks:
194
+ Enabled: true
195
+
196
+ Lint/NumberedParameterAssignment:
197
+ Enabled: true
198
+
199
+ Lint/OrAssignmentToConstant:
200
+ Enabled: true
201
+
202
+ Lint/RedundantDirGlobSort:
203
+ Enabled: true
204
+
205
+ Lint/RequireRelativeSelfPath:
206
+ Enabled: true
207
+
208
+ Lint/SymbolConversion:
209
+ Enabled: true
210
+
211
+ Lint/ToEnumArguments:
212
+ Enabled: true
213
+
214
+ Lint/TripleQuotes:
215
+ Enabled: true
216
+
217
+ Lint/UnexpectedBlockArity:
218
+ Enabled: true
219
+
220
+ Lint/UnmodifiedReduceAccumulator:
221
+ Enabled: true
222
+
223
+ Security/IoMethods:
224
+ Enabled: true
225
+
226
+ Style/ArgumentsForwarding:
227
+ Enabled: true
228
+
229
+ Style/CollectionCompact:
230
+ Enabled: true
231
+
232
+ Style/DocumentDynamicEvalDefinition:
233
+ Enabled: true
234
+
235
+ Style/EndlessMethod:
236
+ Enabled: true
237
+
238
+ Style/HashConversion:
239
+ Enabled: true
240
+
241
+ Style/HashExcept:
242
+ Enabled: true
243
+
244
+ Style/IfWithBooleanLiteralBranches:
245
+ Enabled: true
246
+
247
+ Style/InPatternThen:
248
+ Enabled: true
249
+
250
+ Style/MultilineInPatternThen:
251
+ Enabled: true
252
+
253
+ Style/NegatedIfElseCondition:
254
+ Enabled: true
255
+
256
+ Style/NilLambda:
257
+ Enabled: true
258
+
259
+ Style/NumberedParameters:
260
+ Enabled: true
261
+
262
+ Style/NumberedParametersLimit:
263
+ Enabled: true
264
+
265
+ Style/QuotedSymbols:
266
+ Enabled: true
267
+
268
+ Style/RedundantArgument:
269
+ Enabled: true
270
+
271
+ Style/RedundantSelfAssignmentBranch:
272
+ Enabled: true
273
+
274
+ Style/SelectByRegexp:
275
+ Enabled: true
276
+
277
+ Style/StringChars:
278
+ Enabled: true
279
+
280
+ Style/SwapValues:
281
+ Enabled: true
data/Dangerfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ rubocop.lint inline_comment: true
4
+
5
+ periphery.binary_path = "bin/periphery"
6
+ periphery.scan(
7
+ project: "spec/support/fixtures/test.xcodeproj",
8
+ schemes: "test",
9
+ targets: "test"
10
+ )
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in danger-periphery.gemspec
6
+ gemspec
7
+
8
+ gem "bundler", "~> 2.0"
9
+ gem "danger"
10
+ gem "danger-rubocop"
11
+ gem "guard", "~> 2.14"
12
+ gem "guard-rspec", "~> 4.7"
13
+ gem "listen", "3.0.7"
14
+ gem "pry"
15
+ gem "rake", "~> 10.0"
16
+ gem "rspec", "~> 3.4"
17
+ gem "rubocop"
18
+ gem "yard"
data/Guardfile ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A guardfile for making Danger Plugins
4
+ # For more info see https://github.com/guard/guard#readme
5
+
6
+ # To run, use `bundle exec guard`.
7
+
8
+ guard :rspec, cmd: "bundle exec rspec" do
9
+ require "guard/rspec/dsl"
10
+ dsl = Guard::RSpec::Dsl.new(self)
11
+
12
+ # RSpec files
13
+ rspec = dsl.rspec
14
+ watch(rspec.spec_helper) { rspec.spec_dir }
15
+ watch(rspec.spec_support) { rspec.spec_dir }
16
+ watch(rspec.spec_files)
17
+
18
+ # Ruby files
19
+ ruby = dsl.ruby
20
+ dsl.watch_spec_files_for(ruby.lib_files)
21
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2021 Ryosuke Ito <rito.0305@gmail.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # danger-periphery
2
+
3
+ A Danger plugin to detect unused codes.
4
+
5
+ ## Installation
6
+
7
+ You need to install [Periphery](https://github.com/peripheryapp/periphery) beforehand.
8
+
9
+ Currently `danger-periphery` is in early development stage so it's not published to rubygems.org yet.
10
+
11
+ Write the following code in your Gemfile.
12
+
13
+ gem "danger-periphery", git: "https://github.com/manicmaniac/danger-periphery.git"
14
+
15
+ ## Usage
16
+
17
+ If you already have `.periphery.yml`, the easiest way to use is just add this to your Dangerfile.
18
+
19
+ periphery.scan
20
+
21
+ You can specify the path to executable in this way.
22
+
23
+ periphery.binary_path = "bin/periphery"
24
+
25
+ You can pass command line options to `periphery.scan` like the following.
26
+ See `periphery scan -h` for available options.
27
+
28
+ periphery.scan(
29
+ project: "Foo.xcodeproj",
30
+ schemes: ["foo", "bar"],
31
+ targets: "foo",
32
+ clean_build: true
33
+ )
34
+
35
+ ## Development
36
+
37
+ 1. Clone this repo
38
+ 2. Run `bundle install` to setup dependencies.
39
+ 3. Run `bin/download_periphery` to install Periphery.
40
+ 4. Run `bundle exec rake spec` to run the tests.
41
+ 5. Use `bundle exec guard` to automatically have tests run as you make changes.
42
+ 6. Make your changes.
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+
7
+ RSpec::Core::RakeTask.new(:specs)
8
+
9
+ task default: :specs
10
+
11
+ task :spec do
12
+ Rake::Task["specs"].invoke
13
+ Rake::Task["rubocop"].invoke
14
+ Rake::Task["spec_docs"].invoke
15
+ end
16
+
17
+ desc "Run RuboCop on the lib/specs directory"
18
+ RuboCop::RakeTask.new(:rubocop) do |task|
19
+ task.patterns = ["lib/**/*.rb", "spec/**/*.rb"]
20
+ end
21
+
22
+ desc "Ensure that the plugin passes `danger plugins lint`"
23
+ task :spec_docs do
24
+ sh "bundle exec danger plugins lint"
25
+ end
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ cd "$(dirname "$0")"
4
+ version="2.8.1"
5
+ curl -Lo periphery.zip "https://github.com/peripheryapp/periphery/releases/download/$version/periphery-v$version.zip"
6
+ unzip periphery.zip
7
+ rm periphery.zip LICENSE.md
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "danger-periphery"
9
+ spec.version = DangerPeriphery::VERSION
10
+ spec.authors = ["Ryosuke Ito"]
11
+ spec.email = ["rito.0305@gmail.com"]
12
+ spec.description = "A Danger plugin to detect unused codes."
13
+ spec.summary = spec.description
14
+ spec.homepage = "https://github.com/manicmaniac/danger-periphery"
15
+ spec.license = "MIT"
16
+ spec.required_ruby_version = ">= 2.3.0"
17
+
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "danger-plugin-api", "~> 1.0"
24
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "periphery/runner"
4
+ require "periphery/scan_log_parser"
5
+
6
+ module Danger
7
+ # Analyze Swift files and detect unused codes in your project.
8
+ # This is done using [Periphery](https://github.com/peripheryapp/periphery).
9
+ #
10
+ # @example Specifying options to Periphery.
11
+ #
12
+ # periphery.scan(
13
+ # project: "Foo.xcodeproj"
14
+ # schemes: ["foo", "bar"],
15
+ # targets: "foo",
16
+ # clean_build: true
17
+ # )
18
+ #
19
+ # @see manicmaniac/danger-periphery
20
+ # @tags swift
21
+ class DangerPeriphery < Plugin
22
+ # Path to Periphery executable.
23
+ # By default the value is nil and the executable is searched from $PATH.
24
+ # @return [String]
25
+ attr_accessor :binary_path
26
+
27
+ # Scans Swift files.
28
+ # Raises an error when Periphery executable is not found.
29
+ #
30
+ # @param [Hash] options Options passed to Periphery with the following translation rules.
31
+ # 1. Replace all underscores with hyphens in each key.
32
+ # 2. Prepend double hyphens to each key.
33
+ # 3. If value is an array, transform it to comma-separated string.
34
+ # 4. If value is true, drop value and treat it as option without argument.
35
+ # 5. Override some options like --disable-update-check, --format, --quiet and so.
36
+ # @return [void]
37
+ def scan(**options)
38
+ output = Periphery::Runner.new(binary_path).scan(options.merge(disable_update_check: true, format: "xcode", quiet: true))
39
+ entries = Periphery::ScanLogParser.new.parse(output)
40
+ files = files_in_diff
41
+ entries.
42
+ select { |entry| files.include?(entry.path) }.
43
+ each { |entry| warn(entry.message, file: entry.path, line: entry.line) }
44
+ end
45
+
46
+ private
47
+
48
+ def files_in_diff
49
+ # Taken from https://github.com/ashfurrow/danger-ruby-swiftlint/blob/5184909aab00f12954088684bbf2ce5627e08ed6/lib/danger_plugin.rb#L214-L216
50
+ renamed_files_hash = git.renamed_files.map { |rename| [rename[:before], rename[:after]] }.to_h
51
+ post_rename_modified_files = git.modified_files.map { |modified_file| renamed_files_hash[modified_file] || modified_file }
52
+ (post_rename_modified_files - git.deleted_files) + git.added_files
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+
5
+ module Periphery
6
+ class Runner
7
+ attr_reader :binary_path
8
+
9
+ def initialize(binary_path)
10
+ @binary_path = binary_path || "periphery"
11
+ end
12
+
13
+ def scan(options)
14
+ arguments = [binary_path, "scan"] + scan_arguments(options)
15
+ stdout, stderr, status = Open3.capture3(*arguments)
16
+ raise "error: #{arguments} exited with status code #{status.exitstatus}. #{stderr}" unless status.success?
17
+
18
+ stdout
19
+ end
20
+
21
+ def scan_arguments(options)
22
+ options.
23
+ select { |_key, value| value }.
24
+ map { |key, value| value.kind_of?(TrueClass) ? [key, nil] : [key, value] }.
25
+ map { |key, value| value.kind_of?(Array) ? [key, value.join(",")] : [key, value] }.
26
+ map { |key, value| ["--#{key.to_s.tr('_', '-')}", value] }.
27
+ flatten.
28
+ compact
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Periphery
4
+ class ScanLogParser
5
+ def parse(string)
6
+ string.lines.map do |line|
7
+ match = line.match(/^(?<path>.+):(?<line>\d+):(?<column>\d+): warning: (?<message>.*)\n?$/)
8
+ ScanLogEntry.new(relative_path(match[:path]), match[:line].to_i, match[:column].to_i, match[:message]) if match
9
+ end.compact
10
+ end
11
+
12
+ private
13
+
14
+ def relative_path(path, base = Pathname.getwd)
15
+ Pathname.new(path).relative_path_from(base).to_s
16
+ end
17
+ end
18
+
19
+ ScanLogEntry = Struct.new(:path, :line, :column, :message)
20
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DangerPeriphery
4
+ VERSION = "0.0.1"
5
+ end