Skip to content

bug(cli): use platform-aware directory handling for Windows output paths #26

Description

@Hebilicious

Problem

writeFileRecursive() in cli.ts at 94bf4d8 derives the parent directory with a forward-slash-only expression:

fs.mkdir(path.replace(/\/[^/]*$/, ""), { recursive: true })
  .then(() => fs.writeFile(path, data));

The caller obtains an absolute native path using node:path.resolve(). For a Windows path using backslashes, the expression leaves the full filename intact. It therefore attempts to create a directory at the intended output file path before writing to that same path.

Isolated reproduction

import { win32 } from "node:path";

const output = String.raw`C:\project\.cssforge\output.css`;
console.log(output.replace(/\/[^/]*$/, ""));
// C:\project\.cssforge\output.css — incorrect parent

console.log(win32.dirname(output));
// C:\project\.cssforge — expected parent

The path-expression difference above was reproduced directly. Native Windows file-system execution still needs a regression test.

Proposed fix

Use the platform-aware dirname() function from node:path for production paths:

await fs.mkdir(dirname(outputPath), { recursive: true });
await fs.writeFile(outputPath, data);

Acceptance criteria

  • CSS, JSON, and TypeScript outputs use platform-aware parent-directory handling.
  • Tests cover a filename in the current directory, nested relative paths, absolute paths, and paths containing spaces.
  • At least one real CLI integration test runs on Windows, alongside a POSIX runner.
  • Tests verify that the result is a file with the expected content, not a directory named after the output file.
  • Include this coverage in the packed npm CLI smoke tests introduced by chore(distribution): make npm the primary release channel and keep JSR as fallback #22.

This issue is deliberately separate from output-mode validation so each fix can be implemented and reviewed independently.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions