Skip to content

Commit 53ba833

Browse files
committed
chore: move deployer logic into Deployer class
1 parent a2c54e7 commit 53ba833

3 files changed

Lines changed: 144 additions & 138 deletions

File tree

packages/cli/src/commands/deploy.ts

Lines changed: 3 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,16 @@
22
import { Command, Program, BaseCommandOptions } from "./types";
33
import { createLogger } from "./utils/createLogger";
44
import {
5-
DeployPackage,
65
intlMsg,
76
parseManifestFileOption,
8-
DeployJob,
9-
DeployStep,
107
parseLogFileOption,
118
Deployer,
129
defaultDeployManifest,
1310
} from "../lib";
1411

15-
import { DeployManifest } from "@polywrap/polywrap-manifest-types-js";
1612
import fs from "fs";
17-
import nodePath from "path";
13+
import path from "path";
1814
import yaml from "yaml";
19-
import { validate } from "jsonschema";
2015

2116
const defaultManifestStr = defaultDeployManifest.join(" | ");
2217
const pathStr = intlMsg.commands_deploy_options_o_path();
@@ -26,9 +21,6 @@ export interface DeployCommandOptions extends BaseCommandOptions {
2621
outputFile: string | false;
2722
}
2823

29-
type ManifestJob = DeployManifest["jobs"][number];
30-
type ManifestStep = ManifestJob["steps"][number];
31-
3224
export const deploy: Command = {
3325
setup: (program: Program) => {
3426
program
@@ -71,69 +63,10 @@ async function run(options: Required<DeployCommandOptions>): Promise<void> {
7163
const logger = createLogger({ verbose, quiet, logFile });
7264

7365
const deployer = await Deployer.create(manifestFile, logger);
74-
75-
const allStepsFromAllJobs = Object.entries(deployer.manifest.jobs).flatMap(
76-
([jobName, job]) => {
77-
return job.steps.map((step) => ({
78-
jobName,
79-
...step,
80-
}));
81-
}
82-
);
83-
84-
const packageNames = [
85-
...new Set(allStepsFromAllJobs.map((step) => step.package)),
86-
];
87-
88-
sanitizePackages(packageNames);
89-
90-
await deployer.cacheDeployModules(packageNames);
91-
92-
const packageMapEntries = await Promise.all(
93-
packageNames.map(async (packageName) => {
94-
const deployerPackage = await deployer.getDeployModule(packageName);
95-
return [packageName, deployerPackage];
96-
})
97-
);
98-
99-
const packageMap = Object.fromEntries(packageMapEntries);
100-
101-
const stepToPackageMap: Record<
102-
string,
103-
DeployPackage & { jobName: string }
104-
> = {};
105-
106-
for (const step of allStepsFromAllJobs) {
107-
stepToPackageMap[step.name] = {
108-
...packageMap[step.package],
109-
jobName: step.jobName,
110-
};
111-
}
112-
113-
validateManifestWithExts(deployer.manifest, stepToPackageMap);
114-
115-
const jobs = Object.entries(deployer.manifest.jobs).map(([jobName, job]) => {
116-
const steps: DeployStep[] = job.steps.map((step) => {
117-
return new DeployStep({
118-
name: step.name,
119-
uriOrStepResult: step.uri,
120-
deployModule: stepToPackageMap[step.name].deployModule,
121-
config: step.config ?? {},
122-
});
123-
});
124-
125-
return new DeployJob({
126-
name: jobName,
127-
steps,
128-
config: job.config ?? {},
129-
logger,
130-
});
131-
});
132-
133-
const jobResults = await Promise.all(jobs.map((job) => job.run()));
66+
const jobResults = await deployer.run();
13467

13568
if (outputFile) {
136-
const outputFileExt = nodePath.extname(outputFile).substring(1);
69+
const outputFileExt = path.extname(outputFile).substring(1);
13770
if (!outputFileExt) throw new Error("Require output file extension");
13871
switch (outputFileExt) {
13972
case "yaml":
@@ -153,61 +86,3 @@ async function run(options: Required<DeployCommandOptions>): Promise<void> {
15386
}
15487
process.exit(0);
15588
}
156-
157-
function sanitizePackages(packages: string[]) {
158-
const unrecognizedPackages: string[] = [];
159-
160-
const availableDeployers = fs.readdirSync(
161-
nodePath.join(__dirname, "..", "lib", "defaults", "deploy-modules")
162-
);
163-
164-
packages.forEach((p) => {
165-
if (!availableDeployers.includes(p)) {
166-
unrecognizedPackages.push(p);
167-
}
168-
});
169-
170-
if (unrecognizedPackages.length) {
171-
throw new Error(
172-
`Unrecognized packages: ${unrecognizedPackages.join(", ")}`
173-
);
174-
}
175-
}
176-
177-
function validateManifestWithExts(
178-
deployManifest: DeployManifest,
179-
stepToPackageMap: Record<string, DeployPackage & { jobName: string }>
180-
) {
181-
const errors = Object.entries(stepToPackageMap).flatMap(
182-
([stepName, step]) => {
183-
const jobEntry = Object.entries(deployManifest.jobs).find(
184-
([jobName]) => jobName === step.jobName
185-
) as [string, ManifestJob];
186-
187-
const job = jobEntry[1];
188-
189-
const stepToValidate = job.steps.find(
190-
(s) => s.name === stepName
191-
) as ManifestStep;
192-
193-
return step.manifestExt
194-
? validate(
195-
{
196-
...job.config,
197-
...stepToValidate.config,
198-
},
199-
step.manifestExt
200-
).errors
201-
: [];
202-
}
203-
);
204-
205-
if (errors.length) {
206-
throw new Error(
207-
[
208-
`Validation errors encountered while sanitizing DeployManifest format ${deployManifest.format}`,
209-
...errors.map((error) => error.toString()),
210-
].join("\n")
211-
);
212-
}
213-
}

packages/cli/src/lib/deploy/Deployer.ts

Lines changed: 141 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,33 @@
11
/* eslint-disable @typescript-eslint/no-var-requires */
22

3-
import { DeployModule } from "./DeployModule";
4-
import { loadDeployManifest, loadDeployManifestExt } from "../project";
5-
import { CacheDirectory } from "../CacheDirectory";
6-
import { Logger } from "../logging";
3+
import {
4+
DeployStep,
5+
DeployModule,
6+
DeployPackage,
7+
DeployJob,
8+
DeployJobResult
9+
} from ".";
10+
import {
11+
loadDeployManifest,
12+
loadDeployManifestExt,
13+
CacheDirectory,
14+
Logger
15+
} from "..";
716

817
import { DeployManifest } from "@polywrap/polywrap-manifest-types-js";
9-
import { Schema as JsonSchema } from "jsonschema";
18+
import { Schema as JsonSchema, validate } from "jsonschema";
1019
import path from "path";
11-
import nodePath from "path";
20+
import fs from "fs";
1221

1322
interface DeployerConfig {
1423
cache: CacheDirectory;
1524
logger: Logger;
1625
defaultModulesCached: boolean;
1726
}
1827

28+
type DeployManifestJob = DeployManifest["jobs"][number];
29+
type DeployManifestStep = DeployManifestJob["steps"][number];
30+
1931
export class Deployer {
2032
public static cacheLayout = {
2133
root: "deploy/",
@@ -43,13 +55,95 @@ export class Deployer {
4355
): Promise<Deployer> {
4456
const deployManifest = await loadDeployManifest(manifest, logger);
4557
const cache = new CacheDirectory({
46-
rootDir: nodePath.dirname(manifest),
58+
rootDir: path.dirname(manifest),
4759
subDir: Deployer.cacheLayout.root,
4860
});
4961
return new Deployer(deployManifest, cache, logger);
5062
}
5163

52-
public async getDeployModule(
64+
public async run(): Promise<DeployJobResult[]> {
65+
const allStepsFromAllJobs = Object.entries(this.manifest.jobs).flatMap(
66+
([jobName, job]) => {
67+
return job.steps.map((step) => ({
68+
jobName,
69+
...step,
70+
}));
71+
}
72+
);
73+
74+
const packageNames = [
75+
...new Set(allStepsFromAllJobs.map((step) => step.package)),
76+
];
77+
78+
this._sanitizePackages(packageNames);
79+
80+
await this._cacheDeployModules(packageNames);
81+
82+
const packageMapEntries = await Promise.all(
83+
packageNames.map(async (packageName) => {
84+
const deployerPackage = await this._getDeployModule(packageName);
85+
return [packageName, deployerPackage];
86+
})
87+
);
88+
89+
const packageMap = Object.fromEntries(packageMapEntries);
90+
91+
const stepToPackageMap: Record<
92+
string,
93+
DeployPackage & { jobName: string }
94+
> = {};
95+
96+
for (const step of allStepsFromAllJobs) {
97+
stepToPackageMap[step.name] = {
98+
...packageMap[step.package],
99+
jobName: step.jobName,
100+
};
101+
}
102+
103+
this._validateManifestWithExts(this.manifest, stepToPackageMap);
104+
105+
const jobs = Object.entries(this.manifest.jobs).map(([jobName, job]) => {
106+
const steps: DeployStep[] = job.steps.map((step) => {
107+
return new DeployStep({
108+
name: step.name,
109+
uriOrStepResult: step.uri,
110+
deployModule: stepToPackageMap[step.name].deployModule,
111+
config: step.config ?? {},
112+
});
113+
});
114+
115+
return new DeployJob({
116+
name: jobName,
117+
steps,
118+
config: job.config ?? {},
119+
logger: this._config.logger,
120+
});
121+
});
122+
123+
return await Promise.all(jobs.map((job) => job.run()));
124+
}
125+
126+
private _sanitizePackages(packages: string[]) {
127+
const unrecognizedPackages: string[] = [];
128+
129+
const availableDeployers = fs.readdirSync(
130+
path.join(__dirname, "..", "defaults", "deploy-modules")
131+
);
132+
133+
packages.forEach((p) => {
134+
if (!availableDeployers.includes(p)) {
135+
unrecognizedPackages.push(p);
136+
}
137+
});
138+
139+
if (unrecognizedPackages.length) {
140+
throw new Error(
141+
`Unrecognized packages: ${unrecognizedPackages.join(", ")}`
142+
);
143+
}
144+
}
145+
146+
private async _getDeployModule(
53147
moduleName: string
54148
): Promise<{
55149
deployModule: DeployModule;
@@ -77,7 +171,7 @@ export class Deployer {
77171
};
78172
}
79173

80-
public async cacheDeployModules(modules: string[]): Promise<void> {
174+
private async _cacheDeployModules(modules: string[]): Promise<void> {
81175
if (this._config.defaultModulesCached) {
82176
return;
83177
}
@@ -94,4 +188,42 @@ export class Deployer {
94188

95189
this._config.defaultModulesCached = true;
96190
}
191+
192+
private _validateManifestWithExts(
193+
deployManifest: DeployManifest,
194+
stepToPackageMap: Record<string, DeployPackage & { jobName: string }>
195+
) {
196+
const errors = Object.entries(stepToPackageMap).flatMap(
197+
([stepName, step]) => {
198+
const jobEntry = Object.entries(deployManifest.jobs).find(
199+
([jobName]) => jobName === step.jobName
200+
) as [string, DeployManifestJob];
201+
202+
const job = jobEntry[1];
203+
204+
const stepToValidate = job.steps.find(
205+
(s) => s.name === stepName
206+
) as DeployManifestStep;
207+
208+
return step.manifestExt
209+
? validate(
210+
{
211+
...job.config,
212+
...stepToValidate.config,
213+
},
214+
step.manifestExt
215+
).errors
216+
: [];
217+
}
218+
);
219+
220+
if (errors.length) {
221+
throw new Error(
222+
[
223+
`Validation errors encountered while sanitizing DeployManifest format ${deployManifest.format}`,
224+
...errors.map((error) => error.toString()),
225+
].join("\n")
226+
);
227+
}
228+
}
97229
}

packages/cli/src/lib/project/PolywrapProject.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import fsExtra from "fs-extra";
2828
export interface PolywrapProjectConfig extends ProjectConfig {
2929
polywrapManifestPath: string;
3030
buildManifestPath?: string;
31-
deployManifestPath?: string;
3231
}
3332

3433
export interface BuildManifestConfig {

0 commit comments

Comments
 (0)