Skip to content

Commit

Permalink
feat(mode): support overwriteMode (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackHole1 committed Nov 7, 2023
1 parent 5208999 commit f28d4f1
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ pnpm add @oomol-lab/sparse-file
* `filepath`: string - Sparse file paths to create/resize
* `size`: number - Sparse file size
* `options?.safe`: boolean - Safe mode, default: true
* `options?.mode`: number - File mode, default: 0o644
* `options?.mode`: number - File mode. By default, the mode is only set when creating a file, unless overwriteMode is specified. default: 0o644
* `options?.overwriteMode`: boolean - Overwrite mode. When the overwrite mode is allowed, the mode will be set even if the file exists. default: false

In safe mode, an error will occur if the size is less than 0 or greater than `Number.MAX_SAFE_INTEGER`. Additionally, it will be rejected if the passed size is larger than the current file size.

Expand Down
77 changes: 71 additions & 6 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,79 @@ describe("create sparse without safe mode", () => {
});
});

it.concurrent<TestContext>("create sparse with custom mode", async (ctx) => {
await createSparse(ctx.file, 1, {
mode: 0o600,
describe("custom mode", () => {
it.concurrent<TestContext>("create sparse with custom mode", async (ctx) => {
await createSparse(ctx.file, 1, {
mode: 0o600,
});

const stat = await fs.stat(ctx.file);

expect(stat.mode & 0o777).eq(0o600);
});

it.concurrent<TestContext>("should overwrite mode", async (ctx) => {
{
const fh = await fs.open(ctx.file, "w", 0o644);
await fh.writeFile(Buffer.alloc(1));
await fh.sync();
await fh.close();
}

await createSparse(ctx.file, 10, {
mode: 0o600,
overwriteMode: true,
});
const stat = await fs.stat(ctx.file);
expect(stat.mode & 0o777).eq(0o600);
});

it.concurrent<TestContext>("should overwrite mode when size same", async (ctx) => {
{
const fh = await fs.open(ctx.file, "w", 0o644);
await fh.writeFile(Buffer.alloc(1));
await fh.sync();
await fh.close();
}

await createSparse(ctx.file, 1, {
mode: 0o600,
overwriteMode: true,
});
const stat = await fs.stat(ctx.file);
expect(stat.mode & 0o777).eq(0o600);
});

const stat = await fs.stat(ctx.file);
it.concurrent<TestContext>("should maintain the original mode", async (ctx) => {
{
const fh = await fs.open(ctx.file, "w", 0o644);
await fh.writeFile(Buffer.alloc(1));
await fh.sync();
await fh.close();
}

await createSparse(ctx.file, 10, {
mode: 0o600,
overwriteMode: true,
});
const stat = await fs.stat(ctx.file);
expect(stat.mode & 0o777).eq(0o600);
});

expect(stat.mode & 0o777).eq(0o600);
it.concurrent<TestContext>("should overwrite mode when use default mode", async (ctx) => {
{
const fh = await fs.open(ctx.file, "w", 0o600);
await fh.writeFile(Buffer.alloc(1));
await fh.sync();
await fh.close();
}

await createSparse(ctx.file, 1, {
overwriteMode: true,
});
const stat = await fs.stat(ctx.file);
expect(stat.mode & 0o777).eq(0o644);
});
});

describe.concurrent("physical file size", () => {
Expand All @@ -138,7 +203,7 @@ describe.concurrent("physical file size", () => {
expect(await physicalFileSize(ctx.file)).eq(0);
});

it<TestContext>("should return 0 when file is empty sparsefile", async (ctx) => {
it<TestContext>("should return actual size when file not is empty sparsefile", async (ctx) => {
const fh = await fs.open(ctx.file, "w");
const { blksize } = await fh.stat();
await fh.write(Buffer.alloc(1));
Expand Down
15 changes: 14 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ export interface SparseOptions {
*/
safe?: boolean;
/**
* By default, the mode is only set when creating a file, unless overwriteMode is specified.
* @default 0o644
*/
mode?: number;
/**
* When the overwrite mode is allowed, the mode will be set even if the file exists.
* @default false
*/
overwriteMode?: boolean;
}

export const createSparse = async (filepath: string, size: number, options?: SparseOptions): Promise<void> => {
const fh = await open(filepath, options?.mode || 0o644);
const mode = options?.mode || 0o644;
const fh = await open(filepath, mode);

const curState = await fs.stat(filepath);
if (options?.safe !== false) {
Expand All @@ -33,6 +40,9 @@ export const createSparse = async (filepath: string, size: number, options?: Spa
}

if (curState.size === size) {
if (options?.overwriteMode) {
await fh.chmod(mode);
}
await fh.close();
return;
}
Expand All @@ -45,6 +55,9 @@ export const createSparse = async (filepath: string, size: number, options?: Spa
}

await fh.truncate(size);
if (options?.overwriteMode) {
await fh.chmod(mode);
}
await fh.sync();
await fh.close();
};
Expand Down

0 comments on commit f28d4f1

Please sign in to comment.