codify-plugin-lib 1.0.182-beta56 → 1.0.182-beta58
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/pty/index.d.ts +4 -0
- package/dist/pty/seqeuntial-pty.js +3 -2
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +55 -1
- package/package.json +1 -1
- package/src/pty/index.ts +4 -0
- package/src/pty/seqeuntial-pty.ts +3 -2
- package/src/utils/index.ts +67 -1
package/dist/pty/index.d.ts
CHANGED
|
@@ -21,6 +21,9 @@ export declare enum SpawnStatus {
|
|
|
21
21
|
*
|
|
22
22
|
* @property {boolean} [interactive] - Indicates whether the spawned process needs
|
|
23
23
|
* to be interactive. Only works within apply (not plan). Defaults to true.
|
|
24
|
+
*
|
|
25
|
+
* @property {boolean} [disableWrapping] - Forces the terminal width to 10_000 to disable wrapping.
|
|
26
|
+
* In applys, this is off by default while it is on during plans.
|
|
24
27
|
*/
|
|
25
28
|
export interface SpawnOptions {
|
|
26
29
|
cwd?: string;
|
|
@@ -28,6 +31,7 @@ export interface SpawnOptions {
|
|
|
28
31
|
interactive?: boolean;
|
|
29
32
|
requiresRoot?: boolean;
|
|
30
33
|
stdin?: boolean;
|
|
34
|
+
disableWrapping?: boolean;
|
|
31
35
|
}
|
|
32
36
|
export declare class SpawnError extends Error {
|
|
33
37
|
data: string;
|
|
@@ -49,7 +49,8 @@ export class SequentialPty {
|
|
|
49
49
|
...historyIgnore
|
|
50
50
|
};
|
|
51
51
|
// Initial terminal dimensions
|
|
52
|
-
|
|
52
|
+
// Set to a really large value to prevent wrapping
|
|
53
|
+
const initialCols = options?.disableWrapping ? 10_000 : process.stdout.columns ?? 80;
|
|
53
54
|
const initialRows = process.stdout.rows ?? 24;
|
|
54
55
|
const args = options?.interactive ? ['-i', '-c', cmd] : ['-c', cmd];
|
|
55
56
|
// Run the command in a pty for interactivity
|
|
@@ -67,7 +68,7 @@ export class SequentialPty {
|
|
|
67
68
|
});
|
|
68
69
|
const resizeListener = () => {
|
|
69
70
|
const { columns, rows } = process.stdout;
|
|
70
|
-
mPty.resize(columns, rows);
|
|
71
|
+
mPty.resize(columns, options?.disableWrapping ? 10_000 : rows);
|
|
71
72
|
};
|
|
72
73
|
// Listen to resize events for the terminal window;
|
|
73
74
|
process.stdout.on('resize', resizeListener);
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -27,4 +27,11 @@ export declare const Utils: {
|
|
|
27
27
|
getPrimaryShellRc(): string;
|
|
28
28
|
getShellRcFiles(): string[];
|
|
29
29
|
isDirectoryOnPath(directory: string): Promise<boolean>;
|
|
30
|
+
assertBrewInstalled(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Installs a package via the system package manager. This will use Homebrew on macOS and apt on Ubuntu/Debian or dnf on Fedora.
|
|
33
|
+
* @param packageName
|
|
34
|
+
*/
|
|
35
|
+
installViaPkgMgr(packageName: string): Promise<boolean>;
|
|
36
|
+
linuxDistro(): Promise<"arch" | "centos" | "debian" | "fedora" | "rhel" | "ubuntu" | undefined>;
|
|
30
37
|
};
|
package/dist/utils/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
1
2
|
import os from 'node:os';
|
|
2
3
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
4
|
+
import { SpawnStatus, getPty } from '../pty/index.js';
|
|
4
5
|
export function isDebug() {
|
|
5
6
|
return process.env.DEBUG != null && process.env.DEBUG.includes('codify'); // TODO: replace with debug library
|
|
6
7
|
}
|
|
@@ -138,4 +139,57 @@ export const Utils = {
|
|
|
138
139
|
const lines = pathQuery.split(':');
|
|
139
140
|
return lines.includes(directory);
|
|
140
141
|
},
|
|
142
|
+
async assertBrewInstalled() {
|
|
143
|
+
const $ = getPty();
|
|
144
|
+
const brewCheck = await $.spawnSafe('which brew', { interactive: true });
|
|
145
|
+
if (brewCheck.status === SpawnStatus.ERROR) {
|
|
146
|
+
throw new Error(`Homebrew is not installed. Cannot install git-lfs without Homebrew installed.
|
|
147
|
+
|
|
148
|
+
Brew can be installed using Codify:
|
|
149
|
+
{
|
|
150
|
+
"type": "homebrew",
|
|
151
|
+
}`);
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
/**
|
|
155
|
+
* Installs a package via the system package manager. This will use Homebrew on macOS and apt on Ubuntu/Debian or dnf on Fedora.
|
|
156
|
+
* @param packageName
|
|
157
|
+
*/
|
|
158
|
+
async installViaPkgMgr(packageName) {
|
|
159
|
+
const $ = getPty();
|
|
160
|
+
if (Utils.isMacOS()) {
|
|
161
|
+
await this.assertBrewInstalled();
|
|
162
|
+
const { status } = await $.spawnSafe(`brew install ${packageName}`, { interactive: true, env: { HOMEBREW_NO_AUTO_UPDATE: 1 } });
|
|
163
|
+
return status === SpawnStatus.SUCCESS;
|
|
164
|
+
}
|
|
165
|
+
if (Utils.isLinux()) {
|
|
166
|
+
const isAptInstalled = await $.spawnSafe('which apt');
|
|
167
|
+
if (isAptInstalled.status === SpawnStatus.SUCCESS) {
|
|
168
|
+
const { status } = await $.spawnSafe(`apt install ${packageName}`, { interactive: true, env: { DEBIAN_FRONTEND: 'noninteractive' } });
|
|
169
|
+
return status === SpawnStatus.SUCCESS;
|
|
170
|
+
}
|
|
171
|
+
const isDnfInstalled = await $.spawnSafe('which dnf');
|
|
172
|
+
if (isDnfInstalled.status === SpawnStatus.SUCCESS) {
|
|
173
|
+
const { status } = await $.spawnSafe(`dnf install ${packageName} -y`, { interactive: true });
|
|
174
|
+
return status === SpawnStatus.SUCCESS;
|
|
175
|
+
}
|
|
176
|
+
const isYumInstalled = await $.spawnSafe('which yum');
|
|
177
|
+
if (isYumInstalled.status === SpawnStatus.SUCCESS) {
|
|
178
|
+
const { status } = await $.spawnSafe(`yum install ${packageName} -y`, { interactive: true });
|
|
179
|
+
return status === SpawnStatus.SUCCESS;
|
|
180
|
+
}
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
},
|
|
185
|
+
async linuxDistro() {
|
|
186
|
+
const osRelease = await fs.readFile('/etc/os-release', 'utf8');
|
|
187
|
+
const lines = osRelease.split('\n');
|
|
188
|
+
for (const line of lines) {
|
|
189
|
+
if (line.startsWith('ID=')) {
|
|
190
|
+
return line.slice(3).trim();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
141
195
|
};
|
package/package.json
CHANGED
package/src/pty/index.ts
CHANGED
|
@@ -25,6 +25,9 @@ export enum SpawnStatus {
|
|
|
25
25
|
*
|
|
26
26
|
* @property {boolean} [interactive] - Indicates whether the spawned process needs
|
|
27
27
|
* to be interactive. Only works within apply (not plan). Defaults to true.
|
|
28
|
+
*
|
|
29
|
+
* @property {boolean} [disableWrapping] - Forces the terminal width to 10_000 to disable wrapping.
|
|
30
|
+
* In applys, this is off by default while it is on during plans.
|
|
28
31
|
*/
|
|
29
32
|
export interface SpawnOptions {
|
|
30
33
|
cwd?: string;
|
|
@@ -32,6 +35,7 @@ export interface SpawnOptions {
|
|
|
32
35
|
interactive?: boolean;
|
|
33
36
|
requiresRoot?: boolean;
|
|
34
37
|
stdin?: boolean;
|
|
38
|
+
disableWrapping?: boolean;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
export class SpawnError extends Error {
|
|
@@ -62,7 +62,8 @@ export class SequentialPty implements IPty {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// Initial terminal dimensions
|
|
65
|
-
|
|
65
|
+
// Set to a really large value to prevent wrapping
|
|
66
|
+
const initialCols = options?.disableWrapping ? 10_000 : process.stdout.columns ?? 80
|
|
66
67
|
const initialRows = process.stdout.rows ?? 24;
|
|
67
68
|
|
|
68
69
|
const args = options?.interactive ? ['-i', '-c', cmd] : ['-c', cmd]
|
|
@@ -85,7 +86,7 @@ export class SequentialPty implements IPty {
|
|
|
85
86
|
|
|
86
87
|
const resizeListener = () => {
|
|
87
88
|
const { columns, rows } = process.stdout;
|
|
88
|
-
mPty.resize(columns, rows);
|
|
89
|
+
mPty.resize(columns, options?.disableWrapping ? 10_000 : rows);
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
// Listen to resize events for the terminal window;
|
package/src/utils/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { OS } from 'codify-schemas';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
2
3
|
import os from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
|
|
5
|
-
import {
|
|
6
|
+
import { SpawnStatus, getPty } from '../pty/index.js';
|
|
6
7
|
|
|
7
8
|
export function isDebug(): boolean {
|
|
8
9
|
return process.env.DEBUG != null && process.env.DEBUG.includes('codify'); // TODO: replace with debug library
|
|
@@ -175,6 +176,71 @@ export const Utils = {
|
|
|
175
176
|
const lines = pathQuery.split(':');
|
|
176
177
|
return lines.includes(directory);
|
|
177
178
|
},
|
|
179
|
+
|
|
180
|
+
async assertBrewInstalled(): Promise<void> {
|
|
181
|
+
const $ = getPty();
|
|
182
|
+
const brewCheck = await $.spawnSafe('which brew', { interactive: true });
|
|
183
|
+
if (brewCheck.status === SpawnStatus.ERROR) {
|
|
184
|
+
throw new Error(
|
|
185
|
+
`Homebrew is not installed. Cannot install git-lfs without Homebrew installed.
|
|
186
|
+
|
|
187
|
+
Brew can be installed using Codify:
|
|
188
|
+
{
|
|
189
|
+
"type": "homebrew",
|
|
190
|
+
}`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Installs a package via the system package manager. This will use Homebrew on macOS and apt on Ubuntu/Debian or dnf on Fedora.
|
|
197
|
+
* @param packageName
|
|
198
|
+
*/
|
|
199
|
+
async installViaPkgMgr(packageName: string): Promise<boolean> {
|
|
200
|
+
const $ = getPty();
|
|
201
|
+
|
|
202
|
+
if (Utils.isMacOS()) {
|
|
203
|
+
await this.assertBrewInstalled();
|
|
204
|
+
const { status } = await $.spawnSafe(`brew install ${packageName}`, { interactive: true, env: { HOMEBREW_NO_AUTO_UPDATE: 1 } });
|
|
205
|
+
return status === SpawnStatus.SUCCESS;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (Utils.isLinux()) {
|
|
209
|
+
const isAptInstalled = await $.spawnSafe('which apt');
|
|
210
|
+
if (isAptInstalled.status === SpawnStatus.SUCCESS) {
|
|
211
|
+
const { status } = await $.spawnSafe(`apt install ${packageName}`, { interactive: true, env: { DEBIAN_FRONTEND: 'noninteractive' } });
|
|
212
|
+
return status === SpawnStatus.SUCCESS;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const isDnfInstalled = await $.spawnSafe('which dnf');
|
|
216
|
+
if (isDnfInstalled.status === SpawnStatus.SUCCESS) {
|
|
217
|
+
const { status } = await $.spawnSafe(`dnf install ${packageName} -y`, { interactive: true });
|
|
218
|
+
return status === SpawnStatus.SUCCESS;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const isYumInstalled = await $.spawnSafe('which yum');
|
|
222
|
+
if (isYumInstalled.status === SpawnStatus.SUCCESS) {
|
|
223
|
+
const { status } = await $.spawnSafe(`yum install ${packageName} -y`, { interactive: true });
|
|
224
|
+
return status === SpawnStatus.SUCCESS;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return false;
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
async linuxDistro(): Promise<'arch' | 'centos' | 'debian' | 'fedora' | 'rhel' | 'ubuntu' | undefined> {
|
|
234
|
+
const osRelease = await fs.readFile('/etc/os-release', 'utf8');
|
|
235
|
+
const lines = osRelease.split('\n');
|
|
236
|
+
for (const line of lines) {
|
|
237
|
+
if (line.startsWith('ID=')) {
|
|
238
|
+
return line.slice(3).trim() as any;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
178
244
|
};
|
|
179
245
|
|
|
180
246
|
|