codify-plugin-lib 1.0.181 → 1.0.182-beta10
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/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/plugin/plugin.js +5 -2
- package/dist/pty/background-pty.d.ts +1 -0
- package/dist/pty/background-pty.js +17 -6
- package/dist/pty/index.d.ts +19 -1
- package/dist/pty/seqeuntial-pty.d.ts +17 -0
- package/dist/pty/seqeuntial-pty.js +117 -0
- package/dist/resource/parsed-resource-settings.d.ts +3 -1
- package/dist/resource/parsed-resource-settings.js +4 -6
- package/dist/resource/resource-settings.d.ts +5 -1
- package/dist/resource/resource-settings.js +1 -1
- package/dist/test.d.ts +1 -0
- package/dist/test.js +5 -0
- package/dist/utils/file-utils.d.ts +16 -0
- package/dist/utils/file-utils.js +172 -0
- package/dist/utils/functions.d.ts +12 -0
- package/dist/utils/functions.js +74 -0
- package/dist/utils/index.d.ts +26 -0
- package/dist/utils/index.js +111 -0
- package/dist/utils/internal-utils.d.ts +12 -0
- package/dist/utils/internal-utils.js +74 -0
- package/dist/utils/verbosity-level.d.ts +5 -0
- package/dist/utils/verbosity-level.js +9 -0
- package/package.json +2 -2
- package/src/index.ts +4 -1
- package/src/plan/plan.test.ts +6 -1
- package/src/plugin/plugin.test.ts +11 -2
- package/src/plugin/plugin.ts +5 -2
- package/src/pty/background-pty.ts +18 -6
- package/src/pty/index.test.ts +7 -4
- package/src/pty/index.ts +20 -2
- package/src/pty/seqeuntial-pty.ts +148 -0
- package/src/pty/sequential-pty.test.ts +179 -0
- package/src/resource/parsed-resource-settings.ts +8 -7
- package/src/resource/resource-controller-stateful-mode.test.ts +2 -1
- package/src/resource/resource-controller.test.ts +22 -4
- package/src/resource/resource-settings.test.ts +29 -2
- package/src/resource/resource-settings.ts +13 -2
- package/src/utils/file-utils.test.ts +7 -0
- package/src/utils/file-utils.ts +216 -0
- package/src/utils/{utils.ts → functions.ts} +0 -16
- package/src/utils/index.ts +144 -0
- package/src/utils/{utils.test.ts → internal-utils.test.ts} +1 -1
- package/src/utils/test-utils.test.ts +5 -2
- package/src/utils/verbosity-level.ts +11 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export function isDebug() {
|
|
4
|
+
return process.env.DEBUG != null && process.env.DEBUG.includes('codify'); // TODO: replace with debug library
|
|
5
|
+
}
|
|
6
|
+
export var Shell;
|
|
7
|
+
(function (Shell) {
|
|
8
|
+
Shell["ZSH"] = "zsh";
|
|
9
|
+
Shell["BASH"] = "bash";
|
|
10
|
+
Shell["SH"] = "sh";
|
|
11
|
+
Shell["KSH"] = "ksh";
|
|
12
|
+
Shell["CSH"] = "csh";
|
|
13
|
+
Shell["FISH"] = "fish";
|
|
14
|
+
})(Shell || (Shell = {}));
|
|
15
|
+
export const Utils = {
|
|
16
|
+
getUser() {
|
|
17
|
+
return os.userInfo().username;
|
|
18
|
+
},
|
|
19
|
+
getSystemInfo() {
|
|
20
|
+
return {
|
|
21
|
+
os: os.type(),
|
|
22
|
+
shell: this.getShell(),
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
isMacOS() {
|
|
26
|
+
return os.platform() === 'darwin';
|
|
27
|
+
},
|
|
28
|
+
isLinux() {
|
|
29
|
+
return os.platform() === 'linux';
|
|
30
|
+
},
|
|
31
|
+
getShell() {
|
|
32
|
+
const shell = process.env.SHELL || '';
|
|
33
|
+
if (shell.endsWith('bash')) {
|
|
34
|
+
return Shell.BASH;
|
|
35
|
+
}
|
|
36
|
+
if (shell.endsWith('zsh')) {
|
|
37
|
+
return Shell.ZSH;
|
|
38
|
+
}
|
|
39
|
+
if (shell.endsWith('sh')) {
|
|
40
|
+
return Shell.SH;
|
|
41
|
+
}
|
|
42
|
+
if (shell.endsWith('csh')) {
|
|
43
|
+
return Shell.CSH;
|
|
44
|
+
}
|
|
45
|
+
if (shell.endsWith('ksh')) {
|
|
46
|
+
return Shell.KSH;
|
|
47
|
+
}
|
|
48
|
+
if (shell.endsWith('fish')) {
|
|
49
|
+
return Shell.FISH;
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
},
|
|
53
|
+
getPrimaryShellRc() {
|
|
54
|
+
return this.getShellRcFiles()[0];
|
|
55
|
+
},
|
|
56
|
+
getShellRcFiles() {
|
|
57
|
+
const shell = process.env.SHELL || '';
|
|
58
|
+
const homeDir = os.homedir();
|
|
59
|
+
if (shell.endsWith('bash')) {
|
|
60
|
+
// Linux typically uses .bashrc, macOS uses .bash_profile
|
|
61
|
+
if (Utils.isLinux()) {
|
|
62
|
+
return [
|
|
63
|
+
path.join(homeDir, '.bashrc'),
|
|
64
|
+
path.join(homeDir, '.bash_profile'),
|
|
65
|
+
path.join(homeDir, '.profile'),
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
return [
|
|
69
|
+
path.join(homeDir, '.bash_profile'),
|
|
70
|
+
path.join(homeDir, '.bashrc'),
|
|
71
|
+
path.join(homeDir, '.profile'),
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
if (shell.endsWith('zsh')) {
|
|
75
|
+
return [
|
|
76
|
+
path.join(homeDir, '.zshrc'),
|
|
77
|
+
path.join(homeDir, '.zprofile'),
|
|
78
|
+
path.join(homeDir, '.zshenv'),
|
|
79
|
+
];
|
|
80
|
+
}
|
|
81
|
+
if (shell.endsWith('sh')) {
|
|
82
|
+
return [
|
|
83
|
+
path.join(homeDir, '.profile'),
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
if (shell.endsWith('ksh')) {
|
|
87
|
+
return [
|
|
88
|
+
path.join(homeDir, '.profile'),
|
|
89
|
+
path.join(homeDir, '.kshrc'),
|
|
90
|
+
];
|
|
91
|
+
}
|
|
92
|
+
if (shell.endsWith('csh')) {
|
|
93
|
+
return [
|
|
94
|
+
path.join(homeDir, '.cshrc'),
|
|
95
|
+
path.join(homeDir, '.login'),
|
|
96
|
+
path.join(homeDir, '.logout'),
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
if (shell.endsWith('fish')) {
|
|
100
|
+
return [
|
|
101
|
+
path.join(homeDir, '.config/fish/config.fish'),
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
// Default to bash-style files
|
|
105
|
+
return [
|
|
106
|
+
path.join(homeDir, '.bashrc'),
|
|
107
|
+
path.join(homeDir, '.bash_profile'),
|
|
108
|
+
path.join(homeDir, '.profile'),
|
|
109
|
+
];
|
|
110
|
+
},
|
|
111
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ResourceConfig, StringIndexedObject } from 'codify-schemas';
|
|
2
|
+
export declare function splitUserConfig<T extends StringIndexedObject>(config: ResourceConfig & T): {
|
|
3
|
+
parameters: T;
|
|
4
|
+
coreParameters: ResourceConfig;
|
|
5
|
+
};
|
|
6
|
+
export declare function setsEqual(set1: Set<unknown>, set2: Set<unknown>): boolean;
|
|
7
|
+
export declare function untildify(pathWithTilde: string): string;
|
|
8
|
+
export declare function tildify(pathWithTilde: string): string;
|
|
9
|
+
export declare function resolvePathWithVariables(pathWithVariables: string): string;
|
|
10
|
+
export declare function addVariablesToPath(pathWithoutVariables: string): string;
|
|
11
|
+
export declare function unhome(pathWithHome: string): string;
|
|
12
|
+
export declare function areArraysEqual(isElementEqual: ((desired: unknown, current: unknown) => boolean) | undefined, desired: unknown, current: unknown): boolean;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export function splitUserConfig(config) {
|
|
4
|
+
const coreParameters = {
|
|
5
|
+
type: config.type,
|
|
6
|
+
...(config.name ? { name: config.name } : {}),
|
|
7
|
+
...(config.dependsOn ? { dependsOn: config.dependsOn } : {}),
|
|
8
|
+
};
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10
|
+
const { type, name, dependsOn, ...parameters } = config;
|
|
11
|
+
return {
|
|
12
|
+
parameters: parameters,
|
|
13
|
+
coreParameters,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function setsEqual(set1, set2) {
|
|
17
|
+
return set1.size === set2.size && [...set1].every((v) => set2.has(v));
|
|
18
|
+
}
|
|
19
|
+
const homeDirectory = os.homedir();
|
|
20
|
+
export function untildify(pathWithTilde) {
|
|
21
|
+
return homeDirectory ? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory) : pathWithTilde;
|
|
22
|
+
}
|
|
23
|
+
export function tildify(pathWithTilde) {
|
|
24
|
+
return homeDirectory ? pathWithTilde.replace(homeDirectory, '~') : pathWithTilde;
|
|
25
|
+
}
|
|
26
|
+
export function resolvePathWithVariables(pathWithVariables) {
|
|
27
|
+
// @ts-expect-error Ignore this for now
|
|
28
|
+
return pathWithVariables.replace(/\$([A-Z_]+[A-Z0-9_]*)|\${([A-Z0-9_]*)}/ig, (_, a, b) => process.env[a || b]);
|
|
29
|
+
}
|
|
30
|
+
export function addVariablesToPath(pathWithoutVariables) {
|
|
31
|
+
let result = pathWithoutVariables;
|
|
32
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
33
|
+
if (!value || !path.isAbsolute(value) || value === '/' || key === 'HOME' || key === 'PATH' || key === 'SHELL' || key === 'PWD') {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
result = result.replaceAll(value, `$${key}`);
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
export function unhome(pathWithHome) {
|
|
41
|
+
return pathWithHome.includes('$HOME') ? pathWithHome.replaceAll('$HOME', os.homedir()) : pathWithHome;
|
|
42
|
+
}
|
|
43
|
+
export function areArraysEqual(isElementEqual, desired, current) {
|
|
44
|
+
if (!desired || !current) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (!Array.isArray(desired) || !Array.isArray(current)) {
|
|
48
|
+
throw new Error(`A non-array value:
|
|
49
|
+
|
|
50
|
+
Desired: ${JSON.stringify(desired, null, 2)}
|
|
51
|
+
|
|
52
|
+
Current: ${JSON.stringify(desired, null, 2)}
|
|
53
|
+
|
|
54
|
+
Was provided even though type array was specified.
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
if (desired.length !== current.length) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const desiredCopy = [...desired];
|
|
61
|
+
const currentCopy = [...current];
|
|
62
|
+
// Algorithm for to check equality between two un-ordered; un-hashable arrays using
|
|
63
|
+
// an isElementEqual method. Time: O(n^2)
|
|
64
|
+
for (let counter = desiredCopy.length - 1; counter >= 0; counter--) {
|
|
65
|
+
const idx = currentCopy.findIndex((e2) => (isElementEqual
|
|
66
|
+
?? ((a, b) => a === b))(desiredCopy[counter], e2));
|
|
67
|
+
if (idx === -1) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
desiredCopy.splice(counter, 1);
|
|
71
|
+
currentCopy.splice(idx, 1);
|
|
72
|
+
}
|
|
73
|
+
return currentCopy.length === 0;
|
|
74
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codify-plugin-lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.182-beta10",
|
|
4
4
|
"description": "Library plugin library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"ajv": "^8.12.0",
|
|
23
23
|
"ajv-formats": "^2.1.1",
|
|
24
24
|
"clean-deep": "^3.4.0",
|
|
25
|
-
"codify-schemas": "1.0.
|
|
25
|
+
"codify-schemas": "1.0.86-beta5",
|
|
26
26
|
"lodash.isequal": "^4.5.0",
|
|
27
27
|
"nanoid": "^5.0.9",
|
|
28
28
|
"strip-ansi": "^7.1.0",
|
package/src/index.ts
CHANGED
|
@@ -12,7 +12,10 @@ export * from './resource/parsed-resource-settings.js';
|
|
|
12
12
|
export * from './resource/resource.js'
|
|
13
13
|
export * from './resource/resource-settings.js'
|
|
14
14
|
export * from './stateful-parameter/stateful-parameter.js'
|
|
15
|
-
export * from './utils/utils.js'
|
|
15
|
+
export * from './utils/file-utils.js'
|
|
16
|
+
export * from './utils/functions.js'
|
|
17
|
+
export * from './utils/index.js'
|
|
18
|
+
export * from './utils/verbosity-level.js'
|
|
16
19
|
|
|
17
20
|
export async function runPlugin(plugin: Plugin) {
|
|
18
21
|
const messageHandler = new MessageHandler(plugin);
|
package/src/plan/plan.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { Plan } from './plan.js';
|
|
3
|
-
import { ParameterOperation, ResourceOperation } from 'codify-schemas';
|
|
3
|
+
import { OS, ParameterOperation, ResourceOperation } from 'codify-schemas';
|
|
4
4
|
import { TestConfig, TestResource } from '../utils/test-utils.test.js';
|
|
5
5
|
import { ResourceController } from '../resource/resource-controller.js';
|
|
6
6
|
import { ParsedResourceSettings } from '../resource/parsed-resource-settings.js';
|
|
@@ -152,6 +152,7 @@ describe('Plan entity tests', () => {
|
|
|
152
152
|
getSettings(): ResourceSettings<any> {
|
|
153
153
|
return {
|
|
154
154
|
id: 'type',
|
|
155
|
+
operatingSystems: [OS.Darwin],
|
|
155
156
|
parameterSettings: {
|
|
156
157
|
propZ: { type: 'array', isElementEqual: (a, b) => b.includes(a) }
|
|
157
158
|
}
|
|
@@ -184,6 +185,7 @@ describe('Plan entity tests', () => {
|
|
|
184
185
|
getSettings(): ResourceSettings<any> {
|
|
185
186
|
return {
|
|
186
187
|
id: 'type',
|
|
188
|
+
operatingSystems: [OS.Darwin],
|
|
187
189
|
parameterSettings: {
|
|
188
190
|
propZ: {
|
|
189
191
|
type: 'array',
|
|
@@ -236,6 +238,7 @@ describe('Plan entity tests', () => {
|
|
|
236
238
|
getSettings(): ResourceSettings<TestConfig> {
|
|
237
239
|
return {
|
|
238
240
|
id: 'type',
|
|
241
|
+
operatingSystems: [OS.Darwin],
|
|
239
242
|
parameterSettings: {
|
|
240
243
|
propA: { type: 'string' },
|
|
241
244
|
propB: { type: 'string', canModify: true },
|
|
@@ -289,6 +292,7 @@ describe('Plan entity tests', () => {
|
|
|
289
292
|
getSettings(): ResourceSettings<TestConfig> {
|
|
290
293
|
return {
|
|
291
294
|
id: 'type',
|
|
295
|
+
operatingSystems: [OS.Darwin],
|
|
292
296
|
parameterSettings: {
|
|
293
297
|
propA: { type: 'string' },
|
|
294
298
|
propB: { type: 'string', canModify: true },
|
|
@@ -351,6 +355,7 @@ function createTestResource() {
|
|
|
351
355
|
getSettings(): ResourceSettings<TestConfig> {
|
|
352
356
|
return {
|
|
353
357
|
id: 'type',
|
|
358
|
+
operatingSystems: [OS.Darwin],
|
|
354
359
|
parameterSettings: {
|
|
355
360
|
propA: {
|
|
356
361
|
default: 'defaultA'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
2
|
import { Plugin } from './plugin.js';
|
|
3
|
-
import { ApplyRequestData, ParameterOperation, ResourceOperation, StringIndexedObject } from 'codify-schemas';
|
|
3
|
+
import { ApplyRequestData, OS, ParameterOperation, ResourceOperation, StringIndexedObject } from 'codify-schemas';
|
|
4
4
|
import { Resource } from '../resource/resource.js';
|
|
5
5
|
import { Plan } from '../plan/plan.js';
|
|
6
6
|
import { spy } from 'sinon';
|
|
@@ -17,7 +17,8 @@ interface TestConfig extends StringIndexedObject {
|
|
|
17
17
|
class TestResource extends Resource<TestConfig> {
|
|
18
18
|
getSettings(): ResourceSettings<TestConfig> {
|
|
19
19
|
return {
|
|
20
|
-
id: 'testResource'
|
|
20
|
+
id: 'testResource',
|
|
21
|
+
operatingSystems: [OS.Darwin],
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -154,6 +155,7 @@ describe('Plugin tests', () => {
|
|
|
154
155
|
getSettings(): ResourceSettings<TestConfig> {
|
|
155
156
|
return {
|
|
156
157
|
id: 'typeId',
|
|
158
|
+
operatingSystems: [OS.Darwin],
|
|
157
159
|
schema,
|
|
158
160
|
}
|
|
159
161
|
}
|
|
@@ -192,6 +194,7 @@ describe('Plugin tests', () => {
|
|
|
192
194
|
getSettings(): ResourceSettings<TestConfig> {
|
|
193
195
|
return {
|
|
194
196
|
id: 'typeId',
|
|
197
|
+
operatingSystems: [OS.Darwin],
|
|
195
198
|
schema,
|
|
196
199
|
importAndDestroy: {
|
|
197
200
|
requiredParameters: []
|
|
@@ -285,6 +288,7 @@ describe('Plugin tests', () => {
|
|
|
285
288
|
getSettings(): ResourceSettings<TestConfig> {
|
|
286
289
|
return {
|
|
287
290
|
id: 'type',
|
|
291
|
+
operatingSystems: [OS.Darwin],
|
|
288
292
|
schema: {
|
|
289
293
|
'$schema': 'http://json-schema.org/draft-07/schema',
|
|
290
294
|
'$id': 'https://www.codifycli.com/ssh-config.json',
|
|
@@ -330,6 +334,7 @@ describe('Plugin tests', () => {
|
|
|
330
334
|
getSettings(): ResourceSettings<TestConfig> {
|
|
331
335
|
return {
|
|
332
336
|
...super.getSettings(),
|
|
337
|
+
operatingSystems: [OS.Darwin],
|
|
333
338
|
allowMultiple: {
|
|
334
339
|
identifyingParameters: ['path', 'paths']
|
|
335
340
|
}
|
|
@@ -351,6 +356,7 @@ describe('Plugin tests', () => {
|
|
|
351
356
|
getSettings(): ResourceSettings<TestConfig> {
|
|
352
357
|
return {
|
|
353
358
|
...super.getSettings(),
|
|
359
|
+
operatingSystems: [OS.Darwin],
|
|
354
360
|
parameterSettings: {
|
|
355
361
|
path: { type: 'directory' },
|
|
356
362
|
paths: { type: 'array', itemType: 'directory' }
|
|
@@ -407,6 +413,7 @@ describe('Plugin tests', () => {
|
|
|
407
413
|
getSettings(): ResourceSettings<TestConfig> {
|
|
408
414
|
return {
|
|
409
415
|
id: 'ssh-config',
|
|
416
|
+
operatingSystems: [OS.Darwin],
|
|
410
417
|
parameterSettings: {
|
|
411
418
|
hosts: { type: 'stateful', definition: new TestStatefulParameter() }
|
|
412
419
|
},
|
|
@@ -454,6 +461,7 @@ describe('Plugin tests', () => {
|
|
|
454
461
|
getSettings(): ResourceSettings<TestConfig> {
|
|
455
462
|
return {
|
|
456
463
|
id: 'ssh-config',
|
|
464
|
+
operatingSystems: [OS.Darwin],
|
|
457
465
|
allowMultiple: true
|
|
458
466
|
}
|
|
459
467
|
}
|
|
@@ -476,6 +484,7 @@ describe('Plugin tests', () => {
|
|
|
476
484
|
getSettings(): ResourceSettings<TestConfig> {
|
|
477
485
|
return {
|
|
478
486
|
id: 'ssh-config',
|
|
487
|
+
operatingSystems: [OS.Darwin],
|
|
479
488
|
}
|
|
480
489
|
}
|
|
481
490
|
})
|
package/src/plugin/plugin.ts
CHANGED
|
@@ -21,10 +21,11 @@ import { ApplyValidationError } from '../common/errors.js';
|
|
|
21
21
|
import { Plan } from '../plan/plan.js';
|
|
22
22
|
import { BackgroundPty } from '../pty/background-pty.js';
|
|
23
23
|
import { getPty } from '../pty/index.js';
|
|
24
|
+
import { SequentialPty } from '../pty/seqeuntial-pty.js';
|
|
24
25
|
import { Resource } from '../resource/resource.js';
|
|
25
26
|
import { ResourceController } from '../resource/resource-controller.js';
|
|
26
27
|
import { ptyLocalStorage } from '../utils/pty-local-storage.js';
|
|
27
|
-
import { VerbosityLevel } from '../utils/
|
|
28
|
+
import { VerbosityLevel } from '../utils/verbosity-level.js';
|
|
28
29
|
|
|
29
30
|
export class Plugin {
|
|
30
31
|
planStorage: Map<string, Plan<any>>;
|
|
@@ -75,6 +76,7 @@ export class Plugin {
|
|
|
75
76
|
dependencies: r.dependencies,
|
|
76
77
|
type: r.typeId,
|
|
77
78
|
sensitiveParameters,
|
|
79
|
+
operatingSystems: r.settings.operatingSystems,
|
|
78
80
|
}
|
|
79
81
|
})
|
|
80
82
|
}
|
|
@@ -121,6 +123,7 @@ export class Plugin {
|
|
|
121
123
|
import: {
|
|
122
124
|
requiredParameters: requiredPropertyNames,
|
|
123
125
|
},
|
|
126
|
+
operatingSystems: resource.settings.operatingSystems,
|
|
124
127
|
sensitiveParameters,
|
|
125
128
|
allowMultiple
|
|
126
129
|
}
|
|
@@ -232,7 +235,7 @@ export class Plugin {
|
|
|
232
235
|
throw new Error('Malformed plan with resource that cannot be found');
|
|
233
236
|
}
|
|
234
237
|
|
|
235
|
-
await resource.apply(plan)
|
|
238
|
+
await ptyLocalStorage.run(new SequentialPty(), async () => resource.apply(plan))
|
|
236
239
|
|
|
237
240
|
// Validate using desired/desired. If the apply was successful, no changes should be reported back.
|
|
238
241
|
// Default back desired back to current if it is not defined (for destroys only)
|
|
@@ -6,7 +6,8 @@ import * as fs from 'node:fs/promises';
|
|
|
6
6
|
import stripAnsi from 'strip-ansi';
|
|
7
7
|
|
|
8
8
|
import { debugLog } from '../utils/debug.js';
|
|
9
|
-
import {
|
|
9
|
+
import { Shell, Utils } from '../utils/index.js';
|
|
10
|
+
import { VerbosityLevel } from '../utils/verbosity-level.js';
|
|
10
11
|
import { IPty, SpawnError, SpawnOptions, SpawnResult } from './index.js';
|
|
11
12
|
import { PromiseQueue } from './promise-queue.js';
|
|
12
13
|
|
|
@@ -19,8 +20,10 @@ EventEmitter.defaultMaxListeners = 1000;
|
|
|
19
20
|
* without a tty (or even a stdin) attached so interactive commands will not work.
|
|
20
21
|
*/
|
|
21
22
|
export class BackgroundPty implements IPty {
|
|
23
|
+
private historyIgnore = Utils.getShell() === Shell.ZSH ? { HISTORY_IGNORE: '*' } : { HISTIGNORE: '*' };
|
|
22
24
|
private basePty = pty.spawn(this.getDefaultShell(), ['-i'], {
|
|
23
|
-
env: process.env,
|
|
25
|
+
env: { ...process.env, ...this.historyIgnore },
|
|
26
|
+
name: nanoid(6),
|
|
24
27
|
handleFlowControl: true
|
|
25
28
|
});
|
|
26
29
|
|
|
@@ -128,9 +131,18 @@ export class BackgroundPty implements IPty {
|
|
|
128
131
|
|
|
129
132
|
return new Promise(resolve => {
|
|
130
133
|
// zsh-specific commands
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
// switch (Utils.getShell()) {
|
|
135
|
+
// case Shell.ZSH: {
|
|
136
|
+
// this.basePty.write('setopt HIST_NO_STORE;\n');
|
|
137
|
+
// break;
|
|
138
|
+
// }
|
|
139
|
+
//
|
|
140
|
+
// default: {
|
|
141
|
+
// this.basePty.write('export HISTIGNORE=\'history*\';\n');
|
|
142
|
+
// break;
|
|
143
|
+
// }
|
|
144
|
+
// }
|
|
145
|
+
|
|
134
146
|
this.basePty.write(' unset PS1;\n');
|
|
135
147
|
this.basePty.write(' unset PS0;\n')
|
|
136
148
|
this.basePty.write(' echo setup complete\\"\n')
|
|
@@ -147,6 +159,6 @@ export class BackgroundPty implements IPty {
|
|
|
147
159
|
}
|
|
148
160
|
|
|
149
161
|
private getDefaultShell(): string {
|
|
150
|
-
return process.
|
|
162
|
+
return process.env.SHELL!;
|
|
151
163
|
}
|
|
152
164
|
}
|
package/src/pty/index.test.ts
CHANGED
|
@@ -3,8 +3,9 @@ import { TestConfig, TestResource } from '../utils/test-utils.test.js';
|
|
|
3
3
|
import { getPty, IPty } from './index.js';
|
|
4
4
|
import { Plugin } from '../plugin/plugin.js'
|
|
5
5
|
import { CreatePlan } from '../plan/plan-types.js';
|
|
6
|
-
import { ResourceOperation } from 'codify-schemas';
|
|
6
|
+
import { OS, ResourceOperation } from 'codify-schemas';
|
|
7
7
|
import { ResourceSettings } from '../resource/resource-settings.js';
|
|
8
|
+
import { SequentialPty } from './seqeuntial-pty.js';
|
|
8
9
|
|
|
9
10
|
describe('General tests for PTYs', () => {
|
|
10
11
|
it('Can get pty within refresh', async () => {
|
|
@@ -45,7 +46,8 @@ describe('General tests for PTYs', () => {
|
|
|
45
46
|
const testResource1 = new class extends TestResource {
|
|
46
47
|
getSettings(): ResourceSettings<TestConfig> {
|
|
47
48
|
return {
|
|
48
|
-
id: 'type1'
|
|
49
|
+
id: 'type1',
|
|
50
|
+
operatingSystems: [OS.Darwin],
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -64,6 +66,7 @@ describe('General tests for PTYs', () => {
|
|
|
64
66
|
getSettings(): ResourceSettings<TestConfig> {
|
|
65
67
|
return {
|
|
66
68
|
id: 'type2',
|
|
69
|
+
operatingSystems: [OS.Darwin],
|
|
67
70
|
}
|
|
68
71
|
}
|
|
69
72
|
|
|
@@ -103,11 +106,11 @@ describe('General tests for PTYs', () => {
|
|
|
103
106
|
expect(pty1).to.eq(pty2);
|
|
104
107
|
})
|
|
105
108
|
|
|
106
|
-
it('
|
|
109
|
+
it('Sequential pty should be available for applies', async () => {
|
|
107
110
|
const testResource = new class extends TestResource {
|
|
108
111
|
create(plan: CreatePlan<TestConfig>): Promise<void> {
|
|
109
112
|
const $ = getPty();
|
|
110
|
-
expect($).to.
|
|
113
|
+
expect($).to.instanceof(SequentialPty)
|
|
111
114
|
}
|
|
112
115
|
}
|
|
113
116
|
|
package/src/pty/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ptyLocalStorage } from '../utils/pty-local-storage.js';
|
|
2
2
|
|
|
3
3
|
export interface SpawnResult {
|
|
4
|
-
status: '
|
|
4
|
+
status: 'error' | 'success';
|
|
5
5
|
exitCode: number;
|
|
6
6
|
data: string;
|
|
7
7
|
}
|
|
@@ -11,9 +11,27 @@ export enum SpawnStatus {
|
|
|
11
11
|
ERROR = 'error',
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Represents the configuration options for spawning a child process.
|
|
16
|
+
*
|
|
17
|
+
* @interface SpawnOptions
|
|
18
|
+
*
|
|
19
|
+
* @property {string} [cwd] - Specifies the working directory of the child process.
|
|
20
|
+
* If not provided, the current working directory of the parent process is used.
|
|
21
|
+
*
|
|
22
|
+
* @property {Record<string, unknown>} [env] - Defines environment key-value pairs
|
|
23
|
+
* that will be available to the child process. If not specified, the child process
|
|
24
|
+
* will inherit the environment variables of the parent process.
|
|
25
|
+
*
|
|
26
|
+
* @property {boolean} [interactive] - Indicates whether the spawned process needs
|
|
27
|
+
* to be interactive. Only works within apply (not plan). Defaults to true.
|
|
28
|
+
*/
|
|
14
29
|
export interface SpawnOptions {
|
|
15
30
|
cwd?: string;
|
|
16
|
-
env?: Record<string, unknown
|
|
31
|
+
env?: Record<string, unknown>;
|
|
32
|
+
interactive?: boolean;
|
|
33
|
+
requiresRoot?: boolean;
|
|
34
|
+
stdin?: boolean;
|
|
17
35
|
}
|
|
18
36
|
|
|
19
37
|
export class SpawnError extends Error {
|