Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(CLI): Infra manifest support default modules #910

Merged
merged 3 commits into from
Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions packages/cli/src/__tests__/e2e/infra.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,68 @@ describe("e2e tests for infra command", () => {
]);
});

test("Should correctly fetch default & local module", async () => {
await runW3CLI(
["infra", "up"],
getTestCaseDir(4),
);

await waitForPorts([
{ port: 5001, expected: true },
{ port: 8546, expected: true },
]);

await runW3CLI(
["infra", "down"],
getTestCaseDir(4),
);
});

test("Should correctly open one process for default module because modules flag overwrites it", async () => {
await runW3CLI(
["infra", "up", "--modules=eth-ens-ipfs"],
getTestCaseDir(4),
);

await waitForPorts([
{ port: 5001, expected: true },
]);

await runW3CLI(
["infra", "down", "--modules=eth-ens-ipfs"],
getTestCaseDir(4),
);
});

test("Should throw because default module declared in manifest is not recognized", async () => {
const { stderr } = await runW3CLI(
["infra", "up", "--manifest=./web3api.infra.wrong.yaml"],
getTestCaseDir(4),
);

expect(stderr).toContain(
`Module random-module not found as default\nDefault Modules available: `
);
});

test("Should correctly fetch different local modules when they are declared as folder or file", async () => {
await runW3CLI(
["infra", "up"],
getTestCaseDir(4),
);

await waitForPorts([
{ port: 5001, expected: true },
{ port: 8546, expected: true },
{ port: 8547, expected: true },
]);

await runW3CLI(
["infra", "down"],
getTestCaseDir(4),
);
});

