Merge pull request #6954 from nadworny/fix/azure_techdocs_archive_stripping

Disable default stripping of ZIP archive
This commit is contained in:
Fredrik Adelöw
2021-08-26 11:57:10 +02:00
committed by GitHub
5 changed files with 51 additions and 3 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': minor
---
The `ZipArchiveResponse` class now accepts an optional `stripFirstDirectory` parameter. Note that its default value is `false`, which leads to a breaking change in behaviour to previous versions of the class. If you use this class explicitly and want to retain the old behaviour, add a `true` parameter value to its constructor.
@@ -22,11 +22,15 @@ import { ZipArchiveResponse } from './ZipArchiveResponse';
const archiveData = fs.readFileSync(
resolvePath(__filename, '../../__fixtures__/mock-main.zip'),
);
const archiveDataWithExtraDir = fs.readFileSync(
resolvePath(__filename, '../../__fixtures__/mock-with-extra-root-dir.zip'),
);
describe('ZipArchiveResponse', () => {
beforeEach(() => {
mockFs({
'/test-archive.zip': archiveData,
'/test-archive-with-extra-root-dir.zip': archiveDataWithExtraDir,
'/tmp': mockFs.directory(),
});
});
@@ -58,6 +62,36 @@ describe('ZipArchiveResponse', () => {
]);
});
it('should read files and strip root dir if requested', async () => {
const stream = fs.createReadStream('/test-archive-with-extra-root-dir.zip');
const res = new ZipArchiveResponse(
stream,
'',
'/tmp',
'etag',
undefined,
true,
);
const files = await res.files();
expect(files).toEqual([
{
path: 'mkdocs.yml',
content: expect.any(Function),
},
{
path: 'docs/index.md',
content: expect.any(Function),
},
]);
const contents = await Promise.all(files.map(f => f.content()));
expect(contents.map(c => c.toString('utf8').trim())).toEqual([
'site_name: Test',
'# Test',
]);
});
it('should read files with filter', async () => {
const stream = fs.createReadStream('/test-archive.zip');
@@ -38,6 +38,7 @@ export class ZipArchiveResponse implements ReadTreeResponse {
private readonly workDir: string,
public readonly etag: string,
private readonly filter?: (path: string, info: { size: number }) => boolean,
private readonly stripFirstDirectory?: boolean,
) {
if (subPath) {
if (!subPath.endsWith('/')) {
@@ -67,7 +68,9 @@ export class ZipArchiveResponse implements ReadTreeResponse {
}
private shouldBeIncluded(entry: Entry): boolean {
const strippedPath = stripFirstDirectoryFromPath(entry.path);
const strippedPath = this.stripFirstDirectory
? stripFirstDirectoryFromPath(entry.path)
: entry.path;
if (this.subPath) {
if (!strippedPath.startsWith(this.subPath)) {
@@ -99,7 +102,11 @@ export class ZipArchiveResponse implements ReadTreeResponse {
if (this.shouldBeIncluded(entry)) {
files.push({
path: this.getInnerPath(stripFirstDirectoryFromPath(entry.path)),
path: this.getInnerPath(
this.stripFirstDirectory
? stripFirstDirectoryFromPath(entry.path)
: entry.path,
),
content: () => entry.buffer(),
});
} else {
@@ -148,7 +155,9 @@ export class ZipArchiveResponse implements ReadTreeResponse {
// as a zip can have files with directories without directory entries
if (entry.type === 'File' && this.shouldBeIncluded(entry)) {
const entryPath = this.getInnerPath(
stripFirstDirectoryFromPath(entry.path),
this.stripFirstDirectory
? stripFirstDirectoryFromPath(entry.path)
: entry.path,
);
const dirname = platformPath.dirname(entryPath);
if (dirname) {