Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

jscpd

kucherenko331.1kMIT4.0.5TypeScript support: included

detector of copy/paste in files

readme

jscpd

npm jscpd license npm

codecov FOSSA Status Backers on Open Collective Sponsors on Open Collective

NPM

Copy/paste detector for programming source code, supports 150+ formats.

Copy/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. The jscpd tool implements Rabin-Karp algorithm for searching duplications.

Table of content

Features

  • Detect duplications in programming source code, use semantic of programing languages, can skip comments, empty lines etc.
  • Detect duplications in embedded blocks of code, like <script> or <style> sections in html
  • Blame authors of duplications
  • Generate XML report in pmd-cpd format, JSON report, HTML report
  • Integrate with CI systems, use thresholds for level of duplications

Getting started

Installation

$ npm install -g jscpd

Usage

$ npx jscpd /path/to/source

or

$ jscpd /path/to/code

or

$ jscpd --pattern "src/**/*.js"

Options

Pattern

Glob pattern for find files to detect

  • Cli options: --pattern, -p
  • Type: string
  • Default: "*/"

Example:

 $ jscpd --pattern "**/*.js"

Min Tokens

Minimal block size of code in tokens. The block of code less than min-tokens will be skipped.

  • Cli options: --min-tokens, -k
  • Type: number
  • Default: 50

    This option is called minTokens in the config file.

Min Lines

Minimal block size of code in lines. The block of code less than min-lines will be skipped.

  • Cli options: --min-lines, -l
  • Type: number
  • Default: 5

    Max Lines

Maximum file size in lines. The file bigger than max-lines will be skipped.

  • Cli options: --max-lines, -x
  • Type: number
  • Default: 1000

    Max Size

Maximum file size in bytes. The file bigger than max-size will be skipped.

  • Cli options: --max-size, -z
  • Type: string
  • Default: 100kb

    Threshold

The threshold for duplication level, check if current level of duplications bigger than threshold jscpd exit with error.

  • Cli options: --threshold, -t
  • Type: number
  • Default: null

    Config

The path to configuration file. The config should be in json format. Supported options in config file can be the same with cli options.

  • Cli options: --config, -c
  • Type: path
  • Default: null

    Ignore

The option with glob patterns to ignore from analyze. For multiple globs you can use comma as separator. Example:

$ jscpd --ignore "**/*.min.js,**/*.map" /path/to/files
  • Cli options: --ignore, -i
  • Type: string
  • Default: null

    Reporters

    The list of reporters. Reporters use for output information of clones and duplication process.

