UNPKG

17.5 kBMarkdownView Raw
1<p align="center">
2 <img src="https://raw.githubusercontent.com/kucherenko/jscpd/master/assets/logo.svg?sanitize=true">
3</p>
4
5## jscpd
6[![npm](https://img.shields.io/npm/v/jscpd.svg?style=flat-square)](https://www.npmjs.com/package/jscpd)
7![jscpd](https://raw.githubusercontent.com/kucherenko/jscpd/master/assets/jscpd-badge.svg?sanitize=true)
8[![license](https://img.shields.io/github/license/kucherenko/jscpd.svg?style=flat-square)](https://github.com/kucherenko/jscpd/blob/master/LICENSE)
9[![npm](https://img.shields.io/npm/dw/jscpd.svg?style=flat-square)](https://www.npmjs.com/package/jscpd)
10
11
12[![codecov](https://codecov.io/gh/kucherenko/jscpd/branch/master/graph/badge.svg)](https://codecov.io/gh/kucherenko/jscpd)
13[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fkucherenko%2Fjscpd.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fkucherenko%2Fjscpd?ref=badge_shield)
14[![Backers on Open Collective](https://opencollective.com/jscpd/backers/badge.svg)](#backers)
15[![Sponsors on Open Collective](https://opencollective.com/jscpd/sponsors/badge.svg)](#sponsors)
16
17[![NPM](https://nodei.co/npm/jscpd.png)](https://nodei.co/npm/jscpd/)
18
19> Copy/paste detector for programming source code, supports [150+ formats](../../supported_formats.md).
20
21Copy/paste is a common technical debt on a lot of projects. The jscpd gives the ability to find duplicated blocks implemented on more than 150 programming languages and digital formats of documents.
22The jscpd tool implements [Rabin-Karp](https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm) algorithm for searching duplications.
23
24## Table of content
25
26- [Features](#features)
27- [Getting started](#getting-started)
28 - [Installation](#installation)
29 - [Usage](#usage)
30- [Options](#options)
31- [Config File](#config-file)
32- [Ignored Blocks](#ignored-blocks)
33- [Reporters](#jscpd-reporters)
34 - [HTML](#html)
35 - [Badge](#badge)
36 - [PMD CPD XML](#pmd-cpd-xml)
37 - [JSON](#json-reporters)
38- [API](#api)
39- [Changelog](#changelog)
40- [Who uses jscpd](#who-uses-jscpd)
41- [Contributors](#contributors)
42- [Backers](#backers)
43- [Sponsors](#sponsors)
44- [License](#license)
45
46
47## Features
48 - Detect duplications in programming source code, use semantic of programing languages, can skip comments, empty lines etc.
49 - Detect duplications in embedded blocks of code, like `<script>` or `<style>` sections in html
50 - Blame authors of duplications
51 - Generate XML report in pmd-cpd format, JSON report, [HTML report](http://kucherenko.github.io/jscpd-report.html)
52 - Integrate with CI systems, use thresholds for level of duplications
53
54## Getting started
55
56### Installation
57```bash
58$ npm install -g jscpd
59```
60### Usage
61```bash
62$ npx jscpd /path/to/source
63```
64or
65
66```bash
67$ jscpd /path/to/code
68```
69or
70
71```bash
72$ jscpd --pattern "src/**/*.js"
73```
74## Options
75### Pattern
76
77Glob pattern for find files to detect
78
79 - Cli options: `--pattern`, `-p`
80 - Type: **string**
81 - Default: "**/*"
82
83Example:
84 ```bash
85 $ jscpd --pattern "**/*.js"
86 ```
87
88### Min Tokens
89
90Minimal block size of code in tokens. The block of code less than `min-tokens` will be skipped.
91
92 - Cli options: `--min-tokens`, `-k`
93 - Type: **number**
94 - Default: **50**
95
96 *This option is called ``minTokens`` in the config file.*
97
98### Min Lines
99
100Minimal block size of code in lines. The block of code less than `min-lines` will be skipped.
101
102 - Cli options: `--min-lines`, `-l`
103 - Type: **number**
104 - Default: **5**
105### Max Lines
106
107Maximum file size in lines. The file bigger than `max-lines` will be skipped.
108
109 - Cli options: `--max-lines`, `-x`
110 - Type: **number**
111 - Default: **1000**
112### Max Size
113
114Maximum file size in bytes. The file bigger than `max-size` will be skipped.
115
116 - Cli options: `--max-size`, `-z`
117 - Type: **string**
118 - Default: **100kb**
119### Threshold
120
121The threshold for duplication level, check if current level of duplications bigger than threshold jscpd exit with error.
122
123 - Cli options: `--threshold`, `-t`
124 - Type: **number**
125 - Default: **null**
126### Config
127
128The path to configuration file. The config should be in `json` format. Supported options in config file can be the same with cli options.
129
130 - Cli options: `--config`, `-c`
131 - Type: **path**
132 - Default: **null**
133### Ignore
134
135The option with glob patterns to ignore from analyze. For multiple globs you can use comma as separator.
136Example:
137```bash
138$ jscpd --ignore "**/*.min.js,**/*.map" /path/to/files
139```
140 - Cli options: `--ignore`, `-i`
141 - Type: **string**
142 - Default: **null**
143### Reporters
144The list of reporters. Reporters use for output information of clones and duplication process.
145
146Available reporters:
147 - **console** - report about clones to console;
148 - **consoleFull** - report about clones to console with blocks of code;
149 - **json** - output `jscpd-report.json` file with clones report in json format;
150 - **xml** - output `jscpd-report.xml` file with clones report in xml format;
151 - **csv** - output `jscpd-report.csv` file with clones report in csv format;
152 - **markdown** - output `jscpd-report.md` file with clones report in markdown format;
153 - **html** - generate html report to `html/` folder;
154 - **sarif** - generate a report in SARIF format (https://github.com/oasis-tcs/sarif-spec), save it to `jscpd-sarif.json` file;
155 - **verbose** - output a lot of debug information to console;
156
157> Note: A reporter can be developed manually, see [@jscpd/finder](../finder) package.
158
159 - Cli options: `--reporters`, `-r`
160 - Type: **string**
161 - Default: **console**
162### Output
163
164The path to directory for reports. JSON and XML reports will be saved there.
165
166 - Cli options: `--output`, `-o`
167 - Type: **path**
168 - Default: **./report/**
169
170### Mode
171The mode of detection quality.
172 - `strict` - use all types of symbols as token, skip only blocks marked as ignored.
173 - `mild` - skip blocks marked as ignored and new lines and empty symbols.
174 - `weak` - skip blocks marked as ignored and new lines and empty symbols and comments.
175
176> Note: A mode can be developed manually, see API section.
177
178 - Cli options: `--mode`, `-m`
179 - Type: **string**
180 - Default: **mild**
181### Format
182
183The list of formats to detect for duplications. Available over [150 formats](../../supported_formats.md).
184
185Example:
186```bash
187$ jscpd --format "php,javascript,markup,css" /path/to/files
188```
189
190 - Cli options: `--format`, `-f`
191 - Type: **string**
192 - Default: **{all formats}**
193### Blame
194Get information about authors and dates of duplicated blocks from git.
195
196 - Cli options: `--blame`, `-b`
197 - Type: **boolean**
198 - Default: **false**
199### Silent
200Don't write a lot of information to a console.
201
202Example:
203```
204$ jscpd /path/to/source --silent
205Duplications detection: Found 60 exact clones with 3414(46.81%) duplicated lines in 100 (31 formats) files.
206Execution Time: 1381.759ms
207```
208 - Cli options: `--silent`, `-s`
209 - Type: **boolean**
210 - Default: **false**
211### Absolute
212Use the absolute path in reports.
213
214
215 - Cli options: `--absolute`, `-a`
216 - Type: **boolean**
217 - Default: **false**
218### Ignore Case
219Ignore case of symbols in code (experimental).
220
221
222 - Cli options: `--ignoreCase`
223 - Type: **boolean**
224 - Default: **false**
225
226### No Symlinks
227Do not follow symlinks.
228
229 - Cli options: `--noSymlinks`, `-n`
230 - Type: **boolean**
231 - Default: **false**
232
233### Skip Local
234Use for detect duplications in different folders only. For correct usage of `--skipLocal` option you should provide list of path's with more than one item.
235
236Example:
237```bash
238jscpd --skipLocal /path/to/folder1/ /path/to/folder2/
239```
240will detect clones in separate folders only, clones from same folder will be skipped.
241
242
243 - Cli options: `--skipLocal`
244 - Type: **boolean**
245 - Default: **false**
246
247### Formats Extensions
248Define the list of formats with file extensions. Available over [150 formats](../../supported_formats.md).
249
250In following example jscpd will analyze files `*.es` and `*.es6` as javascript and `*.dt` files as dart:
251```bash
252$ jscpd --formats-exts javascript:es,es6;dart:dt /path/to/code
253```
254> Note: formats defined in the option redefine default configuration, you should define all need formats manually or create two configuration for run `jscpd`
255
256 - Cli options: `--formats-exts`
257 - Type: **string**
258 - Default: **null**
259
260### Store
261
262Stores used for collect information about code, by default all information collect in memory.
263
264Available stores:
265 - **leveldb** - leveldb store all data to files. The store recommended as store for big repositories. Should install @jscpd/leveldb-store before;
266
267> Note: A store can be developed manually, see [@jscpd/finder](../finder) package and [@jscpd/leveldb-store](../leveldb-store) as example.
268
269 - Cli options: `--store`
270 - Type: **string**
271 - Default: **null**
272
273### Ignore Pattern
274Ignore code blocks matching the regexp patterns.
275
276 - Cli options: `--ignore-pattern`
277 - Type: **string**
278 - Default: **null**
279
280Example:
281```
282$ jscpd /path/to/source --ignore-pattern "import.*from\s*'.*'"
283```
284Excludes import statements from the calculation.
285
286## Config File
287
288Put `.jscpd.json` file in the root of the projects:
289```json
290{
291 "threshold": 0,
292 "reporters": ["html", "console", "badge"],
293 "ignore": ["**/__snapshots__/**"],
294 "absolute": true
295}
296```
297
298Also you can use section in `package.json`:
299
300```json
301{
302 ...
303 "jscpd": {
304 "threshold": 0.1,
305 "reporters": ["html", "console", "badge"],
306 "ignore": ["**/__snapshots__/**"],
307 "absolute": true,
308 "gitignore": true
309 }
310 ...
311}
312
313
314```
315
316### Exit code
317
318By default, the tool exits with code 0 even code duplications were
319detected. This behaviour can be changed by specifying a custom exit
320code for error states.
321
322Example:
323```bash
324jscpd --exitCode 1 .
325```
326
327- Cli options: `--exitCode`
328- Type: **number**
329- Default: **0**
330
331
332## Ignored Blocks
333
334Mark blocks in code as ignored:
335```javascript
336/* jscpd:ignore-start */
337import lodash from 'lodash';
338import React from 'react';
339import {User} from './models';
340import {UserService} from './services';
341/* jscpd:ignore-end */
342```
343
344```html
345<!--
346// jscpd:ignore-start
347-->
348<meta data-react-helmet="true" name="theme-color" content="#cb3837"/>
349<link data-react-helmet="true" rel="stylesheet" href="https://static.npmjs.com/103af5b8a2b3c971cba419755f3a67bc.css"/>
350<link data-react-helmet="true" rel="stylesheet" href="https://static.npmjs.com/cms/flatpages.css"/>
351<link data-react-helmet="true" rel="apple-touch-icon" sizes="120x120" href="https://static.npmjs.com/58a19602036db1daee0d7863c94673a4.png"/>
352<link data-react-helmet="true" rel="apple-touch-icon" sizes="144x144" href="https://static.npmjs.com/7a7ffabbd910fc60161bc04f2cee4160.png"/>
353<link data-react-helmet="true" rel="apple-touch-icon" sizes="152x152" href="https://static.npmjs.com/34110fd7686e2c90a487ca98e7336e99.png"/>
354<link data-react-helmet="true" rel="apple-touch-icon" sizes="180x180" href="https://static.npmjs.com/3dc95981de4241b35cd55fe126ab6b2c.png"/>
355<link data-react-helmet="true" rel="icon" type="image/png" href="https://static.npmjs.com/b0f1a8318363185cc2ea6a40ac23eeb2.png" sizes="32x32"/>
356<!--
357// jscpd:ignore-end
358-->
359```
360
361## Reporters
362
363### HTML
364
365[Demo report](http://kucherenko.github.io/jscpd-report.html)
366### Badge
367![jscpd](../../assets/jscpd-badge.svg)
368
369More info [jscpd-badge-reporter](https://github.com/kucherenko/jscpd-badge-reporter)
370### PMD CPD XML
371```xml
372<?xml version="1.0" encoding="utf-8"?>
373<pmd-cpd>
374 <duplication lines="10">
375 <file path="/path/to/file" line="1">
376 <codefragment><![CDATA[ ...first code fragment... ]]></codefragment>
377 </file>
378 <file path="/path/to/file" line="5">
379 <codefragment><![CDATA[ ...second code fragment...}]]></codefragment>
380 </file>
381 <codefragment><![CDATA[ ...duplicated fragment... ]]></codefragment>
382 </duplication>
383</pmd-cpd>
384```
385### JSON reporters
386```json
387{
388 "duplicates": [{
389 "format": "javascript",
390 "lines": 27,
391 "fragment": "...code fragment... ",
392 "tokens": 0,
393 "firstFile": {
394 "name": "tests/fixtures/javascript/file2.js",
395 "start": 1,
396 "end": 27,
397 "startLoc": {
398 "line": 1,
399 "column": 1
400 },
401 "endLoc": {
402 "line": 27,
403 "column": 2
404 }
405 },
406 "secondFile": {
407 "name": "tests/fixtures/javascript/file1.js",
408 "start": 1,
409 "end": 24,
410 "startLoc": {
411 "line": 1,
412 "column": 1
413 },
414 "endLoc": {
415 "line": 24,
416 "column": 2
417 }
418 }
419 }],
420 "statistic": {
421 "detectionDate": "2018-11-09T15:32:02.397Z",
422 "formats": {
423 "javascript": {
424 "sources": {
425 "/path/to/file": {
426 "lines": 24,
427 "sources": 1,
428 "clones": 1,
429 "duplicatedLines": 26,
430 "percentage": 45.33,
431 "newDuplicatedLines": 0,
432 "newClones": 0
433 }
434 },
435 "total": {
436 "lines": 297,
437 "sources": 1,
438 "clones": 1,
439 "duplicatedLines": 26,
440 "percentage": 45.33,
441 "newDuplicatedLines": 0,
442 "newClones": 0
443 }
444 }
445 },
446 "total": {
447 "lines": 297,
448 "sources": 6,
449 "clones": 5,
450 "duplicatedLines": 26,
451 "percentage": 45.33,
452 "newDuplicatedLines": 0,
453 "newClones": 0
454 }
455 }
456}
457```
458## API
459
460
461For integration copy/paste detection to your application you can use programming API:
462
463`jscpd` Promise API
464```typescript
465import {IClone} from '@jscpd/core';
466import {jscpd} from 'jscpd';
467
468const clones: Promise<IClone[]> = jscpd(process.argv);
469```
470
471`jscpd` async/await API
472```typescript
473import {IClone} from '@jscpd/core';
474import {jscpd} from 'jscpd';
475(async () => {
476 const clones: IClone[] = await jscpd(['', '', __dirname + '/../fixtures', '-m', 'weak', '--silent']);
477 console.log(clones);
478})();
479
480```
481
482`detectClones` API
483```typescript
484import {detectClones} from "jscpd";
485
486(async () => {
487 const clones = await detectClones({
488 path: [
489 __dirname + '/../fixtures'
490 ],
491 silent: true
492 });
493 console.log(clones);
494})()
495```
496
497`detectClones` with persist store
498```typescript
499import {detectClones} from "jscpd";
500import {IMapFrame, MemoryStore} from "@jscpd/core";
501
502(async () => {
503 const store = new MemoryStore<IMapFrame>();
504
505 await detectClones({
506 path: [
507 __dirname + '/../fixtures'
508 ],
509 }, store);
510
511 await detectClones({
512 path: [
513 __dirname + '/../fixtures'
514 ],
515 silent: true
516 }, store);
517})()
518```
519
520In case of deep customisation of detection process you can build your own tool:
521If you are going to detect clones in file system you can use [@jscpd/finder](../finder) for make a powerful detector.
522In case of detect clones in browser or not node.js environment you can build your own solution base on [@jscpd/code](../core)
523
524## Changelog
525[Changelog](CHANGELOG.md)
526
527## Who uses jscpd
528 - [Code-Inspector](https://www.code-inspector.com/) is a code analysis and technical debt management service.
529 - [Mega-Linter](https://nvuillam.github.io/mega-linter/) is a 100% open-source linters aggregator for CI (GitHub Action & other CI tools) or to run locally
530 - [vscode-jscpd](https://marketplace.visualstudio.com/items?itemName=paulhoughton.vscode-jscpd) VSCode Copy/Paste detector plugin.
531
532## Contributors
533
534This project exists thanks to all the people who contribute.
535<a href="https://github.com/kucherenko/jscpd/contributors"><img src="https://opencollective.com/jscpd/contributors.svg?width=890&button=false" /></a>
536## Backers
537
538Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/jscpd#backer)]
539
540<a href="https://opencollective.com/jscpd#backers" target="_blank"><img src="https://opencollective.com/jscpd/backers.svg?width=890"></a>
541## Sponsors
542
543Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/jscpd#sponsor)]
544
545<a href="https://opencollective.com/jscpd/sponsor/0/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/0/avatar.svg"></a>
546<a href="https://opencollective.com/jscpd/sponsor/1/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/1/avatar.svg"></a>
547<a href="https://opencollective.com/jscpd/sponsor/2/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/2/avatar.svg"></a>
548<a href="https://opencollective.com/jscpd/sponsor/3/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/3/avatar.svg"></a>
549<a href="https://opencollective.com/jscpd/sponsor/4/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/4/avatar.svg"></a>
550<a href="https://opencollective.com/jscpd/sponsor/5/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/5/avatar.svg"></a>
551<a href="https://opencollective.com/jscpd/sponsor/6/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/6/avatar.svg"></a>
552<a href="https://opencollective.com/jscpd/sponsor/7/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/7/avatar.svg"></a>
553<a href="https://opencollective.com/jscpd/sponsor/8/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/8/avatar.svg"></a>
554<a href="https://opencollective.com/jscpd/sponsor/9/website" target="_blank"><img src="https://opencollective.com/jscpd/sponsor/9/avatar.svg"></a>
555
556![ga tracker](https://www.google-analytics.com/collect?v=1&a=257770996&t=pageview&dl=https%3A%2F%2Fgithub.com%2Fkucherenko%2Fjscpd&ul=en-us&de=UTF-8&cid=978224512.1377738459&tid=UA-730549-17&z=887657232 "ga tracker")
557
558## License
559
560[MIT](LICENSE) © Andrey Kucherenko