Add support for file globbing to fs:delete

Signed-off-by: Gavin Clarke <431018+gavinclarkeuk@users.noreply.github.com>
This commit is contained in:
Gavin Clarke
2025-02-09 16:45:44 +00:00
committed by GitHub
parent edfd0d2951
commit 3d6ef79fb6
6 changed files with 66 additions and 7 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Support file globbing in fs:delete
+1
View File
@@ -93,6 +93,7 @@
"concat-stream": "^2.0.0",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"fast-glob": "^3.3.3",
"fs-extra": "^11.2.0",
"globby": "^11.0.0",
"isbinaryfile": "^5.0.0",
@@ -33,4 +33,19 @@ export const examples: TemplateExample[] = [
],
}),
},
{
description: 'Delete files with wildcard',
example: yaml.stringify({
steps: [
{
action: 'fs:delete',
id: 'deleteFiles',
name: 'Delete files',
input: {
files: ['*.txt'],
},
},
],
}),
},
];
@@ -95,6 +95,15 @@ describe('fs:delete', () => {
).rejects.toThrow(
/Relative path is not allowed to refer to a directory outside its parent/,
);
await expect(
action.handler({
...mockContext,
input: { files: ['../../../**/index.js'] },
}),
).rejects.toThrow(
/Relative path is not allowed to refer to a directory outside its parent/,
);
});
it('should call fs.rm with the correct values', async () => {
@@ -114,4 +123,25 @@ describe('fs:delete', () => {
expect(fileExists).toBe(false);
});
});
it('should handle wildcards', async () => {
const files = ['unit-test-a.js', 'unit-test-b.js'];
files.forEach(file => {
const filePath = resolvePath(workspacePath, file);
const fileExists = fs.existsSync(filePath);
expect(fileExists).toBe(true);
});
await action.handler({
...mockContext,
input: { files: ['unit-*.js'] },
});
files.forEach(file => {
const filePath = resolvePath(workspacePath, file);
const fileExists = fs.existsSync(filePath);
expect(fileExists).toBe(false);
});
});
});
@@ -18,6 +18,7 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
import { InputError } from '@backstage/errors';
import { resolveSafeChildPath } from '@backstage/backend-plugin-api';
import fs from 'fs-extra';
import fg from 'fast-glob';
import { examples } from './delete.examples';
/**
@@ -52,14 +53,20 @@ export const createFilesystemDeleteAction = () => {
}
for (const file of ctx.input.files) {
const filepath = resolveSafeChildPath(ctx.workspacePath, file);
const safeFilepath = resolveSafeChildPath(ctx.workspacePath, file);
const resolvedPaths = await fg(safeFilepath, {
cwd: ctx.workspacePath,
absolute: true,
});
try {
await fs.remove(filepath);
ctx.logger.info(`File ${filepath} deleted successfully`);
} catch (err) {
ctx.logger.error(`Failed to delete file ${filepath}:`, err);
throw err;
for (const filepath of resolvedPaths) {
try {
await fs.remove(filepath);
ctx.logger.info(`File ${filepath} deleted successfully`);
} catch (err) {
ctx.logger.error(`Failed to delete file ${filepath}:`, err);
throw err;
}
}
}
},
+1
View File
@@ -7753,6 +7753,7 @@ __metadata:
esbuild: ^0.24.0
express: ^4.17.1
express-promise-router: ^4.1.0
fast-glob: ^3.3.3
fs-extra: ^11.2.0
globby: ^11.0.0
isbinaryfile: ^5.0.0