danger-periphery 0.0.1
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 +7 -0
- data/.github/workflows/lint.yml +12 -0
- data/.github/workflows/test.yml +10 -0
- data/.gitignore +10 -0
- data/.rspec +3 -0
- data/.rubocop.yml +281 -0
- data/Dangerfile +10 -0
- data/Gemfile +18 -0
- data/Guardfile +21 -0
- data/LICENSE.txt +22 -0
- data/README.md +42 -0
- data/Rakefile +25 -0
- data/bin/download_periphery +7 -0
- data/danger-periphery.gemspec +24 -0
- data/lib/danger_plugin.rb +55 -0
- data/lib/periphery/runner.rb +31 -0
- data/lib/periphery/scan_log_parser.rb +20 -0
- data/lib/version.rb +5 -0
- data/spec/danger_plugin_spec.rb +88 -0
- data/spec/periphery/runner_spec.rb +78 -0
- data/spec/periphery/scan_log_parser_spec.rb +50 -0
- data/spec/spec_helper.rb +83 -0
- data/spec/support/fixtures/github_pr.json +381 -0
- data/spec/support/fixtures/test/main.swift +3 -0
- data/spec/support/fixtures/test.xcodeproj/project.pbxproj +286 -0
- metadata +89 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path("spec_helper", __dir__)
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
describe Danger::DangerPeriphery do
|
7
|
+
it "should be a plugin" do
|
8
|
+
expect(Danger::DangerPeriphery.new(nil)).to be_a Danger::Plugin
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with Dangerfile" do
|
12
|
+
let(:dangerfile) { testing_dangerfile }
|
13
|
+
let(:periphery) { dangerfile.periphery }
|
14
|
+
|
15
|
+
before do
|
16
|
+
periphery.binary_path = binary("periphery")
|
17
|
+
json = File.read("#{File.dirname(__FILE__)}/support/fixtures/github_pr.json") # example json: `curl https://api.github.com/repos/danger/danger-plugin-template/pulls/18 > github_pr.json`
|
18
|
+
allow(periphery.github).to receive(:pr_json).and_return(json)
|
19
|
+
allow(Pathname).to receive(:getwd).and_return fixtures_path
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when periphery is not installed" do
|
23
|
+
before { periphery.binary_path = "not_installed" }
|
24
|
+
|
25
|
+
it "fails with error" do
|
26
|
+
expect { periphery.scan }.to raise_error Errno::ENOENT
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when .swift files not in diff" do
|
31
|
+
before do
|
32
|
+
allow(periphery.git).to receive(:renamed_files).and_return []
|
33
|
+
allow(periphery.git).to receive(:modified_files).and_return []
|
34
|
+
allow(periphery.git).to receive(:deleted_files).and_return []
|
35
|
+
allow(periphery.git).to receive(:added_files).and_return []
|
36
|
+
end
|
37
|
+
|
38
|
+
it "reports nothing" do
|
39
|
+
periphery.scan(
|
40
|
+
project: fixture("test.xcodeproj"),
|
41
|
+
targets: "test",
|
42
|
+
schemes: "test"
|
43
|
+
)
|
44
|
+
|
45
|
+
expect(dangerfile.status_report[:warnings]).to be_empty
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when .swift files were added" do
|
50
|
+
before do
|
51
|
+
allow(periphery.git).to receive(:renamed_files).and_return []
|
52
|
+
allow(periphery.git).to receive(:modified_files).and_return []
|
53
|
+
allow(periphery.git).to receive(:deleted_files).and_return []
|
54
|
+
allow(periphery.git).to receive(:added_files).and_return ["test/main.swift"]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "reports unused code" do
|
58
|
+
periphery.scan(
|
59
|
+
project: fixture("test.xcodeproj"),
|
60
|
+
targets: "test",
|
61
|
+
schemes: "test"
|
62
|
+
)
|
63
|
+
|
64
|
+
expect(dangerfile.status_report[:warnings]).to eq(["Enum 'UnusedEnum' is unused"])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when .swift files were modified" do
|
69
|
+
before do
|
70
|
+
allow(periphery.git).to receive(:renamed_files).and_return []
|
71
|
+
allow(periphery.git).to receive(:modified_files).and_return ["test/main.swift"]
|
72
|
+
allow(periphery.git).to receive(:deleted_files).and_return []
|
73
|
+
allow(periphery.git).to receive(:added_files).and_return []
|
74
|
+
end
|
75
|
+
|
76
|
+
it "reports unused code" do
|
77
|
+
periphery.scan(
|
78
|
+
project: fixture("test.xcodeproj"),
|
79
|
+
targets: "test",
|
80
|
+
schemes: "test"
|
81
|
+
)
|
82
|
+
|
83
|
+
expect(dangerfile.status_report[:warnings]).to eq(["Enum 'UnusedEnum' is unused"])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "periphery/runner"
|
4
|
+
|
5
|
+
module Periphery
|
6
|
+
describe Runner do
|
7
|
+
subject(:runner) { described_class.new(binary_path) }
|
8
|
+
|
9
|
+
let(:binary_path) { binary("periphery") }
|
10
|
+
|
11
|
+
describe "#scan" do
|
12
|
+
subject { runner.scan(options) }
|
13
|
+
|
14
|
+
context "with valid args" do
|
15
|
+
let(:options) do
|
16
|
+
{
|
17
|
+
project: fixture("test.xcodeproj"),
|
18
|
+
targets: "test",
|
19
|
+
schemes: "test"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "runs scan without args" do
|
24
|
+
expect(subject).to include "warning:"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#scan_arguments" do
|
30
|
+
subject { runner.scan_arguments(options) }
|
31
|
+
|
32
|
+
context "with empty options" do
|
33
|
+
let(:options) { {} }
|
34
|
+
|
35
|
+
it { is_expected.to be_empty }
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with options that takes no argument" do
|
39
|
+
let(:options) do
|
40
|
+
{
|
41
|
+
clean_build: true,
|
42
|
+
skip_build: true
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns correct arguments" do
|
47
|
+
expect(subject).to eq %w(--clean-build --skip-build)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with options that takes an argument" do
|
52
|
+
let(:options) do
|
53
|
+
{
|
54
|
+
project: "test.xcodeproj",
|
55
|
+
targets: "test1,test2"
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns correct arguments" do
|
60
|
+
expect(subject).to eq %w(--project test.xcodeproj --targets test1,test2)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with options that takes an array as argument" do
|
65
|
+
let(:options) do
|
66
|
+
{
|
67
|
+
project: "test.xcodeproj",
|
68
|
+
targets: %w(test1 test2)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns correct arguments" do
|
73
|
+
expect(subject).to eq %w(--project test.xcodeproj --targets test1,test2)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "periphery/scan_log_parser"
|
4
|
+
|
5
|
+
module Periphery
|
6
|
+
describe ScanLogParser do
|
7
|
+
describe "#parse" do
|
8
|
+
subject { described_class.new.parse(string) }
|
9
|
+
|
10
|
+
context "with empty string" do
|
11
|
+
let(:string) { "" }
|
12
|
+
|
13
|
+
it { is_expected.to be_empty }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "with a valid string" do
|
17
|
+
let(:string) do
|
18
|
+
<<~LOG
|
19
|
+
* Inspecting project...
|
20
|
+
* Building danger-periphery...
|
21
|
+
* Indexing...
|
22
|
+
* Analyzing...
|
23
|
+
|
24
|
+
/Users/manicmaniac/danger-periphery/main.swift:1:1: warning: Typealias 'UnusedTypeAlias' is unused
|
25
|
+
/Users/manicmaniac/danger-periphery/main.swift:2:1: warning: Class 'UnusedClass' is unused
|
26
|
+
/Users/manicmaniac/danger-periphery/main.swift:3:1: warning: Protocol 'UnusedProtocol' is unused
|
27
|
+
|
28
|
+
* Seeing false positives?
|
29
|
+
- Periphery only analyzes files that are members of the targets you specify.
|
30
|
+
References to declarations identified as unused may reside in files that are members of other targets, e.g test targets.
|
31
|
+
- By default, Periphery does not assume that all public declarations are in use.
|
32
|
+
You can instruct it to do so with the --retain-public option.
|
33
|
+
- Periphery is a very precise tool, false positives often turn out to be correct after further investigation.
|
34
|
+
- If it really is a false positive, please report it - https://github.com/peripheryapp/periphery/issues.
|
35
|
+
LOG
|
36
|
+
end
|
37
|
+
|
38
|
+
before { allow(Pathname).to receive(:getwd).and_return Pathname.new("/Users/manicmaniac/danger-periphery") }
|
39
|
+
|
40
|
+
it "parses all warnings without garbages" do
|
41
|
+
expect(subject).to eq [
|
42
|
+
ScanLogEntry.new("main.swift", 1, 1, "Typealias 'UnusedTypeAlias' is unused"),
|
43
|
+
ScanLogEntry.new("main.swift", 2, 1, "Class 'UnusedClass' is unused"),
|
44
|
+
ScanLogEntry.new("main.swift", 3, 1, "Protocol 'UnusedProtocol' is unused")
|
45
|
+
]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
ROOT = Pathname.new(File.expand_path("..", __dir__))
|
5
|
+
$:.unshift("#{ROOT}lib".to_s)
|
6
|
+
$:.unshift("#{ROOT}spec".to_s)
|
7
|
+
|
8
|
+
require "bundler/setup"
|
9
|
+
require "pry"
|
10
|
+
|
11
|
+
require "rspec"
|
12
|
+
require "danger"
|
13
|
+
|
14
|
+
if `git remote -v` == ""
|
15
|
+
puts "You cannot run tests without setting a local git remote on this repo"
|
16
|
+
puts "It's a weird side-effect of Danger's internals."
|
17
|
+
exit(0)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Use coloured output, it's the best.
|
21
|
+
RSpec.configure do |config|
|
22
|
+
config.filter_gems_from_backtrace "bundler"
|
23
|
+
config.color = true
|
24
|
+
config.tty = true
|
25
|
+
end
|
26
|
+
|
27
|
+
require "danger_plugin"
|
28
|
+
|
29
|
+
# These functions are a subset of https://github.com/danger/danger/blob/master/spec/spec_helper.rb
|
30
|
+
# If you are expanding these files, see if it's already been done ^.
|
31
|
+
|
32
|
+
# A silent version of the user interface,
|
33
|
+
# it comes with an extra function `.string` which will
|
34
|
+
# strip all ANSI colours from the string.
|
35
|
+
|
36
|
+
# rubocop:disable Lint/NestedMethodDefinition
|
37
|
+
def testing_ui
|
38
|
+
@output = StringIO.new
|
39
|
+
def @output.winsize
|
40
|
+
[20, 9999]
|
41
|
+
end
|
42
|
+
|
43
|
+
cork = Cork::Board.new(out: @output)
|
44
|
+
def cork.string
|
45
|
+
out.string.gsub(/\e\[([;\d]+)?m/, "")
|
46
|
+
end
|
47
|
+
cork
|
48
|
+
end
|
49
|
+
# rubocop:enable Lint/NestedMethodDefinition
|
50
|
+
|
51
|
+
# Example environment (ENV) that would come from
|
52
|
+
# running a PR on TravisCI
|
53
|
+
def testing_env
|
54
|
+
{
|
55
|
+
"HAS_JOSH_K_SEAL_OF_APPROVAL" => "true",
|
56
|
+
"TRAVIS_PULL_REQUEST" => "800",
|
57
|
+
"TRAVIS_REPO_SLUG" => "artsy/eigen",
|
58
|
+
"TRAVIS_COMMIT_RANGE" => "759adcbd0d8f...13c4dc8bb61d",
|
59
|
+
"DANGER_GITHUB_API_TOKEN" => "123sbdq54erfsd3422gdfio"
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
# A stubbed out Dangerfile for use in tests
|
64
|
+
def testing_dangerfile
|
65
|
+
env = Danger::EnvironmentManager.new(testing_env)
|
66
|
+
Danger::Dangerfile.new(env, testing_ui)
|
67
|
+
end
|
68
|
+
|
69
|
+
def fixtures_path
|
70
|
+
Pathname.new("../support/fixtures").expand_path(__FILE__)
|
71
|
+
end
|
72
|
+
|
73
|
+
def fixture(filename)
|
74
|
+
fixtures_path.join(filename).to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
def binaries_path
|
78
|
+
Pathname.new("../../bin").expand_path(__FILE__)
|
79
|
+
end
|
80
|
+
|
81
|
+
def binary(filename)
|
82
|
+
binaries_path.join(filename).to_s
|
83
|
+
end
|