Skip to content

Commit ce7182e

Browse files
authored
Merge pull request #11151 from quarto-dev/bugfix/2671
Make `--output-dir` work on cross-device destinations
2 parents 91628f8 + 5a703d7 commit ce7182e

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

news/changelog-1.6.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ All changes included in 1.6:
7575

7676
### Websites
7777

78+
- ([#2671](https://github.com/quarto-dev/quarto-cli/issues/2671)): Ensure that `--output-dir` works across filesystem boundaries.
7879
- ([#8932](https://github.com/quarto-dev/quarto-cli/issues/8932)): Escape render ids in markdown pipeline to allow special characters in sidebars/navbars, etc.
7980
- ([#10616](https://github.com/quarto-dev/quarto-cli/issues/10268)): Add a `z-index` setting to the 'back to top' button to ensure it is always visible.
8081

src/command/render/project.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Copyright (C) 2020-2022 Posit Software, PBC
55
*/
66

7-
import { ensureDirSync, existsSync } from "../../deno_ral/fs.ts";
7+
import { ensureDirSync, existsSync, safeMoveSync } from "../../deno_ral/fs.ts";
88
import { dirname, isAbsolute, join, relative } from "../../deno_ral/path.ts";
99
import { info, warning } from "../../deno_ral/log.ts";
1010
import { mergeProjectMetadata } from "../../config/metadata.ts";
@@ -530,7 +530,7 @@ export async function renderProject(
530530
if (!renderedFile.isTransient) {
531531
const outputFile = join(formatOutputDir, renderedFile.file);
532532
ensureDirSync(dirname(outputFile));
533-
Deno.renameSync(join(projDir, renderedFile.file), outputFile);
533+
safeMoveSync(join(projDir, renderedFile.file), outputFile);
534534
}
535535

536536
// files dir

src/core/path.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import {
1818

1919
import { warning } from "../deno_ral/log.ts";
2020

21-
import { existsSync, expandGlobSync } from "../deno_ral/fs.ts";
21+
export { safeRemoveSync } from "../deno_ral/fs.ts";
22+
23+
import { existsSync, expandGlobSync, safeRemoveSync } from "../deno_ral/fs.ts";
2224

2325
import * as ld from "./lodash.ts";
2426

@@ -41,19 +43,6 @@ export function safeRemoveIfExists(file: string) {
4143
}
4244
}
4345

44-
export function safeRemoveSync(
45-
file: string,
46-
options: Deno.RemoveOptions = {},
47-
) {
48-
try {
49-
Deno.removeSync(file, options);
50-
} catch (e) {
51-
if (existsSync(file)) {
52-
throw e;
53-
}
54-
}
55-
}
56-
5746
export function removeIfEmptyDir(dir: string): boolean {
5847
if (existsSync(dir)) {
5948
let empty = true;

src/deno_ral/fs.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import { fromFileUrl } from "./path.ts";
88
import { resolve, SEP as SEPARATOR } from "./path.ts";
9+
import { copySync } from "fs/copy";
10+
import { existsSync } from "fs/exists";
911

1012
export { ensureDir, ensureDirSync } from "fs/ensure-dir";
1113
export { existsSync } from "fs/exists";
@@ -74,3 +76,31 @@ export function toPathString(
7476
): string {
7577
return pathUrl instanceof URL ? fromFileUrl(pathUrl) : pathUrl;
7678
}
79+
80+
export function safeMoveSync(
81+
src: string,
82+
dest: string,
83+
): void {
84+
try {
85+
Deno.renameSync(src, dest);
86+
} catch (err) {
87+
if (err.code !== "EXDEV") {
88+
throw err;
89+
}
90+
copySync(src, dest, { overwrite: true });
91+
safeRemoveSync(src, { recursive: true });
92+
}
93+
}
94+
95+
export function safeRemoveSync(
96+
file: string,
97+
options: Deno.RemoveOptions = {},
98+
) {
99+
try {
100+
Deno.removeSync(file, options);
101+
} catch (e) {
102+
if (existsSync(file)) {
103+
throw e;
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)