woshiccm / pecker Goto Github PK
View Code? Open in Web Editor NEWCodePecker is a tool to detect unused Swift code.
License: MIT License
CodePecker is a tool to detect unused Swift code.
License: MIT License
工程下.pecker.yml文件配置:
reporter: "json"
output_file: "~/Jenkins/workspace/lark/ios/app-analyse/ios-client-master-appsize-verify"
输入命令行pecker ~/Jenkins/workspace/lark/ios/app-analyse/ios-client-master-appsize-verify -i ~/E/Z/Lark-awwlhnagktjjwaendjbfipmvwrcf/Index/DataStore,
报错:[1] 85594 illegal hardware instruction pecker -i ~/E/Z/Lark-awwlhnagktjjwaendjbfipmvwrcf/Index/DataStore
version 0.4.0
does not work
protocol SomeProtocol {
func doSomething()
}
class Implementation: SomeProtocol {
func doSomething() { // Warning
}
}
doSomething
is called from other code via the protocol
struct Model: Codable {
enum CodingKeys: String, CodingKey { // Warning
case value
}
let value: String
}
I installed the latest version 0.3.0
but if I run pecker -v
I get 0.0.1
as the result
With skip_public
rule enabled (which already is by default),
This case is detected as unused.
public extension NSParagraphStyle {
static var level1: NSParagraphStyle { ... }
}
This one is not.
extension NSParagraphStyle {
public static var level1: NSParagraphStyle { ... }
}
Hi,
First of all, thanks for great tool. Amazing job 💪
I found one missed thing that is nice to have. It is custom path for configuration yaml file. For example, SwiftLint allows it in the following way:
${PODS_ROOT}/SwiftLint/swiftlint --config ../.swiftlint.yml
Does it make sense for you? Could you, please, provide something similar?
/redacted/Pecker/.build/checkouts/swift-syntax/Sources/SwiftSyntax/SyntaxParser.swift:195:57: error: missing argument for parameter #3 in call
let c_top = swiftparse_parse_string(c_parser, source)
^
, <#Int#>
_InternalSwiftSyntaxParser.swiftparse_parse_string:1:13: note: 'swiftparse_parse_string' declared here
public func swiftparse_parse_string(_: swiftparse_parser_t!, _ source: UnsafePointer<CChar>!, _ len: Int) -> swiftparse_client_node_t!
^
make: *** [build] Error 1
By default, SwiftUI generates a struct which conforms to PreviewProvider
, e.g.:
import SwiftUI
struct SettingsView: View {
var body: some View {
...
}
}
#if DEBUG
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
#endif
In the default configuration, pecker reports SettingsView_Previews
as unused. It would be good to add a rule to ignore structs which conform to PreviewProvider.
Pecker currently requires the BUILD_ROOT environment variable to be set, if an index store path is not passed. Without a BUILD_ROOT, it fails silently. It would be good to document that this is required as an env var.
In an ideal world, we could also provide the user a commend line option to specify the name of the target - then we could infer a default DerivedData path to use for the IndexDB
Since Pecker reports Swift methods that are only used by Obj-C code as unused, it would be nice to have an option to remove methods/properties annotated with @objc
from reporting.
Installed manually and run make install
.
Error message as below
/Pecker/.build/checkouts/Yams/Sources/Yams/Emitter.swift:338:32: warning: initialization of 'UnsafeMutablePointer<yaml_version_directive_t>' (aka 'UnsafeMutablePointer<yaml_version_directive_s>') results in a dangling pointer
versionDirective = UnsafeMutablePointer(&versionDirectiveValue)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/tieda/Desktop/Pecker/.build/checkouts/Yams/Sources/Yams/Emitter.swift:338:53: note: implicit argument conversion from 'yaml_version_directive_t' (aka 'yaml_version_directive_s') to 'UnsafeMutablePointer<yaml_version_directive_t>' (aka 'UnsafeMutablePointer<yaml_version_directive_s>') produces a pointer valid only for the duration of the call to 'init(_:)'
versionDirective = UnsafeMutablePointer(&versionDirectiveValue)
^~~~~~~~~~~~~~~~~~~~~~
/Users/tieda/Desktop/Pecker/.build/checkouts/Yams/Sources/Yams/Emitter.swift:338:53: note: use 'withUnsafeMutablePointer' in order to explicitly convert argument to pointer valid for a defined scope
versionDirective = UnsafeMutablePointer(&versionDirectiveValue)
^
/Users/tieda/Desktop/Pecker/.build/checkouts/swift-syntax/Sources/SwiftSyntax/RawSyntax.swift:120:46: error: value of type 'CSyntaxNode' (aka 'swiftparse_syntax_node_t') has no member 'range'
let textSize = hasCustomText ? Int(cnode.range.length) : 0
~~~~~ ^~~~~
/Users/tieda/Desktop/Pecker/.build/checkouts/swift-syntax/Sources/SwiftSyntax/RawSyntax.swift:153:35: error: value of type 'CSyntaxNode' (aka 'swiftparse_syntax_node_t') has no member 'range'
let startOffset = Int(cnode.range.offset)
~~~~~ ^~~~~
/Users/tieda/Desktop/Pecker/.build/checkouts/swift-syntax/Sources/SwiftSyntax/RawSyntax.swift:157:55: error: value of type 'CSyntaxNode' (aka 'swiftparse_syntax_node_t') has no member 'range'
let end = utf8.index(begin, offsetBy: Int(cnode.range.length))
~~~~~ ^~~~~
/Users/tieda/Desktop/Pecker/.build/checkouts/swift-syntax/Sources/SwiftSyntax/RawSyntax.swift:873:32: error: value of type 'CSyntaxNode' (aka 'swiftparse_syntax_node_t') has no member 'range'
let byteLength = Int(cnode.range.length)
~~~~~ ^~~~~
/Users/tieda/Desktop/Pecker/.build/checkouts/swift-syntax/Sources/SwiftSyntax/SyntaxParser.swift:195:57: error: missing argument for parameter #3 in call
let c_top = swiftparse_parse_string(c_parser, source)
^
, <#Int#>
_InternalSwiftSyntaxParser.swiftparse_parse_string:1:13: note: 'swiftparse_parse_string' declared here
public func swiftparse_parse_string(_: swiftparse_parser_t!, _ source: UnsafePointer<CChar>!, _ len: Int) -> swiftparse_client_node_t!
^
[101/104] Compiling SwiftSyntax AbsolutePosition.swift
make: *** [build] Error 1
Thanks in advance for looking into this :)
If you have an extension (such as a Notification Service Extension) then you end up with a class called NotificationService
(this can be changed).
Apple knows to run this because of an entry in the Info.plist "NSExtensionPrincipalClass" which equals "$(PRODUCT_MODULE_NAME).NotificationService".
Pecker is raising a warning for this main class, but it is in fact being used.
I'm integrating Pecker via Run Script Phase
.
It stopped working as soon as I upgraded Xcode to version 11.4
.
Pecker version: 0.1.0
Error:
Command PhaseScriptExecution failed with a nonzero exit code
There isn't much info besides this:
bash PhaseScriptExecution Run\ Pecker /Users/fernando.fernandes/Library/Developer/Xcode/DerivedData/TEST-awvaoxeibgfjlqccvsjwuqsmgoij/Build/Intermediates.noindex/TEST.build/Debug-iphoneos/TEST.build/Script-0765326C23FF1DBB00BB6B45.sh (in target 'TEST' from project 'TEST') cd /Users/fernando.fernandes/Downloads/source/backslash-f/TEST/Xcode/TEST /bin/sh -c /Users/fernando.fernandes/Library/Developer/Xcode/DerivedData/TEST-awvaoxeibgfjlqccvsjwuqsmgoij/Build/Intermediates.noindex/TEST.build/Debug-iphoneos/TEST.build/Script-0765326C23FF1DBB00BB6B45.sh
Please advise, thanks.
Would support for objectiv-c in future? If no, how to develop to this feature base on Pecker? Thanks.
I cannot install Pecker on Big Sur (possibly due to being beta, but maybe you know).
If trying via Homebrew it throws an error, and trying a manual install via make install
throws the following build error:
Cloning https://github.com/apple/swift-argument-parser.git
Resolving https://github.com/apple/swift-argument-parser.git at main
warning: Swift compiler no longer supports statically linking the Swift libraries. They're included in the OS by default starting with macOS Mojave 10.14.4 beta 3. For macOS Mojave 10.14.3 and earlier, there's an optional Swift library package that can be downloaded from "More Downloads" for Apple Developers at https://developer.apple.com/download/more/
warning: Swift compiler no longer supports statically linking the Swift libraries. They're included in the OS by default starting with macOS Mojave 10.14.4 beta 3. For macOS Mojave 10.14.3 and earlier, there's an optional Swift library package that can be downloaded from "More Downloads" for Apple Developers at https://developer.apple.com/download/more/
warning: Swift compiler no longer supports statically linking the Swift libraries. They're included in the OS by default starting with macOS Mojave 10.14.4 beta 3. For macOS Mojave 10.14.3 and earlier, there's an optional Swift library package that can be downloaded from "More Downloads" for Apple Developers at https://developer.apple.com/download/more/
/Users/christian/Pecker/.build/checkouts/Yams/Sources/Yams/Emitter.swift:338:32: warning: initialization of 'UnsafeMutablePointer<yaml_version_directive_t>' (aka 'UnsafeMutablePointer<yaml_version_directive_s>') results in a dangling pointer
versionDirective = UnsafeMutablePointer(&versionDirectiveValue)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/christian/Pecker/.build/checkouts/Yams/Sources/Yams/Emitter.swift:338:53: note: implicit argument conversion from 'yaml_version_directive_t' (aka 'yaml_version_directive_s') to 'UnsafeMutablePointer<yaml_version_directive_t>' (aka 'UnsafeMutablePointer<yaml_version_directive_s>') produces a pointer valid only for the duration of the call to 'init(_:)'
versionDirective = UnsafeMutablePointer(&versionDirectiveValue)
^~~~~~~~~~~~~~~~~~~~~~
/Users/christian/Pecker/.build/checkouts/Yams/Sources/Yams/Emitter.swift:338:53: note: use 'withUnsafeMutablePointer' in order to explicitly convert argument to pointer valid for a defined scope
versionDirective = UnsafeMutablePointer(&versionDirectiveValue)
^
/Users/christian/Pecker/Sources/Pecker/PeckerCommand.swift:22:6: error: referencing initializer 'init(name:help:)' on 'Flag' requires the types 'Bool' and 'Int' be equivalent
@Flag(name: .shortAndLong, help: "Print the version and exit")
^
/Users/christian/Pecker/.build/checkouts/swift-argument-parser/Sources/ArgumentParser/Parsable Properties/Flag.swift:273:1: note: where 'Value' = 'Bool'
extension Flag where Value == Int {
^
make: *** [build] Error 1
christian@Christians-MacBook-Pro Pecker %
It looks like test methods declared in extensions currently show warnings as false positives despite the xctest
rule being enabled. The following testExample()
method shows a warning.
class MyTestClass: XCTestCase {
}
extension MyTestClass {
func testExample() { // This shows a warning as being unused
XCTAssertTrue(true)
}
}
Installed Pecker 0.3.0 with Homebrew and running Pecker as a Run Script Phase in Xcode.
Running with Pecker's defaults and without a yaml file, all my tests show an unused warning.
I tried to add this yaml file:
excluded: # paths to ignore during detecting. Takes precedence over `included`.
- Pods
blacklist_superclass: # all the class inherit from class specified in the list will ignore
- XCTestCase
This succeeded in removing the Cocoapods warnings but I still see all my tests.
My project is part of an Xcode workspace.
It has a few targets (iOS, iOS Tests, Mac, Mac Tests)
We currently install Swiftlint with Cocoapods, so it would be really nice to have Pecker support for Cocoapods as well. Currently the install process requires manually cloning the project, so it won't get installed automatically when new developers clone our repo. Another option could be to integrate the project as a Swift package - that technically might work now? I'm not sure how to integrate a Swift package for development and not build it into the app, though
Consider the following code:
import Foundation
@objc protocol ProtocolWithOptionalMethods: AnyObject {
func a()
@objc optional func b()
}
class Superclass: NSObject, ProtocolWithOptionalMethods {
func a() {
print("a")
}
}
class Subclass: Superclass {
func b() {
print("b")
}
}
Currently, Pecker reports function b() was never used; consider removing it
, but b is in fact used as an implementation of the optional method. I put together an example project to demonstrate this here: https://github.com/noahsark769/NGPeckerExamples/blob/master/NGPeckerExamples/OptionalFunctionFromSuperclass.swift#L23
Hey there! I noticed that the fully build pecker
executable, in default configuration, doesn't output any error logs when run. For example, if you run it on a path that doesn't exist, it will swallow the error and not print anything.
It would be really nice to have a better error logging system to provide feedback to users running the executable, since right now the error state and the "no unused code" state look the same.
The Usage section of the readme tells us to “Integrate pecker into an Xcode scheme to get warnings and errors displayed in the IDE. Just add a new "Run Script Phase" with:” but as far as I know, that's not possible as-written:
So this looks like a minor typo but stilll begs the question: What was meant here?
Currently it's possible to pecker:ignore
classes/structs/enums, but not extensions. For example:
class IgnoreInExtensionExample {
}
// pecker:ignore
extension IgnoreInExtensionExample {
func unused() {
}
}
In this example, unused()
is still reported as unused, even though the intention was to ignore it. This feature is nice to have because we have a bunch of extensions for base XCTestCase classes.
With the following .pecker.yml
:
reporter: "json"
disabled_rules:
- skip_public
excluded: # paths to ignore during detecting. Takes precedence over `included`.
- Carthage
- Pods
blacklist_symbols: # symbols to ignore during detecting, contains class, struct, enum, etc.
- AppDelegate
- viewDidLoad
output_file: "./peckerout"
I get an illegal instruction when running pecker on CIFilter.io:
$ BUILD_ROOT=~/Library/Developer/Xcode/DerivedData/CIFilter.io-hibrtvbjsqlofacdruluolzdaqib/Index/DataStore/ pecker ./
Illegal instruction: 4
If I remove the output_file
line, the script runs correctly.
If you have a subclass of XCTestCase (e.g. a BaseTestCase where you put your generic testing utilities), Pecker currently reports tests that inherit from this subclass these as unused. For example:
import XCTest
class BaseTestCase: XCTestCase {
}
extension BaseTestCase {
func a() {
print("a")
}
}
class TestCase: BaseTestCase { // currently reported as unused
func test() { // currently reported as unused
self.a()
}
}
Working example in repo: https://github.com/noahsark769/NGPeckerExamples/blob/master/NGPeckerExamplesTests/XCTestSuperclassMethodUsedBySubclass.swift#L11
We have a UITableViewCell class with a corresponding XIB. We register it to the UITableView using tableView.register(nib, reuseIdentifier)
and dequeue it as per standard implementation.
As the cell class is not directly referenced, a warning is incorrectly raised.
Environment
When I was trying to debug pecker with xcode, the following error log was output, so it couldn't be executed
dyld: Library not loaded: @rpath/lib_InternalSwiftSyntaxParser.dylib
While moving from xcode 14.2 to 14.3 the build script for packer is failing giving the error as
phase script execution failed xcode
I have the latest cocoapod of 1.12.1
It looks like Pecker is not compatible with Xcode 14.3
通过 pod install 安装,Pods 里对应的文件夹没有可配置文件 ,建议默认就忽略 pods 下面的内容
We use Brew in our CI pipeline to install tools. It would be really useful to be able to install also Pecker through Brew
Hello, I recently saw this project in my GitHub feed and I was wondering how is it different from Periphery? And if Pecker was better or just completely different...
We have a few true positives in our codebase which we'd like to keep around since they're not used yet but will soon be used. It would be nice if we could disable the pecker checker with a comment, similar to Swiftlint. Something like:
func myUnsusedFunction() { // pecker:ignore
}
// or:
// pecker:ignore:next
func myUnusedFunction() {
print("Blah")
}
We use Quick for testing, which means that our tests inherit from QuickSpec. Since this isn't supported out of the box, it would be nice for us to be able to ignore all subclasses of Quickspec by default.
It seems the best way would be to make the SuperClassRule customizable via .pecker.yml
for this.
protocol Protocol {
var variable: Bool { get }
func function(parameter: String?) -> String?
}
Implementing this Protocol in a class and satisfying conformance in extension works for variable but not for function.
class Class: Protocol { }
extension Class {
var variable: Bool { // no warning
return "Temp"
}
func function (parameter: String?) -> { // warning
return parameter
}
}
@IBAction func someFunction() {
currently returns a warning, but it is used/called by our UIStoryboard!
Structure Types if used in typecasting while decoding the Data using Codable protocol using "as" keyword creating a warning.
I'm getting a warning "Pecker: function testSomeFunction() was never used; consider removing it" in a test class. This is true for any test function in a class which doesn't immediately subclass XCTestCase.
class FooTests: XCTestCase {
func testSomething() { // No Warning
}
}
class BarTests: FooTests {
func testSomethingElse() { // Warning
}
}
Given that it's still a valid test class, I wouldn't expect this to raise a warning! (Temporary workaround has just been to exclude the tests directory, though this isn't ideal)
I can't see any warning what
https://github.com/woshiccm/Pecker#pecker is showing.
I did as below:
https://github.com/woshiccm/Pecker#pecker
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.