@hurshb50/setup-ubuntu 1.1.0 → 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 -5
- package/distribution/assets/fonts/comic-code/ComicCodeLigatures-Bold.otf +0 -0
- package/distribution/assets/fonts/comic-code/ComicCodeLigatures-BoldItalic.otf +0 -0
- package/distribution/assets/fonts/comic-code/ComicCodeLigatures-Italic.otf +0 -0
- package/distribution/assets/fonts/comic-code/ComicCodeLigatures-Medium.otf +0 -0
- package/distribution/assets/fonts/comic-code/ComicCodeLigatures-MediumItalic.otf +0 -0
- package/distribution/assets/fonts/comic-code/ComicCodeLigatures-Regular.otf +0 -0
- package/distribution/assets/fonts/nerd-fonts-symbols/symbols-nerd-font-mono-regular.otf +0 -0
- package/distribution/assets/fonts/nerd-fonts-symbols/symbols-nerd-font-regular.otf +0 -0
- package/distribution/setup-ubuntu.mjs +51 -43
- 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.
|
|
@@ -29,10 +29,6 @@ function path() {
|
|
|
29
29
|
export PATH="$HOME/.local/bin:$PATH"
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
function package_manager() {
|
|
33
|
-
export VP_PACKAGE_MANAGER="npm@12"
|
|
34
|
-
}
|
|
35
|
-
|
|
36
32
|
function setup_history() {
|
|
37
33
|
shopt -s histappend
|
|
38
34
|
shopt -s checkwinsize
|
|
@@ -129,13 +125,16 @@ function fuzzy_finder() {
|
|
|
129
125
|
fi
|
|
130
126
|
}
|
|
131
127
|
|
|
128
|
+
function typescript_toolchain() {
|
|
129
|
+
. "/home/hpatel/.config/vite-plus/env"
|
|
130
|
+
}
|
|
131
|
+
|
|
132
132
|
function run() {
|
|
133
133
|
if ! is_interactive; then
|
|
134
134
|
return
|
|
135
135
|
fi
|
|
136
136
|
|
|
137
137
|
path
|
|
138
|
-
package_manager
|
|
139
138
|
load_auto_suggestion
|
|
140
139
|
setup_history
|
|
141
140
|
completion
|
|
@@ -146,6 +145,7 @@ function run() {
|
|
|
146
145
|
disable_legacy
|
|
147
146
|
swap_capslock_and_esc
|
|
148
147
|
fuzzy_finder
|
|
148
|
+
typescript_toolchain
|
|
149
149
|
start_auto_suggestion
|
|
150
150
|
}
|
|
151
151
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -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.
|
|
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
|
};
|
|
@@ -499,7 +502,7 @@ var PasswordManager = class {
|
|
|
499
502
|
const task = new Task("Password Manager");
|
|
500
503
|
context.logger.add(task);
|
|
501
504
|
task.start();
|
|
502
|
-
const dependencies = ["
|
|
505
|
+
const dependencies = [alsaPackageName(await fs.readFile(path.join("/", "etc", "os-release"), "utf8")), "1password"];
|
|
503
506
|
if (await context.dependencyManager.isInstalled(dependencies)) {
|
|
504
507
|
task.finish();
|
|
505
508
|
return;
|
|
@@ -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(", ")}`);
|
|
@@ -529,6 +533,10 @@ var PasswordManager = class {
|
|
|
529
533
|
task.finish();
|
|
530
534
|
}
|
|
531
535
|
};
|
|
536
|
+
function alsaPackageName(osRelease) {
|
|
537
|
+
const versionId = osRelease.match(/^VERSION_ID="?([\d.]+)"?$/m)?.[1];
|
|
538
|
+
return Number.parseInt(versionId ?? "", 10) >= 24 ? "libasound2t64" : "libasound2";
|
|
539
|
+
}
|
|
532
540
|
//#endregion
|
|
533
541
|
//#region source/modules/shell-configuration/shell-configuration.ts
|
|
534
542
|
var ShellConfiguration = class {
|
|
@@ -576,7 +584,7 @@ var TerminalView = class {
|
|
|
576
584
|
task.continue(`Installing dependencies: ${dependencies.join(", ")}`);
|
|
577
585
|
await context.dependencyManager.install(dependencies, task);
|
|
578
586
|
task.continue("Install oh-my-posh");
|
|
579
|
-
await
|
|
587
|
+
await util.promisify(childProcess.exec)("curl -s https://ohmyposh.dev/install.sh | bash -s");
|
|
580
588
|
}
|
|
581
589
|
const sourceFilePath = path.join(context.directories.assets, "oh-my-posh.toml");
|
|
582
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
|
}
|