Merge pull request #12511 from backstage/blam/symlinks-in-scaffolder
Treat Symlink files as binaries
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Don't resolve symlinks, treat them as binary files and copy them as-is
|
||||
@@ -97,6 +97,52 @@ describe('serializeDirectoryContents', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should ignore symlinked files', async () => {
|
||||
mockFs({
|
||||
root: {
|
||||
'a.txt': 'some text',
|
||||
sym: mockFs.symlink({
|
||||
path: './a.txt',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
await expect(serializeDirectoryContents('root')).resolves.toEqual([
|
||||
{
|
||||
path: 'a.txt',
|
||||
executable: false,
|
||||
content: Buffer.from('some text', 'utf8'),
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should ignore symlinked folder files', async () => {
|
||||
mockFs({
|
||||
root: {
|
||||
'a.txt': 'some text',
|
||||
linkme: {
|
||||
'b.txt': 'lols',
|
||||
},
|
||||
sym: mockFs.symlink({
|
||||
path: './linkme',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
await expect(serializeDirectoryContents('root')).resolves.toEqual([
|
||||
{
|
||||
path: 'a.txt',
|
||||
executable: false,
|
||||
content: Buffer.from('some text', 'utf8'),
|
||||
},
|
||||
{
|
||||
path: 'linkme/b.txt',
|
||||
executable: false,
|
||||
content: Buffer.from('lols', 'utf8'),
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should ignore gitignored files', async () => {
|
||||
mockFs({
|
||||
root: {
|
||||
|
||||
@@ -186,6 +186,10 @@ describe('fetch:template', () => {
|
||||
},
|
||||
'.${{ values.name }}': '${{ values.itemList | dump }}',
|
||||
'a-binary-file.png': aBinaryFile,
|
||||
symlink: mockFs.symlink({
|
||||
path: 'a-binary-file.png',
|
||||
}),
|
||||
|
||||
'{% if values.showDummyFile %}dummy-file.txt{% else %}{% endif %}':
|
||||
'dummy file',
|
||||
'${{ "dummy-file2.txt" if values.showDummyFile else "" }}':
|
||||
@@ -265,6 +269,17 @@ describe('fetch:template', () => {
|
||||
.then(fObj => fObj.mode),
|
||||
).resolves.toEqual(parseInt('100755', 8));
|
||||
});
|
||||
it('copies file symlinks as-is without processing them', async () => {
|
||||
await expect(
|
||||
fs
|
||||
.lstat(`${workspacePath}/target/symlink`)
|
||||
.then(i => i.isSymbolicLink()),
|
||||
).resolves.toBe(true);
|
||||
|
||||
await expect(
|
||||
fs.realpath(`${workspacePath}/target/symlink`),
|
||||
).resolves.toBe(`${workspacePath}/target/a-binary-file.png`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('copyWithoutRender', () => {
|
||||
|
||||
@@ -229,10 +229,11 @@ export function createFetchTemplateAction(options: {
|
||||
await fs.ensureDir(outputPath);
|
||||
} else {
|
||||
const inputFilePath = resolveSafeChildPath(templateDir, location);
|
||||
const stats = await fs.promises.lstat(inputFilePath);
|
||||
|
||||
if (await isBinaryFile(inputFilePath)) {
|
||||
if (stats.isSymbolicLink() || (await isBinaryFile(inputFilePath))) {
|
||||
ctx.logger.info(
|
||||
`Copying binary file ${location} to template output path.`,
|
||||
`Copying file binary or symbolic link at ${location}, to template output path.`,
|
||||
);
|
||||
await fs.copy(inputFilePath, outputPath);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user