From a2c7d0337d0a809e4e642f38178adbd0c2b5a894 Mon Sep 17 00:00:00 2001 From: Matthias Giger Date: Sat, 25 Nov 2023 20:33:43 +0100 Subject: [PATCH] fix(path): optionally keep existing contents in directory Useful when checking out into an existing git repository folder. release-npm --- config.js | 5 ++++- package.json | 24 ++++++++++++------------ test/helper.test.js | 44 ++++++++++++++++++++++++++++++++++++++++++-- utility/helper.js | 2 +- utility/prompt.js | 4 ++-- 5 files changed, 61 insertions(+), 18 deletions(-) diff --git a/config.js b/config.js index 7f7aee2..4bebeec 100644 --- a/config.js +++ b/config.js @@ -5,4 +5,7 @@ import temporaryDirectory from 'temp-dir' const nodeModulesCacheDir = findCacheDir({ name: 'create-now', thunk: true }) const npxCacheDirectory = (template) => join(temporaryDirectory, 'create-now', template) -export const cachePath = nodeModulesCacheDir || npxCacheDirectory +export function cachePath() { + const path = nodeModulesCacheDir ?? npxCacheDirectory + return typeof path === 'function' ? path() : path +} diff --git a/package.json b/package.json index 00a794f..0e64314 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,22 @@ "dependencies": { "download-git-repo": "^3.0.2", "ejs": "^3.1.9", - "find-cache-dir": "^4.0.0", + "find-cache-dir": "^5.0.0", "isbinaryfile": "^5.0.0", - "logua": "^2.3.0", - "node-fetch": "^3.3.1", + "logua": "^3.0.2", + "node-fetch": "^3.3.2", "prompts": "^2.4.2", "temp-dir": "^3.0.0", "validate-npm-package-name": "^5.0.0" }, + "devDependencies": { + "is-png": "^3.0.1", + "jest-fixture": "^4.1.0", + "mock-stdin": "^1.0.0", + "padua": "^2.0.7", + "read-chunk": "^4.0.3", + "vitest": "^0.34.6" + }, "type": "module", "sideEffects": true, "main": "index.js", @@ -43,14 +51,6 @@ "generator", "init" ], - "devDependencies": { - "is-png": "^3.0.1", - "jest-fixture": "^4.1.0", - "mock-stdin": "^1.0.0", - "padua": "^2.0.0", - "read-chunk": "^4.0.3", - "vitest": "^0.32.2" - }, "prettier": "padua/configuration/.prettierrc.json", "eslintConfig": { "extends": "./node_modules/padua/configuration/eslint.cjs", @@ -65,6 +65,6 @@ "provenance": true }, "engines": { - "node": ">= 16" + "node": ">= 18" } } diff --git a/test/helper.test.js b/test/helper.test.js index 515d65f..f1440d1 100644 --- a/test/helper.test.js +++ b/test/helper.test.js @@ -1,4 +1,4 @@ -import { existsSync, rmSync, readdirSync } from 'fs' +import { existsSync, rmSync, readdirSync, mkdirSync } from 'fs' import { join } from 'path' import { stdin } from 'mock-stdin' import { test, expect, beforeAll, afterAll, vi } from 'vitest' @@ -85,7 +85,7 @@ test('Clears non-empty destination path on confirmed prompt.', async () => { setTimeout(() => sendKeystrokes().then(), 5) - expect(await getDestinationPath('test/fixture/helper/non-empty')).toEqual(join(cwd, 'non-empty')) + expect(await getDestinationPath('test/fixture/helper/non-empty')).toEqual(join(cwd, 'non-empty')) // Actual prompt. expect(existsSync(join(cwd, 'non-empty'))).toBeTruthy() // Directory was cleared. expect(readdirSync(join(cwd, 'non-empty')).length === 0).toBeTruthy() @@ -93,3 +93,43 @@ test('Clears non-empty destination path on confirmed prompt.', async () => { // Clean up created directories. rmSync(join(cwd, 'non-empty'), { recursive: true }) }) + +test('Existing git repository is kept when overriding a folder.', async () => { + // Restore as otherwise previous test causes issues. + io.restore() + io = stdin() + + const cwd = join(process.cwd(), 'test/fixture/helper') + + if (existsSync(join(cwd, 'non-empty-git'))) { + rmSync(join(cwd, 'non-empty-git'), { recursive: true }) + } + + mkdirSync(join(cwd, 'non-empty-git')) + + // Add file as contents. + expect(readdirSync(join(cwd, 'non-empty-git')).length === 0).toBeTruthy() + writeFile('test/fixture/helper/non-empty-git/index.js', 'console.log("hello")') + writeFile('test/fixture/helper/non-empty-git/.git/.gitkeep', 'console.log("hello")') + expect(readdirSync(join(cwd, 'non-empty-git')).length === 2).toBeTruthy() + expect(mockExit.mock.calls.length).toBe(0) + + // Mock confirm. + const sendKeystrokes = async () => { + io.send('n') + io.send(keys.enter) + } + + setTimeout(() => sendKeystrokes().then(), 5) + + expect(await getDestinationPath('test/fixture/helper/non-empty-git')).toEqual( + join(cwd, 'non-empty-git'), + ) // Actual prompt. + + expect(existsSync(join(cwd, 'non-empty-git'))).toBeTruthy() + // Directory was cleared. + expect(readdirSync(join(cwd, 'non-empty-git')).length).toBe(2) + + // Clean up created directories. + rmSync(join(cwd, 'non-empty-git'), { recursive: true }) +}) diff --git a/utility/helper.js b/utility/helper.js index b17386b..31d4b00 100644 --- a/utility/helper.js +++ b/utility/helper.js @@ -23,7 +23,7 @@ export const getDestinationPath = async (input = process.cwd(), skipClear = fals const clear = await promptClear(destinationPath) if (!clear) { - log('Exiting, directory already exists', 'error') + log('Keeping existing contents, might be overriden when copying the template') } else { // Clear directory to ensure proper npm install. rmSync(destinationPath, { recursive: true }) diff --git a/utility/prompt.js b/utility/prompt.js index 640821e..85e5d7c 100644 --- a/utility/prompt.js +++ b/utility/prompt.js @@ -51,8 +51,8 @@ export const promptClear = async (directory) => { const response = await prompts({ type: 'confirm', name: 'clear', - message: `A directory ${directory} already exists, should it be overridden?` + message: `A directory ${directory} already exists, should it be emptied first?`, }) return response.clear -} \ No newline at end of file +}