easy-devops 0.1.7 → 0.1.8

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.
@@ -370,9 +370,93 @@ async function installCertbot() {
370
370
  console.log(chalk.gray(`\n [${methodNum}] ${label}\n`));
371
371
  }
372
372
 
373
+ // ── Check winget availability and offer to install if missing ─────────────────
374
+ let wingetAvailable = false;
375
+ const wingetCheck = await run('where.exe winget 2>$null');
376
+ wingetAvailable = wingetCheck.success && wingetCheck.stdout.trim();
377
+
378
+ if (!wingetAvailable) {
379
+ console.log(chalk.yellow('\n ⚠ winget is not installed on this system.'));
380
+ console.log(chalk.gray(' winget (Windows Package Manager) provides the easiest installation method.'));
381
+
382
+ let installWinget;
383
+ try {
384
+ ({ installWinget } = await inquirer.prompt([{
385
+ type: 'confirm',
386
+ name: 'installWinget',
387
+ message: 'Would you like to install winget (App Installer) from Microsoft Store?',
388
+ default: true,
389
+ }]));
390
+ } catch { /* user cancelled */ }
391
+
392
+ if (installWinget) {
393
+ console.log(chalk.cyan('\n Opening Microsoft Store to install App Installer...'));
394
+ console.log(chalk.gray(' Please complete the installation, then run this command again.\n'));
395
+
396
+ // Try to open Microsoft Store
397
+ const storeOpened = await run(
398
+ 'Start-Process "ms-windows-store://pdp/?ProductId=9NBLGGH4NNS1"',
399
+ { timeout: 10000 }
400
+ ).catch(() => ({ success: false }));
401
+
402
+ if (storeOpened.success) {
403
+ console.log(chalk.green(' Microsoft Store opened successfully.'));
404
+ console.log(chalk.gray(' After installing App Installer, winget will be available.\n'));
405
+ } else {
406
+ console.log(chalk.yellow(' Could not open Microsoft Store directly.'));
407
+ console.log(chalk.gray(' Please manually install "App Installer" from:'));
408
+ console.log(chalk.cyan(' https://apps.microsoft.com/store/detail/app-installer/9NBLGGH4NNS1\n'));
409
+ }
410
+
411
+ // Optional: try direct download of App Installer
412
+ let tryDownload;
413
+ try {
414
+ ({ tryDownload } = await inquirer.prompt([{
415
+ type: 'confirm',
416
+ name: 'tryDownload',
417
+ message: 'Would you like to try downloading App Installer directly?',
418
+ default: false,
419
+ }]));
420
+ } catch { tryDownload = false; }
421
+
422
+ if (tryDownload) {
423
+ const appInstallerUrl = 'https://aka.ms/getwinget';
424
+ const appInstallerDest = '$env:TEMP\\AppInstaller.msixbundle';
425
+
426
+ console.log(chalk.gray('\n Downloading App Installer...'));
427
+ const downloaded = await downloadFile(appInstallerUrl, appInstallerDest);
428
+
429
+ if (downloaded) {
430
+ console.log(chalk.gray(' Running App Installer...'));
431
+ await run(`Start-Process -FilePath '${appInstallerDest}' -Wait`, { timeout: 300000 });
432
+
433
+ // Re-check for winget
434
+ const recheck = await run('where.exe winget 2>$null');
435
+ if (recheck.success && recheck.stdout.trim()) {
436
+ console.log(chalk.green('\n ✓ winget installed successfully!\n'));
437
+ wingetAvailable = true;
438
+ } else {
439
+ console.log(chalk.yellow('\n App Installer ran but winget is not yet available.'));
440
+ console.log(chalk.gray(' You may need to restart your terminal or sign out/in.\n'));
441
+ }
442
+ } else {
443
+ console.log(chalk.yellow('\n Could not download App Installer automatically.\n'));
444
+ }
445
+ }
446
+
447
+ // If still no winget, continue with other methods
448
+ if (!wingetAvailable) {
449
+ console.log(chalk.gray(' Continuing with alternative installation methods...\n'));
450
+ }
451
+ } else {
452
+ console.log(chalk.gray(' Skipping winget installation. Using alternative methods...\n'));
453
+ }
454
+ }
455
+
373
456
  // ── Method 1: winget (win-acme - has better success rate) ─────────────────────
374
- if ((await run('where.exe winget 2>$null')).success) {
457
+ if (wingetAvailable) {
375
458
  step('Trying winget (win-acme) ...');
459
+ console.log(chalk.gray(' Running: winget install win-acme.win-acme\n'));
376
460
  const exitCode = await runLive(
377
461
  'winget install -e --id win-acme.win-acme --accept-package-agreements --accept-source-agreements',
378
462
  { timeout: 180000 },
@@ -382,8 +466,9 @@ async function installCertbot() {
382
466
  }
383
467
 
384
468
  // ── Method 2: winget (certbot EFF) ────────────────────────────────────────────
385
- if ((await run('where.exe winget 2>$null')).success) {
469
+ if (wingetAvailable) {
386
470
  step('Trying winget (EFF.Certbot) ...');
471
+ console.log(chalk.gray(' Running: winget install EFF.Certbot\n'));
387
472
  const exitCode = await runLive(
388
473
  'winget install -e --id EFF.Certbot --accept-package-agreements --accept-source-agreements',
389
474
  { timeout: 180000 },
@@ -485,8 +570,8 @@ async function installCertbot() {
485
570
  // ── Method 9: Manual installer path ───────────────────────────────────────────
486
571
  console.log(chalk.yellow('\n All automatic methods failed.'));
487
572
  console.log(chalk.gray(' You can manually download one of these on another PC:'));
488
- console.log(chalk.gray(' • certbot: https://certbot.eff.org/instructions?ws=other&os=windows'));
489
- console.log(chalk.gray(' • win-acme: https://github.com/win-acme/win-acme/releases'));
573
+ console.log(chalk.gray(' • certbot: https://certbot.eff.org/instructions?ws=other&os=windows'));
574
+ console.log(chalk.gray(' • win-acme: https://github.com/win-acme/win-acme/releases'));
490
575
  console.log(chalk.gray(' Then transfer to this server and use "Specify local installer" below.\n'));
491
576
 
492
577
  let localChoice;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easy-devops",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "A unified DevOps management tool with CLI and web dashboard for managing Nginx, SSL certificates, and Node.js on Linux and Windows servers.",
5
5
  "keywords": [
6
6
  "devops",