cpd 5.0.4 → 5.0.6
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 +48 -161
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
# cpd — Rust Copy/Paste Detector
|
|
2
2
|
|
|
3
|
-
Fast copy/paste detector for programming source code. Rust rewrite of [jscpd](https://github.com/kucherenko/jscpd)
|
|
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.
|
|
4
|
+
|
|
5
|
+
Also available as an npm package: [`jscpd@5`](https://www.npmjs.com/package/jscpd) (installs both `jscpd` and `cpd` commands) or [`cpd`](https://www.npmjs.com/package/cpd) (installs `cpd` command only).
|
|
4
6
|
|
|
5
7
|
## Performance
|
|
6
8
|
|
|
7
|
-
| Codebase | Files | jscpd v4 (Node.js) | cpd v5 (Rust) | Speedup |
|
|
8
|
-
|
|
9
|
-
| Multi-format fixtures |
|
|
10
|
-
|
|
|
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 | 164 MB | 15.80 s | 0.43 s | 36.9× |
|
|
13
|
+
| CopilotKit | 17K | 902 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.
|
|
11
16
|
|
|
12
17
|
## Install
|
|
13
18
|
|
|
14
19
|
### npm (recommended)
|
|
15
20
|
|
|
16
21
|
```bash
|
|
22
|
+
# installs both jscpd and cpd commands
|
|
23
|
+
npm install -g jscpd
|
|
24
|
+
|
|
25
|
+
# installs only the cpd command
|
|
17
26
|
npm install -g cpd
|
|
18
27
|
```
|
|
19
28
|
|
|
20
|
-
Prebuilt binaries for 6 platforms — no Node.js runtime required
|
|
21
|
-
|
|
22
|
-
| Package | OS | Arch | libc |
|
|
23
|
-
|---------|----|------|------|
|
|
24
|
-
| `cpd-darwin-arm64` | macOS | arm64 | — |
|
|
25
|
-
| `cpd-darwin-x64` | macOS | x64 | — |
|
|
26
|
-
| `cpd-linux-arm64-gnu` | Linux | arm64 | glibc |
|
|
27
|
-
| `cpd-linux-x64-gnu` | Linux | x64 | glibc |
|
|
28
|
-
| `cpd-linux-x64-musl` | Linux | x64 | musl |
|
|
29
|
-
| `cpd-windows-x64-msvc` | Windows | x64 | — |
|
|
29
|
+
Prebuilt binaries for 6 platforms — no Node.js runtime required.
|
|
30
30
|
|
|
31
31
|
### crates.io
|
|
32
32
|
|
|
@@ -34,135 +34,45 @@ Prebuilt binaries for 6 platforms — no Node.js runtime required:
|
|
|
34
34
|
cargo install jscpd
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
Installs both `jscpd` and `cpd` binaries.
|
|
38
|
+
|
|
37
39
|
### From source
|
|
38
40
|
|
|
39
41
|
```bash
|
|
40
42
|
git clone https://github.com/kucherenko/jscpd.git
|
|
41
43
|
cd jscpd/rust
|
|
42
44
|
cargo build --release
|
|
43
|
-
#
|
|
45
|
+
# binaries at target/release/jscpd and target/release/cpd
|
|
44
46
|
```
|
|
45
47
|
|
|
46
48
|
## Quick Start
|
|
47
49
|
|
|
48
50
|
```bash
|
|
49
|
-
# Scan current directory (defaults: min-tokens 50, min-lines 5)
|
|
50
51
|
cpd .
|
|
51
|
-
|
|
52
|
-
# Scan specific paths
|
|
53
52
|
cpd ./src ./lib
|
|
54
|
-
|
|
55
|
-
# Git blame with side-by-side author comparison
|
|
56
53
|
cpd . --blame --reporters console-full
|
|
57
|
-
|
|
58
|
-
# Output to JSON + HTML
|
|
59
54
|
cpd . --reporters json,html
|
|
60
|
-
|
|
61
|
-
# Fail CI if duplication exceeds threshold
|
|
62
|
-
cpd . --threshold 10 --exit-code
|
|
63
|
-
|
|
64
|
-
# List all 225+ supported formats
|
|
55
|
+
cpd . --threshold 10
|
|
65
56
|
cpd --list
|
|
66
57
|
```
|
|
67
58
|
|
|
68
|
-
##
|
|
69
|
-
|
|
70
|
-
| Flag | Short | Default | Description |
|
|
71
|
-
|------|-------|---------|-------------|
|
|
72
|
-
| `--min-tokens` | `-k` | 50 | Minimum tokens to consider a duplicate |
|
|
73
|
-
| `--min-lines` | `-l` | 5 | Minimum lines to consider a duplicate |
|
|
74
|
-
| `--max-lines` | `-x` | — | Maximum lines per duplicate block |
|
|
75
|
-
| `--mode` | `-m` | mild | Detection mode: `mild`, `weak`, `strict` |
|
|
76
|
-
| `--skip-comments` | — | — | Alias for `--mode weak` |
|
|
77
|
-
| `--format` | `-f` | all | Comma-separated formats to check |
|
|
78
|
-
| `--ignore-pattern` | `-i` | — | Glob patterns to ignore |
|
|
79
|
-
| `--reporters` | `-r` | console | comma-separated reporters |
|
|
80
|
-
| `--output` | `-o` | report | Output directory for file reporters |
|
|
81
|
-
| `--config` | `-c` | — | Path to config file (`.jscpd.json`) |
|
|
82
|
-
| `--exit-code` | — | — | Exit non-zero if duplicates found |
|
|
83
|
-
| `--threshold` | `-t` | — | Max duplication % before exit 1 |
|
|
84
|
-
| `--blame` | `-b` | — | Enrich clones with git blame data |
|
|
85
|
-
| `--no-gitignore` | — | — | Ignore `.gitignore` files |
|
|
86
|
-
| `--follow-symlinks` | — | — | Follow symbolic links |
|
|
87
|
-
| `--max-size` | `-z` | 512 KB | Skip files larger than N bytes |
|
|
88
|
-
| `--workers` | — | auto | Number of worker threads |
|
|
89
|
-
| `--no-colors` | — | — | Disable ANSI color output |
|
|
90
|
-
| `--skip-local` | — | — | Skip clones within the same directory |
|
|
91
|
-
| `--silent` | `-s` | — | Suppress console output |
|
|
92
|
-
| `--no-tips` | — | — | Suppress tips and promotional messages |
|
|
93
|
-
| `--list` | — | — | List all supported formats and exit |
|
|
94
|
-
|
|
95
|
-
## Reporters
|
|
96
|
-
|
|
97
|
-
13 built-in reporters:
|
|
98
|
-
|
|
99
|
-
| Reporter | Output |
|
|
100
|
-
|----------|--------|
|
|
101
|
-
| `console` | Clone list + statistics table (default) |
|
|
102
|
-
| `console-full` | Source snippets + optional blame comparison |
|
|
103
|
-
| `json` | `report/cpd.json` |
|
|
104
|
-
| `xml` | `report/cpd.xml` |
|
|
105
|
-
| `csv` | `report/cpd.csv` |
|
|
106
|
-
| `html` | `report/cpd.html` |
|
|
107
|
-
| `markdown` | `report/cpd.md` |
|
|
108
|
-
| `badge` | `report/cpd-badge.svg` |
|
|
109
|
-
| `sarif` | `report/cpd.sarif.json` (GitHub Code Scanning) |
|
|
110
|
-
| `ai` | Token-efficient output for LLM pipelines |
|
|
111
|
-
| `xcode` | Xcode-compatible warnings |
|
|
112
|
-
| `threshold` | Exit 1 if duplication % exceeds `--threshold` |
|
|
113
|
-
| `silent` | No console output |
|
|
114
|
-
|
|
115
|
-
Combine reporters: `--reporters console,json,html`
|
|
116
|
-
|
|
117
|
-
## Git Blame
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
cpd . --blame --reporters console-full
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Produces a side-by-side author comparison:
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
176 │ Andrii Kucherenko │ <= │ 196 │ Josh Soref │ ## TODO
|
|
127
|
-
177 │ Andrii Kucherenko │ <= │ 197 │ Josh Soref │
|
|
128
|
-
180 │ Andrii Kucherenko │ == │ 200 │ Andrii Kucherenko │ ## License
|
|
129
|
-
```
|
|
59
|
+
## Architecture
|
|
130
60
|
|
|
131
|
-
`==` = same author (original). `<=` = different author (potential copy).
|
|
132
|
-
|
|
133
|
-
## Config File
|
|
134
|
-
|
|
135
|
-
Create `.jscpd.json` in your project root:
|
|
136
|
-
|
|
137
|
-
```json
|
|
138
|
-
{
|
|
139
|
-
"minTokens": 30,
|
|
140
|
-
"minLines": 3,
|
|
141
|
-
"format": ["javascript", "typescript", "python"],
|
|
142
|
-
"ignorePattern": ["node_modules", "dist", "*.min.js"],
|
|
143
|
-
"reporters": ["console", "json"],
|
|
144
|
-
"output": "report",
|
|
145
|
-
"threshold": 5,
|
|
146
|
-
"blame": false,
|
|
147
|
-
"noGitignore": false,
|
|
148
|
-
"noColors": false,
|
|
149
|
-
"silent": false
|
|
150
|
-
}
|
|
151
61
|
```
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
62
|
+
jscpd/cpd (CLI binary)
|
|
63
|
+
├── cpd-core — Detection algorithm (Rabin-Karp rolling hash)
|
|
64
|
+
├── cpd-tokenizer — Language tokenization (223 formats)
|
|
65
|
+
├── cpd-finder — File walking, orchestration, git blame
|
|
66
|
+
└── cpd-reporter — Output formatting (13 reporters)
|
|
157
67
|
```
|
|
158
|
-
Clone found (javascript)
|
|
159
|
-
- app.vue:javascript [10:1 - 35:2] (25 lines, 180 tokens)
|
|
160
|
-
utils.js [40:1 - 65:2]
|
|
161
68
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
69
|
+
| Crate | Version | Purpose |
|
|
70
|
+
|-------|---------|---------|
|
|
71
|
+
| `cpd-core` | [0.1.3](https://crates.io/crates/cpd-core) | Detection algorithm, rolling hash, models |
|
|
72
|
+
| `cpd-tokenizer` | [0.1.3](https://crates.io/crates/cpd-tokenizer) | Language tokenization (223 formats) |
|
|
73
|
+
| `cpd-finder` | [0.1.4](https://crates.io/crates/cpd-finder) | File walking, orchestration, git blame |
|
|
74
|
+
| `cpd-reporter` | [0.1.4](https://crates.io/crates/cpd-reporter) | Output formatting (13 reporters) |
|
|
75
|
+
| `jscpd` | [5.0.4](https://crates.io/crates/jscpd) | CLI binary and entry point |
|
|
166
76
|
|
|
167
77
|
## Programmatic Usage (Rust)
|
|
168
78
|
|
|
@@ -180,54 +90,31 @@ println!("Found {} clones", result.clones.len());
|
|
|
180
90
|
println!("Analyzed {} files", result.statistics.total.sources);
|
|
181
91
|
```
|
|
182
92
|
|
|
183
|
-
##
|
|
93
|
+
## Building
|
|
184
94
|
|
|
95
|
+
Requires Rust 1.87+ (see `rust-toolchain.toml`).
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
cargo build --release
|
|
99
|
+
cargo test
|
|
185
100
|
```
|
|
186
|
-
jscpd (binary)
|
|
187
|
-
├── cpd-core — Detection algorithm (Rabin-Karp rolling hash)
|
|
188
|
-
├── cpd-tokenizer — Language tokenization (225+ formats)
|
|
189
|
-
├── cpd-finder — File walking, orchestration, git blame
|
|
190
|
-
└── cpd-reporter — Output formatting (13 reporters)
|
|
191
|
-
```
|
|
192
101
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
| `jscpd` | [5.0.2](https://crates.io/crates/jscpd) | CLI binary and entry point |
|
|
102
|
+
## Documentation
|
|
103
|
+
|
|
104
|
+
- **[docs/rust.md](../docs/rust.md)** — Full CLI reference, all options, reporters, config file, differences from v4
|
|
105
|
+
- **[docs/typescript.md](../docs/typescript.md)** — TypeScript/Node.js engine (v4.x) documentation
|
|
106
|
+
- **[docs/ai-ready.md](../docs/ai-ready.md)** — AI reporter, agent skills, MCP server
|
|
107
|
+
- **[docs/api.md](../docs/api.md)** — Programming APIs (TypeScript and Rust)
|
|
200
108
|
|
|
201
109
|
## Known Differences from jscpd v4
|
|
202
110
|
|
|
203
111
|
| Feature | jscpd v4 (Node.js) | cpd v5 (Rust) |
|
|
204
112
|
|---------|--------------------|-----------------|
|
|
205
|
-
| `--
|
|
206
|
-
|
|
|
207
|
-
| `--
|
|
208
|
-
| Programming API | `jscpd()` Promise API, `detectClones()` | Rust crate API; no Node.js API |
|
|
209
|
-
| Config file | `.jscpd.json` with camelCase keys | Same |
|
|
210
|
-
| Cross-format detection | Vue, Svelte, Astro, Markdown | Same — per-block tokenization |
|
|
211
|
-
| Token counts | May differ slightly | May differ by 1–2%; clone detection matches |
|
|
212
|
-
| `--reporters` | All v4 reporters | All v4 reporters except `full` (use `console-full`) |
|
|
113
|
+
| `--store` (LevelDB) | Persistent store for large repos | Not supported |
|
|
114
|
+
| Programming API | `jscpd()` Promise, `detectClones()` | Rust crate API; no Node.js API |
|
|
115
|
+
| `--reporters` | All v4 reporters | All except `full` (use `console-full`) |
|
|
213
116
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
### Prerequisites
|
|
217
|
-
|
|
218
|
-
- Rust 1.87+ (see `rust-toolchain.toml`)
|
|
219
|
-
|
|
220
|
-
### Build
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
cargo build --release
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Run Tests
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
cargo test
|
|
230
|
-
```
|
|
117
|
+
See [docs/rust.md](../docs/rust.md) for the full differences table.
|
|
231
118
|
|
|
232
119
|
## License
|
|
233
120
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cpd",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.6",
|
|
4
4
|
"description": "Copy/paste detector — fast Rust-based CLI for code duplication detection",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cpd": "./run-cpd.js"
|
|
@@ -10,16 +10,16 @@
|
|
|
10
10
|
"platform-map.js"
|
|
11
11
|
],
|
|
12
12
|
"optionalDependencies": {
|
|
13
|
-
"cpd-linux-x64-gnu": "5.0.
|
|
14
|
-
"cpd-linux-arm64-gnu": "5.0.
|
|
15
|
-
"cpd-linux-x64-musl": "5.0.
|
|
16
|
-
"cpd-darwin-arm64": "5.0.
|
|
17
|
-
"cpd-darwin-x64": "5.0.
|
|
18
|
-
"cpd-windows-x64-msvc": "5.0.
|
|
13
|
+
"cpd-linux-x64-gnu": "5.0.6",
|
|
14
|
+
"cpd-linux-arm64-gnu": "5.0.6",
|
|
15
|
+
"cpd-linux-x64-musl": "5.0.6",
|
|
16
|
+
"cpd-darwin-arm64": "5.0.6",
|
|
17
|
+
"cpd-darwin-x64": "5.0.6",
|
|
18
|
+
"cpd-windows-x64-msvc": "5.0.6"
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
|
-
"url": "https://github.com/kucherenko/jscpd",
|
|
22
|
+
"url": "git+https://github.com/kucherenko/jscpd.git",
|
|
23
23
|
"directory": "rust"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|