Path: blob/main/src/project/project-gitignore.ts
12924 views
/*1* project-gitignore.ts2*3* Copyright (C) 2020-2022 Posit Software, PBC4*/56import { join } from "../deno_ral/path.ts";7import { existsSync, walkSync } from "../deno_ral/fs.ts";89import { which } from "../core/path.ts";10import { execProcess } from "../core/process.ts";1112import { kQuartoScratch } from "./project-scratch.ts";13import { lines } from "../core/text.ts";14import { isEnvDir } from "../core/jupyter/capabilities.ts";15import { isWindows } from "../deno_ral/platform.ts";1617export const kQuartoIgnore = [`/${kQuartoScratch}/`, `**/*.quarto_ipynb`];1819export async function ensureGitignore(20dir: string,21forceEnv = false,22): Promise<boolean> {23// if .gitignore exists, then ensure it has the requisite entries24const gitignorePath = join(dir, ".gitignore");25if (existsSync(gitignorePath)) {26const gitignore = lines(Deno.readTextFileSync(gitignorePath))27.map((line) => line.trim());28const requiredEntries: string[] = [];29for (const requiredEntry of gitignoreEntries(dir, forceEnv)) {30if (!gitignore.includes(requiredEntry)) {31requiredEntries.push(requiredEntry);32}33}34// see if we need to gitignore any .local files35const kLocalEntry = `/_*.local`;36if (!gitignore.includes(kLocalEntry)) {37for (const walk of walkSync(dir, { maxDepth: 1 })) {38if (walk.name.match(/^_.*?\.local$/)) {39requiredEntries.push(kLocalEntry);40break;41}42}43}4445if (requiredEntries.length > 0) {46writeGitignore(dir, gitignore.concat(requiredEntries));47return true;48} else {49return false;50}51} else if (forceEnv) {52await createGitignore(dir, forceEnv);53return true;54} else if (await which("git")) {55// if it doesn't exist then auto-create if we are in a git project or we had the force flag56const result = await execProcess({57cmd: "git",58args: ["rev-parse"],59cwd: dir,60stdout: "piped",61stderr: "piped",62});63if (result.success) {64await createGitignore(dir, forceEnv);65return true;66} else {67return false;68}69} else {70return false;71}72}7374export function createGitignore(dir: string, forceEnv = false) {75writeGitignore(dir, gitignoreEntries(dir, forceEnv));76}7778export function gitignoreEntries(dir: string, forceEnv = false) {79// detect virtual environment80const kEnv = "env/";81if (forceEnv || isEnvDir(join(dir, kEnv))) {82return ["/" + kEnv].concat(kQuartoIgnore);83} else {84return kQuartoIgnore;85}86}8788function writeGitignore(dir: string, lines: string[]) {89// write gitignore90const lineEnding = isWindows ? "\r\n" : "\n";91Deno.writeTextFileSync(92join(dir, ".gitignore"),93lines.join(lineEnding) + lineEnding,94);95}969798