Available reporters:

  • console - report about clones to console;
  • consoleFull - report about clones to console with blocks of code;
  • json - output jscpd-report.json file with clones report in json format;
  • xml - output jscpd-report.xml file with clones report in xml format;
  • csv - output jscpd-report.csv file with clones report in csv format;
  • markdown - output jscpd-report.md file with clones report in markdown format;
  • html - generate html report to html/ folder;
  • sarif - generate a report in SARIF format (https://github.com/oasis-tcs/sarif-spec), save it to jscpd-sarif.json file;
  • verbose - output a lot of debug information to console;

Note: A reporter can be developed manually, see @jscpd/finder package.

  • Cli options: --reporters, -r
  • Type: string
  • Default: console

    Output

The path to directory for reports. JSON and XML reports will be saved there.

  • Cli options: --output, -o
  • Type: path
  • Default: ./report/

Mode

The mode of detection quality.

  • strict - use all types of symbols as token, skip only blocks marked as ignored.
  • mild - skip blocks marked as ignored and new lines and empty symbols.
  • weak - skip blocks marked as ignored and new lines and empty symbols and comments.

Note: A mode can be developed manually, see API section.

  • Cli options: --mode, -m
  • Type: string
  • Default: mild

    Format

The list of formats to detect for duplications. Available over 150 formats.

Example:

$ jscpd --format "php,javascript,markup,css" /path/to/files
  • Cli options: --format, -f
  • Type: string
  • Default: {all formats}

    Blame

    Get information about authors and dates of duplicated blocks from git.

  • Cli options: --blame, -b

  • Type: boolean
  • Default: false

    Silent

    Don't write a lot of information to a console.

Example:

$ jscpd /path/to/source --silent
Duplications detection: Found 60 exact clones with 3414(46.81%) duplicated lines in 100 (31 formats) files.
Execution Time: 1381.759ms
  • Cli options: --silent, -s
  • Type: boolean
  • Default: false

    Absolute

    Use the absolute path in reports.
  • Cli options: --absolute, -a
  • Type: boolean
  • Default: false

    Ignore Case

    Ignore case of symbols in code (experimental).
  • Cli options: --ignoreCase
  • Type: boolean
  • Default: false

Do not follow symlinks.

  • Cli options: --noSymlinks, -n
  • Type: boolean
  • Default: false

Skip Local

Use 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.

Example:

jscpd --skipLocal /path/to/folder1/ /path/to/folder2/

will detect clones in separate folders only, clones from same folder will be skipped.

  • Cli options: --skipLocal
  • Type: boolean
  • Default: false

Formats Extensions

Define the list of formats with file extensions. Available over 150 formats.

In following example jscpd will analyze files *.es and *.es6 as javascript and *.dt files as dart:

$ jscpd --formats-exts javascript:es,es6;dart:dt /path/to/code

Note: formats defined in the option redefine default configuration, you should define all need formats manually or create two configuration for run jscpd

  • Cli options: --formats-exts
  • Type: string
  • Default: null

Store

Stores used for collect information about code, by default all information collect in memory.

Available stores:

  • leveldb - leveldb store all data to files. The store recommended as store for big repositories. Should install @jscpd/leveldb-store before;

Note: A store can be developed manually, see @jscpd/finder package and @jscpd/leveldb-store as example.

  • Cli options: --store
  • Type: string
  • Default: null

Ignore Pattern

Ignore code blocks matching the regexp patterns.

  • Cli options: --ignore-pattern
  • Type: string
  • Default: null

Example:

$ jscpd /path/to/source --ignore-pattern "import.*from\s*'.*'"

Excludes import statements from the calculation.

Config File

Put .jscpd.json file in the root of the projects:

{
  "threshold": 0,
  "reporters": ["html", "console", "badge"],
  "ignore": ["**/__snapshots__/**"],
  "absolute": true
}

Also you can use section in package.json:

{
  ...
  "jscpd": {
    "threshold": 0.1,
    "reporters": ["html", "console", "badge"],
    "ignore": ["**/__snapshots__/**"],
    "absolute": true,
    "gitignore": true
  }
  ...
}

Exit code

By default, the tool exits with code 0 even code duplications were detected. This behaviour can be changed by specifying a custom exit code for error states.

Example:

jscpd --exitCode 1 .
  • Cli options: --exitCode
  • Type: number
  • Default: 0

Ignored Blocks

Mark blocks in code as ignored:

/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */
<!--
// jscpd:ignore-start
-->
<meta data-react-helmet="true" name="theme-color" content="#cb3837"/>
<link data-react-helmet="true" rel="stylesheet" href="https://static.npmjs.com/103af5b8a2b3c971cba419755f3a67bc.css"/>
<link data-react-helmet="true" rel="stylesheet" href="https://static.npmjs.com/cms/flatpages.css"/>
<link data-react-helmet="true" rel="apple-touch-icon" sizes="120x120" href="https://static.npmjs.com/58a19602036db1daee0d7863c94673a4.png"/>
<link data-react-helmet="true" rel="apple-touch-icon" sizes="144x144" href="https://static.npmjs.com/7a7ffabbd910fc60161bc04f2cee4160.png"/>
<link data-react-helmet="true" rel="apple-touch-icon" sizes="152x152" href="https://static.npmjs.com/34110fd7686e2c90a487ca98e7336e99.png"/>
<link data-react-helmet="true" rel="apple-touch-icon" sizes="180x180" href="https://static.npmjs.com/3dc95981de4241b35cd55fe126ab6b2c.png"/>
<link data-react-helmet="true" rel="icon" type="image/png" href="https://static.npmjs.com/b0f1a8318363185cc2ea6a40ac23eeb2.png" sizes="32x32"/>
<!--
// jscpd:ignore-end
-->

Reporters

HTML

Demo report

Badge

jscpd

More info jscpd-badge-reporter

PMD CPD XML

<?xml version="1.0" encoding="utf-8"?>
<pmd-cpd>
  <duplication lines="10">
      <file path="/path/to/file" line="1">
        <codefragment><![CDATA[ ...first code fragment... ]]></codefragment>
      </file>
      <file path="/path/to/file" line="5">
        <codefragment><![CDATA[ ...second code fragment...}]]></codefragment>
      </file>
      <codefragment><![CDATA[ ...duplicated fragment... ]]></codefragment>
  </duplication>
