{"id":13562527,"url":"https://github.com/ashanbrown/forbidigo","last_synced_at":"2026-01-20T06:37:35.215Z","repository":{"id":40624263,"uuid":"209344028","full_name":"ashanbrown/forbidigo","owner":"ashanbrown","description":"Go linter for forbidding identifiers","archived":false,"fork":false,"pushed_at":"2025-01-25T23:39:48.000Z","size":125,"stargazers_count":153,"open_issues_count":6,"forks_count":13,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-19T07:55:27.825Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ashanbrown.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-18T15:34:17.000Z","updated_at":"2025-10-09T08:50:02.000Z","dependencies_parsed_at":"2023-11-11T23:24:39.618Z","dependency_job_id":"94514a84-196e-4c80-a1b0-6025ba367967","html_url":"https://github.com/ashanbrown/forbidigo","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/ashanbrown/forbidigo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashanbrown%2Fforbidigo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashanbrown%2Fforbidigo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashanbrown%2Fforbidigo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashanbrown%2Fforbidigo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ashanbrown","download_url":"https://codeload.github.com/ashanbrown/forbidigo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashanbrown%2Fforbidigo/sbom","scorecard":{"id":211456,"data":{"date":"2025-08-11","repo":{"name":"github.com/ashanbrown/forbidigo","commit":"77ce5aa20dff41f82b9dee111b3d338bdd88f8a3"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":3,"reason":"Found 10/26 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/ashanbrown/forbidigo/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/ashanbrown/forbidigo/build.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/ashanbrown/forbidigo/build.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/ashanbrown/forbidigo/build.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 27 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T00:50:03.422Z","repository_id":40624263,"created_at":"2025-08-17T00:50:03.422Z","updated_at":"2025-08-17T00:50:03.422Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28597714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T02:08:49.799Z","status":"ssl_error","status_checked_at":"2026-01-20T02:08:44.148Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-08-01T13:01:09.567Z","updated_at":"2026-01-20T06:37:35.203Z","avatar_url":"https://github.com/ashanbrown.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# forbidigo\n\n[![Github Actions](https://github.com/ashanbrown/forbidigo/actions/workflows/build.yml/badge.svg)](https://github.com/ashanbrown/forbidigo/actions/workflows/build.yml?query=branch%3Amaster)\n\n`forbidigo` is recommended to be run as part of [golangci-lint](https://github.com/golangci/golangci-lint) where it can be controlled using file-based configuration and `//nolint` directives, but it can also be run as a standalone tool.\n\n## Installation\n```\ngo install github.com/ashanbrown/forbidigo@latest\n```\n\n## Usage\n```\nforbidigo [flags...] patterns... -- packages...\n```\n\nIf no patterns are specified, the default pattern of `^(fmt\\.Print.*|print|println)$` is used to eliminate debug statements.  By default,\nfunctions (and whole files), that are identifies as Godoc examples (https://blog.golang.org/examples) are excluded from \nchecking.\n\nBy default, patterns get matched against the actual expression as it appears in\nthe source code. The effect is that `^fmt\\.Print.*$` will not match when that\npackage gets imported with `import fmt2 \"fmt\"` and then the function gets\ncalled with `fmt2.Print`.\n\nThis makes it hard to match packages that may get imported under a variety of\ndifferent names, for example because there is no established convention or the\nname is so generic that import aliases have to be used. To solve this,\nforbidigo also supports a more advanced mode where it uses type information to\nidentify what an expression references. This needs to be enabled through the\n`analyze_types` command line parameter. Beware this may have a performance\nimpact because additional information is required for the analysis.  Note that \n[builtin types](https://pkg.go.dev/builtin) types (`error`, `byte`, etc) are \nconsidered to have the package name \"\" (empty string).\n\nReplacing the literal source code works for items in a package as in the\n`fmt2.Print` example above and also for struct fields and methods. For those,\n`\u003cpackage name\u003e.\u003ctype name\u003e.\u003cfield or method name\u003e` replaces the source code\ntext. `\u003cpackage name\u003e` is what the package declares in its `package` statement,\nwhich may be different from last part of the import path:\n```go\nimport \"example.com/some/pkg\" // pkg uses `package somepkg`\ns := somepkg.SomeStruct{}\ns.SomeMethod() // -\u003e somepkg.SomeStruct.SomeMethod\n```\n\nPointers are treated like the type they point to:\n```go\nvar cf *spew.ConfigState = ...\ncf.Dump() // -\u003e spew.ConfigState.Dump\n```\n\nWhen a type is an alias for a type in some other package, the name of that\nother package will be used.\n\nAn imported identifier gets replaced as if it had been imported without `import .`\n*and* also gets matched literally, so in this example both `^ginkgo.FIt$`\nand `^FIt$` would catch the usage of `FIt`:\n```go\nimport . \"github.com/onsi/ginkgo/v2\"\nFIt(...) // -\u003e ginkgo.FIt, FIt\n```\n\nBeware that looking up the package name has limitations. When a struct embeds\nsome other type, references to the inherited fields or methods get resolved\nwith the outer struct as type:\n```go\npackage foo\n\ntype InnerStruct {\n    SomeField int\n}\n\nfunc (i innerStruct) SomeMethod() {}\n\ntype OuterStruct {\n    InnerStruct\n}\n\ns := OuterStruct{}\ns.SomeMethod() // -\u003e foo.OuterStruct.SomeMethod\ni := s.SomeField // -\u003e foo.OuterStruct.SomeField\n```\n\nWhen a method gets called via some interface, that invocation also only\ngets resolved to the interface, not the underlying implementation:\n```go\n// innerStruct as above\n\ntype myInterface interface {\n    SomeMethod()\n}\n\nvar i myInterface = InnerStruct{}\ni.SomeMethod() // -\u003e foo.myInterface.SomeMethod\n```\n\nUsing the package name is simple, but the name is not necessarily unique. For\nmore advanced cases, it is possible to specify more complex patterns. Such\npatterns are strings that contain JSON or YAML for a struct.\n\nThe full pattern struct has the following fields:\n\n* `msg`: an additional comment that gets added to the error message when a\n  pattern matches.\n* `p`: the regular expression that matches the source code or, when `analyze_flags` is set, the expanded\n  expression including the package name.\n* `pkg`: a regular expression for the full package import path. The package\n  path includes the package version if the package has a version \u003e= 2. This is\n  only supported when `analyze_types` is enabled.\n\nTo distinguish such patterns from traditional regular expression patterns, the\nencoding must start with a `{` or contain line breaks. When using just JSON\nencoding, backslashes must get quoted inside strings. When using YAML, this\nisn't necessary. The following pattern strings are equivalent:\n```\n{p: \"^fmt\\\\.Println$\", msg: \"do not write to stdout\"}\n\n{p: ^fmt\\.Println$,\n    msg: do not write to stdout,\n}\n\n{p: ^fmt\\.Println$, msg: do not write to stdout}\n\np: ^fmt\\.Println$\nmsg: do not write to stdout\n```\n\nA larger set of interesting patterns might include:\n\n* `^fmt\\.Print.*$` -- forbid use of Print statements because they are likely just for debugging\n* `^ginkgo\\.F[A-Z].*$` -- forbid ginkgo focused commands (used for debug issues)\n* `^spew\\.Dump$` -- forbid dumping detailed data to stdout\n* `^spew.ConfigState\\.Dump$` -- also forbid it via a `ConfigState`\n* `^spew\\.Dump(# please do not spew to stdout)?$` -- forbid spewing, with a custom message\n* `{p: ^spew\\.Dump$, msg: please do not spew to stdout}` -- the same with separate msg field\n\n### Flags\n- **-set_exit_status** (default false) - Set exit status to 1 if any issues are found.\n- **-exclude_godoc_examples** (default true) - Controls whether godoc examples are identified and excluded\n- **-tests** (default true) - Controls whether tests are included\n- **-analyze_types** (default false) - Replace literal source code before matching\n\n## Purpose\n\nTo prevent leaving format statements and temporary statements such as Ginkgo FIt, FDescribe, etc.\n\n## Ignoring issues\n\nYou can ignore a particular issue by including the directive `//permit` on that line.  *This feature is disabled inside `golangci-lint` to encourage ignoring issues using the `// nolint` directive common for all linters (nolinting well is hard and I didn't want to make an effort do it exactly right within this linter).*\n\n## Contributing\n\nPull requests welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashanbrown%2Fforbidigo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fashanbrown%2Fforbidigo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashanbrown%2Fforbidigo/lists"}