Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/blockset-glob-project-path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@faustwp/cli": patch
---

fix[faustwp-cli]: resolve `faust blockset` globs against the build directory so blocks are discovered on Windows and under project paths containing glob characters
10 changes: 8 additions & 2 deletions packages/faustwp-cli/src/blockset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ export function parsePhpAssetFile(phpContent: string): PhpAsset {
* @returns {Promise<string[]>} - An array of paths to block.json files.
*/
export async function fetchBlockFiles(): Promise<string[]> {
return glob(`${FAUST_BUILD_DIR}/**/block.json`, {
// Search from `cwd` rather than interpolating the path into the pattern:
// a project path is data, and glob would read its `\` and `[]` as syntax.
return glob('**/block.json', {
cwd: FAUST_BUILD_DIR,
absolute: true,
ignore: IGNORE_NODE_MODULES,
});
}
Expand Down Expand Up @@ -128,7 +132,9 @@ export async function processBlockFiles(files: string[]): Promise<void> {
}

// Remove any other PHP files
const phpFiles = await glob(`${destDir}/**/*.php`, {
const phpFiles = await glob('**/*.php', {
cwd: destDir,
absolute: true,
ignore: IGNORE_NODE_MODULES,
});
await Promise.all(phpFiles.map((file) => fs.remove(file)));
Expand Down
65 changes: 65 additions & 0 deletions packages/faustwp-cli/tests/blockset/fetchBlockFiles.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import fs from 'fs-extra';
import os from 'os';
import path from 'path';

// A project path is data, not pattern syntax: `[1]` here stands in for any glob
// character a real checkout may contain, and for the `\` separators every
// Windows path is built from.
const PROJECT_DIR_NAME = 'my site[1]';

describe('blockset file discovery', () => {
let projectDir: string;
let cwdSpy: jest.SpyInstance<string, []>;

beforeEach(async () => {
const tmpDir = await fs.realpath(
await fs.mkdtemp(path.join(os.tmpdir(), 'faust-blockset-')),
);
projectDir = path.join(tmpDir, PROJECT_DIR_NAME);
await fs.ensureDir(projectDir);

cwdSpy = jest.spyOn(process, 'cwd').mockReturnValue(projectDir);
jest.resetModules();
});

afterEach(async () => {
const tmpDir = path.dirname(projectDir);
cwdSpy.mockRestore();
await fs.remove(tmpDir);
});

async function seedCompiledBlock(buildDir: string): Promise<string> {
const blockDir = path.join(buildDir, 'MyCustomBlock');
await fs.ensureDir(blockDir);
await fs.writeJson(path.join(blockDir, 'block.json'), {
name: 'faust/my-custom-block',
});
await fs.writeFile(path.join(blockDir, 'render.php'), '<?php\n');

return blockDir;
}

it('finds compiled block.json files when the project path contains glob syntax', async () => {
const { FAUST_BUILD_DIR, fetchBlockFiles } = await import(
'../../src/blockset'
);
const blockDir = await seedCompiledBlock(FAUST_BUILD_DIR);

await expect(fetchBlockFiles()).resolves.toEqual([
path.join(blockDir, 'block.json'),
]);
});

it('removes PHP files from processed blocks when the project path contains glob syntax', async () => {
const { BLOCKS_DIR, FAUST_BUILD_DIR, processBlockFiles } = await import(
'../../src/blockset'
);
const blockDir = await seedCompiledBlock(FAUST_BUILD_DIR);

await processBlockFiles([path.join(blockDir, 'block.json')]);

const destDir = path.join(BLOCKS_DIR, 'MyCustomBlock');
expect(await fs.pathExists(path.join(destDir, 'block.json'))).toBe(true);
expect(await fs.pathExists(path.join(destDir, 'render.php'))).toBe(false);
});
});