{"id":3195,"url":"https://github.com/woshiccm/Pecker","last_synced_at":"2025-08-03T13:32:07.917Z","repository":{"id":40614254,"uuid":"225575217","full_name":"woshiccm/Pecker","owner":"woshiccm","description":"CodePecker is a tool to detect unused Swift code.","archived":false,"fork":false,"pushed_at":"2022-04-08T07:21:31.000Z","size":3704,"stargazers_count":1468,"open_issues_count":12,"forks_count":62,"subscribers_count":26,"default_branch":"master","last_synced_at":"2025-07-24T21:45:05.194Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/woshiccm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-03T09:02:41.000Z","updated_at":"2025-07-13T01:02:52.000Z","dependencies_parsed_at":"2022-07-14T22:46:48.833Z","dependency_job_id":null,"html_url":"https://github.com/woshiccm/Pecker","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/woshiccm/Pecker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woshiccm%2FPecker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woshiccm%2FPecker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woshiccm%2FPecker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woshiccm%2FPecker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/woshiccm","download_url":"https://codeload.github.com/woshiccm/Pecker/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woshiccm%2FPecker/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266936502,"owners_count":24009417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-24T02:00:09.469Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:16:34.130Z","updated_at":"2025-08-03T13:32:07.544Z","avatar_url":"https://github.com/woshiccm.png","language":"Swift","funding_links":[],"categories":["Tools","Swift","build tool"],"sub_categories":["Web View"],"readme":"\u003eNotice: The \"dyld: Library not loaded: @rpath/lib_InternalSwiftSyntaxParser.dylib\" or missing warnings are caused by a SwiftSyntax issue, [SwiftSyntax with Swift 5.1](https://forums.swift.org/t/swiftsyntax-with-swift-5-1/29051).\n\n# Pecker\n\n**Pecker** detects unused code. It's based on [IndexStoreDB](https://github.com/apple/indexstore-db.git) and [SwiftSyntax](https://github.com/apple/swift-syntax.git).\n\n![](assets/example.png)\n\n\u003e Chinese Readme: [中文版readme](README_CN.md).\n\n## Motivation\n\nAs your Swift project codebase grows, it is hard to locate unused code. You need to tell if some constructs are still in used. `pecker` does this job for you, easy and accurate.\n\n## Features\n`pecker` detects the following Swift constructs:\n\n1. `class`\n2. `struct`\n3. `enum`\n4. `protocol`\n5. `func`\n6. `typealias`\n7. `operator`\n\n## Installation\n\nThere're more than one way to install `pecker`.\n\n### Using [Homebrew](http://brew.sh/)\n\n```sh\n$ brew install woshiccm/homebrew-tap/pecker\n```\n\n### Using [CocoaPods](https://cocoapods.org):\n\n```sh\npod 'Pecker'\n```\n\nThis will download the `pecker` binaries and dependencies in `Pods/` during your next run of `pod install` and will allow you to invoke it via `${PODS_ROOT}/Pecker/bin/pecker` in your script build phases.\n\nThis is the recommended way to install a specific version of `pecker` since it supports installing a specific stable version rather than head version.\n\n### Using [Mint](https://github.com/yonaskolb/mint):\n\n```\nmint install woshiccm/Pecker\n\n```\n\n### Compiling from source\n\n```\n$ git clone https://github.com/woshiccm/Pecker.git\n$ cd Pecker\n$ make install\n```\n\nWith that installed and in the `bin` folder, now it's ready to serve.\n\n## Usage\n\n### Xcode\n\nIntegrate `pecker` into an Xcode scheme to get warnings and errors displayed in the IDE. Just add a new \"Run Script Phase\" with:\n\n```bash\nif which pecker \u003e/dev/null; then\n  pecker\nelse\n  echo \"warning: Pecker not installed, download from https://github.com/woshiccm/Pecker\"\nfi\n```\n\n![](assets/runscript.png)\n\nAlternatively, if you've installed Pecker via CocoaPods the script should look like this:\n\n```bash\n${PODS_ROOT}/Pecker/bin/pecker\n```\n\n### Terminal\n\n\u003eNote:  \n\n\u003e1. In terminal, since project index path can't be retrieved automatically there, so you need to set index path through `-i/--index-store-path`\n\u003e2. Need to set reporter as `json` and set `output_file`, the path can be both relative and absolute. If output_file is not specified, it defaults to be `pecker.result.json` in your project.\n\nFor example:\n\nIn `.pecker.yml`, the configuration is:\n\n```\nreporter: \"json\"\noutput_file: pecker.result.json\n```\n\nIn terminal, you input:\n\n```\n$ pecker --path /Users/ming/Desktop/Testttt -i /Users/ming/Library/Developer/Xcode/DerivedData/Testttt-aohluxvofrwtfagozexmpeifvryf/Index/DataStore\n```\n  \n### Command Line\n\n```\npecker [OPTIONS]\n```\n\n* `-v/--version`: Prints the `pecker` version and exits.\n* `--config`: The custom path for configuration yaml file.\n* `-i/--index-store-path`: The Index path of your project, if unspecified, the default is ~Library/Developer/Xcode/DerivedData/{your project}/Index/DataStore.\n\nRun `pecker` in the project target to detect. Project will search Swift files recursively.\n\n## Rules\n\nCurrent only 5 rules are included in Pecker, They are `skip_public`, `xctest`, `attributes`, `xml`, `comment`. You can add them to ` disabled_rules` if you don't need it. You can also check Source/PeckerKit/Rules directory to see their implementation.\n\n### skip_public\nThis rule means skip detect public class, struct, function, etc. Usually the public code is provided for other users, so it is difficult to determine whether it is used. So we don't detect it by default. But in some cases, such as using `submodule` to organize code, you need to detect public code, you can add it to ` disabled_rules`.\n\n### xctest\nXCTest is special, we stipulate that ignore classes inherited from XCTestCase and functions of this class that hasPrefix \"test\" and do not contain parameters. \n\n```swift\nclass ExampleUITests: XCTestCase {\n\n    func testExample() { //used\n    }\n\n    func test(name: String) { // unused\n    }\n    \n    func get() { // unused\n    }\n}\n\n```\n\n### attributes\n\nIf a Declaration contains the attribute in `BlackListAttribute`, skip. Such as `IBAction`, we are continuously collecting, if you find new cases, please let us know.\n\n```swift  \n@IBAction func buttonTap(_ sender: Any) { // used       \n}\n```\n\n### XML\n\nIf code is being used in .xib or storyboard, we say it's in use.\n\n#### comment  \n\nCode can be ignored with a comment inside a source file with the following format:\n\n* Ignore specified code\n\n```\n// pecker:ignore \n```\n\nFor example:\n\n```swift\n// pecker:ignore\nclass TestCommentObject { // skip\n    \n    // pecker:ignore\n    func test1() { // skip\n    }\n    \n    func test2() { // unused\n    }\n}\n```\n\n* Ignore all symbols under scope   \n\n```\n// pecker:ignore all\n```\n\nFor example:\n\n```swift\n// pecker:ignore all\nclass TestCommentObject { // skip\n    \n    func test1() { // skip\n    }\n    \n    struct SubClass { // skip\n        \n        func test2() { // skip\n        }\n    }\n}\n\n```\n\n#### Other rules\n\nThese rules are used by default, you cannot configure them.\n\n**override**\n\nSkip declarations that override another. This works for both subclass overrides \u0026 protocol extension overrides.\n\n```swift\n\nprotocol ExampleProtocol {\n\tfunc test() // used\n}\n\nclass Example: ExampleProtocol {\n    func test() { // used\n    }\n}\n\nclass Animal {\n    func run() {  // used\n    }\n}\n\nclass Dog: Animal {\n    override func run() { // used\n    }\n}\n\n```\n\n**extensions**\n\nReferenced elsewhere means used, except for extensions.\n\n```swift\nclass UnusedExample { // unused\n    \n}\n\nextension UnusedExample {\n    \n}\n\n```\n\n\n### Configuration\n\nThis is optional, will use default, if unspecified. Configure `pecker` by adding a `.pecker.yml` file from the directory you'll\nrun `pecker` from. The following parameters can be configured:\n\nRule inclusion:\n\n* `disabled_rules`: Disable rules from the default enabled set.\n\nReporter inclusion: \n\n* xcode: Warnings displayed in the IDE.\n* json: you can set path by `output_file`, and the path can be both  relative and absolute path, if unspecified, the default is `pecker.result.json` in current project directory.\n\n   \n   ![](assets/jsonresult.png)\n\n```yaml\nreporter: \"xcode\"\n\ndisabled_rules:\n  - skip_public\n\nincluded: # paths to include during detecting. `--path` is ignored if present.\n  - ./\n  \nexcluded: # paths to ignore during detecting. Takes precedence over `included`.\n  - Carthage\n  - Pods\n\nexcludedGroupName: # names of group to ignore during detecting.\n  - SwiftPeckerTestUITests\n\nblacklist_files: # files to ignore during detecting, only need to add file name, the file extension default is swift.\n  - HomeViewController\n\nblacklist_symbols: # symbols to ignore during detecting, contains class, struct, enum, etc.\n  - AppDelegate\n  - viewDidLoad\n\nblacklist_superclass: # all the class inherit from class specified in the list will ignore\n  - UITableViewCell\n\n# If output_file is not specified, the defaults to be pecker.result.json in your project\n\noutput_file: pecker.result.jsonthe path can be both relative and absolute.\n```\n\n  \n## Contributions and support\n\n`pecker` is developed completely in the open.\n\nAny contributing and pull requests are warmly welcome. If you are interested in developing `pecker`, submit ideas and submit pull requests!\n\n\n## Licence\n`pecker` is released under the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoshiccm%2FPecker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwoshiccm%2FPecker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoshiccm%2FPecker/lists"}