Add support for file globbing to fs:delete
Signed-off-by: Gavin Clarke <431018+gavinclarkeuk@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
Support file globbing in fs:delete
|
||||
@@ -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",
|
||||
|
||||
+15
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user