</pmd-cpd>

JSON reporters

{
  "duplicates": [{
      "format": "javascript",
      "lines": 27,
      "fragment": "...code fragment... ",
      "tokens": 0,
      "firstFile": {
        "name": "tests/fixtures/javascript/file2.js",
        "start": 1,
        "end": 27,
        "startLoc": {
          "line": 1,
          "column": 1
        },
        "endLoc": {
          "line": 27,
          "column": 2
        }
      },
      "secondFile": {
        "name": "tests/fixtures/javascript/file1.js",
        "start": 1,
        "end": 24,
        "startLoc": {
          "line": 1,
          "column": 1
        },
        "endLoc": {
          "line": 24,
          "column": 2
        }
      }
  }],
  "statistic": {
    "detectionDate": "2018-11-09T15:32:02.397Z",
    "formats": {
      "javascript": {
        "sources": {
          "/path/to/file": {
            "lines": 24,
            "sources": 1,
            "clones": 1,
            "duplicatedLines": 26,
            "percentage": 45.33,
            "newDuplicatedLines": 0,
            "newClones": 0
          }
        },
        "total": {
          "lines": 297,
          "sources": 1,
          "clones": 1,
          "duplicatedLines": 26,
          "percentage": 45.33,
          "newDuplicatedLines": 0,
          "newClones": 0
        }
      }
    },
    "total": {
      "lines": 297,
      "sources": 6,
      "clones": 5,
      "duplicatedLines": 26,
      "percentage": 45.33,
      "newDuplicatedLines": 0,
      "newClones": 0
    }
  }
}

API

For integration copy/paste detection to your application you can use programming API:

jscpd Promise API

import {IClone} from '@jscpd/core';
import {jscpd} from 'jscpd';

const clones: Promise<IClone[]> = jscpd(process.argv);

jscpd async/await API

import {IClone} from '@jscpd/core';
import {jscpd} from 'jscpd';
(async () => {
  const clones: IClone[] = await jscpd(['', '', __dirname + '/../fixtures', '-m', 'weak', '--silent']);
  console.log(clones);
})();

detectClones API

import {detectClones} from "jscpd";

(async () => {
  const clones = await detectClones({
    path: [
      __dirname + '/../fixtures'
    ],
    silent: true
  });
  console.log(clones);
})()

detectClones with persist store

import {detectClones} from "jscpd";
import {IMapFrame, MemoryStore} from "@jscpd/core";

(async () => {
  const store = new MemoryStore<IMapFrame>();

  await detectClones({
    path: [
      __dirname + '/../fixtures'
    ],
  }, store);

  await detectClones({
    path: [
      __dirname + '/../fixtures'
    ],
    silent: true
  }, store);
})()

