From e46214f98bf03a8f40b79fabcbb17fb37e47b94a Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Tue, 1 Oct 2024 13:01:59 -0400 Subject: [PATCH 1/3] Allow ignoring liquid files using .shopifyignore Co-authored-by: Julien Henrotte --- .../src/cli/services/init/template/cleanup.ts | 1 + packages/cli-kit/src/public/node/liquid.ts | 28 +++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/app/src/cli/services/init/template/cleanup.ts b/packages/app/src/cli/services/init/template/cleanup.ts index 7c09318236..7d0ad797cd 100644 --- a/packages/app/src/cli/services/init/template/cleanup.ts +++ b/packages/app/src/cli/services/init/template/cleanup.ts @@ -7,6 +7,7 @@ export default async function cleanup(webOutputDirectory: string) { joinPath(webOutputDirectory, '**', '.git'), joinPath(webOutputDirectory, '**', '.github'), joinPath(webOutputDirectory, '**', '.gitmodules'), + joinPath(webOutputDirectory, '**', '.shopifyignore'), joinPath(webOutputDirectory, 'LICENSE*'), joinPath(webOutputDirectory, '**', 'frontend/LICENSE*'), joinPath(webOutputDirectory, 'package.json.cli2'), diff --git a/packages/cli-kit/src/public/node/liquid.ts b/packages/cli-kit/src/public/node/liquid.ts index cc36956ba5..db1ce8bbae 100644 --- a/packages/cli-kit/src/public/node/liquid.ts +++ b/packages/cli-kit/src/public/node/liquid.ts @@ -1,4 +1,15 @@ -import {mkdir, readFile, copyFile, chmod, isDirectory, writeFile, fileHasExecutablePermissions, glob} from './fs.js' +import { + mkdir, + readFile, + copyFile, + chmod, + isDirectory, + writeFile, + fileHasExecutablePermissions, + glob, + fileExists, + matchGlob, +} from './fs.js' import {joinPath, dirname, relativePath} from './path.js' import {outputContent, outputToken, outputDebug} from '../../public/node/output.js' import {Liquid} from 'liquidjs' @@ -29,6 +40,12 @@ export async function recursiveLiquidTemplateCopy(from: string, to: string, data outputDebug(outputContent`Copying template from directory ${outputToken.path(from)} to ${outputToken.path(to)}`) const templateFiles: string[] = await glob(joinPath(from, '**/*'), {dot: true}) + const ignoreFilePath = joinPath(from, '.shopifyignore') + let ignorePatterns: string[] = [] + if (await fileExists(ignoreFilePath)) { + ignorePatterns = (await readFile(ignoreFilePath)).split('\n').filter((line) => line.trim().length > 0) + } + const sortedTemplateFiles = templateFiles .map((path) => path.split('/')) .sort((lhs, rhs) => (lhs.length < rhs.length ? 1 : -1)) @@ -36,9 +53,16 @@ export async function recursiveLiquidTemplateCopy(from: string, to: string, data await Promise.all( sortedTemplateFiles.map(async (templateItemPath) => { const outputPath = await renderLiquidTemplate(joinPath(to, relativePath(from, templateItemPath)), data) + const isIgnored = ignorePatterns.some((pattern) => { + const path = relativePath(from, templateItemPath) + const cleanPattern = pattern.replace(/^\.\//, '') + + return matchGlob(path, cleanPattern) || path.startsWith(cleanPattern) + }) + if (await isDirectory(templateItemPath)) { await mkdir(outputPath) - } else if (templateItemPath.endsWith('.liquid')) { + } else if (templateItemPath.endsWith('.liquid') && !isIgnored) { await mkdir(dirname(outputPath)) const content = await readFile(templateItemPath) const contentOutput = await renderLiquidTemplate(content, data) From f98594388929aab64e2b729deadc194434905c04 Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Tue, 8 Oct 2024 16:15:29 -0400 Subject: [PATCH 2/3] Naming liquid ignore file more semantically Co-authored-by: Julien Henrotte --- .../src/cli/services/init/template/cleanup.ts | 2 +- .../cli-kit/src/public/node/liquid.test.ts | 36 +++++++++++++++++++ packages/cli-kit/src/public/node/liquid.ts | 12 +++---- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/app/src/cli/services/init/template/cleanup.ts b/packages/app/src/cli/services/init/template/cleanup.ts index 7d0ad797cd..fa46e90b37 100644 --- a/packages/app/src/cli/services/init/template/cleanup.ts +++ b/packages/app/src/cli/services/init/template/cleanup.ts @@ -7,7 +7,7 @@ export default async function cleanup(webOutputDirectory: string) { joinPath(webOutputDirectory, '**', '.git'), joinPath(webOutputDirectory, '**', '.github'), joinPath(webOutputDirectory, '**', '.gitmodules'), - joinPath(webOutputDirectory, '**', '.shopifyignore'), + joinPath(webOutputDirectory, '**', '.cli-liquid-bypass'), joinPath(webOutputDirectory, 'LICENSE*'), joinPath(webOutputDirectory, '**', 'frontend/LICENSE*'), joinPath(webOutputDirectory, 'package.json.cli2'), diff --git a/packages/cli-kit/src/public/node/liquid.test.ts b/packages/cli-kit/src/public/node/liquid.test.ts index 52b4bc1d4d..eecefcadf3 100644 --- a/packages/cli-kit/src/public/node/liquid.test.ts +++ b/packages/cli-kit/src/public/node/liquid.test.ts @@ -51,4 +51,40 @@ describe('recursiveLiquidTemplateCopy', () => { expect(JSON.parse(outPackageJson)).toEqual(packageJson) }) }) + + test('ignores files and folders in .cli-liquid-bypass', async () => { + const bypassPatterns = ['ignored.liquid', 'ignored-folder'] + + // Given + await inTemporaryDirectory(async (tmpDir) => { + // Given + const from = joinPath(tmpDir, 'from') + const ignoredFolder = joinPath(from, 'ignored-folder') + const to = joinPath(tmpDir, 'to') + await mkdir(from) + await mkdir(ignoredFolder) + await mkdir(to) + + const bypassFile = joinPath(from, '.cli-liquid-bypass') + const ignoredFile = joinPath(from, 'ignored.liquid') + const folderIgnoredFile = joinPath(ignoredFolder, 'ignored2.liquid') + const processedFile = joinPath(from, 'processed.md.liquid') + await writeFile(bypassFile, bypassPatterns.join('\n')) + await writeFile(ignoredFile, '# {{variable}}') + await writeFile(folderIgnoredFile, '# {{variable}}') + await writeFile(processedFile, '# {{variable}}') + + // When + await recursiveLiquidTemplateCopy(from, to, {variable: 'test'}) + + // Then + const outFile = joinPath(to, 'ignored.liquid') + const outFolderFile = joinPath(to, 'ignored-folder/ignored2.liquid') + const outProcessedFile = joinPath(to, 'processed.md') + + await expect(readFile(outFile)).resolves.toEqual('# {{variable}}') + await expect(readFile(outFolderFile)).resolves.toEqual('# {{variable}}') + await expect(readFile(outProcessedFile)).resolves.toEqual('# test') + }) + }) }) diff --git a/packages/cli-kit/src/public/node/liquid.ts b/packages/cli-kit/src/public/node/liquid.ts index db1ce8bbae..95640c0a44 100644 --- a/packages/cli-kit/src/public/node/liquid.ts +++ b/packages/cli-kit/src/public/node/liquid.ts @@ -40,10 +40,10 @@ export async function recursiveLiquidTemplateCopy(from: string, to: string, data outputDebug(outputContent`Copying template from directory ${outputToken.path(from)} to ${outputToken.path(to)}`) const templateFiles: string[] = await glob(joinPath(from, '**/*'), {dot: true}) - const ignoreFilePath = joinPath(from, '.shopifyignore') - let ignorePatterns: string[] = [] - if (await fileExists(ignoreFilePath)) { - ignorePatterns = (await readFile(ignoreFilePath)).split('\n').filter((line) => line.trim().length > 0) + const bypassPaths = joinPath(from, '.cli-liquid-bypass') + let bypassPatterns: string[] = [] + if (await fileExists(bypassPaths)) { + bypassPatterns = (await readFile(bypassPaths)).split('\n').filter((line) => line.trim().length > 0) } const sortedTemplateFiles = templateFiles @@ -53,7 +53,7 @@ export async function recursiveLiquidTemplateCopy(from: string, to: string, data await Promise.all( sortedTemplateFiles.map(async (templateItemPath) => { const outputPath = await renderLiquidTemplate(joinPath(to, relativePath(from, templateItemPath)), data) - const isIgnored = ignorePatterns.some((pattern) => { + const bypass = bypassPatterns.some((pattern) => { const path = relativePath(from, templateItemPath) const cleanPattern = pattern.replace(/^\.\//, '') @@ -62,7 +62,7 @@ export async function recursiveLiquidTemplateCopy(from: string, to: string, data if (await isDirectory(templateItemPath)) { await mkdir(outputPath) - } else if (templateItemPath.endsWith('.liquid') && !isIgnored) { + } else if (templateItemPath.endsWith('.liquid') && !bypass) { await mkdir(dirname(outputPath)) const content = await readFile(templateItemPath) const contentOutput = await renderLiquidTemplate(content, data) From 09ca5144576eb0bb43f7bda9465b0d8a0c5b0c59 Mon Sep 17 00:00:00 2001 From: Paulo Margarido <64600052+paulomarg@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:46:13 -0400 Subject: [PATCH 3/3] Ensure liquid bypass file is cleaned up in tests Co-authored-by: Julien Henrotte --- packages/app/src/cli/services/init/template/cleanup.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/app/src/cli/services/init/template/cleanup.test.ts b/packages/app/src/cli/services/init/template/cleanup.test.ts index 1d6a1c2cf7..51a4240c06 100644 --- a/packages/app/src/cli/services/init/template/cleanup.test.ts +++ b/packages/app/src/cli/services/init/template/cleanup.test.ts @@ -9,6 +9,7 @@ describe('cleanup', () => { await Promise.all([ // should keep these writeFile(joinPath(tmpDir, 'server.js'), 'console.log()'), + writeFile(joinPath(tmpDir, 'cli-liquid-bypass'), '*'), mkdir(joinPath(tmpDir, 'node_modules')), // should delete these @@ -40,6 +41,7 @@ describe('cleanup', () => { await expect(fileExists(joinPath(tmpDir, '.git'))).resolves.toBe(false) await expect(fileExists(joinPath(tmpDir, '.github'))).resolves.toBe(false) await expect(fileExists(joinPath(tmpDir, '.gitmodules'))).resolves.toBe(false) + await expect(fileExists(joinPath(tmpDir, '.cli-liquid-bypass'))).resolves.toBe(false) await expect(fileExists(joinPath(tmpDir, 'frontend', '.git'))).resolves.toBe(false) await expect(fileExists(joinPath(tmpDir, 'package.json.cli2'))).resolves.toBe(false) })