Skip to content

fix: use temp directory for jscpd output on Windows (#270)#271

Merged
avifenesh merged 3 commits intomainfrom
fix/deslop-windows-bugs-270
Feb 25, 2026
Merged

fix: use temp directory for jscpd output on Windows (#270)#271
avifenesh merged 3 commits intomainfrom
fix/deslop-windows-bugs-270

Conversation

@avifenesh
Copy link
Collaborator

Summary

  • Fixed runDuplicateDetection in lib/patterns/cli-enhancers.js creating a mangled filename on Windows when --output NUL was passed to jscpd via execFileSync (no shell interpretation)
  • Replaced platform-specific null device (NUL//dev/null) with a temp directory via os.tmpdir() that is cleaned up in a finally block
  • Moved mkdtempSync inside try-catch to preserve graceful degradation when tmpdir creation fails

Test Plan

  • 5 new regression tests for temp directory lifecycle (creation, cleanup on success, cleanup on failure, mkdtempSync failure, no NUL/dev-null references)
  • All 128 cli-enhancers tests pass
  • All validators pass (npm run validate)
  • Manual verification: run /deslop on Windows, confirm no nul or mangled-path files in project root

Notes

Closes #270

On Windows, passing NUL to execFileSync (no shell) treats it as a
literal filename, creating a mangled "nul" directory. Replace with
fs.mkdtempSync temp directory that is cleaned up in a finally block.
Move temp directory creation inside try block so mkdtempSync failures
(e.g., ENOSPC) return null instead of throwing. Add conditional guard
in finally block. Add test for mkdtempSync failure scenario.
Copilot AI review requested due to automatic review settings February 25, 2026 10:44
@avifenesh avifenesh merged commit b12b395 into main Feb 25, 2026
11 checks passed
@avifenesh avifenesh deleted the fix/deslop-windows-bugs-270 branch February 25, 2026 10:48
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Windows-specific jscpd invocation bug in the slop-detection CLI enhancers by avoiding null-device output paths and using a temporary output directory instead.

Changes:

  • Switch runDuplicateDetection() to write jscpd output into a temp directory (os.tmpdir() + mkdtempSync) and remove it in a finally block.
  • Add regression tests covering temp directory creation/cleanup and ensuring no NUL//dev/null output path usage.
  • Document the fix in CHANGELOG.md.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
lib/patterns/cli-enhancers.js Replaces --output NUL//dev/null with a temp output directory and cleans it up reliably.
tests/cli-enhancers.test.js Adds regression tests validating temp dir lifecycle and absence of null-device output paths.
CHANGELOG.md Adds an Unreleased “Fixed” entry describing the Windows jscpd output fix and tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +350 to +351
// On Windows, NUL passed via execFileSync (no shell) is treated as a literal filename,
// creating a mangled path in the working directory.
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explanatory comment is a bit inaccurate: execFileSync doesn’t treat NUL as a filename—jscpd interprets the --output value and ends up creating the mangled path on Windows. Consider rewording to attribute the behavior to jscpd and clarify that NUL//dev/null aren’t valid output paths for jscpd in this mode.

Suggested change
// On Windows, NUL passed via execFileSync (no shell) is treated as a literal filename,
// creating a mangled path in the working directory.
// jscpd interprets the value passed to --output itself, so using NUL or /dev/null here
// results in jscpd creating a mangled path on Windows rather than discarding the output.

Copilot uses AI. Check for mistakes.

it('should use temp directory for jscpd output instead of NUL', () => {
const mkdtempSpy = jest.spyOn(fs, 'mkdtempSync');
const rmSpy = jest.spyOn(fs, 'rmSync').mockImplementation(() => {});
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests spy on fs.rmSync but also mock it to a no-op. Since runDuplicateDetection() uses a real fs.mkdtempSync(), this can leave real temp directories behind on disk (cleanup runs but is stubbed). Prefer spying without overriding implementation (call-through), or ensure the created temp dir is actually removed in test teardown.

Suggested change
const rmSpy = jest.spyOn(fs, 'rmSync').mockImplementation(() => {});
const rmSpy = jest.spyOn(fs, 'rmSync');

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[deslop] Two Windows-specific bugs: literal nul file creation + broken jscpd output path

2 participants