Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/project/project-gitignore.ts
6446 views
1
/*
2
* project-gitignore.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import { join } from "../deno_ral/path.ts";
8
import { existsSync, walkSync } from "../deno_ral/fs.ts";
9
10
import { which } from "../core/path.ts";
11
import { execProcess } from "../core/process.ts";
12
13
import { kQuartoScratch } from "./project-scratch.ts";
14
import { lines } from "../core/text.ts";
15
import { isEnvDir } from "../core/jupyter/capabilities.ts";
16
import { isWindows } from "../deno_ral/platform.ts";
17
18
export const kQuartoIgnore = [`/${kQuartoScratch}/`, `**/*.quarto_ipynb`];
19
20
export async function ensureGitignore(
21
dir: string,
22
forceEnv = false,
23
): Promise<boolean> {
24
// if .gitignore exists, then ensure it has the requisite entries
25
const gitignorePath = join(dir, ".gitignore");
26
if (existsSync(gitignorePath)) {
27
const gitignore = lines(Deno.readTextFileSync(gitignorePath))
28
.map((line) => line.trim());
29
const requiredEntries: string[] = [];
30
for (const requiredEntry of gitignoreEntries(dir, forceEnv)) {
31
if (!gitignore.includes(requiredEntry)) {
32
requiredEntries.push(requiredEntry);
33
}
34
}
35
// see if we need to gitignore any .local files
36
const kLocalEntry = `/_*.local`;
37
if (!gitignore.includes(kLocalEntry)) {
38
for (const walk of walkSync(dir, { maxDepth: 1 })) {
39
if (walk.name.match(/^_.*?\.local$/)) {
40
requiredEntries.push(kLocalEntry);
41
break;
42
}
43
}
44
}
45
46
if (requiredEntries.length > 0) {
47
writeGitignore(dir, gitignore.concat(requiredEntries));
48
return true;
49
} else {
50
return false;
51
}
52
} else if (forceEnv) {
53
await createGitignore(dir, forceEnv);
54
return true;
55
} else if (await which("git")) {
56
// if it doesn't exist then auto-create if we are in a git project or we had the force flag
57
const result = await execProcess({
58
cmd: "git",
59
args: ["rev-parse"],
60
cwd: dir,
61
stdout: "piped",
62
stderr: "piped",
63
});
64
if (result.success) {
65
await createGitignore(dir, forceEnv);
66
return true;
67
} else {
68
return false;
69
}
70
} else {
71
return false;
72
}
73
}
74
75
export function createGitignore(dir: string, forceEnv = false) {
76
writeGitignore(dir, gitignoreEntries(dir, forceEnv));
77
}
78
79
export function gitignoreEntries(dir: string, forceEnv = false) {
80
// detect virtual environment
81
const kEnv = "env/";
82
if (forceEnv || isEnvDir(join(dir, kEnv))) {
83
return ["/" + kEnv].concat(kQuartoIgnore);
84
} else {
85
return kQuartoIgnore;
86
}
87
}
88
89
function writeGitignore(dir: string, lines: string[]) {
90
// write gitignore
91
const lineEnding = isWindows ? "\r\n" : "\n";
92
Deno.writeTextFileSync(
93
join(dir, ".gitignore"),
94
lines.join(lineEnding) + lineEnding,
95
);
96
}
97
98