cpd 5.0.2 → 5.0.3

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.
Files changed (2) hide show
  1. package/README.md +234 -0
  2. package/package.json +7 -7
package/README.md ADDED
@@ -0,0 +1,234 @@
1
+ # cpd — Rust Copy/Paste Detector
2
+
3
+ Fast copy/paste detector for programming source code. Rust rewrite of [jscpd](https://github.com/kucherenko/jscpd) with 10–30× faster detection, git blame, and 225+ language formats.
4
+
5
+ ## Performance
6
+
7
+ | Codebase | Files | jscpd v4 (Node.js) | cpd v5 (Rust) | Speedup |
8
+ |----------|-------|--------------------|----------------|---------|
9
+ | Multi-format fixtures | 353 | 1.59 s | 0.45 s | 3.5× |
10
+ | Rust sources (homogeneous) | 46 | 0.87 s | 0.03 s | 29× |
11
+
12
+ ## Install
13
+
14
+ ### npm (recommended)
15
+
16
+ ```bash
17
+ npm install -g cpd
18
+ ```
19
+
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 | — |
30
+
31
+ ### crates.io
32
+
33
+ ```bash
34
+ cargo install jscpd
35
+ ```
36
+
37
+ ### From source
38
+
39
+ ```bash
40
+ git clone https://github.com/kucherenko/jscpd.git
41
+ cd jscpd/rust
42
+ cargo build --release
43
+ # binary at target/release/cpd
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ ```bash
49
+ # Scan current directory (defaults: min-tokens 50, min-lines 5)
50
+ cpd .
51
+
52
+ # Scan specific paths
53
+ cpd ./src ./lib
54
+
55
+ # Git blame with side-by-side author comparison
56
+ cpd . --blame --reporters console-full
57
+
58
+ # Output to JSON + HTML
59
+ 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
65
+ cpd --list
66
+ ```
67
+
68
+ ## Options
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
+ ```
130
+
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
+ ```
152
+
153
+ ## Cross-Format Detection
154
+
155
+ Vue SFC (`.vue`), Svelte (`.svelte`), Astro (`.astro`), and Markdown files are tokenized per-block, enabling duplicate detection across file types:
156
+
157
+ ```
158
+ Clone found (javascript)
159
+ - app.vue:javascript [10:1 - 35:2] (25 lines, 180 tokens)
160
+ utils.js [40:1 - 65:2]
161
+
162
+ Clone found (yaml)
163
+ - docker-compose.yml:yaml [7:1 - 25:33] (18 lines, 36 tokens)
164
+ config.yml:yaml [7:1 - 25:37]
165
+ ```
166
+
167
+ ## Programmatic Usage (Rust)
168
+
169
+ ```rust
170
+ use cpd_finder::orchestrate::{RunConfig, run};
171
+
172
+ let config = RunConfig {
173
+ paths: vec!["./src".into()],
174
+ min_tokens: 50,
175
+ ..Default::default()
176
+ };
177
+
178
+ let result = run(&config).unwrap();
179
+ println!("Found {} clones", result.clones.len());
180
+ println!("Analyzed {} files", result.statistics.total.sources);
181
+ ```
182
+
183
+ ## Architecture
184
+
185
+ ```
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
+
193
+ | Crate | crates.io | Purpose |
194
+ |-------|-----------|---------|
195
+ | `cpd-core` | [0.1.1](https://crates.io/crates/cpd-core) | Detection algorithm, rolling hash, models |
196
+ | `cpd-tokenizer` | [0.1.1](https://crates.io/crates/cpd-tokenizer) | Language tokenization (225+ formats) |
197
+ | `cpd-finder` | [0.1.2](https://crates.io/crates/cpd-finder) | File walking, orchestration, git blame |
198
+ | `cpd-reporter` | [0.1.2](https://crates.io/crates/cpd-reporter) | Output formatting (13 reporters) |
199
+ | `jscpd` | [5.0.2](https://crates.io/crates/jscpd) | CLI binary and entry point |
200
+
201
+ ## Known Differences from jscpd v4
202
+
203
+ | Feature | jscpd v4 (Node.js) | cpd v5 (Rust) |
204
+ |---------|--------------------|-----------------|
205
+ | `--blame` in `console-full` | Per-line side-by-side author comparison | Same — `==` / `<=` markers |
206
+ | `--store` (LevelDB) | Persistent store for large repos | Not supported. Use jscpd v4.x |
207
+ | `--formatsExts` | Custom format-to-extension mapping | Not supported. Use `--format` |
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`) |
213
+
214
+ ## Building
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
+ ```
231
+
232
+ ## License
233
+
234
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cpd",
3
- "version": "5.0.2",
3
+ "version": "5.0.3",
4
4
  "description": "Copy/paste detector — fast Rust-based CLI for code duplication detection",
5
5
  "bin": {
6
6
  "cpd": "./run-cpd.js"
@@ -10,12 +10,12 @@
10
10
  "platform-map.js"
11
11
  ],
12
12
  "optionalDependencies": {
13
- "cpd-linux-x64-gnu": "5.0.2",
14
- "cpd-linux-arm64-gnu": "5.0.2",
15
- "cpd-linux-x64-musl": "5.0.2",
16
- "cpd-darwin-arm64": "5.0.2",
17
- "cpd-darwin-x64": "5.0.2",
18
- "cpd-windows-x64-msvc": "5.0.2"
13
+ "cpd-linux-x64-gnu": "5.0.3",
14
+ "cpd-linux-arm64-gnu": "5.0.3",
15
+ "cpd-linux-x64-musl": "5.0.3",
16
+ "cpd-darwin-arm64": "5.0.3",
17
+ "cpd-darwin-x64": "5.0.3",
18
+ "cpd-windows-x64-msvc": "5.0.3"
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",