dslop 1.0.7 → 1.1.0
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/CHANGELOG.md +12 -0
- package/README.md +2 -0
- package/dist/index.js +47 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.1.0
|
|
4
|
+
|
|
5
|
+
[compare changes](https://github.com/turf-sports/dslop/compare/v1.0.7...v1.1.0)
|
|
6
|
+
|
|
7
|
+
### 🚀 Enhancements
|
|
8
|
+
|
|
9
|
+
- Add --staged flag to check uncommitted changes ([48d66b1](https://github.com/turf-sports/dslop/commit/48d66b1))
|
|
10
|
+
|
|
11
|
+
### ❤️ Contributors
|
|
12
|
+
|
|
13
|
+
- Siddharth Sharma <sharmasiddharthcs@gmail.com>
|
|
14
|
+
|
|
3
15
|
## v1.0.7
|
|
4
16
|
|
|
5
17
|
## v1.0.6
|
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ npm i -g dslop
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
dslop . # scan current directory
|
|
19
|
+
dslop --staged # check uncommitted changes for dupes
|
|
19
20
|
dslop ./src -m 6 -s 80 # 6 line min, 80% similarity
|
|
20
21
|
dslop . --cross-package # only cross-package dupes (monorepos)
|
|
21
22
|
dslop . --json # json output
|
|
@@ -28,6 +29,7 @@ dslop . --json # json output
|
|
|
28
29
|
| `-m, --min-lines` | 4 | min lines per block |
|
|
29
30
|
| `-s, --similarity` | 70 | similarity threshold (0-100) |
|
|
30
31
|
| `-e, --extensions` | ts,tsx,js,jsx | file extensions |
|
|
32
|
+
| `--staged` | | only show dupes involving uncommitted changes |
|
|
31
33
|
| `--cross-package` | | only show dupes across packages |
|
|
32
34
|
| `--json` | | json output |
|
|
33
35
|
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
// index.ts
|
|
4
4
|
import { parseArgs } from "util";
|
|
5
|
+
import { execSync } from "child_process";
|
|
6
|
+
import path4 from "path";
|
|
5
7
|
|
|
6
8
|
// src/constants.ts
|
|
7
9
|
var DEFAULT_MIN_LINES = 4;
|
|
@@ -6559,7 +6561,27 @@ async function scanDirectory(targetPath, options) {
|
|
|
6559
6561
|
}
|
|
6560
6562
|
|
|
6561
6563
|
// index.ts
|
|
6562
|
-
var VERSION = process.env.npm_package_version || "1.0
|
|
6564
|
+
var VERSION = process.env.npm_package_version || "1.1.0";
|
|
6565
|
+
function getChangedFiles(targetPath) {
|
|
6566
|
+
const absolutePath = path4.resolve(targetPath);
|
|
6567
|
+
try {
|
|
6568
|
+
const staged = execSync("git diff --cached --name-only", { cwd: absolutePath, encoding: "utf-8" });
|
|
6569
|
+
const unstaged = execSync("git diff --name-only", { cwd: absolutePath, encoding: "utf-8" });
|
|
6570
|
+
const untracked = execSync("git ls-files --others --exclude-standard", { cwd: absolutePath, encoding: "utf-8" });
|
|
6571
|
+
const files = new Set;
|
|
6572
|
+
for (const file of [...staged.split(`
|
|
6573
|
+
`), ...unstaged.split(`
|
|
6574
|
+
`), ...untracked.split(`
|
|
6575
|
+
`)]) {
|
|
6576
|
+
if (file.trim()) {
|
|
6577
|
+
files.add(path4.resolve(absolutePath, file.trim()));
|
|
6578
|
+
}
|
|
6579
|
+
}
|
|
6580
|
+
return files;
|
|
6581
|
+
} catch {
|
|
6582
|
+
return new Set;
|
|
6583
|
+
}
|
|
6584
|
+
}
|
|
6563
6585
|
function showHelp() {
|
|
6564
6586
|
console.log(`
|
|
6565
6587
|
dslop - Detect Similar/Duplicate Lines Of Programming
|
|
@@ -6575,6 +6597,7 @@ Options:
|
|
|
6575
6597
|
-s, --similarity <n> Minimum similarity threshold 0-100 (default: ${Math.round(DEFAULT_SIMILARITY * 100)})
|
|
6576
6598
|
-e, --extensions <s> File extensions to scan (default: ${DEFAULT_EXTENSIONS.join(",")})
|
|
6577
6599
|
-i, --ignore <s> Patterns to ignore (default: ${DEFAULT_IGNORE_PATTERNS.slice(0, 4).join(",")},...)
|
|
6600
|
+
--staged Only show duplicates involving uncommitted changes
|
|
6578
6601
|
--no-normalize Disable string/number normalization
|
|
6579
6602
|
--cross-package Only show duplicates across different packages/apps (monorepo mode)
|
|
6580
6603
|
--json Output as JSON
|
|
@@ -6583,8 +6606,8 @@ Options:
|
|
|
6583
6606
|
|
|
6584
6607
|
Examples:
|
|
6585
6608
|
dslop . Scan current directory
|
|
6609
|
+
dslop --staged Check uncommitted changes for duplicates
|
|
6586
6610
|
dslop ./src -m 6 -s 80 Scan src with 6 line min, 80% similarity
|
|
6587
|
-
dslop . -e ts,tsx --json Scan TypeScript files, output JSON
|
|
6588
6611
|
dslop . --cross-package Only duplicates across packages (great for monorepos)
|
|
6589
6612
|
`);
|
|
6590
6613
|
}
|
|
@@ -6601,6 +6624,7 @@ async function main() {
|
|
|
6601
6624
|
ignore: { type: "string", short: "i", default: DEFAULT_IGNORE_PATTERNS.join(",") },
|
|
6602
6625
|
normalize: { type: "boolean", default: true },
|
|
6603
6626
|
"no-normalize": { type: "boolean", default: false },
|
|
6627
|
+
staged: { type: "boolean", default: false },
|
|
6604
6628
|
"cross-package": { type: "boolean", default: false },
|
|
6605
6629
|
json: { type: "boolean", default: false },
|
|
6606
6630
|
help: { type: "boolean", short: "h", default: false },
|
|
@@ -6622,6 +6646,7 @@ async function main() {
|
|
|
6622
6646
|
const extensions = values.extensions.split(",").map((e) => e.trim());
|
|
6623
6647
|
const ignorePatterns = values.ignore.split(",").map((p) => p.trim());
|
|
6624
6648
|
const normalize2 = !values["no-normalize"];
|
|
6649
|
+
const staged = values.staged;
|
|
6625
6650
|
const crossPackage = values["cross-package"];
|
|
6626
6651
|
const jsonOutput = values.json;
|
|
6627
6652
|
if (minLines < 2) {
|
|
@@ -6638,14 +6663,23 @@ async function main() {
|
|
|
6638
6663
|
minLines,
|
|
6639
6664
|
normalize: normalize2
|
|
6640
6665
|
};
|
|
6666
|
+
const changedFiles = staged ? getChangedFiles(targetPath) : null;
|
|
6667
|
+
if (staged && changedFiles?.size === 0) {
|
|
6668
|
+
console.log(`
|
|
6669
|
+
No uncommitted changes found.`);
|
|
6670
|
+
process.exit(0);
|
|
6671
|
+
}
|
|
6641
6672
|
console.log(`
|
|
6642
6673
|
Scanning ${targetPath}...`);
|
|
6643
6674
|
console.log(` Extensions: ${extensions.join(", ")}`);
|
|
6644
6675
|
console.log(` Min block size: ${minLines} lines`);
|
|
6645
6676
|
console.log(` Similarity threshold: ${Math.round(similarity * 100)}%`);
|
|
6646
6677
|
console.log(` Normalization: ${normalize2 ? "enabled" : "disabled"}`);
|
|
6678
|
+
if (staged) {
|
|
6679
|
+
console.log(` Staged mode: checking ${changedFiles.size} changed files against codebase`);
|
|
6680
|
+
}
|
|
6647
6681
|
if (crossPackage) {
|
|
6648
|
-
console.log(` Cross-package mode: enabled
|
|
6682
|
+
console.log(` Cross-package mode: enabled`);
|
|
6649
6683
|
}
|
|
6650
6684
|
console.log();
|
|
6651
6685
|
try {
|
|
@@ -6662,6 +6696,9 @@ Scanning ${targetPath}...`);
|
|
|
6662
6696
|
const detectStart = performance.now();
|
|
6663
6697
|
let duplicates = findDuplicates(blocks, similarity, targetPath);
|
|
6664
6698
|
const detectTime = performance.now() - detectStart;
|
|
6699
|
+
if (staged && changedFiles) {
|
|
6700
|
+
duplicates = duplicates.filter((group) => group.matches.some((m) => changedFiles.has(m.filePath)));
|
|
6701
|
+
}
|
|
6665
6702
|
if (crossPackage) {
|
|
6666
6703
|
duplicates = duplicates.filter((group) => {
|
|
6667
6704
|
const packages = new Set(group.matches.map((m) => {
|
|
@@ -6674,7 +6711,13 @@ Scanning ${targetPath}...`);
|
|
|
6674
6711
|
console.log(`Found ${duplicates.length} duplicate groups in ${Math.round(detectTime)}ms
|
|
6675
6712
|
`);
|
|
6676
6713
|
if (duplicates.length === 0) {
|
|
6677
|
-
|
|
6714
|
+
if (staged) {
|
|
6715
|
+
console.log("No duplicates in your changes. You're good!");
|
|
6716
|
+
} else if (crossPackage) {
|
|
6717
|
+
console.log("No cross-package duplicates found!");
|
|
6718
|
+
} else {
|
|
6719
|
+
console.log("No duplicates found!");
|
|
6720
|
+
}
|
|
6678
6721
|
process.exit(0);
|
|
6679
6722
|
}
|
|
6680
6723
|
if (jsonOutput) {
|