test("Tears down environment", async () => {
await runW3CLI(
["infra", "up"],
Expand Down
51 changes: 38 additions & 13 deletions packages/cli/src/lib/infra/Infra.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {

import { InfraManifest } from "@web3api/core-js";
import path from "path";
import fs, { readdirSync } from "fs";
import fs, { lstatSync, readdirSync } from "fs";
import YAML from "js-yaml";
import { copySync } from "fs-extra";

Expand Down Expand Up @@ -100,12 +100,10 @@ export class Infra {
> {
const modulesWithPaths = await this._fetchModules();

const s = await this._dockerCompose.commands.config({
return await this._dockerCompose.commands.config({
...this._defaultDockerOptions,
config: modulesWithPaths.map((m) => m.path),
});

return s;
}

public async getVars(): Promise<string[]> {
Expand Down Expand Up @@ -147,12 +145,20 @@ export class Infra {
infraManifest,
} = this._config;

const manifestModules = Object.entries(infraManifest?.modules ?? {}).map(
([name, value]) => ({
const manifestModules: NamedModule[] = Object.entries(
infraManifest?.modules ?? {}
).map(([name, value]) => {
if (value === "default") {
return {
name,
path: this._fetchPathForDefaultModule(name),
};
}
return {
name,
...value,
})
);
};
});

if (!modulesToUse || !modulesToUse.length) {
return manifestModules;
Expand Down Expand Up @@ -282,7 +288,7 @@ export class Infra {
return this._fetchedModulesData;
}

const modules = await this.getFilteredModules();
const modules = this.getFilteredModules();

if (!modules.length) {
throw new Error("No modules to fetch");
Expand Down Expand Up @@ -330,10 +336,12 @@ export class Infra {
const basePath = path.join(this.getCacheModulesPath(), "local");

for (const module of modules) {
const modulePath = path.join(basePath, module.name);

const isFile = lstatSync(module.path).isFile();
const modulePath = path.join(
basePath,
isFile ? module.path : module.name
);
copySync(module.path, modulePath);

const composePath = this.tryResolveComposeFile(
modulePath,
this._defaultModuleComposePaths
Expand All @@ -352,6 +360,21 @@ export class Infra {
return Object.prototype.hasOwnProperty.call(object, "path");
}

private _fetchPathForDefaultModule(module: string): string {
const defaultModules = readdirSync(this._config.defaultInfraModulesPath);
const defaultModulePath = defaultModules.find(
(defaultModules) => defaultModules === module
);
if (!defaultModulePath) {
throw new Error(
`Module ${module} not found as default\nDefault Modules available: ${defaultModules
.map((m) => `\n- ${m}`)
.join("")}`
);
}
return path.join(this._config.defaultInfraModulesPath, defaultModulePath);
}

private tryResolveComposeFile(
moduleDir: string,
pathsToTry: string[],
Expand All @@ -363,7 +386,9 @@ export class Infra {
);
}

const pathToTry = path.join(moduleDir, pathsToTry[0]);
const pathToTry = lstatSync(moduleDir).isFile()
? moduleDir
: path.join(moduleDir, pathsToTry[0]);

if (fs.existsSync(pathToTry)) {
return pathToTry;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable @typescript-eslint/naming-convention */
/* tslint:disable */
/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
* and run json-schema-to-typescript to regenerate this file.
*/

export type DefaultModule = "default";

export interface InfraManifest {
format: "0.0.1-prealpha.2";
dockerCompose?: string;
env?: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.*$".
*/
[k: string]: string | number;
};
modules: {
/**
* This interface was referenced by `undefined`'s JSON-Schema definition
* via the `patternProperty` "^.*$".
*/
[k: string]: RemoteModule | LocalModule | DefaultModule;
};
__type: "InfraManifest";
}
export interface RemoteModule {
package: string;
registry: string;
version: string;
dockerComposePath?: string;
}
export interface LocalModule {
path: string;
}
10 changes: 8 additions & 2 deletions packages/js/core/src/manifest/formats/web3api.infra/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,27 @@
import {
InfraManifest as InfraManifest0_0_1_prealpha_1
} from "./0.0.1-prealpha.1";
import {
InfraManifest as InfraManifest0_0_1_prealpha_2
} from "./0.0.1-prealpha.2";

export {
InfraManifest0_0_1_prealpha_1,
InfraManifest0_0_1_prealpha_2,
};

export enum InfraManifestFormats {
"0.0.1-prealpha.1" = "0.0.1-prealpha.1",
"0.0.1-prealpha.2" = "0.0.1-prealpha.2",
}

export type AnyInfraManifest =
| InfraManifest0_0_1_prealpha_1
| InfraManifest0_0_1_prealpha_2

export type InfraManifest = InfraManifest0_0_1_prealpha_1;
export type InfraManifest = InfraManifest0_0_1_prealpha_2;

export const latestInfraManifestFormat = InfraManifestFormats["0.0.1-prealpha.1"]
export const latestInfraManifestFormat = InfraManifestFormats["0.0.1-prealpha.2"]

export { migrateInfraManifest } from "./migrate";

Expand Down
13 changes: 12 additions & 1 deletion packages/js/core/src/manifest/formats/web3api.infra/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {
latestInfraManifestFormat
} from ".";

import {
migrate as migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_2
} from "./migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2";

import { Tracer } from "@web3api/tracing-js";

Expand All @@ -19,6 +22,7 @@ type Migrator = {
};

export const migrators: Migrator = {
"0.0.1-prealpha.1": migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_2,
};

export const migrateInfraManifest = Tracer.traceFunc(
Expand All @@ -34,6 +38,13 @@ export const migrateInfraManifest = Tracer.traceFunc(
throw new Error(`Unrecognized InfraManifestFormat "${manifest.format}"`);
}

throw new Error(`This should never happen, InfraManifest migrators is empty. from: ${from}, to: ${to}`);
const migrator = migrators[from];
if (!migrator) {
throw new Error(
`Migrator from InfraManifestFormat "${from}" to "${to}" is not available`
);
}

return migrator(manifest);
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable @typescript-eslint/naming-convention */

import { InfraManifest as OldManifest } from "../0.0.1-prealpha.1";
import { InfraManifest as NewManifest } from "../0.0.1-prealpha.2";

export function migrate(old: OldManifest): NewManifest {
return {
...old,
format: "0.0.1-prealpha.2",
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from ".";

import schema_0_0_1_prealpha_1 from "@web3api/manifest-schemas/formats/web3api.infra/0.0.1-prealpha.1.json";
import schema_0_0_1_prealpha_2 from "@web3api/manifest-schemas/formats/web3api.infra/0.0.1-prealpha.2.json";
import { Tracer } from "@web3api/tracing-js"

import {
Expand All @@ -25,6 +26,7 @@ type InfraManifestSchemas = {

const schemas: InfraManifestSchemas = {
"0.0.1-prealpha.1": schema_0_0_1_prealpha_1,
"0.0.1-prealpha.2": schema_0_0_1_prealpha_2,
};

const validator = new Validator();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"id": "InfraManifest",
"type": "object",
"additionalProperties": false,
"required": ["format", "modules"],
"properties": {
"format": {
"type": "string",
"const": "0.0.1-prealpha.2"
},
"dockerCompose": {
"type": "string"
},
"env": {
"patternProperties": {
"^.*$": {
"type": ["string", "number"]
}
},
"additionalProperties": false
},
"modules": {
"patternProperties": {
"^.*$": {
"oneOf": [
{"$ref": "#/definitions/remoteModule"},
{"$ref": "#/definitions/localModule"},
{"$ref": "#/definitions/defaultModule"}
]
}
}
}
},
"definitions": {
"remoteModule": {
"type": "object",
"additionalProperties": false,
"properties": {
"package": {
"type": "string"
},
"registry": {
"type": "string"
},
"version": {
"type": "string"
},
"dockerComposePath": {
"type": "string"
}
},
"required": ["package", "version", "registry"]
},
"localModule": {
"type": "object",
"additionalProperties": false,
"properties": {
"path": {
"type": "string"
}
},
"required": ["path"]
},
"defaultModule": {
"type": "string",
"const": "default"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: '3'
services:
mainnet-fork:
image: 'trufflesuite/ganache-cli:v6.12.2'
ports:
- '8546:8545'
command: -l 8000000 --deterministic --hostname=0.0.0.0 --chainId 1 --fork https://mainnet.infura.io/v3/d119148113c047ca90f0311ed729c466
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: '3'
services:
mainnet-fork:
image: 'trufflesuite/ganache-cli:v6.12.2'
ports:
- '8547:8545'
command: -l 8000000 --deterministic --hostname=0.0.0.0 --chainId 3 --fork https://ropsten.infura.io/v3/d119148113c047ca90f0311ed729c466
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
format: 0.0.1-prealpha.2
modules:
random-module: default
Loading