cpd 5.1.0 → 5.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,37 +1,29 @@
1
- # cpd — Rust Copy/Paste Detector
1
+ # jscpd — Rust engine
2
2
 
3
- Fast copy/paste detector for programming source code. 24-37x faster than Node.js. Rust rewrite of [jscpd](https://github.com/kucherenko/jscpd), supports 223 language formats.
3
+ Copy/paste detector for programming source code. A self-contained binary that finds duplicated blocks across 224 language formats, writes reports in 15 formats and can fail CI when duplication grows.
4
4
 
5
- Also available as an npm package: [`jscpd@5`](https://www.npmjs.com/package/jscpd) (installs the `jscpd` command) or [`cpd`](https://www.npmjs.com/package/cpd) (installs the `cpd` command). The crates.io install exposes both `jscpd` and `cpd` binaries.
6
-
7
- ## Performance
8
-
9
- | Codebase | Files | Size | jscpd v4 (Node.js) | cpd v5 (Rust) | Speedup |
10
- |----------|-------|------|--------------------|----------------|---------|
11
- | Multi-format fixtures | 548 | 1.5 MB | 1.03 s | 0.03 s | 34.3× |
12
- | Svelte source | 9K | 38 MB | 15.80 s | 0.43 s | 36.9× |
13
- | CopilotKit | 17K | 159 MB | 82.89 s | 3.44 s | 24.1× |
14
-
15
- See [performance-comparison.md](../docs/performance-comparison.md) for full methodology and raw data.
5
+ Published as [`jscpd`](https://www.npmjs.com/package/jscpd) on npm (installs the `jscpd` command), [`cpd`](https://www.npmjs.com/package/cpd) on npm (installs the `cpd` command), and [`jscpd`](https://crates.io/crates/jscpd) on crates.io (installs both). Full documentation: [jscpd.dev](https://jscpd.dev) and [docs/rust.md](../docs/rust.md).
16
6
 
17
7
  ## Install
18
8
 
19
- ### npm (recommended)
9
+ ### npm
20
10
 
21
11
  ```bash
22
- # npm — installs the jscpd command
12
+ # installs the jscpd command
23
13
  npm install -g jscpd
24
14
 
25
- # npm — installs only the cpd command
15
+ # installs only the cpd command
26
16
  npm install -g cpd
27
17
  ```
28
18
 
29
- Prebuilt binaries for 7 platforms — no Node.js runtime required.
19
+ Prebuilt binaries for 8 platforms (macOS arm64/x64, Linux arm64/x64 with glibc or musl, Windows arm64/x64) — no Node.js runtime required.
30
20
 
31
21
  ### crates.io
32
22
 
33
23
  ```bash
34
24
  cargo install jscpd
25
+ # or, without compiling (prebuilt release binaries via cargo-binstall):
26
+ cargo binstall jscpd
35
27
  ```
36
28
 
37
29
  Installs both `jscpd` and `cpd` binaries.
@@ -64,12 +56,14 @@ cargo build --release
64
56
  ## Quick Start
65
57
 
66
58
  ```bash
67
- cpd .
68
- cpd ./src ./lib
69
- cpd . --blame --reporters console-full
70
- cpd . --reporters json,html
71
- cpd . --threshold 10
72
- cpd --list
59
+ jscpd .
60
+ jscpd ./src ./lib
61
+ jscpd . --blame --reporters console-full
62
+ jscpd . --reporters json,html
63
+ jscpd . --threshold 10
64
+ jscpd --baseline-from-ref origin/main --fail-on-new-clones .
65
+ jscpd --mcp .
66
+ jscpd --list
73
67
  ```
74
68
 
75
69
  ## Architecture
@@ -77,18 +71,20 @@ cpd --list
77
71
  ```
78
72
  jscpd/cpd (CLI binary)
79
73
  ├── cpd-core — Detection algorithm (Rabin-Karp rolling hash)
80
- ├── cpd-tokenizer — Language tokenization (223 formats)
81
- ├── cpd-finder — File walking, orchestration, git blame
82
- └── cpd-reporter — Output formatting (13 reporters)
74
+ ├── cpd-tokenizer — Language tokenization (224 formats)
75
+ ├── cpd-finder — File walking, orchestration, baseline, git blame
76
+ └── cpd-reporter — Output formatting (15 reporters)
83
77
  ```
84
78
 
85
- | Crate | Version | Purpose |
86
- |-------|---------|---------|
87
- | `cpd-core` | [0.1.3](https://crates.io/crates/cpd-core) | Detection algorithm, rolling hash, models |
88
- | `cpd-tokenizer` | [0.1.3](https://crates.io/crates/cpd-tokenizer) | Language tokenization (223 formats) |
89
- | `cpd-finder` | [0.1.4](https://crates.io/crates/cpd-finder) | File walking, orchestration, git blame |
90
- | `cpd-reporter` | [0.1.4](https://crates.io/crates/cpd-reporter) | Output formatting (13 reporters) |
91
- | `jscpd` | [5.0.4](https://crates.io/crates/jscpd) | CLI binary and entry point |
79
+ | Crate | Purpose |
80
+ |-------|---------|
81
+ | [`jscpd`](https://crates.io/crates/jscpd) | CLI binary and entry point (`crates/cpd`) |
82
+ | [`cpd-core`](https://crates.io/crates/cpd-core) | Detection algorithm, rolling hash, models |
83
+ | [`cpd-tokenizer`](https://crates.io/crates/cpd-tokenizer) | Language tokenization (224 formats); pure, no I/O |
84
+ | [`cpd-finder`](https://crates.io/crates/cpd-finder) | File walking, orchestration, git blame |
85
+ | [`cpd-reporter`](https://crates.io/crates/cpd-reporter) | Output formatting (15 reporters) |
86
+
87
+ Current versions are in each crate's `Cargo.toml`; `scripts/sync-version.mjs` keeps them and the npm packages in step. The workspace layout, npm launcher packages and platform packages are described in [docs/packages.md](../docs/packages.md).
92
88
 
93
89
  ## Programmatic Usage (Rust)
94
90
 
@@ -106,33 +102,41 @@ println!("Found {} clones", result.clones.len());
106
102
  println!("Analyzed {} files", result.statistics.total.sources);
107
103
  ```
108
104
 
109
- ## Building
105
+ See [docs/api.md](../docs/api.md) and [examples/rust-cpd-finder](../examples/rust-cpd-finder).
106
+
107
+ ## Building and testing
110
108
 
111
- Requires Rust 1.87+ (see `rust-toolchain.toml`).
109
+ Requires Rust 1.96+ (the MSRV declared in `Cargo.toml`, enforced by the `msrv`
110
+ job in CI). Development uses the exact toolchain pinned in `rust-toolchain.toml`.
112
111
 
113
112
  ```bash
114
113
  cargo build --release
115
- cargo test
114
+ cargo nextest run --workspace # or: cargo test --workspace
115
+ cargo clippy --workspace --all-targets -- -D warnings
116
+ cargo fmt --all --check
117
+
118
+ # End-to-end run over the multi-format corpus (what CI's smoke job does)
119
+ ./target/release/jscpd ../fixtures --reporters console,json --output ../smoke-report --min-tokens 50
116
120
  ```
117
121
 
118
- ## Documentation
122
+ After changing the format table in `crates/cpd-tokenizer/src/formats.rs`, regenerate the root [FORMATS.md](../FORMATS.md) with `node scripts/gen-formats-md.mjs`.
119
123
 
120
- - **[docs/rust.md](../docs/rust.md)** — Full CLI reference, all options, reporters, config file, differences from v4
121
- - **[docs/typescript.md](../docs/typescript.md)** — TypeScript/Node.js engine (v4.x) documentation
122
- - **[docs/ai-ready.md](../docs/ai-ready.md)** — AI reporter, agent skills, MCP server
123
- - **[docs/api.md](../docs/api.md)** — Programming APIs (TypeScript and Rust)
124
+ ## Benchmarks
124
125
 
125
- ## Known Differences from jscpd v4
126
+ Compared against other copy/paste detectors (jscpd-rs, Duplo, Fallow, Simian, PMD CPD) on the repository's `fixtures/` corpus — timing, detection counts, cross-format detection and AI-token efficiency — in [benchmark/BENCHMARK.md](../benchmark/BENCHMARK.md). Re-run with [`benchmark/benchmark.sh`](../benchmark/benchmark.sh).
126
127
 
127
- | Feature | jscpd v4 (Node.js) | cpd v5 (Rust) |
128
- |---------|--------------------|-----------------|
129
- | `--store` (LevelDB) | Persistent store for large repos | Not supported |
130
- | Programming API | `jscpd()` Promise, `detectClones()` | Rust crate API; no Node.js API |
131
- | `--reporters` | All v4 reporters | All except `full` (use `console-full`) |
128
+ ## Documentation
129
+
130
+ - **[docs/rust.md](../docs/rust.md)** Full CLI reference, all options, reporters, baseline, summary, config file
131
+ - **[docs/ai-ready.md](../docs/ai-ready.md)** AI reporter, agent skills, MCP server
132
+ - **[docs/api.md](../docs/api.md)** Rust API
133
+ - **[docs/ci-and-hooks.md](../docs/ci-and-hooks.md)** — GitHub Action, Docker, pre-commit hooks
134
+ - **[CHANGELOG.md](CHANGELOG.md)** — Release notes
132
135
 
133
- See [docs/rust.md](../docs/rust.md) for the full differences table.
136
+ ## Coming from jscpd v4?
134
137
 
138
+ The CLI flags, `.jscpd.json` config and reporters are the same; see the [migration table](../docs/rust.md#migrating-from-jscpd-v4) for the few differences. jscpd v4 (TypeScript engine, Node.js API, LevelDB/Redis stores) is maintained on the [`master-v4`](https://github.com/kucherenko/jscpd/tree/master-v4) branch and published as `jscpd@4`.
135
139
 
136
140
  ## License
137
141
 
138
- MIT
142
+ MIT
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "cpd",
3
- "version": "5.1.0",
4
- "description": "Copy/paste detector — fast Rust-based CLI for code duplication detection",
3
+ "version": "5.1.2",
4
+ "description": "Copy/paste detector for programming source code Rust engine, self-contained binary, installs the cpd command",
5
5
  "homepage": "https://jscpd.dev",
6
+ "funding": "https://opencollective.com/jscpd",
6
7
  "bin": {
7
8
  "cpd": "./run-cpd.js"
8
9
  },
@@ -11,13 +12,14 @@
11
12
  "platform-map.js"
12
13
  ],
13
14
  "optionalDependencies": {
14
- "jscpd-linux-x64-gnu": "5.1.0",
15
- "jscpd-linux-arm64-gnu": "5.1.0",
16
- "jscpd-linux-x64-musl": "5.1.0",
17
- "jscpd-darwin-arm64": "5.1.0",
18
- "jscpd-darwin-x64": "5.1.0",
19
- "jscpd-windows-x64-msvc": "5.1.0",
20
- "jscpd-windows-arm64-msvc": "5.1.0"
15
+ "jscpd-linux-x64-gnu": "5.1.2",
16
+ "jscpd-linux-arm64-gnu": "5.1.2",
17
+ "jscpd-linux-x64-musl": "5.1.2",
18
+ "jscpd-linux-arm64-musl": "5.1.2",
19
+ "jscpd-darwin-arm64": "5.1.2",
20
+ "jscpd-darwin-x64": "5.1.2",
21
+ "jscpd-windows-x64-msvc": "5.1.2",
22
+ "jscpd-windows-arm64-msvc": "5.1.2"
21
23
  },
22
24
  "repository": {
23
25
  "type": "git",
package/platform-map.js CHANGED
@@ -27,6 +27,14 @@ const PLATFORM_MAP = {
27
27
  rustTarget: "x86_64-unknown-linux-musl",
28
28
  runner: "ubuntu-latest",
29
29
  },
30
+ "linux-arm64-musl": {
31
+ packageName: "jscpd-linux-arm64-musl",
32
+ os: "linux",
33
+ cpu: "arm64",
34
+ libc: "musl",
35
+ rustTarget: "aarch64-unknown-linux-musl",
36
+ runner: "ubuntu-22.04-arm",
37
+ },
30
38
  "darwin-arm64": {
31
39
  packageName: "jscpd-darwin-arm64",
32
40
  os: "darwin",
@@ -88,4 +96,24 @@ function getPlatformKey() {
88
96
  return undefined;
89
97
  }
90
98
 
91
- module.exports = { PLATFORM_MAP, getPlatformKey };
99
+ /**
100
+ * Human-readable description of the host, e.g. "linux/arm64 (musl)", for
101
+ * error messages.
102
+ */
103
+ function describeHost() {
104
+ const libc = detectLinuxLibc();
105
+ return `${platform}/${arch}${libc ? ` (${libc})` : ""}`;
106
+ }
107
+
108
+ /** Supported platform keys, e.g. ["linux-x64-gnu", ...]. */
109
+ function supportedPlatforms() {
110
+ return Object.keys(PLATFORM_MAP);
111
+ }
112
+
113
+ module.exports = {
114
+ PLATFORM_MAP,
115
+ getPlatformKey,
116
+ detectLinuxLibc,
117
+ describeHost,
118
+ supportedPlatforms,
119
+ };
package/run-cpd.js CHANGED
@@ -3,12 +3,24 @@
3
3
 
4
4
  const path = require("path");
5
5
  const { spawnSync } = require("child_process");
6
- const { getPlatformKey, PLATFORM_MAP } = require("./platform-map");
6
+ const {
7
+ getPlatformKey,
8
+ PLATFORM_MAP,
9
+ describeHost,
10
+ supportedPlatforms,
11
+ } = require("./platform-map");
7
12
 
8
13
  const key = getPlatformKey();
9
14
  if (!key) {
10
15
  console.error(
11
- `cpd: Unsupported platform ${process.platform}/${process.arch}`
16
+ `cpd: no prebuilt binary for this platform: ${describeHost()}`
17
+ );
18
+ console.error(
19
+ `cpd: supported platforms: ${supportedPlatforms().join(", ")}`
20
+ );
21
+ console.error(
22
+ "cpd: build from source instead with `cargo install jscpd` " +
23
+ "(https://github.com/kucherenko/jscpd/tree/master/rust)"
12
24
  );
13
25
  process.exit(1);
14
26
  }