In case of deep customisation of detection process you can build your own tool: If you are going to detect clones in file system you can use @jscpd/finder for make a powerful detector. In case of detect clones in browser or not node.js environment you can build your own solution base on @jscpd/code

Changelog

Changelog

Who uses jscpd

  • Code-Inspector is a code analysis and technical debt management service.
  • Mega-Linter is a 100% open-source linters aggregator for CI (GitHub Action & other CI tools) or to run locally
  • vscode-jscpd VSCode Copy/Paste detector plugin.

Contributors

This project exists thanks to all the people who contribute.

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

ga tracker

License

MIT © Andrey Kucherenko

changelog

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

3.2.1 (2020-04-18)

Bug Fixes

  • fs-extra version: Use fs-extra version 8.0.0 for node.js v8 (f69e7e8), closes #346 #345

3.2.0 (2020-04-08)

Bug Fixes

  • package: update cli-table3 to version 0.6.0 (0b29242)
  • package: update fs-extra to version 9.0.0 (cbae200)

Features

  • detector: skip duplicates in same folder if --skipLocal used (7029ddd), closes #326

3.1.0 (2020-03-11)

Features

  • formats: Add ability to find duplications in txt files (0a46e76), closes #272

3.0.1 (2020-03-10)

Bug Fixes

  • blamer: Fix usage fix of blamer (5f9e125), closes #238
  • package: update blamer to version 1.0.1 (966fca8)

3.0.0 (2020-03-08)

⚠ BREAKING CHANGES

  • xml reporter: fix #331

Bug Fixes

  • package: update commander to version 4.0.1 (f36d545)
  • package: update level to version 6.0.0 (374f659)
  • xml reporter: fix issue with CDATA in xml reporter (5643092), closes #331

Features

  • cli: change cli script for running jscpd (536c44e)

2.0.16 (2019-09-24)

Bug Fixes

  • .snyk, package.json & package-lock.json to reduce vulnerabilities (5fddd70)
  • package: update commander to version 3.0.0 (c41cf11)
  • package: update eventemitter3 to version 4.0.0 (cadd3ab)
  • package: update fs-extra to version 8.0.0 (a1c3936)
  • package: update rimraf to version 3.0.0 (47afcca)
  • package: update snyk to version 2.0.0 (30828ee)
  • readme: fix typo in readme (a49b801)
  • readme: fixes screenshot url (ee6fd67)
  • snap: fix tests snapshots (cc6402d)

2.0.15 (2019-04-24)

Bug Fixes

  • package: update level to version 5.0.1 (913423a)

2.0.14 (2019-04-18)

Bug Fixes

  • prism tokenizer: fix issue with empty name (b80e4e7), closes #223

2.0.13 (2019-03-29)

Bug Fixes

  • html reporter: fix empty statistic issue (49134ab), closes #214

2.0.4 (2019-01-08)

Bug Fixes

  • tokenizer: split c/cpp and c-header/cpp-header formats, now files in headers detects separately (b9be29e), closes #188
  • tokenizer: split c/cpp and c/cpp headers formats (97bbd55)

2.0.3 (2019-01-08)

Bug Fixes

  • detector: fix bug with detection duplicates in single file (2f4eb48), closes #189

2.0.2 (2018-12-28)

Bug Fixes

  • license: change packages with G P L to analog with MIT (8d1081f)

2.0.1 (2018-12-28)

Bug Fixes

  • threshold: add ability to use 0 value for threshold (a18fe71), closes #182

2.0.0 (2018-12-28)

Features

  • store: Add LevelDb store for optimisation memory usage (2f04dd8), closes #66 #184

BREAKING CHANGES

  • store: add persistent store/db

1.2.3 (2018-12-27)

Bug Fixes

  • jscpd: fix bug with mulitiformats files (7d631db)

1.2.2 (2018-12-27)

1.2.1 (2018-12-23)

