↓ Skip to main content

pelicode

Version
License-MIT
Rust

[ 🗣️ Overview | ⚙️ How It Works | 🧭 Navigation ]

pelicode logo

pelicode extracts structural features of code at the function level and compares them with the code of published packages to find similar code that should be reviewed, together with its source and license.


🗣️ Overview
#

Developers no longer write every line themselves. Code comes from AI assistants and from pull requests by people outside the team, and reading all of it to make sure none was copied from somewhere else is not possible.

dependabot checks the versions of your dependencies against package repositories and tells you when to upgrade. pelicode works in a similar spirit for the code itself: it checks the functions in your repository, or only those changed by a commit or a pull request, against the functions of packages published on PyPI, Maven Central, the Go module proxy, RubyGems and crates.io.

Matching is done on normalized syntax trees, not on text, so renamed variables, reformatting, edited comments and a few added or removed statements do not hide a match.

pelicode does not decide whether code is plagiarized or infringes a license. It shows candidates to review, each with the package, version, file, lines and license it was found in. Whether code was reused, and whether that matters, is for a person to judge.

⚙️ How It Works
#

flowchart LR
    R[("PyPI / Maven Central / crates.io
Go proxy / RubyGems")] -->|pelicode crawl| I P["Local projects"] -->|pelicode index| I I["Extract, normalize
and hash functions"] --> D[("SQLite database")] D -->|pelicode stats --refresh| D T["Code to check
(directory or git range)"] -->|pelicode scan| S["Search for
similar functions"] D --> S S --> O["Candidates to review
(text / JSON / CSV)"]
  1. Collect the code of published packages with pelicode crawl (or your own projects with pelicode index).
  2. Extract every function with Tree-sitter, and normalize it: comments and layout are dropped, and identifiers, literals and type names are replaced with placeholders.
  3. Hash each function as a whole, for exact matches, and as a set of fingerprints, for partial matches. Only these hashes, the locations and the provenance are stored; source code is not.
  4. Count how many packages contain each hash with pelicode stats --refresh, so that boilerplate found everywhere can be ignored.
  5. Scan your code with pelicode scan, and review the candidates it reports.

Supported languages are Go, Java, Kotlin, Python, Ruby and Rust.


🧭 Navigation
#