danger-periphery 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|