{"id":13500593,"url":"https://github.com/uber/piranha","last_synced_at":"2026-10-19T08:05:10.945Z","repository":{"id":37372137,"uuid":"160637359","full_name":"uber/piranha","owner":"uber","description":"A tool for refactoring code related to feature flag APIs","archived":false,"fork":false,"pushed_at":"2026-04-02T13:44:03.000Z","size":3495,"stargazers_count":2495,"open_issues_count":68,"forks_count":211,"subscribers_count":45,"default_branch":"master","last_synced_at":"2026-10-16T21:06:51.139Z","etag":null,"topics":["ast","ast-matcher","clang-plugin","code-management","code-quality","deadcode","feature-flags","feature-toggles","java","javascript","objective-c","refactoring","refactoring-tools","stale-flags","swift","swift-syntax"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-12-06T07:38:02.000Z","updated_at":"2026-10-15T07:14:36.000Z","dependencies_parsed_at":"2024-03-27T20:44:47.619Z","dependency_job_id":"0cd31430-a16b-463f-88af-56f0f1cec9e7","html_url":"https://github.com/uber/piranha","commit_stats":{"total_commits":430,"total_committers":37,"mean_commits":"11.621621621621621","dds":0.5674418604651164,"last_synced_commit":"de3fe545e599ed1184dbbb6f38683cdb293e928f"},"previous_names":[],"tags_count":45,"template":false,"template_full_name":null,"purl":"pkg:github/uber/piranha","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fpiranha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fpiranha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fpiranha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fpiranha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uber","download_url":"https://codeload.github.com/uber/piranha/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uber%2Fpiranha/sbom","scorecard":{"id":906212,"data":{"date":"2022-08-15","repo":{"name":"github.com/uber/piranha","commit":"4cea0c2811fccf03c6c30a1008c4caa45e7ac2ba"},"scorecard":{"version":"v4.5.0-28-g6dcfde9","commit":"6dcfde9299033d3b16d81985a9634092411e0cfc"},"score":6,"checks":[{"name":"Maintained","score":10,"reason":"19 commit(s) out of 30 and 25 issue activity out of 30 found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#maintained"}},{"name":"Code-Review","score":8,"reason":"GitHub code reviews found for 26 commits out of the last 30 -- score normalized to 8","details":["Warn: no reviews found for commit: fe1dc2b6365c338e8dbc441e9e08e4715a3b35b7","Warn: no reviews found for commit: 15e6174090ce452569e0501b66fd39232eb5e0ec","Warn: no reviews found for commit: 44599689b48dfcc092b6e6df9f78c5ed7a9a5f3a","Warn: no reviews found for commit: de24b30d0085b53fe86c235774d826f6a4e36eef"],"documentation":{"short":"Determines if the project requires code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no badge detected","details":null,"documentation":{"short":"Determines if the project has a CII Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"no vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#vulnerabilities"}},{"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/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#dangerous-workflow"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: : LICENSE:1"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#license"}},{"name":"Token-Permissions","score":0,"reason":"non read-only tokens detected in GitHub workflows","details":["Warn: no topLevel permission defined: .github/workflows/format.yml:1: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/format.yml/master?enable=permissions","Warn: no topLevel permission defined: .github/workflows/java.yml:1: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/java.yml/master?enable=permissions","Warn: no topLevel permission defined: .github/workflows/lint.yml:1: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/lint.yml/master?enable=permissions","Warn: no topLevel permission defined: .github/workflows/node.js.yml:1: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/node.js.yml/master?enable=permissions","Warn: no topLevel permission defined: .github/workflows/polyglot_release.yml:1: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/polyglot_release.yml/master?enable=permissions","Warn: no topLevel permission defined: .github/workflows/rust.yml:1: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/rust.yml/master?enable=permissions"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"no published package detected","details":["Warn: no GitHub 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/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":7,"reason":"dependency not pinned by hash detected -- score normalized to 7","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/format.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/format.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/format.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/format.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/java.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/java.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/java.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/java.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/java.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/java.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/java.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/java.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/lint.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/lint.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/lint.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.js.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/node.js.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.js.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/node.js.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/polyglot_release.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/polyglot_release.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/polyglot_release.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/polyglot_release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/rust.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/rust.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/rust.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/uber/piranha/rust.yml/master?enable=pin","Info: Dockerfile dependencies are pinned","Info: no insecure (not pinned by hash) dependency downloads found in Dockerfiles","Info: no insecure (not pinned by hash) dependency downloads found in shell scripts"],"documentation":{"short":"Determines if the project has declared and pinned its dependencies.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: java/gradle/wrapper/gradle-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#binary-artifacts"}},{"name":"Dependency-Update-Tool","score":-1,"reason":"internal error: Search.Code: GET https://api.github.com/search/commits?per_page=100\u0026q=repo%3Auber%2Fpiranha+author%3Adependabot%5Bbot%5D: 403 You have exceeded a secondary rate limit. Please wait a few minutes before you try again. []","details":null,"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#dependency-update-tool"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":null,"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":0,"reason":"0 out of 1 artifacts are signed or have provenance","details":["Warn: release artifact v0.1.0-polyglot does not have provenance: https://api.github.com/repos/uber/piranha/releases/70090167","Warn: release artifact v0.1.0-polyglot not signed: https://api.github.com/repos/uber/piranha/releases/70090167"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":8,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'force pushes' disabled on branch 'master'","Info: 'allow deletion' disabled on branch 'master'","Info: status check found to merge onto on branch 'master'","Warn: number of required reviewers is only 1 on branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":null,"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/6dcfde9299033d3b16d81985a9634092411e0cfc/docs/checks.md#security-policy"}}]},"last_synced_at":"2025-08-24T17:26:16.229Z","repository_id":37372137,"created_at":"2025-08-24T17:26:16.229Z","updated_at":"2025-08-24T17:26:16.229Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38351737,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-19T02:00:06.414Z","response_time":53,"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":["ast","ast-matcher","clang-plugin","code-management","code-quality","deadcode","feature-flags","feature-toggles","java","javascript","objective-c","refactoring","refactoring-tools","stale-flags","swift","swift-syntax"],"created_at":"2024-07-31T22:01:06.366Z","updated_at":"2026-10-19T08:05:10.462Z","avatar_url":"https://github.com/uber.png","language":"Rust","funding_links":[],"categories":["Rust","Java","Development","功能切换"],"sub_categories":[],"readme":"# PolyglotPiranha\n\nPolyglotPiranha is a lightweight code transformation toolset for automating large scale changes. At Uber, it is mostly used to clean up stale feature flags.\n\nWe only support languages that are used at Uber. We likely won't be able to add new languages in this repo. There are a number of forks (see https://github.com/uber/piranha/forks for a full list) that may provide additional features.\n\n\n## Installation\n\nTo install Polyglot Piranha, you can use it as a Python library or as a command-line tool.\n\n### Python API\n\nTo install the Python API, run the following command:\n\n```bash\npip install polyglot-piranha\n```\n\n### Command-line Interface\n\nTo install the command-line interface, follow these steps:\n\n1. Install [Rust](https://www.rust-lang.org/tools/install)\n2. Clone the repository: `git clone https://github.com/uber/piranha.git`\n3. Navigate to the cloned directory: `cd piranha`\n4. Build the project: `cargo build --release` (or `cargo build --release --no-default-features` for macOS)\n5. The binary will be generated under `target/release`\n\n## Example Usage\n\n```python\nfrom polyglot_piranha import execute_piranha, PiranhaArguments, Rule, RuleGraph, OutgoingEdges\n\n# Original code snippet\ncode = \"\"\"\nif (obj.isLocEnabled() || x \u003e 0) {\n    // do something\n} else {\n    // do something else!\n}\n\"\"\"\n\n# Define the rule to replace the method call\nr1 = Rule(\n    name=\"replace_method\",\n    query=\"cs :[x].isLocEnabled()\", # cs indicates we are using concrete syntax\n    replace_node=\"*\",\n    replace=\"true\",\n    is_seed_rule=True\n)\n\n# Define the edges for the rule graph. \n# In this case, boolean_literal_cleanup is already defined for java [see src/cleanup_rules]\nedge = OutgoingEdges(\"replace_method\", to=[\"boolean_literal_cleanup\"], scope=\"parent\")\n\n# Create Piranha arguments\npiranha_arguments = PiranhaArguments(\n    code_snippet=code,\n    language=\"java\",\n    rule_graph=RuleGraph(rules=[r1], edges=[edge])\n)\n\n# Execute Piranha and print the transformed code\npiranha_summary = execute_piranha(piranha_arguments)\nprint(piranha_summary[0].content)\n```\n\n\n## Documentation\n\nFor more examples and explanations of the toolset, please check our demos and extended [POLYGLOT_README.md](POLYGLOT_README.md) file.\n\n\n## Feature Flags\n\n\nFeature flags are commonly used to enable gradual rollout or experiment with new features. In a few cases, even after the purpose of the flag is accomplished, the code pertaining to the feature flag is not removed. We refer to such flags as stale flags. The presence of code pertaining to stale flags can have the following drawbacks: \n- Unnecessary code clutter increases the overall complexity w.r.t maintenance resulting in reduced developer productivity \n- The flags can interfere with other experimental flags (e.g., due to nesting under a flag that is always false)\n- Presence of unused code in the source as well as the binary \n- Stale flags can also cause bugs \n\nPolyglotPiranha is a tool that can automatically refactor code related to stale flags. At a higher level, the input to the tool is the name of the flag and the expected behavior, after specifying a list of APIs related to flags in a properties file. Piranha will use these inputs to automatically refactor the code according to the expected behavior.\n\nPolyglotPiranha (as of May 2022) is a common refactoring tool to support multiple languages and feature flag APIs.\nFor legacy language-specific implementations please check following [tag](https://github.com/uber/piranha/releases/tag/last-version-having-legacy-piranha).\n\n\n\nA few additional links on Piranha: \n\n- Research paper published at [PLDI 2024](https://dl.acm.org/doi/10.1145/3656429) on PolyglotPiranha.\n- A technical [report](report.pdf) detailing our experiences with using Piranha at Uber.\n- A [blogpost](https://eng.uber.com/piranha/) presenting more information on Piranha. \n- 6 minute [video](https://www.youtube.com/watch?v=V5XirDs6LX8\u0026feature=emb_logo) overview of Piranha.\n\n## Support\n\nIf you have any questions on how to use Piranha or find any bugs, please [open a GitHub issue](https://github.com/uber/piranha/issues).\n\n## Piranha Development\n\nPiranha uses several grammar repositories with custom patches to support the transformations. While\nthese patches are being upstreamed, there may be discrepancies between the grammars in this \nrepository and the upstream grammars. Therefore, we have built a custom tree-sitter playground\nthat can be used to test the grammars and queries for easier development:\n\nhttps://uber.github.io/piranha/tree-sitter-playground/\n\n## License\nPiranha is licensed under the Apache 2.0 license.  See the LICENSE file for more information.\n\n## Note\n\nThis is not an official Uber product, and provided as is.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuber%2Fpiranha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuber%2Fpiranha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuber%2Fpiranha/lists"}