Bug Fixes

  • blamer: Fix unhandled promise rejection in blamer (23a9b5d), closes #185
  • readme: fix path to screenshot (09ca3b8)

1.2.0 (2018-12-14)

Bug Fixes

  • html reporter: Fix bug with empty lines in code blocks (af99689)

Features

  • html reporter: add graph to report (d051154)

1.1.0 (2018-12-02)

Features

  • html,consoleFull reporters: Add blamed lines to html and consoleFull reporters, add syntax hig (1168bfb)
  • modes: Add custom mode (3aba4cd), closes #172

1.0.3 (2018-11-27)

Bug Fixes

  • options.path: Fix path options (106a6d4), closes #177

1.0.2 (2018-11-27)

Bug Fixes

  • support locally installed reporter and mode (01ee5af)

1.0.1 (2018-11-27)

Bug Fixes

  • add support for trailing slash gitignore pattern (0a48301)

1.0.0 (2018-11-21)

Bug Fixes

  • travis: add installation for jscpd-badge-reporter (d09232f)
  • travis: add scripts running (1bb099c)
  • travis: fix scripts running (fec133b)
  • travis: fix scripts running again (bdccafb)

1.0.0-rc.6 (2018-11-17)

Features

  • reporter: Add html reporter (831447a)

1.0.0-rc.5 (2018-11-15)

1.0.0-rc.4 (2018-11-09)

Features

  • cli: Add ability to point few paths to cli as args (d1e6cfc)
  • readme,reporters,hooks: Add hooks, change reporters interface, cleanup dependencies (dc03298)

1.0.0-rc.3 (2018-10-11)

Bug Fixes

  • cli: Change storage type (4b1a26a)

1.0.0-rc.2 (2018-10-11)

Bug Fixes

  • exec-timer: Fix bug with dependencies (3c52587)

1.0.0-rc.1 (2018-10-11)

Features

  • exec-timer: Add exec timer reporter (d5d865e)

1.0.0-rc.0 (2018-10-07)

Bug Fixes

  • package.json: Add RC prefix for releases (5e6bf00)

Reverts

  • wrong release: remove wrong release (708f98a)

1.0.0-alpha.2 (2018-08-24)

Bug Fixes

  • config: Change config filename (f693e3c)
  • package.json: Fix generation of typedoc (4769cf5)

1.0.0-alpha.1 (2018-08-18)

Features

  • package: add bin script (840af45)

1.0.0-alpha.0 (2018-08-18)

Bug Fixes

  • package: update codemirror to version 5.28.0 (6eb6eab)
  • package: update codemirror to version 5.29.0 (dcfa37b)
  • package: update codemirror to version 5.31.0 (64d0b27)
  • package: update codemirror to version 5.32.0 (452d490)
  • package: update codemirror to version 5.33.0 (f9b5e08)
  • package: update codemirror to version 5.35.0 (d292b73)
  • package: update codemirror to version 5.36.0 (6eb9603)
  • package: update codemirror to version 5.37.0 (5bee414)
  • package: update shelljs to version 0.8.0 (114649d)
  • package.json: Remove not used @types/sinon (6087a0d)
  • silent: Fix ability to use xml, json and other not console reporters in silent mode (16d4710)
  • test: Fix sinon spy (e610f88)

Features

  • cache: Add cache for detection results (41ffaf4)
  • JSCPD: Started 1.0.0 version development, move from coffee to ts, change tokenizer, new report (68ca373)
  • language: add yaml support (7434bcc)
  • options: add ability set formats extensions (6a1e8b1)
  • options: Add debug option for check options of jscpd (aa3968b)
  • reporter: add statistic reporter (01fc2b3)
  • reporter: Add threshold reporter (e8e1b25)
  • reporter: Add xml reporter (6ae45ca)
  • reporters: Add silent reporter (517d2ee)
  • statistic: Add new clones statistic (5c4761d)