Skip to content

Commit

Permalink
chore: move filesystem operations to new file (#1482)
Browse files Browse the repository at this point in the history
## Description

This PR moves a helper function to a dedicated file (filename open to
discussion). This change was planned as part of #1402, we can bring it
in here to reduce the amount of changes we consider at any given time.

## Related Issue

Relates to #1397

## Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Other (security config, docs update, etc)

## Checklist before merging
- [x] Unit,
[Journey](https://github.com/defenseunicorns/pepr/tree/main/journey),
[E2E Tests](https://github.com/defenseunicorns/pepr-excellent-examples),
[docs](https://github.com/defenseunicorns/pepr/tree/main/docs),
[adr](https://github.com/defenseunicorns/pepr/tree/main/adr) added or
updated as needed
- [x] [Contributor Guide
Steps](https://docs.pepr.dev/main/contribute/#submitting-a-pull-request)
followed
  • Loading branch information
samayer12 authored Nov 22, 2024
1 parent adf7c37 commit a936a1c
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 65 deletions.
3 changes: 2 additions & 1 deletion src/cli/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { dependencies, version } from "./init/templates";
import { RootCmd } from "./root";
import { peprFormat } from "./format";
import { Option } from "commander";
import { createDirectoryIfNotExists, validateCapabilityNames, parseTimeout } from "../lib/helpers";
import { validateCapabilityNames, parseTimeout } from "../lib/helpers";
import { sanitizeResourceName } from "../sdk/sdk";
import { determineRbacMode } from "./build.helpers";
import { createDirectoryIfNotExists } from "../lib/filesystemService";
const peprTS = "pepr.ts";
let outputDir: string = "dist";
export type Reloader = (opts: BuildResult<BuildOptions>) => void | Promise<void>;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/assets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { deploy } from "./deploy";
import { loadCapabilities } from "./loader";
import { allYaml, zarfYaml, overridesFile, zarfYamlChart } from "./yaml";
import { namespaceComplianceValidator, replaceString } from "../helpers";
import { createDirectoryIfNotExists, dedent } from "../helpers";
import { dedent } from "../helpers";
import { resolve } from "path";
import {
chartYaml,
Expand All @@ -27,6 +27,7 @@ import { apiTokenSecret, service, tlsSecret, watcherService } from "./networking
import { watcher, moduleSecret } from "./pods";

import { clusterRoleBinding, serviceAccount, storeRole, storeRoleBinding } from "./rbac";
import { createDirectoryIfNotExists } from "../filesystemService";
export class Assets {
readonly name: string;
readonly tls: TLSOut;
Expand Down
54 changes: 54 additions & 0 deletions src/lib/filesystemService.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors

import { describe, jest, expect, it } from "@jest/globals";
import { createDirectoryIfNotExists } from "./filesystemService";
import { promises as fs } from "fs";

jest.mock("fs", () => {
return {
promises: {
access: jest.fn(),
mkdir: jest.fn(),
},
};
});

describe("createDirectoryIfNotExists function", () => {
it("should create a directory if it doesn't exist", async () => {
(fs.access as jest.Mock).mockRejectedValue({ code: "ENOENT" } as never);
(fs.mkdir as jest.Mock).mockResolvedValue(undefined as never);

const directoryPath = "/pepr/pepr-test-module/asdf";

await createDirectoryIfNotExists(directoryPath);

expect(fs.access).toHaveBeenCalledWith(directoryPath);
expect(fs.mkdir).toHaveBeenCalledWith(directoryPath, { recursive: true });
});

it("should not create a directory if it already exists", async () => {
jest.resetAllMocks();
(fs.access as jest.Mock).mockResolvedValue(undefined as never);

const directoryPath = "/pepr/pepr-test-module/asdf";

await createDirectoryIfNotExists(directoryPath);

expect(fs.access).toHaveBeenCalledWith(directoryPath);
expect(fs.mkdir).not.toHaveBeenCalled();
});

it("should throw an error for other fs.access errors", async () => {
jest.resetAllMocks();
(fs.access as jest.Mock).mockRejectedValue({ code: "ERROR" } as never);

const directoryPath = "/pepr/pepr-test-module/asdf";

try {
await createDirectoryIfNotExists(directoryPath);
} catch (error) {
expect(error.code).toEqual("ERROR");
}
});
});
16 changes: 16 additions & 0 deletions src/lib/filesystemService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors

import { promises } from "fs";

export async function createDirectoryIfNotExists(path: string) {
try {
await promises.access(path);
} catch (error) {
if (error.code === "ENOENT") {
await promises.mkdir(path, { recursive: true });
} else {
throw error;
}
}
}
50 changes: 0 additions & 50 deletions src/lib/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Event } from "./enums";
import {
addVerbIfNotExists,
bindingAndCapabilityNSConflict,
createDirectoryIfNotExists,
createRBACMap,
filterNoMatchReason,
dedent,
Expand All @@ -26,7 +25,6 @@ import {
import { sanitizeResourceName } from "../sdk/sdk";
import * as fc from "fast-check";
import { expect, describe, test, jest, beforeEach, afterEach } from "@jest/globals";
import { promises as fs } from "fs";
import { SpiedFunction } from "jest-mock";
import { KubernetesObject, kind } from "kubernetes-fluent-client";

Expand All @@ -39,15 +37,6 @@ jest.mock("kubernetes-fluent-client", () => {
};
});

jest.mock("fs", () => {
return {
promises: {
access: jest.fn(),
mkdir: jest.fn(),
},
};
});

const mockCapabilities: CapabilityExport[] = JSON.parse(`[
{
"name": "hello-pepr",
Expand Down Expand Up @@ -371,45 +360,6 @@ describe("addVerbIfNotExists", () => {
});
});

describe("createDirectoryIfNotExists function", () => {
test("should create a directory if it doesn't exist", async () => {
(fs.access as jest.Mock).mockRejectedValue({ code: "ENOENT" } as never);
(fs.mkdir as jest.Mock).mockResolvedValue(undefined as never);

const directoryPath = "/pepr/pepr-test-module/asdf";

await createDirectoryIfNotExists(directoryPath);

expect(fs.access).toHaveBeenCalledWith(directoryPath);
expect(fs.mkdir).toHaveBeenCalledWith(directoryPath, { recursive: true });
});

test("should not create a directory if it already exists", async () => {
jest.resetAllMocks();
(fs.access as jest.Mock).mockResolvedValue(undefined as never);

const directoryPath = "/pepr/pepr-test-module/asdf";

await createDirectoryIfNotExists(directoryPath);

expect(fs.access).toHaveBeenCalledWith(directoryPath);
expect(fs.mkdir).not.toHaveBeenCalled();
});

test("should throw an error for other fs.access errors", async () => {
jest.resetAllMocks();
(fs.access as jest.Mock).mockRejectedValue({ code: "ERROR" } as never);

const directoryPath = "/pepr/pepr-test-module/asdf";

try {
await createDirectoryIfNotExists(directoryPath);
} catch (error) {
expect(error.code).toEqual("ERROR");
}
});
});

describe("hasAnyOverlap", () => {
test("returns true for overlapping arrays", () => {
expect(hasAnyOverlap([1, 2, 3], [3, 4, 5])).toBe(true);
Expand Down
13 changes: 0 additions & 13 deletions src/lib/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors

import { promises as fs } from "fs";
import { KubernetesObject } from "kubernetes-fluent-client";
import Log from "./logger";
import { Binding, CapabilityExport } from "./types";
Expand Down Expand Up @@ -191,18 +190,6 @@ export function createRBACMap(capabilities: CapabilityExport[]): RBACMap {
}, {});
}

export async function createDirectoryIfNotExists(path: string) {
try {
await fs.access(path);
} catch (error) {
if (error.code === "ENOENT") {
await fs.mkdir(path, { recursive: true });
} else {
throw error;
}
}
}

export function hasEveryOverlap<T>(array1: T[], array2: T[]): boolean {
if (!Array.isArray(array1) || !Array.isArray(array2)) {
return false;
Expand Down

0 comments on commit a936a1c

Please sign in to comment.