codify-plugin-test 0.0.53-beta16 → 0.0.53-beta17
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.js +6 -6
- package/dist/plugin-process.js.map +1 -1
- package/dist/test-utils.d.ts +37 -1
- package/dist/test-utils.js +83 -3
- package/dist/test-utils.js.map +1 -1
- package/package.json +1 -1
- package/src/plugin-process.ts +6 -6
- package/src/test-utils.test.ts +5 -5
- package/src/test-utils.ts +100 -3
package/dist/plugin-process.js
CHANGED
|
@@ -4,7 +4,7 @@ import { nanoid } from 'nanoid';
|
|
|
4
4
|
import { fork } from 'node:child_process';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { spawnSafe } from './spawn.js';
|
|
7
|
-
import {
|
|
7
|
+
import { TestUtils } from './test-utils.js';
|
|
8
8
|
const ajv = new Ajv.default({
|
|
9
9
|
strict: true
|
|
10
10
|
});
|
|
@@ -34,35 +34,35 @@ export class PluginProcess {
|
|
|
34
34
|
this.handleIncomingRequests(this.childProcess);
|
|
35
35
|
}
|
|
36
36
|
async initialize() {
|
|
37
|
-
return
|
|
37
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
38
38
|
cmd: 'initialize',
|
|
39
39
|
data: { verbosityLevel: 3 },
|
|
40
40
|
requestId: nanoid(6),
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
async validate(data) {
|
|
44
|
-
return
|
|
44
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
45
45
|
cmd: 'validate',
|
|
46
46
|
data,
|
|
47
47
|
requestId: nanoid(6),
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
async plan(data) {
|
|
51
|
-
return
|
|
51
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
52
52
|
cmd: 'plan',
|
|
53
53
|
data,
|
|
54
54
|
requestId: nanoid(6),
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
async apply(data) {
|
|
58
|
-
return
|
|
58
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
59
59
|
cmd: 'apply',
|
|
60
60
|
data,
|
|
61
61
|
requestId: nanoid(6),
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
async import(data) {
|
|
65
|
-
return
|
|
65
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
66
66
|
cmd: 'import',
|
|
67
67
|
data,
|
|
68
68
|
requestId: nanoid(6),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-process.js","sourceRoot":"","sources":["../src/plugin-process.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAGL,wBAAwB,EAIxB,gBAAgB,EAEhB,UAAU,EAKX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAgB,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"plugin-process.js","sourceRoot":"","sources":["../src/plugin-process.ts"],"names":[],"mappings":"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"}
|
package/dist/test-utils.d.ts
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
import { IpcMessageV2 } from 'codify-schemas';
|
|
2
2
|
import { ChildProcess } from 'node:child_process';
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const TestUtils: {
|
|
4
4
|
sendMessageAndAwaitResponse(process: ChildProcess, message: IpcMessageV2): Promise<any>;
|
|
5
5
|
ensureHomebrewInstalled(pluginPath: string): Promise<void>;
|
|
6
|
+
getShell(): "bash" | "zsh";
|
|
7
|
+
/**
|
|
8
|
+
* Get the primary shell rc file path
|
|
9
|
+
*/
|
|
10
|
+
getPrimaryShellRc(): string;
|
|
11
|
+
/**
|
|
12
|
+
* Get the source command for the shell rc file
|
|
13
|
+
* Usage: execSync(TestUtils.getSourceCommand())
|
|
14
|
+
*/
|
|
15
|
+
getSourceCommand(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Get shell-specific command to run with sourced environment
|
|
18
|
+
* Usage: execSync(TestUtils.getShellCommand('which brew'))
|
|
19
|
+
*/
|
|
20
|
+
getShellCommand(command: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Get shell name for execSync shell option
|
|
23
|
+
*/
|
|
24
|
+
getShellName(): string;
|
|
25
|
+
/**
|
|
26
|
+
* Get interactive shell command
|
|
27
|
+
* Usage: execSync(TestUtils.getInteractiveCommand('my-alias'))
|
|
28
|
+
*/
|
|
29
|
+
getInteractiveCommand(command: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Get which command output format based on shell
|
|
32
|
+
*/
|
|
33
|
+
getAliasWhichCommand(aliasName: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Check if running on macOS
|
|
36
|
+
*/
|
|
37
|
+
isMacOS(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Check if running on Linux
|
|
40
|
+
*/
|
|
41
|
+
isLinux(): boolean;
|
|
6
42
|
};
|
package/dist/test-utils.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import Ajv from 'ajv';
|
|
2
2
|
import { IpcMessageSchema, MessageStatus, SpawnStatus } from 'codify-schemas';
|
|
3
|
-
import
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
4
5
|
import { PluginTester } from './plugin-tester.js';
|
|
6
|
+
import { testSpawn } from './spawn.js';
|
|
5
7
|
const ajv = new Ajv.default({
|
|
6
8
|
strict: true
|
|
7
9
|
});
|
|
8
10
|
const ipcMessageValidator = ajv.compile(IpcMessageSchema);
|
|
9
|
-
export const
|
|
11
|
+
export const TestUtils = {
|
|
10
12
|
sendMessageAndAwaitResponse(process, message) {
|
|
11
13
|
return new Promise((resolve, reject) => {
|
|
12
14
|
process.on('message', (response) => {
|
|
@@ -32,6 +34,84 @@ export const CodifyTestUtils = {
|
|
|
32
34
|
if (homebrewQuery.status !== SpawnStatus.SUCCESS) {
|
|
33
35
|
await PluginTester.install(pluginPath, [{ type: 'homebrew' }]);
|
|
34
36
|
}
|
|
35
|
-
}
|
|
37
|
+
},
|
|
38
|
+
getShell() {
|
|
39
|
+
const shell = process.env.SHELL || '';
|
|
40
|
+
if (shell.includes('bash')) {
|
|
41
|
+
return 'bash';
|
|
42
|
+
}
|
|
43
|
+
if (shell.includes('zsh')) {
|
|
44
|
+
return 'zsh';
|
|
45
|
+
}
|
|
46
|
+
// Default to bash for tests
|
|
47
|
+
return 'bash';
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* Get the primary shell rc file path
|
|
51
|
+
*/
|
|
52
|
+
getPrimaryShellRc() {
|
|
53
|
+
const shell = TestUtils.getShell();
|
|
54
|
+
const homeDir = os.homedir();
|
|
55
|
+
if (shell === 'bash') {
|
|
56
|
+
return path.join(homeDir, '.bashrc');
|
|
57
|
+
}
|
|
58
|
+
if (shell === 'zsh') {
|
|
59
|
+
return path.join(homeDir, '.zshrc');
|
|
60
|
+
}
|
|
61
|
+
throw new Error('Unsupported shell');
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* Get the source command for the shell rc file
|
|
65
|
+
* Usage: execSync(TestUtils.getSourceCommand())
|
|
66
|
+
*/
|
|
67
|
+
getSourceCommand() {
|
|
68
|
+
return `source ${TestUtils.getPrimaryShellRc()}`;
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* Get shell-specific command to run with sourced environment
|
|
72
|
+
* Usage: execSync(TestUtils.getShellCommand('which brew'))
|
|
73
|
+
*/
|
|
74
|
+
getShellCommand(command) {
|
|
75
|
+
return `${TestUtils.getSourceCommand()}; ${command}`;
|
|
76
|
+
},
|
|
77
|
+
/**
|
|
78
|
+
* Get shell name for execSync shell option
|
|
79
|
+
*/
|
|
80
|
+
getShellName() {
|
|
81
|
+
return TestUtils.getShell();
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* Get interactive shell command
|
|
85
|
+
* Usage: execSync(TestUtils.getInteractiveCommand('my-alias'))
|
|
86
|
+
*/
|
|
87
|
+
getInteractiveCommand(command) {
|
|
88
|
+
const shell = TestUtils.getShell();
|
|
89
|
+
return shell === 'bash'
|
|
90
|
+
? `bash -i -c "${command}"`
|
|
91
|
+
: `zsh -i -c "${command}"`;
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* Get which command output format based on shell
|
|
95
|
+
*/
|
|
96
|
+
getAliasWhichCommand(aliasName) {
|
|
97
|
+
const shell = TestUtils.getShell();
|
|
98
|
+
// zsh outputs: "alias_name: aliased to command"
|
|
99
|
+
// bash outputs: "alias alias_name='command'"
|
|
100
|
+
return shell === 'bash'
|
|
101
|
+
? `${TestUtils.getShellCommand(`alias ${aliasName}`)}`
|
|
102
|
+
: `${TestUtils.getShellCommand(`which ${aliasName}`)}`;
|
|
103
|
+
},
|
|
104
|
+
/**
|
|
105
|
+
* Check if running on macOS
|
|
106
|
+
*/
|
|
107
|
+
isMacOS() {
|
|
108
|
+
return os.platform() === 'darwin';
|
|
109
|
+
},
|
|
110
|
+
/**
|
|
111
|
+
* Check if running on Linux
|
|
112
|
+
*/
|
|
113
|
+
isLinux() {
|
|
114
|
+
return os.platform() === 'linux';
|
|
115
|
+
},
|
|
36
116
|
};
|
|
37
117
|
//# sourceMappingURL=test-utils.js.map
|
package/dist/test-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAgB,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE5F,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../src/test-utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/plugin-process.ts
CHANGED
|
@@ -21,7 +21,7 @@ import * as os from 'node:os';
|
|
|
21
21
|
import path from 'node:path';
|
|
22
22
|
|
|
23
23
|
import { spawnSafe } from './spawn.js';
|
|
24
|
-
import {
|
|
24
|
+
import { TestUtils } from './test-utils.js';
|
|
25
25
|
|
|
26
26
|
const ajv = new Ajv.default({
|
|
27
27
|
strict: true
|
|
@@ -64,7 +64,7 @@ export class PluginProcess {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
async initialize(): Promise<InitializeResponseData> {
|
|
67
|
-
return
|
|
67
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
68
68
|
cmd: 'initialize',
|
|
69
69
|
data: { verbosityLevel: 3 },
|
|
70
70
|
requestId: nanoid(6),
|
|
@@ -72,7 +72,7 @@ export class PluginProcess {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
async validate(data: ValidateRequestData): Promise<ValidateResponseData> {
|
|
75
|
-
return
|
|
75
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
76
76
|
cmd: 'validate',
|
|
77
77
|
data,
|
|
78
78
|
requestId: nanoid(6),
|
|
@@ -80,7 +80,7 @@ export class PluginProcess {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
async plan(data: PlanRequestData): Promise<PlanResponseData> {
|
|
83
|
-
return
|
|
83
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
84
84
|
cmd: 'plan',
|
|
85
85
|
data,
|
|
86
86
|
requestId: nanoid(6),
|
|
@@ -88,7 +88,7 @@ export class PluginProcess {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
async apply(data: ApplyRequestData): Promise<void> {
|
|
91
|
-
return
|
|
91
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
92
92
|
cmd: 'apply',
|
|
93
93
|
data,
|
|
94
94
|
requestId: nanoid(6),
|
|
@@ -96,7 +96,7 @@ export class PluginProcess {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
async import(data: ImportRequestData): Promise<ImportResponseData> {
|
|
99
|
-
return
|
|
99
|
+
return TestUtils.sendMessageAndAwaitResponse(this.childProcess, {
|
|
100
100
|
cmd: 'import',
|
|
101
101
|
data,
|
|
102
102
|
requestId: nanoid(6),
|
package/src/test-utils.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import { ChildProcess } from 'node:child_process';
|
|
3
3
|
import { Readable } from 'stream';
|
|
4
|
-
import {
|
|
4
|
+
import { TestUtils } from './test-utils.js';
|
|
5
5
|
import { describe, expect, it, vi } from 'vitest';
|
|
6
6
|
import { MessageStatus } from 'codify-schemas';
|
|
7
7
|
import { nanoid } from 'nanoid';
|
|
@@ -22,7 +22,7 @@ describe('Test Utils tests', async () => {
|
|
|
22
22
|
const sendMock = vi.spyOn(process, 'send');
|
|
23
23
|
const requestId = nanoid(6);
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
TestUtils.sendMessageAndAwaitResponse(process, { cmd: 'message', data: 'data', requestId })
|
|
26
26
|
|
|
27
27
|
expect(sendMock.mock.calls.length).to.eq(1);
|
|
28
28
|
expect(sendMock.mock.calls[0][0]).to.deep.eq({ cmd: 'message', data: 'data', requestId });
|
|
@@ -38,7 +38,7 @@ describe('Test Utils tests', async () => {
|
|
|
38
38
|
// Note that the response must end in _Response. In accordance to the message schema rules.
|
|
39
39
|
process.emit('message', { cmd: 'message_Response', status: MessageStatus.SUCCESS, data: 'data', requestId })
|
|
40
40
|
})(),
|
|
41
|
-
|
|
41
|
+
TestUtils.sendMessageAndAwaitResponse(process, { cmd: 'message', data: 'data', requestId }),
|
|
42
42
|
]);
|
|
43
43
|
|
|
44
44
|
expect(result[1]).to.eq('data')
|
|
@@ -54,7 +54,7 @@ describe('Test Utils tests', async () => {
|
|
|
54
54
|
// Note that the response must end in _Response. In accordance to the message schema rules.
|
|
55
55
|
process.emit('message', { cmd: 'message_Response', status: MessageStatus.ERROR, data: 'error message', requestId })
|
|
56
56
|
})(),
|
|
57
|
-
|
|
57
|
+
TestUtils.sendMessageAndAwaitResponse(process, { cmd: 'message', data: 'data', requestId }),
|
|
58
58
|
])).rejects.toThrowError(new Error('error message'))
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -70,7 +70,7 @@ describe('Test Utils tests', async () => {
|
|
|
70
70
|
process.emit('message', { cmd: 'randomMessage2', status: MessageStatus.SUCCESS, data: 'message2', requestId: nanoid(6) })
|
|
71
71
|
process.emit('message', { cmd: 'message_Response', status: MessageStatus.SUCCESS, data: 'data', requestId })
|
|
72
72
|
})(),
|
|
73
|
-
|
|
73
|
+
TestUtils.sendMessageAndAwaitResponse(process, { cmd: 'message', data: 'data', requestId }),
|
|
74
74
|
]);
|
|
75
75
|
|
|
76
76
|
// Only the final _Response message should be returned.
|
package/src/test-utils.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import Ajv from 'ajv';
|
|
2
2
|
import { IpcMessageSchema, IpcMessageV2, MessageStatus, SpawnStatus } from 'codify-schemas';
|
|
3
3
|
import { ChildProcess } from 'node:child_process';
|
|
4
|
-
import
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
|
|
5
7
|
import { PluginTester } from './plugin-tester.js';
|
|
8
|
+
import { testSpawn } from './spawn.js';
|
|
6
9
|
|
|
7
10
|
const ajv = new Ajv.default({
|
|
8
11
|
strict: true
|
|
9
12
|
});
|
|
10
13
|
const ipcMessageValidator = ajv.compile(IpcMessageSchema);
|
|
11
14
|
|
|
12
|
-
export const
|
|
15
|
+
export const TestUtils = {
|
|
13
16
|
sendMessageAndAwaitResponse(process: ChildProcess, message: IpcMessageV2): Promise<any> {
|
|
14
17
|
return new Promise((resolve, reject) => {
|
|
15
18
|
process.on('message', (response: IpcMessageV2) => {
|
|
@@ -37,6 +40,100 @@ export const CodifyTestUtils = {
|
|
|
37
40
|
if (homebrewQuery.status !== SpawnStatus.SUCCESS) {
|
|
38
41
|
await PluginTester.install(pluginPath, [{ type: 'homebrew' }])
|
|
39
42
|
}
|
|
40
|
-
}
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
getShell(): 'bash' | 'zsh' {
|
|
46
|
+
const shell = process.env.SHELL || '';
|
|
47
|
+
|
|
48
|
+
if (shell.includes('bash')) {
|
|
49
|
+
return 'bash';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (shell.includes('zsh')) {
|
|
53
|
+
return 'zsh';
|
|
54
|
+
}
|
|
41
55
|
|
|
56
|
+
// Default to bash for tests
|
|
57
|
+
return 'bash';
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get the primary shell rc file path
|
|
62
|
+
*/
|
|
63
|
+
getPrimaryShellRc(): string {
|
|
64
|
+
const shell = TestUtils.getShell();
|
|
65
|
+
const homeDir = os.homedir();
|
|
66
|
+
|
|
67
|
+
if (shell === 'bash') {
|
|
68
|
+
return path.join(homeDir, '.bashrc')
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (shell === 'zsh') {
|
|
72
|
+
return path.join(homeDir, '.zshrc');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
throw new Error('Unsupported shell')
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get the source command for the shell rc file
|
|
80
|
+
* Usage: execSync(TestUtils.getSourceCommand())
|
|
81
|
+
*/
|
|
82
|
+
getSourceCommand(): string {
|
|
83
|
+
return `source ${TestUtils.getPrimaryShellRc()}`;
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get shell-specific command to run with sourced environment
|
|
88
|
+
* Usage: execSync(TestUtils.getShellCommand('which brew'))
|
|
89
|
+
*/
|
|
90
|
+
getShellCommand(command: string): string {
|
|
91
|
+
return `${TestUtils.getSourceCommand()}; ${command}`;
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get shell name for execSync shell option
|
|
96
|
+
*/
|
|
97
|
+
getShellName(): string {
|
|
98
|
+
return TestUtils.getShell();
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Get interactive shell command
|
|
103
|
+
* Usage: execSync(TestUtils.getInteractiveCommand('my-alias'))
|
|
104
|
+
*/
|
|
105
|
+
getInteractiveCommand(command: string): string {
|
|
106
|
+
const shell = TestUtils.getShell();
|
|
107
|
+
|
|
108
|
+
return shell === 'bash'
|
|
109
|
+
? `bash -i -c "${command}"`
|
|
110
|
+
: `zsh -i -c "${command}"`;
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get which command output format based on shell
|
|
115
|
+
*/
|
|
116
|
+
getAliasWhichCommand(aliasName: string): string {
|
|
117
|
+
const shell = TestUtils.getShell();
|
|
118
|
+
|
|
119
|
+
// zsh outputs: "alias_name: aliased to command"
|
|
120
|
+
// bash outputs: "alias alias_name='command'"
|
|
121
|
+
return shell === 'bash'
|
|
122
|
+
? `${TestUtils.getShellCommand(`alias ${aliasName}`)}`
|
|
123
|
+
: `${TestUtils.getShellCommand(`which ${aliasName}`)}`;
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Check if running on macOS
|
|
128
|
+
*/
|
|
129
|
+
isMacOS(): boolean {
|
|
130
|
+
return os.platform() === 'darwin';
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check if running on Linux
|
|
135
|
+
*/
|
|
136
|
+
isLinux(): boolean {
|
|
137
|
+
return os.platform() === 'linux';
|
|
138
|
+
},
|
|
42
139
|
};
|