Skip to content

Commit

Permalink
Merge cd2fbfe into 4a16b09
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason3S authored Sep 1, 2023
2 parents 4a16b09 + cd2fbfe commit b1a49fd
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 13 deletions.
11 changes: 8 additions & 3 deletions packages/cspell-tools/src/app.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ import { createTestHelper } from './test/TestHelper.js';

vi.mock('./gzip/compressFiles.js', () => ({
compressFile: vi.fn().mockImplementation((name: string) => Promise.resolve(name + '.gz')),
OSFlags: { Unix: 3 },
}));

const OSFlags = {
Unix: 3,
};

const mockedCompressFile = vi.mocked(compressFile);

const testHelper = createTestHelper(import.meta.url);
Expand Down Expand Up @@ -224,9 +229,9 @@ describe('Validate the application', () => {
const args = argv('gzip', '*.md', 'package.json');

await expect(app.run(commander, args)).resolves.toBeUndefined();
expect(mockedCompressFile).toHaveBeenCalledWith('README.md');
expect(mockedCompressFile).toHaveBeenCalledWith('CHANGELOG.md');
expect(mockedCompressFile).toHaveBeenCalledWith('package.json');
expect(mockedCompressFile).toHaveBeenCalledWith('README.md', OSFlags.Unix);
expect(mockedCompressFile).toHaveBeenCalledWith('CHANGELOG.md', OSFlags.Unix);
expect(mockedCompressFile).toHaveBeenCalledWith('package.json', OSFlags.Unix);
});

test('app shasum', async () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/cspell-tools/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { processCompileAction } from './compile.js';
import * as compiler from './compiler/index.js';
import { logWithTimestamp } from './compiler/logWithTimestamp.js';
import type { FeatureFlags } from './FeatureFlags/index.js';
import { gzip } from './gzip/index.js';
import { gzip, OSFlags } from './gzip/index.js';
import { reportCheckChecksumFile, reportChecksumForFiles, updateChecksumForFiles } from './shasum/shasum.js';
import { toError } from './util/errors.js';

Expand Down Expand Up @@ -65,7 +65,7 @@ interface ShasumOptions {
export async function run(program: program.Command, argv: string[], flags?: FeatureFlags): Promise<void> {
async function handleGzip(files: string[]): Promise<void> {
try {
await gzip(files);
await gzip(files, OSFlags.Unix);
} catch (error) {
const err = toError(error);
program.error(err.message);
Expand Down
28 changes: 27 additions & 1 deletion packages/cspell-tools/src/gzip/compressFiles.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { gzipSync } from 'node:zlib';

import { describe, expect, test, vi } from 'vitest';

import { compressFile } from './compressFiles.js';
import { compress, compressFile, decompress, OSFlags } from './compressFiles.js';

const content = `
Have a nice day.
Expand All @@ -23,4 +23,30 @@ describe('compressFiles', () => {
expect(mockReadFile).toHaveBeenLastCalledWith('README.md');
expect(mockWriteFile).toHaveBeenLastCalledWith('README.md.gz', gzipSync(content));
});

test('compress/decompress string', async () => {
const gzBufA = await compress(content);
const gzBufB = await compress(content, OSFlags.NTFS);
const gzBufC = await compress(content, OSFlags.Unix);

expect(gzBufB).not.toEqual(gzBufC);

const strA = await decompress(gzBufA, 'utf8');
const strB = await decompress(gzBufB, 'utf8');
const strC = await decompress(gzBufC, 'utf8');

expect(strA).toEqual(content);
expect(strB).toEqual(content);
expect(strC).toEqual(content);

const bufA = await decompress(gzBufA);
const bufB = await decompress(gzBufB);
const bufC = await decompress(gzBufC);

const contentBuf = Buffer.from(content);

expect(bufA).toEqual(contentBuf);
expect(bufB).toEqual(contentBuf);
expect(bufC).toEqual(contentBuf);
});
});
35 changes: 31 additions & 4 deletions packages/cspell-tools/src/gzip/compressFiles.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,43 @@
import { readFile, writeFile } from 'node:fs/promises';
import { promisify } from 'node:util';
import { gzip as gz } from 'node:zlib';
import { gunzip as gunzipCB, gzip as gz } from 'node:zlib';

const gzip = promisify(gz);
const gunzip = promisify(gunzipCB);

export async function compressFile(file: string): Promise<string> {
export enum OSFlags {
FAT = 0,
Unix = 3,
HPFS = 6, // cspell:ignore hpfs
MACOS = 7,
NTFS = 11,
}

// https://docs.fileformat.com/compression/gz/#:~:text=A%20GZ%20file%20is%20a,compression%20formats%20on%20UNIX%20systems.

const OSSystemIDOffset = 9;

export async function compressFile(file: string, os?: OSFlags): Promise<string> {
if (file.endsWith('.gz')) return file;

const targetFile = file + '.gz';

const buf = await readFile(file);
const zBuf = await gzip(buf);
const zBuf = await compress(await readFile(file), os);
await writeFile(targetFile, zBuf);
return targetFile;
}

export async function compress(buf: string | Uint8Array | Buffer, os?: OSFlags): Promise<Uint8Array> {
const zBuf = await gzip(buf);
const osFlag = os ?? zBuf[OSSystemIDOffset];
zBuf[OSSystemIDOffset] = osFlag;
return zBuf;
}
export async function decompress(buf: Uint8Array | Buffer, encoding?: undefined): Promise<Uint8Array>;
export async function decompress(buf: Uint8Array | Buffer, encoding: 'utf8'): Promise<string>;
export async function decompress(buf: Uint8Array | Buffer, encoding: 'utf8' | undefined): Promise<string | Uint8Array>;
export async function decompress(buf: Uint8Array | Buffer, encoding?: 'utf8'): Promise<string | Uint8Array> {
const dBuf = gunzip(buf);
if (!encoding) return dBuf;
return (await dBuf).toString(encoding);
}
5 changes: 3 additions & 2 deletions packages/cspell-tools/src/gzip/gzip.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { globP } from '../util/globP.js';
import type { OSFlags } from './compressFiles.js';
import { compressFile } from './compressFiles.js';

// cspell:ignore nodir

export async function gzip(globs: string[]): Promise<void> {
export async function gzip(globs: string[], os?: OSFlags): Promise<void> {
const files = await globP(globs, { nodir: true });
for (const fileName of files) {
await compressFile(fileName);
await compressFile(fileName, os);
}
}
2 changes: 1 addition & 1 deletion packages/cspell-tools/src/gzip/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { compressFile } from './compressFiles.js';
export { compressFile, OSFlags } from './compressFiles.js';
export { gzip } from './gzip.js';

0 comments on commit b1a49fd

Please sign in to comment.