-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpush.ts
More file actions
131 lines (108 loc) · 3.89 KB
/
push.ts
File metadata and controls
131 lines (108 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import { Args, Flags } from "@oclif/core";
import BaseCommand from "@/lib/base-command";
import { formatCommandScope } from "@/lib/helpers/command";
import { KnockEnv } from "@/lib/helpers/const";
import { formatError, formatErrors, SourceError } from "@/lib/helpers/error";
import * as CustomFlags from "@/lib/helpers/flag";
import { merge } from "@/lib/helpers/object.isomorphic";
import { formatErrorRespMessage, isSuccessResp } from "@/lib/helpers/request";
import { indentString } from "@/lib/helpers/string";
import { spinner } from "@/lib/helpers/ux";
import * as Guide from "@/lib/marshal/guide";
import { WithAnnotation } from "@/lib/marshal/shared/types";
import GuideValidate from "./validate";
export default class GuidePush extends BaseCommand<typeof GuidePush> {
static summary = "Push one or more guides from a local file system to Knock.";
static flags = {
environment: Flags.string({
summary: "The environment to push the guide to. Defaults to development.",
default: KnockEnv.Development,
}),
branch: CustomFlags.branch,
all: Flags.boolean({
summary: "Whether to push all guides from the target directory.",
}),
"guides-dir": CustomFlags.dirPath({
summary: "The target directory path to find all guides to push.",
dependsOn: ["all"],
}),
commit: Flags.boolean({
summary: "Push and commit the guide(s) at the same time",
}),
"commit-message": Flags.string({
summary: "Use the given value as the commit message",
char: "m",
dependsOn: ["commit"],
}),
};
static args = {
guideKey: Args.string({
required: false,
}),
};
async run(): Promise<void> {
const { flags } = this.props;
// 1. First read all guide directories found for the given command.
const target = await Guide.ensureValidCommandTarget(
this.props,
this.runContext,
this.projectConfig,
);
const [guides, readErrors] = await Guide.readAllForCommandTarget(target, {
withExtractedFiles: true,
});
if (readErrors.length > 0) {
this.error(formatErrors(readErrors, { prependBy: "\n\n" }));
}
if (guides.length === 0) {
this.error(`No guide directories found in ${target.context.abspath}`);
}
// 2. Then validate them all ahead of pushing them.
spinner.start(`‣ Validating`);
const apiErrors = await GuideValidate.validateAll(
this.apiV1,
this.props as any, // Type assertion needed since validateAll expects GuideValidate props
guides,
);
if (apiErrors.length > 0) {
this.error(formatErrors(apiErrors, { prependBy: "\n\n" }));
}
spinner.stop();
// 3. Finally push up each guide, abort on the first error.
spinner.start(`‣ Pushing`);
for (const guide of guides) {
const props = merge(this.props, {
flags: { annotate: true },
});
// eslint-disable-next-line no-await-in-loop
const resp = await this.apiV1.upsertGuide<WithAnnotation>(props, {
...guide.content,
key: guide.key,
});
if (isSuccessResp(resp)) {
// Update the guide directory with the successfully pushed guide
// payload from the server.
// eslint-disable-next-line no-await-in-loop
await Guide.writeGuideDirFromData(guide, resp.data.guide!, {
withSchema: true,
});
continue;
}
const error = new SourceError(
formatErrorRespMessage(resp),
Guide.guideJsonPath(guide),
"ApiError",
);
this.error(formatError(error));
}
spinner.stop();
// 4. Display a success message.
const guideKeys = guides.map((g) => g.key);
const actioned = flags.commit ? "pushed and committed" : "pushed";
const scope = formatCommandScope(flags);
this.log(
`‣ Successfully ${actioned} ${guides.length} guide(s) to ${scope}:\n` +
indentString(guideKeys.join("\n"), 4),
);
}
}