@hurshb50/setup-ubuntu 1.1.1 → 1.1.2
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/README.md +1 -1
- package/distribution/assets/.bashrc +5 -0
- package/distribution/setup-ubuntu.mjs +46 -42
- package/package.json +7 -10
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Sets up a fresh Ubuntu machine with tools, configuration, and dotfiles.
|
|
|
8
8
|
sudo apt update
|
|
9
9
|
sudo apt install -y curl ca-certificates
|
|
10
10
|
curl -fsSL https://vite.plus | bash
|
|
11
|
-
vpx @hurshb50/setup-ubuntu
|
|
11
|
+
vpx @hurshb50/setup-ubuntu@latest
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
Vite+ defaults to pnpm, which can hold back freshly published releases. The setup pins npm globally, so later commands need no prefix.
|
|
@@ -125,6 +125,10 @@ function fuzzy_finder() {
|
|
|
125
125
|
fi
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
function typescript_toolchain() {
|
|
129
|
+
. "/home/hpatel/.config/vite-plus/env"
|
|
130
|
+
}
|
|
131
|
+
|
|
128
132
|
function run() {
|
|
129
133
|
if ! is_interactive; then
|
|
130
134
|
return
|
|
@@ -141,6 +145,7 @@ function run() {
|
|
|
141
145
|
disable_legacy
|
|
142
146
|
swap_capslock_and_esc
|
|
143
147
|
fuzzy_finder
|
|
148
|
+
typescript_toolchain
|
|
144
149
|
start_auto_suggestion
|
|
145
150
|
}
|
|
146
151
|
|
|
@@ -7,10 +7,11 @@ import escapes from "ansi-escapes";
|
|
|
7
7
|
import { setTimeout } from "timers/promises";
|
|
8
8
|
import { stdout } from "process";
|
|
9
9
|
import fs from "fs/promises";
|
|
10
|
-
import
|
|
10
|
+
import util from "util";
|
|
11
|
+
import childProcess from "child_process";
|
|
11
12
|
//#region package.json
|
|
12
13
|
var name = "@hurshb50/setup-ubuntu";
|
|
13
|
-
var version = "1.1.
|
|
14
|
+
var version = "1.1.1";
|
|
14
15
|
//#endregion
|
|
15
16
|
//#region source/modules/logger/logger.ts
|
|
16
17
|
var Logger = class Logger {
|
|
@@ -160,10 +161,7 @@ var DependencyManager = class {
|
|
|
160
161
|
}
|
|
161
162
|
async commandExists(command) {
|
|
162
163
|
try {
|
|
163
|
-
|
|
164
|
-
shell: true,
|
|
165
|
-
stdin: "ignore"
|
|
166
|
-
});
|
|
164
|
+
childProcess.execSync(`command -v ${command}`);
|
|
167
165
|
return true;
|
|
168
166
|
} catch {
|
|
169
167
|
const commandFilePath = path.join(os.homedir(), ".local", "bin", command);
|
|
@@ -171,28 +169,22 @@ var DependencyManager = class {
|
|
|
171
169
|
}
|
|
172
170
|
}
|
|
173
171
|
async isInstalled(dependencies) {
|
|
174
|
-
|
|
172
|
+
const exec = util.promisify(childProcess.exec);
|
|
173
|
+
const queryCalls = dependencies.map(async (dependency) => {
|
|
175
174
|
try {
|
|
176
|
-
const { stdout } = await
|
|
177
|
-
"--show",
|
|
178
|
-
"--showformat=${Status}",
|
|
179
|
-
dependency
|
|
180
|
-
]);
|
|
175
|
+
const { stdout } = await exec(`dpkg-query --show --showformat='\${Status}' ${dependency}`);
|
|
181
176
|
return stdout.includes("install ok installed");
|
|
182
177
|
} catch {
|
|
183
178
|
return false;
|
|
184
179
|
}
|
|
185
|
-
})
|
|
180
|
+
});
|
|
181
|
+
return (await Promise.all(queryCalls)).every((query) => query === true);
|
|
186
182
|
}
|
|
187
183
|
async authenticate() {
|
|
188
184
|
if (await this.isAuthenticated()) return;
|
|
189
|
-
process.stdout.write("Administrator access is required to install packages. You may be prompted for your password.\n");
|
|
185
|
+
process.stdout.write("Administrator access is required to install packages. You may be prompted for your password.\n\n");
|
|
190
186
|
try {
|
|
191
|
-
await
|
|
192
|
-
stdin: "inherit",
|
|
193
|
-
stdout: "inherit",
|
|
194
|
-
stderr: "inherit"
|
|
195
|
-
});
|
|
187
|
+
await util.promisify(childProcess.exec)("sudo --validate");
|
|
196
188
|
} catch (error) {
|
|
197
189
|
throw new Error("Administrator access was not granted. Run 'sudo --validate' and then run this tool again.", { cause: error });
|
|
198
190
|
}
|
|
@@ -210,7 +202,7 @@ var DependencyManager = class {
|
|
|
210
202
|
}
|
|
211
203
|
async isAuthenticated() {
|
|
212
204
|
try {
|
|
213
|
-
await
|
|
205
|
+
await util.promisify(childProcess.exec)("sudo --non-interactive --validate");
|
|
214
206
|
return true;
|
|
215
207
|
} catch {
|
|
216
208
|
return false;
|
|
@@ -219,12 +211,16 @@ var DependencyManager = class {
|
|
|
219
211
|
enqueue(managerArguments, task) {
|
|
220
212
|
const operation = this.queue.then(async () => {
|
|
221
213
|
if (!await this.isAuthenticated()) throw new Error("Administrator access is no longer available for apt-get. Run 'sudo --validate' and then run this tool again.");
|
|
222
|
-
const subprocess =
|
|
214
|
+
const subprocess = childProcess.spawn("sudo", [
|
|
223
215
|
"env",
|
|
224
216
|
...["DEBIAN_FRONTEND=noninteractive", "NEEDRESTART_SUSPEND=1"],
|
|
225
217
|
"apt-get",
|
|
226
218
|
...managerArguments
|
|
227
|
-
], {
|
|
219
|
+
], { stdio: [
|
|
220
|
+
"ignore",
|
|
221
|
+
"pipe",
|
|
222
|
+
"pipe"
|
|
223
|
+
] });
|
|
228
224
|
let partial = "";
|
|
229
225
|
const track = (chunk) => {
|
|
230
226
|
partial += chunk.toString();
|
|
@@ -233,9 +229,12 @@ var DependencyManager = class {
|
|
|
233
229
|
const line = lines.at(-1)?.trim();
|
|
234
230
|
if (line) task.continue(line);
|
|
235
231
|
};
|
|
236
|
-
subprocess.stdout
|
|
237
|
-
subprocess.stderr
|
|
238
|
-
await
|
|
232
|
+
subprocess.stdout.on("data", track);
|
|
233
|
+
subprocess.stderr.on("data", track);
|
|
234
|
+
await new Promise((resolve, reject) => {
|
|
235
|
+
subprocess.once("error", reject);
|
|
236
|
+
subprocess.once("close", (code) => code === 0 ? resolve() : reject(/* @__PURE__ */ new Error(`apt-get exited with code ${code}`)));
|
|
237
|
+
});
|
|
239
238
|
});
|
|
240
239
|
this.queue = operation.catch(() => {});
|
|
241
240
|
return operation;
|
|
@@ -322,9 +321,10 @@ var AutoSuggestion = class {
|
|
|
322
321
|
const temporaryDirectoryPath = await fs.mkdtemp(path.join(os.tmpdir(), "ble.sh"));
|
|
323
322
|
const installationFilePath = path.join(temporaryDirectoryPath, "ble-nightly", "ble.sh");
|
|
324
323
|
task.continue("Download ble.sh");
|
|
325
|
-
|
|
324
|
+
const exec = util.promisify(childProcess.exec);
|
|
325
|
+
await exec(`curl -L https://github.com/akinomyoga/ble.sh/releases/download/nightly/ble-nightly.tar.xz | tar xJf - -C ${temporaryDirectoryPath}`);
|
|
326
326
|
task.continue("Install ble.sh");
|
|
327
|
-
await
|
|
327
|
+
await exec(`bash ${installationFilePath} --install ${destinationDirectoryPath}`);
|
|
328
328
|
task.continue("Remove temporary directory");
|
|
329
329
|
await fs.rm(temporaryDirectoryPath, { recursive: true });
|
|
330
330
|
}
|
|
@@ -353,8 +353,9 @@ var Browser = class {
|
|
|
353
353
|
const keyringFilePath = path.join("/", "usr", "share", "keyrings", "google-chrome.gpg");
|
|
354
354
|
const sourceFilePath = path.join("/", "etc", "apt", "sources.list.d", "google-chrome.list");
|
|
355
355
|
task.continue("Set up google chrome sources");
|
|
356
|
-
|
|
357
|
-
await
|
|
356
|
+
const exec = util.promisify(childProcess.exec);
|
|
357
|
+
await exec(`curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor --yes -o ${keyringFilePath}`);
|
|
358
|
+
await exec(`echo 'deb [arch=amd64 signed-by=${keyringFilePath}] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee ${sourceFilePath} > /dev/null`);
|
|
358
359
|
task.continue("Update package manager");
|
|
359
360
|
await context.dependencyManager.update(task);
|
|
360
361
|
task.continue(`Installing dependencies: ${dependencies.join(", ")}`);
|
|
@@ -372,7 +373,7 @@ var CodeEditor = class {
|
|
|
372
373
|
const sourceDirectoryPath = path.join(context.directories.assets, "zed");
|
|
373
374
|
const destinationDirectoryPath = path.join(context.directories.home, ".config", "zed");
|
|
374
375
|
task.continue("Install Zed");
|
|
375
|
-
if (!await context.dependencyManager.commandExists("zed")) await
|
|
376
|
+
if (!await context.dependencyManager.commandExists("zed")) await util.promisify(childProcess.exec)("curl -f https://zed.dev/install.sh | sh");
|
|
376
377
|
task.continue("Copy configuration");
|
|
377
378
|
await fs.cp(sourceDirectoryPath, destinationDirectoryPath, {
|
|
378
379
|
recursive: true,
|
|
@@ -401,8 +402,9 @@ var CodeHost = class {
|
|
|
401
402
|
const keyringFilePath = path.join("/", "usr", "share", "keyrings", "github-cli.gpg");
|
|
402
403
|
const sourceFilePath = path.join("/", "etc", "apt", "sources.list.d", "github-cli.list");
|
|
403
404
|
task.continue("Set up github cli sources");
|
|
404
|
-
|
|
405
|
-
await
|
|
405
|
+
const exec = util.promisify(childProcess.exec);
|
|
406
|
+
await exec(`curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.asc | sudo gpg --dearmor --yes -o ${keyringFilePath}`);
|
|
407
|
+
await exec(`echo "deb [arch=$(dpkg --print-architecture) signed-by=${keyringFilePath}] https://cli.github.com/packages stable main" | sudo tee ${sourceFilePath} > /dev/null`);
|
|
406
408
|
task.continue("Update package manager");
|
|
407
409
|
await context.dependencyManager.update(task);
|
|
408
410
|
task.continue(`Installing dependencies: ${dependencies.join(", ")}`);
|
|
@@ -436,14 +438,15 @@ var ContainerEngine = class {
|
|
|
436
438
|
const keyringFilePath = path.join("/", "usr", "share", "keyrings", "docker.gpg");
|
|
437
439
|
const sourceFilePath = path.join("/", "etc", "apt", "sources.list.d", "docker.list");
|
|
438
440
|
task.continue("Set up docker sources");
|
|
439
|
-
|
|
440
|
-
await
|
|
441
|
+
const exec = util.promisify(childProcess.exec);
|
|
442
|
+
await exec(`curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor --yes -o ${keyringFilePath}`);
|
|
443
|
+
await exec(`echo "deb [arch=$(dpkg --print-architecture) signed-by=${keyringFilePath}] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee ${sourceFilePath} > /dev/null`);
|
|
441
444
|
task.continue("Update package manager");
|
|
442
445
|
await context.dependencyManager.update(task);
|
|
443
446
|
task.continue(`Installing dependencies: ${dependencies.join(", ")}`);
|
|
444
447
|
await context.dependencyManager.install(dependencies, task);
|
|
445
448
|
task.continue("Add user to docker group");
|
|
446
|
-
await
|
|
449
|
+
await exec(`sudo usermod --append --groups docker ${os.userInfo().username}`);
|
|
447
450
|
task.finish();
|
|
448
451
|
}
|
|
449
452
|
};
|
|
@@ -516,12 +519,13 @@ var PasswordManager = class {
|
|
|
516
519
|
const debsigKeyringDirectoryPath = path.join("/", "usr", "share", "debsig", "keyrings", "AC2D62742012EA22");
|
|
517
520
|
const debsigKeyringFilePath = path.join(debsigKeyringDirectoryPath, "debsig.gpg");
|
|
518
521
|
task.continue("Set up 1password sources");
|
|
519
|
-
|
|
520
|
-
await
|
|
521
|
-
await
|
|
522
|
-
await
|
|
523
|
-
await
|
|
524
|
-
await
|
|
522
|
+
const exec = util.promisify(childProcess.exec);
|
|
523
|
+
await exec(`curl -sS https://downloads.1password.com/linux/keys/1password.asc | sudo gpg --dearmor --yes --output ${keyringFilePath}`);
|
|
524
|
+
await exec(`echo 'deb [arch=amd64 signed-by=${keyringFilePath}] https://downloads.1password.com/linux/debian/amd64 stable main' | sudo tee ${sourceFilePath}`);
|
|
525
|
+
await exec(`sudo mkdir -p ${policyDirectoryPath}`);
|
|
526
|
+
await exec(`curl -sS https://downloads.1password.com/linux/debian/debsig/1password.pol | sudo tee ${policyFilePath}`);
|
|
527
|
+
await exec(`sudo mkdir -p ${debsigKeyringDirectoryPath}`);
|
|
528
|
+
await exec(`curl -sS https://downloads.1password.com/linux/keys/1password.asc | sudo gpg --dearmor --yes --output ${debsigKeyringFilePath}`);
|
|
525
529
|
task.continue("Update package manager");
|
|
526
530
|
await context.dependencyManager.update(task);
|
|
527
531
|
task.continue(`Installing dependencies: ${dependencies.join(", ")}`);
|
|
@@ -580,7 +584,7 @@ var TerminalView = class {
|
|
|
580
584
|
task.continue(`Installing dependencies: ${dependencies.join(", ")}`);
|
|
581
585
|
await context.dependencyManager.install(dependencies, task);
|
|
582
586
|
task.continue("Install oh-my-posh");
|
|
583
|
-
await
|
|
587
|
+
await util.promisify(childProcess.exec)("curl -s https://ohmyposh.dev/install.sh | bash -s");
|
|
584
588
|
}
|
|
585
589
|
const sourceFilePath = path.join(context.directories.assets, "oh-my-posh.toml");
|
|
586
590
|
const destinationDirectoryPath = path.join(context.directories.home, ".config", "oh-my-posh");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hurshb50/setup-ubuntu",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"distribution"
|
|
@@ -10,12 +10,9 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@commander-js/extra-typings": "^15.0.0",
|
|
13
|
+
"@types/node": "latest",
|
|
13
14
|
"ansi-escapes": "^7.3.0",
|
|
14
15
|
"ansi-styles": "^7.0.0",
|
|
15
|
-
"execa": "^10.0.1"
|
|
16
|
-
},
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"@types/node": "latest",
|
|
19
16
|
"typescript": "^7.0.2",
|
|
20
17
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.3.1",
|
|
21
18
|
"vite-plus": "^0.2.4",
|
|
@@ -26,13 +23,13 @@
|
|
|
26
23
|
},
|
|
27
24
|
"devEngines": {
|
|
28
25
|
"runtime": {
|
|
29
|
-
"name": "
|
|
30
|
-
"version": "
|
|
26
|
+
"name": "node",
|
|
27
|
+
"version": "24.21.0",
|
|
31
28
|
"onFail": "download"
|
|
32
29
|
},
|
|
33
30
|
"packageManager": {
|
|
34
31
|
"name": "pnpm",
|
|
35
|
-
"version": "12.
|
|
32
|
+
"version": "12.6.0",
|
|
36
33
|
"onFail": "download"
|
|
37
34
|
}
|
|
38
35
|
},
|
|
@@ -55,7 +52,7 @@
|
|
|
55
52
|
"check": "vp check",
|
|
56
53
|
"fix": "vp check --fix",
|
|
57
54
|
"unit-test": "vp test --project unit",
|
|
58
|
-
"integration-test": "
|
|
59
|
-
"end-to-end-test": "
|
|
55
|
+
"integration-test": "node scripts/integration.ts",
|
|
56
|
+
"end-to-end-test": "node scripts/end-to-end.ts"
|
|
60
57
|
}
|
|
61
58
|
}
|