kucherenko / jscpd

Copy/paste detector for programming source code.
MIT License
4.67k stars 205 forks source link

Simpler programmatic API #389

Closed ehmicky closed 4 years ago

ehmicky commented 4 years ago

I have been trying to use the programmatic API as described in the README of @jscpd/core and @jscpd/finder, but the interface is rather complex. Multiple classes need to be built and some knowledge of the inner logic of the codebase is needed to get it working. When I compared with the logic performed in the CLI, it seems to me that there is quite a lot that needs to be done to make a programmatic usage of jscpd work the same as the CLI.

Would it be possible to provide with an additional API function that performs the same logic as the CLI? For example:

const { detectClones } = require('@jscpd/core')

// Same options as in CLI
// Performs everything the CLI does, including reporters, etc.
const clones = await detectClones(options)

At the moment, I am falling back to using the CLI, which is much less performant in watch mode. Thanks for your help!

kucherenko commented 4 years ago

You can try to use jscpd package for simple detection:

More info here - https://github.com/kucherenko/jscpd/tree/master/packages/jscpd#api

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

const clones: Promise<IClone[]> = jscpd(process.argv);
// or
(async () => {
    const clones: IClone[] = await jscpd(['', '', '/path/to/file/or/folder', '-m', 'weak', '--silent']);
})();

Did you try the way to detect clones?

Actually I expected that @jscpd/core and @jscpd/finder will be used for solution with deep customization.

ehmicky commented 4 years ago

Thanks @kucherenko, this is much simpler indeed!

One question though: it seems like when using the in-memory store, it would be re-created each time jscpd() is run. I.e. when jscpd() is run twice, the second call would not re-use the information from the first call. Could you confirm this?

If so, would it possible to re-use stores between jscpd() calls?

kucherenko commented 4 years ago

Starts from jscpd@3.3.8 you can use following code:

import {detectClones} from "jscpd";

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

For persist store you can use the code:

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);
})()
ehmicky commented 4 years ago

Thanks @kucherenko!