diff --git a/packages/@apphosting/common/package.json b/packages/@apphosting/common/package.json index 25ae288e..ed144d7b 100644 --- a/packages/@apphosting/common/package.json +++ b/packages/@apphosting/common/package.json @@ -1,6 +1,6 @@ { "name": "@apphosting/common", - "version": "0.0.5", + "version": "0.0.6", "description": "Shared library code for App Hosting framework adapters", "author": { "name": "Firebase", @@ -17,6 +17,7 @@ }, "scripts": { "build": "tsc", + "test": "ts-mocha -p tsconfig.json 'src/**/*.spec.ts' 'src/*.spec.ts'", "localregistry:start": "npx verdaccio --config ../publish-dev/verdaccio-config.yaml", "localregistry:publish": "(npm view --registry=http://localhost:4873 @apphosting/common && npm unpublish --@apphosting:registry=http://localhost:4873 --force); npm publish --@apphosting:registry=http://localhost:4873" }, diff --git a/packages/@apphosting/common/src/index.spec.ts b/packages/@apphosting/common/src/index.spec.ts new file mode 100644 index 00000000..27bdbd57 --- /dev/null +++ b/packages/@apphosting/common/src/index.spec.ts @@ -0,0 +1,30 @@ +import assert from "assert"; +import fs from "fs"; +import path from "path"; +import os from "os"; +import { updateOrCreateGitignore } from "./index"; + +describe("update or create .gitignore", () => { + let tmpDir: string; + beforeEach(() => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "test-gitignore")); + }); + + afterEach(() => { + fs.rmSync(tmpDir, { recursive: true, force: true }); + }); + + it(".gitignore file exists and is correctly updated with missing paths", () => { + fs.writeFileSync(path.join(tmpDir, ".gitignore"), "existingpath/"); + + updateOrCreateGitignore(tmpDir, ["existingpath/", "newpath/"]); + + const gitignoreContent = fs.readFileSync(path.join(tmpDir, ".gitignore"), "utf-8"); + assert.equal(`existingpath/\nnewpath/`, gitignoreContent); + }); + it(".gitignore file does not exist and is created", () => { + updateOrCreateGitignore(tmpDir, ["chickenpath/", "newpath/"]); + const gitignoreContent = fs.readFileSync(path.join(tmpDir, ".gitignore"), "utf-8"); + assert.equal(`chickenpath/\nnewpath/`, gitignoreContent); + }); +}); diff --git a/packages/@apphosting/common/src/index.ts b/packages/@apphosting/common/src/index.ts index 6319a0cc..f16d32db 100644 --- a/packages/@apphosting/common/src/index.ts +++ b/packages/@apphosting/common/src/index.ts @@ -1,4 +1,6 @@ import { spawn } from "child_process"; +import * as fs from "node:fs"; +import * as path from "node:path"; // Output bundle metadata specifications to be written to bundle.yaml export interface OutputBundleConfig { @@ -139,3 +141,26 @@ export function getBuildOptions(): BuildOptions { projectDirectory: process.cwd(), }; } + +/** + * Updates or creates a .gitignore file with the given entries in the given path + */ +export function updateOrCreateGitignore(dirPath: string, entries: string[]) { + const gitignorePath = path.join(dirPath, ".gitignore"); + + if (!fs.existsSync(gitignorePath)) { + console.log(`creating ${gitignorePath} with entries: ${entries.join("\n")}`); + fs.writeFileSync(gitignorePath, entries.join("\n")); + return; + } + + let content = fs.readFileSync(gitignorePath, "utf-8"); + for (const entry of entries) { + if (!content.split("\n").includes(entry)) { + console.log(`adding ${entry} to ${gitignorePath}`); + content += `\n${entry}`; + } + } + + fs.writeFileSync(gitignorePath, content); +}