@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 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
 
@@ -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 { execa } from "execa";
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.0.3";
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
- await execa("command", ["-v", command], {
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
- return (await Promise.all(dependencies.map(async (dependency) => {
172
+ const exec = util.promisify(childProcess.exec);
173
+ const queryCalls = dependencies.map(async (dependency) => {
175
174
  try {
176
- const { stdout } = await execa("dpkg-query", [
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
- }))).every((installation) => installation === true);
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 execa("sudo", ["--validate"], {
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 execa("sudo", ["--non-interactive", "--validate"], { stdin: "ignore" });
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 = execa("sudo", [
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
- ], { stdin: "ignore" });
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?.on("data", track);
237
- subprocess.stderr?.on("data", track);
238
- await subprocess;
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
- await execa(`curl -L https://github.com/akinomyoga/ble.sh/releases/download/nightly/ble-nightly.tar.xz | tar xJf - -C ${temporaryDirectoryPath}`, { shell: true });
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 execa(`bash ${installationFilePath} --install ${destinationDirectoryPath}`, { shell: true });
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
- await execa(`curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | sudo gpg --dearmor --yes -o ${keyringFilePath}`, { shell: true });
357
- await execa(`echo 'deb [arch=amd64 signed-by=${keyringFilePath}] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee ${sourceFilePath} > /dev/null`, { shell: true });
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 execa("curl -f https://zed.dev/install.sh | sh", { shell: true });
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
- await execa(`curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.asc | sudo gpg --dearmor --yes -o ${keyringFilePath}`, { shell: true });
405
- await execa(`echo "deb [arch=$(dpkg --print-architecture) signed-by=${keyringFilePath}] https://cli.github.com/packages stable main" | sudo tee ${sourceFilePath} > /dev/null`, { shell: true });
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
- await execa(`curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor --yes -o ${keyringFilePath}`, { shell: true });
440
- await execa(`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`, { shell: true });
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 execa(`sudo usermod --append --groups docker ${os.userInfo().username}`, { shell: true });
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 = ["libasound2t64", "1password"];
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
- await execa(`curl -sS https://downloads.1password.com/linux/keys/1password.asc | sudo gpg --dearmor --yes --output ${keyringFilePath}`, { shell: true });
520
- await execa(`echo 'deb [arch=amd64 signed-by=${keyringFilePath}] https://downloads.1password.com/linux/debian/amd64 stable main' | sudo tee ${sourceFilePath}`, { shell: true });
521
- await execa(`sudo mkdir -p ${policyDirectoryPath}`, { shell: true });
522
- await execa(`curl -sS https://downloads.1password.com/linux/debian/debsig/1password.pol | sudo tee ${policyFilePath}`, { shell: true });
523
- await execa(`sudo mkdir -p ${debsigKeyringDirectoryPath}`, { shell: true });
524
- await execa(`curl -sS https://downloads.1password.com/linux/keys/1password.asc | sudo gpg --dearmor --yes --output ${debsigKeyringFilePath}`, { shell: true });
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 execa("curl -s https://ohmyposh.dev/install.sh | bash -s", { shell: true });
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.0",
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": "bun",
30
- "version": "1.4.2",
26
+ "name": "node",
27
+ "version": "24.21.0",
31
28
  "onFail": "download"
32
29
  },
33
30
  "packageManager": {
34
31
  "name": "pnpm",
35
- "version": "12.5.1",
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": "bun scripts/integration.ts",
59
- "end-to-end-test": "bun scripts/end-to-end.ts"
55
+ "integration-test": "node scripts/integration.ts",
56
+ "end-to-end-test": "node scripts/end-to-end.ts"
60
57
  }
61
58
  }