codify-plugin-test 0.0.32 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin-process.d.ts +13 -0
- package/dist/plugin-process.js +112 -0
- package/dist/plugin-process.js.map +1 -0
- package/dist/plugin-tester.d.ts +4 -14
- package/dist/plugin-tester.js +103 -176
- package/dist/plugin-tester.js.map +1 -1
- package/package.json +3 -2
- package/src/plugin-process.ts +179 -0
- package/src/plugin-tester.ts +114 -253
- package/test/plugin-tester.test.ts +71 -67
- package/test/test-plugin.ts +10 -10
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ApplyRequestData, ImportRequestData, ImportResponseData, InitializeResponseData, PlanRequestData, PlanResponseData, ValidateRequestData, ValidateResponseData } from 'codify-schemas';
|
|
2
|
+
import { ChildProcess } from 'node:child_process';
|
|
3
|
+
export declare class PluginProcess {
|
|
4
|
+
childProcess: ChildProcess;
|
|
5
|
+
constructor(pluginPath: string);
|
|
6
|
+
initialize(): Promise<InitializeResponseData>;
|
|
7
|
+
validate(data: ValidateRequestData): Promise<ValidateResponseData>;
|
|
8
|
+
plan(data: PlanRequestData): Promise<PlanResponseData>;
|
|
9
|
+
apply(data: ApplyRequestData): Promise<void>;
|
|
10
|
+
import(data: ImportRequestData): Promise<ImportResponseData>;
|
|
11
|
+
kill(): void;
|
|
12
|
+
private handleSudoRequests;
|
|
13
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import Ajv from 'ajv';
|
|
2
|
+
import { IpcMessageSchema, MessageCmd, SpawnStatus, SudoRequestDataSchema } from 'codify-schemas';
|
|
3
|
+
import { nanoid } from 'nanoid';
|
|
4
|
+
import { fork, spawn } from 'node:child_process';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { CodifyTestUtils } from './test-utils.js';
|
|
7
|
+
const ajv = new Ajv.default({
|
|
8
|
+
strict: true
|
|
9
|
+
});
|
|
10
|
+
const ipcMessageValidator = ajv.compile(IpcMessageSchema);
|
|
11
|
+
const sudoRequestValidator = ajv.compile(SudoRequestDataSchema);
|
|
12
|
+
export class PluginProcess {
|
|
13
|
+
childProcess;
|
|
14
|
+
constructor(pluginPath) {
|
|
15
|
+
if (!path.isAbsolute(pluginPath)) {
|
|
16
|
+
throw new Error('A fully qualified path must be supplied to PluginTester');
|
|
17
|
+
}
|
|
18
|
+
this.childProcess = fork(pluginPath, [], {
|
|
19
|
+
env: { ...process.env },
|
|
20
|
+
execArgv: ['--import', 'tsx/esm'],
|
|
21
|
+
});
|
|
22
|
+
this.handleSudoRequests(this.childProcess);
|
|
23
|
+
}
|
|
24
|
+
async initialize() {
|
|
25
|
+
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
26
|
+
cmd: 'initialize',
|
|
27
|
+
data: {},
|
|
28
|
+
requestId: nanoid(6),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async validate(data) {
|
|
32
|
+
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
33
|
+
cmd: 'validate',
|
|
34
|
+
data,
|
|
35
|
+
requestId: nanoid(6),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async plan(data) {
|
|
39
|
+
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
40
|
+
cmd: 'plan',
|
|
41
|
+
data,
|
|
42
|
+
requestId: nanoid(6),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async apply(data) {
|
|
46
|
+
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
47
|
+
cmd: 'apply',
|
|
48
|
+
data,
|
|
49
|
+
requestId: nanoid(6),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
async import(data) {
|
|
53
|
+
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
54
|
+
cmd: 'import',
|
|
55
|
+
data,
|
|
56
|
+
requestId: nanoid(6),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
kill() {
|
|
60
|
+
this.childProcess.kill();
|
|
61
|
+
}
|
|
62
|
+
handleSudoRequests(process) {
|
|
63
|
+
process.on('message', async (message) => {
|
|
64
|
+
if (!ipcMessageValidator(message)) {
|
|
65
|
+
throw new Error(`Invalid message from plugin. ${JSON.stringify(message, null, 2)}`);
|
|
66
|
+
}
|
|
67
|
+
if (message.cmd === MessageCmd.SUDO_REQUEST) {
|
|
68
|
+
const { data, requestId } = message;
|
|
69
|
+
if (!sudoRequestValidator(data)) {
|
|
70
|
+
throw new Error(`Invalid sudo request from plugin. ${JSON.stringify(sudoRequestValidator.errors, null, 2)}`);
|
|
71
|
+
}
|
|
72
|
+
const { command, options } = data;
|
|
73
|
+
console.log(`Running command with sudo: 'sudo ${command}'`);
|
|
74
|
+
const result = await sudoSpawn(command, options);
|
|
75
|
+
process.send({
|
|
76
|
+
cmd: MessageCmd.SUDO_REQUEST + '_Response',
|
|
77
|
+
data: result,
|
|
78
|
+
requestId,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function sudoSpawn(cmd, opts) {
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
const output = [];
|
|
87
|
+
const _cmd = `sudo ${cmd}`;
|
|
88
|
+
const _process = spawn(`source ~/.zshrc; ${_cmd}`, [], {
|
|
89
|
+
...opts,
|
|
90
|
+
shell: 'zsh',
|
|
91
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
92
|
+
});
|
|
93
|
+
const { stderr, stdout } = _process;
|
|
94
|
+
stdout.setEncoding('utf8');
|
|
95
|
+
stderr.setEncoding('utf8');
|
|
96
|
+
stdout.on('data', (data) => {
|
|
97
|
+
output.push(data.toString());
|
|
98
|
+
});
|
|
99
|
+
stderr.on('data', (data) => {
|
|
100
|
+
output.push(data.toString());
|
|
101
|
+
});
|
|
102
|
+
stdout.pipe(process.stdout);
|
|
103
|
+
stderr.pipe(process.stderr);
|
|
104
|
+
_process.on('close', (code) => {
|
|
105
|
+
resolve({
|
|
106
|
+
data: output.join(''),
|
|
107
|
+
status: code === 0 ? SpawnStatus.SUCCESS : SpawnStatus.ERROR,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=plugin-process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-process.js","sourceRoot":"","sources":["../src/plugin-process.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin-tester.d.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ChildProcess } from 'node:child_process';
|
|
1
|
+
import { ImportResponseData, PlanResponseData, ResourceConfig } from 'codify-schemas';
|
|
3
2
|
export declare class PluginTester {
|
|
4
|
-
|
|
5
|
-
constructor(pluginPath: string);
|
|
6
|
-
fullTest(configs: ResourceConfig[], options?: {
|
|
3
|
+
static fullTest(pluginPath: string, configs: ResourceConfig[], options?: {
|
|
7
4
|
skipUninstall?: boolean;
|
|
8
5
|
validatePlan?: (plans: PlanResponseData[]) => Promise<void> | void;
|
|
9
6
|
validateApply?: (plans: PlanResponseData[]) => Promise<void> | void;
|
|
@@ -14,15 +11,8 @@ export declare class PluginTester {
|
|
|
14
11
|
validateModify?: (plans: PlanResponseData[]) => Promise<void> | void;
|
|
15
12
|
};
|
|
16
13
|
}): Promise<void>;
|
|
17
|
-
uninstall(configs: ResourceConfig[], options?: {
|
|
14
|
+
static uninstall(pluginPath: string, configs: ResourceConfig[], options?: {
|
|
18
15
|
validateDestroy?: (plans: PlanResponseData[]) => Promise<void> | void;
|
|
19
16
|
}): Promise<void>;
|
|
20
|
-
|
|
21
|
-
validate(data: ValidateRequestData): Promise<ValidateResponseData>;
|
|
22
|
-
plan(data: PlanRequestData): Promise<PlanResponseData>;
|
|
23
|
-
apply(data: ApplyRequestData): Promise<void>;
|
|
24
|
-
import(data: ImportRequestData): Promise<ImportResponseData>;
|
|
25
|
-
kill(): void;
|
|
26
|
-
private handleSudoRequests;
|
|
27
|
-
private addNamesToConfigs;
|
|
17
|
+
private static addNamesToConfigs;
|
|
28
18
|
}
|
package/dist/plugin-tester.js
CHANGED
|
@@ -1,86 +1,93 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { ResourceOperation, } from 'codify-schemas';
|
|
3
3
|
import unionBy from 'lodash.unionby';
|
|
4
|
-
import {
|
|
5
|
-
import { fork, spawn } from 'node:child_process';
|
|
6
|
-
import path from 'node:path';
|
|
7
|
-
import { CodifyTestUtils } from './test-utils.js';
|
|
8
|
-
const ajv = new Ajv.default({
|
|
9
|
-
strict: true
|
|
10
|
-
});
|
|
11
|
-
const ipcMessageValidator = ajv.compile(IpcMessageSchema);
|
|
12
|
-
const sudoRequestValidator = ajv.compile(SudoRequestDataSchema);
|
|
4
|
+
import { PluginProcess } from './plugin-process.js';
|
|
13
5
|
export class PluginTester {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
throw new Error('A fully qualified path must be supplied to PluginTester');
|
|
18
|
-
}
|
|
19
|
-
this.childProcess = fork(pluginPath, [], {
|
|
20
|
-
env: { ...process.env },
|
|
21
|
-
execArgv: ['--import', 'tsx/esm', '--inspect=9221'],
|
|
22
|
-
});
|
|
23
|
-
this.handleSudoRequests(this.childProcess);
|
|
24
|
-
}
|
|
25
|
-
async fullTest(configs, options) {
|
|
6
|
+
static async fullTest(pluginPath, configs, options) {
|
|
7
|
+
const ids = configs.map((c) => c.name ? `${c.type}.${c.name}` : c.type).join(', ');
|
|
8
|
+
console.info(chalk.cyan(`Starting full test of [ ${ids} ]...`));
|
|
26
9
|
const { skipUninstall = false, } = options ?? {};
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (options?.validatePlan) {
|
|
46
|
-
await options.validatePlan(plans);
|
|
47
|
-
}
|
|
48
|
-
for (const plan of plans) {
|
|
49
|
-
await this.apply({
|
|
50
|
-
planId: plan.planId
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
if (options?.validateApply) {
|
|
54
|
-
await options.validateApply(plans);
|
|
55
|
-
}
|
|
56
|
-
const importResults = [];
|
|
57
|
-
for (const config of configs) {
|
|
58
|
-
const importResult = await this.import({ config });
|
|
59
|
-
importResults.push(importResult);
|
|
60
|
-
}
|
|
61
|
-
if (options?.validateImport) {
|
|
62
|
-
await options.validateImport(importResults.map((r) => r.result[0]));
|
|
63
|
-
}
|
|
64
|
-
if (options?.testModify) {
|
|
65
|
-
const modifyPlans = [];
|
|
66
|
-
for (const config of options.testModify.modifiedConfigs) {
|
|
67
|
-
modifyPlans.push(await this.plan({
|
|
10
|
+
const plugin = new PluginProcess(pluginPath);
|
|
11
|
+
try {
|
|
12
|
+
console.info(chalk.cyan('Testing initialization...'));
|
|
13
|
+
const initializeResult = await plugin.initialize();
|
|
14
|
+
const unsupportedConfigs = configs.filter((c) => !initializeResult.resourceDefinitions.some((rd) => rd.type === c.type));
|
|
15
|
+
if (unsupportedConfigs.length > 0) {
|
|
16
|
+
throw new Error(`The plugin does not support the following configs supplied:\n ${JSON.stringify(unsupportedConfigs, null, 2)}\n Initialize result: ${JSON.stringify(initializeResult)}`);
|
|
17
|
+
}
|
|
18
|
+
console.info(chalk.cyan('Testing validate...'));
|
|
19
|
+
const validate = await plugin.validate({ configs });
|
|
20
|
+
const invalidConfigs = validate.resourceValidations.filter((v) => !v.isValid);
|
|
21
|
+
if (invalidConfigs.length > 0) {
|
|
22
|
+
throw new Error(`The following configs did not validate:\n ${JSON.stringify(invalidConfigs, null, 2)}`);
|
|
23
|
+
}
|
|
24
|
+
console.info(chalk.cyan('Testing plan...'));
|
|
25
|
+
const plans = [];
|
|
26
|
+
for (const config of configs) {
|
|
27
|
+
plans.push(await plugin.plan({
|
|
68
28
|
desired: config,
|
|
69
29
|
isStateful: false,
|
|
70
30
|
state: undefined,
|
|
71
31
|
}));
|
|
72
32
|
}
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
${JSON.stringify(modifyPlans, null, 2)}`);
|
|
33
|
+
if (options?.validatePlan) {
|
|
34
|
+
await options.validatePlan(plans);
|
|
76
35
|
}
|
|
77
|
-
|
|
78
|
-
|
|
36
|
+
console.info(chalk.cyan('Testing apply...'));
|
|
37
|
+
for (const plan of plans) {
|
|
38
|
+
await plugin.apply({
|
|
79
39
|
planId: plan.planId
|
|
80
40
|
});
|
|
81
41
|
}
|
|
82
|
-
if (options
|
|
83
|
-
await options.
|
|
42
|
+
if (options?.validateApply) {
|
|
43
|
+
await options.validateApply(plans);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
plugin.kill();
|
|
48
|
+
}
|
|
49
|
+
const importPlugin = new PluginProcess(pluginPath);
|
|
50
|
+
try {
|
|
51
|
+
console.info(chalk.cyan('Testing import...'));
|
|
52
|
+
const importResults = [];
|
|
53
|
+
for (const config of configs) {
|
|
54
|
+
const importResult = await importPlugin.import({ config });
|
|
55
|
+
importResults.push(importResult);
|
|
56
|
+
}
|
|
57
|
+
if (options?.validateImport) {
|
|
58
|
+
await options.validateImport(importResults.map((r) => r.result[0]));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
importPlugin.kill();
|
|
63
|
+
}
|
|
64
|
+
if (options?.testModify) {
|
|
65
|
+
const modifyPlugin = new PluginProcess(pluginPath);
|
|
66
|
+
try {
|
|
67
|
+
console.info(chalk.cyan('Testing modify...'));
|
|
68
|
+
const modifyPlans = [];
|
|
69
|
+
for (const config of options.testModify.modifiedConfigs) {
|
|
70
|
+
modifyPlans.push(await modifyPlugin.plan({
|
|
71
|
+
desired: config,
|
|
72
|
+
isStateful: false,
|
|
73
|
+
state: undefined,
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
if (modifyPlans.some((p) => p.operation !== ResourceOperation.MODIFY)) {
|
|
77
|
+
throw new Error(`Error while testing modify. Non-modify results were found in the plan:
|
|
78
|
+
${JSON.stringify(modifyPlans, null, 2)}`);
|
|
79
|
+
}
|
|
80
|
+
for (const plan of modifyPlans) {
|
|
81
|
+
await modifyPlugin.apply({
|
|
82
|
+
planId: plan.planId
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (options.testModify.validateModify) {
|
|
86
|
+
await options.testModify.validateModify(modifyPlans);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
modifyPlugin.kill();
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
if (!skipUninstall) {
|
|
@@ -88,90 +95,38 @@ ${JSON.stringify(modifyPlans, null, 2)}`);
|
|
|
88
95
|
const modifiedConfigs = this.addNamesToConfigs(options?.testModify?.modifiedConfigs ?? []);
|
|
89
96
|
const id = (config) => config.type + (config.name ? `.${config.name}` : '');
|
|
90
97
|
const configsToDestroy = unionBy(modifiedConfigs, configsWithNames, id);
|
|
91
|
-
await this.uninstall(configsToDestroy.toReversed(), options);
|
|
98
|
+
await this.uninstall(pluginPath, configsToDestroy.toReversed(), options);
|
|
92
99
|
}
|
|
93
100
|
}
|
|
94
|
-
async uninstall(configs, options) {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
throw new Error(`Expect resource operation to be 'destory' but instead received plan: \n ${JSON.stringify(plan, null, 2)}`);
|
|
106
|
-
}
|
|
107
|
-
await this.apply({
|
|
108
|
-
planId: plan.planId
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
if (options?.validateDestroy) {
|
|
112
|
-
await options.validateDestroy(plans);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
async initialize() {
|
|
116
|
-
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
117
|
-
cmd: 'initialize',
|
|
118
|
-
data: {},
|
|
119
|
-
requestId: nanoid(6),
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
async validate(data) {
|
|
123
|
-
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
124
|
-
cmd: 'validate',
|
|
125
|
-
data,
|
|
126
|
-
requestId: nanoid(6),
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
async plan(data) {
|
|
130
|
-
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
131
|
-
cmd: 'plan',
|
|
132
|
-
data,
|
|
133
|
-
requestId: nanoid(6),
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
async apply(data) {
|
|
137
|
-
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
138
|
-
cmd: 'apply',
|
|
139
|
-
data,
|
|
140
|
-
requestId: nanoid(6),
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
async import(data) {
|
|
144
|
-
return CodifyTestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
145
|
-
cmd: 'import',
|
|
146
|
-
data,
|
|
147
|
-
requestId: nanoid(6),
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
kill() {
|
|
151
|
-
this.childProcess.kill();
|
|
152
|
-
}
|
|
153
|
-
handleSudoRequests(process) {
|
|
154
|
-
process.on('message', async (message) => {
|
|
155
|
-
if (!ipcMessageValidator(message)) {
|
|
156
|
-
throw new Error(`Invalid message from plugin. ${JSON.stringify(message, null, 2)}`);
|
|
101
|
+
static async uninstall(pluginPath, configs, options) {
|
|
102
|
+
const destroyPlugin = new PluginProcess(pluginPath);
|
|
103
|
+
try {
|
|
104
|
+
console.info(chalk.cyan('Testing destroy...'));
|
|
105
|
+
const plans = [];
|
|
106
|
+
for (const config of configs) {
|
|
107
|
+
plans.push(await destroyPlugin.plan({
|
|
108
|
+
isStateful: true,
|
|
109
|
+
state: config,
|
|
110
|
+
desired: undefined
|
|
111
|
+
}));
|
|
157
112
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
throw new Error(`Invalid sudo request from plugin. ${JSON.stringify(sudoRequestValidator.errors, null, 2)}`);
|
|
113
|
+
for (const plan of plans) {
|
|
114
|
+
if (plan.operation !== ResourceOperation.DESTROY) {
|
|
115
|
+
throw new Error(`Expect resource operation to be 'destroy' but instead received plan: \n ${JSON.stringify(plans, null, 2)}`);
|
|
162
116
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const result = await sudoSpawn(command, options);
|
|
166
|
-
process.send({
|
|
167
|
-
cmd: MessageCmd.SUDO_REQUEST + '_Response',
|
|
168
|
-
data: result,
|
|
169
|
-
requestId,
|
|
117
|
+
await destroyPlugin.apply({
|
|
118
|
+
planId: plan.planId
|
|
170
119
|
});
|
|
171
120
|
}
|
|
172
|
-
|
|
121
|
+
if (options?.validateDestroy) {
|
|
122
|
+
await options.validateDestroy(plans);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
destroyPlugin.kill();
|
|
127
|
+
}
|
|
173
128
|
}
|
|
174
|
-
addNamesToConfigs(configs) {
|
|
129
|
+
static addNamesToConfigs(configs) {
|
|
175
130
|
const configsWithNames = new Array();
|
|
176
131
|
const typeSet = new Set(configs.map((c) => c.type));
|
|
177
132
|
for (const type of typeSet) {
|
|
@@ -184,32 +139,4 @@ ${JSON.stringify(modifyPlans, null, 2)}`);
|
|
|
184
139
|
return configsWithNames;
|
|
185
140
|
}
|
|
186
141
|
}
|
|
187
|
-
async function sudoSpawn(cmd, opts) {
|
|
188
|
-
return new Promise((resolve) => {
|
|
189
|
-
const output = [];
|
|
190
|
-
const _cmd = `sudo ${cmd}`;
|
|
191
|
-
const _process = spawn(`source ~/.zshrc; ${_cmd}`, [], {
|
|
192
|
-
...opts,
|
|
193
|
-
shell: 'zsh',
|
|
194
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
195
|
-
});
|
|
196
|
-
const { stderr, stdout } = _process;
|
|
197
|
-
stdout.setEncoding('utf8');
|
|
198
|
-
stderr.setEncoding('utf8');
|
|
199
|
-
stdout.on('data', (data) => {
|
|
200
|
-
output.push(data.toString());
|
|
201
|
-
});
|
|
202
|
-
stderr.on('data', (data) => {
|
|
203
|
-
output.push(data.toString());
|
|
204
|
-
});
|
|
205
|
-
stdout.pipe(process.stdout);
|
|
206
|
-
stderr.pipe(process.stderr);
|
|
207
|
-
_process.on('close', (code) => {
|
|
208
|
-
resolve({
|
|
209
|
-
data: output.join(''),
|
|
210
|
-
status: code === 0 ? SpawnStatus.SUCCESS : SpawnStatus.ERROR,
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
142
|
//# sourceMappingURL=plugin-tester.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-tester.js","sourceRoot":"","sources":["../src/plugin-tester.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"plugin-tester.js","sourceRoot":"","sources":["../src/plugin-tester.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codify-plugin-test",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.34",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"lodash.matches": "^4.6.0",
|
|
20
20
|
"lodash.differencewith": "4.5.0",
|
|
21
21
|
"lodash.unionby": "^4.8.0",
|
|
22
|
-
"nanoid": "^5.0.9"
|
|
22
|
+
"nanoid": "^5.0.9",
|
|
23
|
+
"chalk": "^5.4.1"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@oclif/prettier-config": "^0.2.1",
|