penguins-eggs 25.12.7 → 25.12.15

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.
Files changed (53) hide show
  1. package/.oclif.manifest.json +1 -1
  2. package/README.md +74 -45
  3. package/README.pdf +13450 -14838
  4. package/addons/eggs/theme/livecd/simple.grub.main.cfg +3 -3
  5. package/conf/distros/buster/calamares/calamares-modules/cleanup/cleanup.sh +1 -1
  6. package/conf/distros/focal/calamares/calamares-modules/cleanup/cleanup.sh +1 -1
  7. package/conf/distros/noble/calamares/calamares-modules/cleanup/cleanup.sh +1 -1
  8. package/conf/distros/noble/calamares/libexec/calamares-l10n-helper.sh +2 -1
  9. package/conf/distros/noble/calamares/settings.yml +1 -0
  10. package/conf/distros/trixie/calamares/calamares-modules/cleanup/cleanup.sh +1 -1
  11. package/dist/classes/cli-autologin.d.ts +37 -4
  12. package/dist/classes/cli-autologin.js +125 -112
  13. package/dist/classes/daddy.js +4 -1
  14. package/dist/classes/incubation/fisherman-helper/initcpio.d.ts +3 -2
  15. package/dist/classes/incubation/fisherman-helper/initcpio.js +25 -20
  16. package/dist/classes/incubation/incubator.d/manjaro.js +1 -0
  17. package/dist/classes/ovary.d/edit-live-fs.d.ts +1 -1
  18. package/dist/classes/ovary.d/edit-live-fs.js +15 -122
  19. package/dist/classes/ovary.d/fertilization.js +1 -1
  20. package/dist/classes/ovary.d/luks-home.js +33 -19
  21. package/dist/classes/ovary.d/luks-root.d.ts +1 -2
  22. package/dist/classes/ovary.d/luks-root.js +46 -27
  23. package/dist/classes/ovary.d/luks-shrink.d.ts +14 -0
  24. package/dist/classes/ovary.d/luks-shrink.js +86 -0
  25. package/dist/classes/ovary.d/produce.js +63 -21
  26. package/dist/classes/ovary.d.ts +3 -1
  27. package/dist/classes/ovary.js +3 -1
  28. package/dist/classes/utils.js +1 -1
  29. package/dist/classes/yolk.js +1 -1
  30. package/dist/commands/produce.js +11 -7
  31. package/dist/interfaces/calamares/i-calamares-branding.d.ts +56 -38
  32. package/dist/interfaces/calamares/i-calamares-branding.js +10 -0
  33. package/dist/krill/classes/prepare.d/users.js +1 -1
  34. package/dist/krill/classes/sequence.d/fstab.js +1 -1
  35. package/dist/krill/classes/sequence.d/mkfs.js +1 -1
  36. package/dist/krill/classes/sequence.d/unpackfs.js +2 -2
  37. package/dist/krill/classes/sequence.d.ts +1 -5
  38. package/dist/krill/classes/sequence.js +26 -29
  39. package/dist/krill/components/finished.js +2 -2
  40. package/dist/krill/components/install.js +2 -2
  41. package/dist/krill/components/keyboard.js +2 -2
  42. package/dist/krill/components/location.js +2 -2
  43. package/dist/krill/components/network.js +2 -2
  44. package/dist/krill/components/partitions.js +2 -2
  45. package/dist/krill/components/summary.js +2 -2
  46. package/dist/krill/components/users.js +2 -2
  47. package/dist/krill/components/welcome.js +2 -2
  48. package/dist/lib/utils.d.ts +1 -0
  49. package/dist/lib/utils.js +46 -0
  50. package/manpages/doc/man/eggs.1.gz +0 -0
  51. package/manpages/doc/man/eggs.html +8 -8
  52. package/package.json +2 -2
  53. package/scripts/restore_homecrypt_krill.sh +93 -0
@@ -29,6 +29,7 @@ import { kernelCopy } from './ovary.d/kernel-copy.js';
29
29
  import { liveCreateStructure } from './ovary.d/live-create-structure.js';
30
30
  import { finished } from './ovary.d/finished.js';
31
31
  import { luksExecuteCommand, buildLuksFormatArgs } from './ovary.d/luks-helpers.js';
32
+ import { luksShrink } from './ovary.d/luks-shrink.js';
32
33
  import { luksGetPassword } from './ovary.d/luks-get-password.js';
33
34
  import { interactiveCryptoConfig, CryptoConfig } from './ovary.d/luks-interactive-crypto-config.js';
34
35
  import { luksHome } from './ovary.d/luks-home.js';
@@ -49,7 +50,7 @@ export default class Ovary {
49
50
  familyId: string;
50
51
  distroId: string;
51
52
  distroLike: string;
52
- distroLliveMediumPath: string;
53
+ distroLiveMediumPath: string;
53
54
  genisoimage: boolean;
54
55
  incubator: Incubator;
55
56
  settings: Settings;
@@ -84,6 +85,7 @@ export default class Ovary {
84
85
  luksExecuteCommand: typeof luksExecuteCommand;
85
86
  buildLuksFormatArgs: typeof buildLuksFormatArgs;
86
87
  luksGetPassword: typeof luksGetPassword;
88
+ luksShrink: typeof luksShrink;
87
89
  interactiveCryptoConfig: typeof interactiveCryptoConfig;
88
90
  luksHome: typeof luksHome;
89
91
  installHomecryptSupport: typeof installHomecryptSupport;
@@ -31,6 +31,7 @@ import { liveCreateStructure } from './ovary.d/live-create-structure.js';
31
31
  import { finished } from './ovary.d/finished.js';
32
32
  // crypt
33
33
  import { luksExecuteCommand, buildLuksFormatArgs } from './ovary.d/luks-helpers.js';
34
+ import { luksShrink } from './ovary.d/luks-shrink.js';
34
35
  import { luksGetPassword } from './ovary.d/luks-get-password.js';
35
36
  import { interactiveCryptoConfig } from './ovary.d/luks-interactive-crypto-config.js';
36
37
  // homecrypt
@@ -55,7 +56,7 @@ export default class Ovary {
55
56
  familyId = '';
56
57
  distroId = '';
57
58
  distroLike = '';
58
- distroLliveMediumPath = '';
59
+ distroLiveMediumPath = '';
59
60
  genisoimage = false;
60
61
  incubator = {};
61
62
  settings = {};
@@ -93,6 +94,7 @@ export default class Ovary {
93
94
  luksExecuteCommand = luksExecuteCommand;
94
95
  buildLuksFormatArgs = buildLuksFormatArgs;
95
96
  luksGetPassword = luksGetPassword;
97
+ luksShrink = luksShrink;
96
98
  interactiveCryptoConfig = interactiveCryptoConfig;
97
99
  // luksHome
98
100
  luksHome = luksHome;
@@ -238,7 +238,7 @@ export default class Utils {
238
238
  * @param device
239
239
  */
240
240
  static uuid(device) {
241
- const uuid = shx.exec(`blkid -s UUID -o value ${device}`).stdout.trim();
241
+ const uuid = shx.exec(`blkid -p -s UUID -o value ${device}`, { silent: true }).stdout.trim();
242
242
  return uuid;
243
243
  }
244
244
  /**
@@ -66,7 +66,7 @@ export default class Yolk {
66
66
  Utils.warning(cmd);
67
67
  await exec(cmd, { capture: true, echo: false });
68
68
  // Create Release date: Sat, 14 Aug 2021 07:42:00 UTC
69
- const now = shx.exec('date -R -u').stdout.trim();
69
+ const now = shx.exec('date -R -u', { silent: true }).stdout.trim();
70
70
  const content = `Archive: stable\nComponent: yolk\nOrigin: penguins-eggs\nArchitecture: ${Utils.uefiArch()} \nDate: ${now}\n`;
71
71
  Utils.warning('Writing Release');
72
72
  fs.writeFileSync('Release', content);
@@ -144,7 +144,7 @@ export default class Produce extends Command {
144
144
  const yolkRenew = flags.yolk;
145
145
  const { nointeractive } = flags;
146
146
  const { noicon } = flags;
147
- // if clone or homecrypt includeRootHome = true
147
+ // if clone, homecrypt, fullcrypt
148
148
  const includeRootHome = flags.includeRootHome || clone || homecrypt;
149
149
  let { kernel } = flags;
150
150
  if (kernel === undefined) {
@@ -209,19 +209,23 @@ export default class Produce extends Command {
209
209
  let message = "this is a GUI system, calamares is available, but NOT installed\n";
210
210
  Utils.warning(message);
211
211
  }
212
- if (fullcrypt && Utils.isAppImage()) {
213
- Utils.warning("eggs --fullcrypt cannot be used on AppImage");
214
- process.exit(0);
212
+ /**
213
+ * se è appImage e fullcrypt esce
214
+ */
215
+ if (Utils.isAppImage() && fullcrypt) {
216
+ Utils.warning("eggs produce --fullcrypt cannot be used on AppImage");
217
+ console.log(`\nyou can try: "sudo eggs produce --homecrypt"`);
218
+ process.exit(9);
215
219
  }
216
- else {
220
+ if (!Utils.isAppImage() && fullcrypt) {
217
221
  const distro = new Distro();
218
- //
219
222
  if (distro.familyId === 'debian' && (distro.codenameId === 'trixie' || distro.codenameId === 'excalibur')) {
220
223
  Utils.info("Use eggs --fullcrypt with extreme caution, and ALWAYS first try it out in a test environment.");
221
224
  Utils.sleep(3000);
222
225
  }
223
226
  else {
224
- Utils.warning("eggs --fullcrypt can be used only with Debian trixie or Devuan excalibur");
227
+ Utils.warning(`eggs produce --fullcrypt cannot be used on ${distro.distroId}/${distro.codenameId}`);
228
+ console.log(`\nyou can try: "sudo eggs produce --homecrypt"`);
225
229
  process.exit(9);
226
230
  }
227
231
  }
@@ -1,46 +1,64 @@
1
1
  /**
2
2
  * ./src/interfaces/i-calamares-branding.ts
3
- * penguins-eggs v.25.7.x / ecmascript 2020
3
+ * penguins-eggs v.25.x / ecmascript 2020
4
4
  * author: Piero Proietti
5
5
  * email: piero.proietti@gmail.com
6
6
  * license: MIT
7
+ *
8
+ * Questa interfaccia è allineata con la struttura reale di branding.desc
9
+ * (basata sull'output 'cat /etc/calamares/branding/eggs/branding.desc').
10
+ */
11
+ /**
12
+ * 💡 Interfaccia per la sezione 'strings'
13
+ * Contiene le informazioni testuali del prodotto.
14
+ */
15
+ export interface IBrandingStrings {
16
+ bootloaderEntryName: string;
17
+ knownIssuesUrl: string;
18
+ productName: string;
19
+ productUrl: string;
20
+ releaseNotesUrl: string;
21
+ shortProductName: string;
22
+ shortVersion: string;
23
+ shortVersionedName: string;
24
+ supportUrl: string;
25
+ version: string;
26
+ versionedName: string;
27
+ }
28
+ /**
29
+ * 💡 Interfaccia per la sezione 'images'
30
+ * Contiene i nomi dei file delle risorse grafiche.
31
+ */
32
+ export interface IBrandingImages {
33
+ productIcon: string;
34
+ productLogo: string;
35
+ productWelcome: string;
36
+ }
37
+ /**
38
+ * 💡 Interfaccia per la sezione 'style'
39
+ * Contiene le definizioni dei colori per l'interfaccia.
40
+ * Nota: Sono incluse sia le varianti con maiuscola che minuscola trovate nel tuo file.
41
+ */
42
+ export interface IBrandingStyle {
43
+ SidebarBackground: string;
44
+ SidebarBackgroundCurrent: string;
45
+ SidebarText: string;
46
+ SidebarTextCurrent: string;
47
+ sidebarBackground: string;
48
+ sidebarBackgroundCurrent: string;
49
+ sidebarText: string;
50
+ sidebarTextCurrent: string;
51
+ }
52
+ /**
53
+ * 💡 Interfaccia Principale: IBranding
54
+ * Mappa la struttura radice del file YAML branding.desc.
7
55
  */
8
56
  export interface IBranding {
9
- /** Il nome completo della distribuzione (es. "My Awesome OS"). */
10
- string_product_name: string;
11
- /** La versione della distribuzione (es. "2025.10"). */
12
- string_product_version: string;
13
- /** Un URL per il sito web del progetto. */
14
- string_product_url?: string;
15
- /** Un titolo per le note di rilascio. */
16
- string_release_title?: string;
17
- /** Il colore principale usato per gli accenti (pulsanti, selezioni). */
18
- color_accent?: string;
19
- /** Colore del testo principale. */
20
- color_text?: string;
21
- /** Colore di sfondo principale della finestra. */
22
- color_background?: string;
23
- /** Colore di sfondo della barra laterale. */
24
- color_sidebar_background?: string;
25
- /** Colore del testo nella barra laterale. */
26
- color_sidebar_text?: string;
27
- /** Logo principale mostrato nell'installer. */
28
- logo?: string;
29
- /** Icona del prodotto. */
30
- product_icon?: string;
31
- /** Icona della finestra dell'applicazione. */
32
- window_icon?: string;
33
- /** Larghezza iniziale della finestra in pixel. */
34
- window_width?: number;
35
- /** Altezza iniziale della finestra in pixel. */
36
- window_height?: number;
37
- /** Se `true`, posiziona la barra laterale a sinistra (default), altrimenti a destra. */
38
- sidebar_on_left?: boolean;
39
- /**
40
- * L'API da usare per lo slideshow. 'qml' per le slideshow tradizionali,
41
- * 'contextual' per quelle basate sul modulo in esecuzione.
42
- */
43
- slideshow_api?: 'qml' | 'contextual';
44
- /** Percorso al file QML principale dello slideshow (se slideshow_api è 'qml'). */
45
- slideshow_qml_path?: string;
57
+ componentName: string;
58
+ slideshow: string;
59
+ slideshowAPI: number;
60
+ welcomeStyleCalamares: boolean;
61
+ images: IBrandingImages;
62
+ strings: IBrandingStrings;
63
+ style: IBrandingStyle;
46
64
  }
@@ -1 +1,11 @@
1
+ /**
2
+ * ./src/interfaces/i-calamares-branding.ts
3
+ * penguins-eggs v.25.x / ecmascript 2020
4
+ * author: Piero Proietti
5
+ * email: piero.proietti@gmail.com
6
+ * license: MIT
7
+ *
8
+ * Questa interfaccia è allineata con la struttura reale di branding.desc
9
+ * (basata sull'output 'cat /etc/calamares/branding/eggs/branding.desc').
10
+ */
1
11
  export {};
@@ -36,7 +36,7 @@ export async function users() {
36
36
  }
37
37
  let hostname = this.krillConfig.hostname;
38
38
  if (hostname === '' || hostname === undefined) {
39
- hostname = shx.exec('cat /etc/hostname').stdout.trim();
39
+ hostname = shx.exec('cat /etc/hostname', { silent: true }).stdout.trim();
40
40
  }
41
41
  let autologin = true;
42
42
  let sameUserPassword = true;
@@ -167,7 +167,7 @@ async function isRotational(device) {
167
167
  // Check if the selected disk is a software raid
168
168
  if (device.startsWith('md')) {
169
169
  // Get the first disk from which the raid is composed
170
- device = shx.exec(`cat /proc/mdstat | grep ${device} | cut -f 5 -d " " | cut -f 1 -d "["`).stdout.trim();
170
+ device = shx.exec(`cat /proc/mdstat | grep ${device} | cut -f 5 -d " " | cut -f 1 -d "["`, { silent: true }).stdout.trim();
171
171
  }
172
172
  response = shx.exec(`cat /sys/block/${device}/queue/rotational`, { silent: true }).stdout.trim();
173
173
  if (response === '1') {
@@ -30,7 +30,7 @@ export default async function mkfs() {
30
30
  if (this.efi) {
31
31
  // usare shx.exec qui
32
32
  const efiDetectCmd = `fdisk -l | grep 'EFI System' | awk '{print $1}'`;
33
- const efiName = shx.exec(efiDetectCmd).stdout.trim();
33
+ const efiName = shx.exec(efiDetectCmd, { silent: true }).stdout.trim();
34
34
  if (efiName) {
35
35
  this.devices.efi.name = efiName;
36
36
  this.devices.efi.mountPoint = '/boot/efi';
@@ -17,8 +17,8 @@ export default async function unpackfs() {
17
17
  const cmd = `unsquashfs -d ${this.installTarget} -f ${squafsPath} ${this.toNull}`;
18
18
  // Usiamo echo false per evitare di intasare il log con migliaia di file
19
19
  const echoNo = Utils.setEcho(false);
20
- console.log('Unpacking filesystem (this may take a while)...');
20
+ // console.log('Unpacking filesystem (this may take a while)...')
21
21
  // Esecuzione
22
22
  await exec(cmd, echoNo);
23
- console.log('Filesystem unpacked successfully.');
23
+ // console.log('Filesystem unpacked successfully.')
24
24
  }
@@ -92,13 +92,9 @@ export default class Sequence {
92
92
  settings: Settings;
93
93
  remix: IRemix;
94
94
  distro: IDistro;
95
- luksMappedName: string;
96
- luksFile: string;
97
- luksDevice: string;
98
- luksMountpoint: string;
99
95
  luksRootName: string;
96
+ cryptedHomeDevice: string;
100
97
  is_clone: boolean;
101
- is_crypted_clone: boolean;
102
98
  unattended: boolean;
103
99
  nointeractive: boolean;
104
100
  chroot: boolean;
@@ -6,6 +6,8 @@
6
6
  * email: piero.proietti@gmail.com
7
7
  * license: MIT
8
8
  */
9
+ import path from 'path';
10
+ const __dirname = path.dirname(new URL(import.meta.url).pathname);
9
11
  import Settings from '../../classes/settings.js';
10
12
  import React from 'react';
11
13
  import { render, Box, Text } from 'ink';
@@ -107,13 +109,13 @@ export default class Sequence {
107
109
  settings = {};
108
110
  remix = {};
109
111
  distro = {};
110
- luksMappedName = 'luks-volume'; // encrypted ISOs
111
- luksFile = ``; // encrypted ISOs
112
- luksDevice = `/dev/mapper/${this.luksMappedName}`; // encrypted ISOs
113
- luksMountpoint = `/mnt`; // encrypted ISOs
114
- luksRootName = ''; // installation encrypted
112
+ // luksMappedName = 'luks-volume' // encrypted ISOs
113
+ // luksFile = `` // encrypted ISOs
114
+ // luksDevice = `/dev/mapper/${this.luksMappedName}` // encrypted ISOs
115
+ // luksMountpoint = `/mnt`
116
+ luksRootName = '';
117
+ cryptedHomeDevice = '/dev/mapper/live-home';
115
118
  is_clone = fs.existsSync('/etc/penguins-eggs.d/is_clone');
116
- is_crypted_clone = fs.existsSync('/etc/penguins-eggs.d/is_crypted_clone');
117
119
  unattended = false;
118
120
  nointeractive = false;
119
121
  chroot = false;
@@ -141,7 +143,7 @@ export default class Sequence {
141
143
  this.devices.swap = {};
142
144
  this.distro = new Distro();
143
145
  this.efi = fs.existsSync('/sys/firmware/efi/efivars');
144
- this.luksFile = `${this.distro.liveMediumPath}live/${this.luksMappedName}`;
146
+ // this.luksFile = `${this.distro.liveMediumPath}live/${this.luksMappedName}`
145
147
  this.luksRootName = `${this.distro.distroLike}_root`;
146
148
  this.luksRootName = this.luksRootName.toLowerCase(); // installation encrypted
147
149
  }
@@ -233,19 +235,6 @@ export default class Sequence {
233
235
  // 5. Core system configuration
234
236
  await this.executeStep("machineid", 46, () => this.machineId());
235
237
  await this.executeStep("Creating fstab", 49, () => this.fstab(this.partitions.installationDevice));
236
- // 6. Crypted clone restoration
237
- if (this.is_crypted_clone) {
238
- await this.executeStep("Restore private data from crypted clone", 55, async () => {
239
- if (fs.existsSync(this.luksFile)) {
240
- const cmd = `eggs syncfrom --rootdir /tmp/calamares-krill-root/ --file ${this.luksFile}`;
241
- await exec(cmd, Utils.setEcho(true));
242
- this.is_clone = true;
243
- }
244
- else {
245
- await Utils.pressKeyToExit(`Cannot find luks-volume file ${this.luksFile}`);
246
- }
247
- });
248
- }
249
238
  // 7. Network and hostname
250
239
  await this.executeStep("Network configuration", 61, () => this.networkCfg());
251
240
  await this.executeStep("Create hostname", 64, () => this.hostname(this.network.domain));
@@ -290,28 +279,34 @@ export default class Sequence {
290
279
  // 10. Always remove CLI autologin
291
280
  await this.executeStep("Remove autologin CLI", 80, () => this.cliAutologin.remove(this.installTarget));
292
281
  // 10. mkinitramfs
293
- await this.executeStep("initramfs configure", 86, () => this.initramfsCfg(this.partitions.installationDevice));
294
- await this.executeStep("initramfs", 87, () => this.initramfs());
282
+ await this.executeStep("initramfs configure", 81, () => this.initramfsCfg(this.partitions.installationDevice));
283
+ await this.executeStep("initramfs", 82, () => this.initramfs());
295
284
  // 11. Bootloader configuration
296
- await this.executeStep("bootloader-config", 81, () => this.bootloaderConfig());
297
- await this.executeStep("grubcfg", 82, () => this.grubcfg());
298
- await this.executeStep("bootloader", 83, () => this.bootloader());
285
+ await this.executeStep("bootloader-config", 83, () => this.bootloaderConfig());
286
+ await this.executeStep("grubcfg", 84, () => this.grubcfg());
287
+ await this.executeStep("bootloader", 85, () => this.bootloader());
299
288
  // 12. Final system setup
300
289
  if (this.distro.familyId === 'debian') {
301
- await this.executeStep("Remove sources-yolk", 84, () => this.execCalamaresModule('sources-yolk-undo'));
290
+ await this.executeStep("Remove sources-yolk", 86, () => this.execCalamaresModule('sources-yolk-undo'));
302
291
  }
303
- await this.executeStep("Add/remove packages", 85, () => this.packages());
292
+ await this.executeStep("Add/remove packages", 87, () => this.packages());
304
293
  await this.executeStep("Remove GUI installer link", 88, () => this.removeInstallerLink());
305
294
  await this.executeStep("Cleanup", 89, async () => {
306
295
  await exec(`rm -f ${this.installTarget}/etc/penguins-eggs.d/is_clone`);
307
- await exec(`rm -f ${this.installTarget}/etc/penguins-eggs.d/is_crypted_clone`);
308
296
  });
297
+ // 6. homecrypt clone restoration
298
+ if (fs.existsSync(this.cryptedHomeDevice)) {
299
+ await this.executeStep("Restoring data from homecrypt", 90, async () => {
300
+ let restoreHomeCrypt = path.resolve(__dirname, '../../../scripts/restore_homecrypt_krill.sh');
301
+ await exec(`${restoreHomeCrypt} ${this.cryptedHomeDevice} ${this.installTarget}`);
302
+ });
303
+ }
309
304
  // 13. Custom final steps
310
305
  const cfs = new CFS();
311
306
  const steps = await cfs.steps();
312
307
  if (steps.length > 0) {
313
308
  for (const step of steps) {
314
- await this.executeStep(`running ${step}`, 90, () => this.execCalamaresModule(step));
309
+ await this.executeStep(`running ${step}`, 91, () => this.execCalamaresModule(step));
315
310
  }
316
311
  }
317
312
  // 14- Handle chroot if requested
@@ -319,6 +314,8 @@ export default class Sequence {
319
314
  const message = `You are in chroot mode under ${this.installTarget}, type "exit" to exit.`;
320
315
  await this.emergencyShell(message);
321
316
  }
317
+ // Before to unmount
318
+ await exec('sync');
322
319
  // 15. Unmounting
323
320
  await this.executeStep("umount Virtual File System", 96, () => this.umountVfs());
324
321
  await this.executeStep("umount File system", 99, () => this.umountFs());
@@ -21,8 +21,8 @@ export default function Finished({ installationDevice = '', hostName = '', userN
21
21
  const settings = yaml.load(fs.readFileSync(configRoot + 'settings.conf', 'utf-8'));
22
22
  const branding = settings.branding;
23
23
  const calamares = yaml.load(fs.readFileSync(configRoot + 'branding/' + branding + '/branding.desc', 'utf-8'));
24
- productName = calamares.string_product_name;
25
- version = calamares.string_product_version;
24
+ productName = calamares.strings.productName;
25
+ version = calamares.strings.version;
26
26
  /**
27
27
  * totale width=75
28
28
  * step width=15
@@ -22,8 +22,8 @@ export default function Install({ message = "Install", percent = 0, spinner = fa
22
22
  const settings = yaml.load(fs.readFileSync(configRoot + 'settings.conf', 'utf-8'));
23
23
  const branding = settings.branding;
24
24
  const calamares = yaml.load(fs.readFileSync(configRoot + 'branding/' + branding + '/branding.desc', 'utf-8'));
25
- productName = calamares.string_product_name;
26
- version = calamares.string_product_version;
25
+ productName = calamares.strings.productName;
26
+ version = calamares.strings.version;
27
27
  let barLen = 53;
28
28
  let progress = Math.round(barLen * percent / 100);
29
29
  let todo = barLen - progress;
@@ -25,8 +25,8 @@ export default function Keyboard({ keyboardModel = '', keyboardLayout = '', keyb
25
25
  const settings = yaml.load(fs.readFileSync(configRoot + 'settings.conf', 'utf-8'));
26
26
  const branding = settings.branding;
27
27
  const calamares = yaml.load(fs.readFileSync(configRoot + 'branding/' + branding + '/branding.desc', 'utf-8'));
28
- productName = calamares.string_product_name;
29
- version = calamares.string_product_version;
28
+ productName = calamares.strings.productName;
29
+ version = calamares.strings.version;
30
30
  /**
31
31
  * totale width=75
32
32
  * step width=15
@@ -25,8 +25,8 @@ export default function Location({ region = '', zone = '', language = '', dateNu
25
25
  const settings = yaml.load(fs.readFileSync(configRoot + 'settings.conf', 'utf-8'));
26
26
  const branding = settings.branding;
27
27
  const calamares = yaml.load(fs.readFileSync(configRoot + 'branding/' + branding + '/branding.desc', 'utf-8'));
28
- productName = calamares.string_product_name;
29
- version = calamares.string_product_version;
28
+ productName = calamares.strings.productName;
29
+ version = calamares.strings.version;
30
30
  /**
31
31
  * totale width=75
32
32
  * step width=15
@@ -25,8 +25,8 @@ export default function Network({ iface, addressType, address, netmask, gateway,
25
25
  const settings = yaml.load(fs.readFileSync(configRoot + 'settings.conf', 'utf-8'));
26
26
  const branding = settings.branding;
27
27
  const calamares = yaml.load(fs.readFileSync(configRoot + 'branding/' + branding + '/branding.desc', 'utf-8'));
28
- productName = calamares.string_product_name;
29
- version = calamares.string_product_version;
28
+ productName = calamares.strings.productName;
29
+ version = calamares.strings.version;
30
30
  /**
31
31
  * totale width=75
32
32
  * step width=15
@@ -29,8 +29,8 @@ export default function Partitions({ installationDevice, installationMode, files
29
29
  brandingFile = configRoot + 'branding/' + branding + '/branding.desc';
30
30
  if (fs.existsSync(brandingFile)) {
31
31
  const calamares = yaml.load(fs.readFileSync(brandingFile, 'utf-8'));
32
- productName = calamares.string_product_name;
33
- version = calamares.string_product_version;
32
+ productName = calamares.strings.productName;
33
+ version = calamares.strings.version;
34
34
  }
35
35
  }
36
36
  /**
@@ -21,8 +21,8 @@ export default function Summary({ username = '', password = '', rootPassword = '
21
21
  const settings = yaml.load(fs.readFileSync(configRoot + 'settings.conf', 'utf-8'));
22
22
  const branding = settings.branding;
23
23
  const calamares = yaml.load(fs.readFileSync(configRoot + 'branding/' + branding + '/branding.desc', 'utf-8'));
24
- productName = calamares.string_product_name;
25
- version = calamares.string_product_version;
24
+ productName = calamares.strings.productName;
25
+ version = calamares.strings.version;
26
26
  /**
27
27
  * totale width=75
28
28
  * step width=15
@@ -35,8 +35,8 @@ export default function Users({ username, fullname, password, rootPassword, host
35
35
  const settings = yaml.load(fs.readFileSync(configRoot + 'settings.conf', 'utf-8'));
36
36
  const branding = settings.branding;
37
37
  const calamares = yaml.load(fs.readFileSync(configRoot + 'branding/' + branding + '/branding.desc', 'utf-8'));
38
- productName = calamares.string_product_name;
39
- version = calamares.string_product_version;
38
+ productName = calamares.strings.productName;
39
+ version = calamares.strings.version;
40
40
  /**
41
41
  * totale width=75
42
42
  * step width=15
@@ -25,8 +25,8 @@ export default function Welcome({ language = '' }) {
25
25
  const settings = yaml.load(fs.readFileSync(configRoot + 'settings.conf', 'utf-8'));
26
26
  const branding = settings.branding;
27
27
  const calamares = yaml.load(fs.readFileSync(configRoot + 'branding/' + branding + '/branding.desc', 'utf-8'));
28
- productName = calamares.string_product_name;
29
- version = calamares.string_product_version;
28
+ productName = calamares.strings.productName;
29
+ version = calamares.strings.version;
30
30
  /**
31
31
  * totale width=75
32
32
  * step width=15
@@ -48,6 +48,7 @@ export declare const shx: {
48
48
  test: (flag: string, pathToCheck: string) => boolean;
49
49
  which: (cmd: string) => string | null;
50
50
  ln: (flag: string, target: string, link: string) => void;
51
+ ls: (arg1?: string | string[], arg2?: string | string[]) => string[];
51
52
  exec: (command: string, options?: {
52
53
  silent?: boolean;
53
54
  }) => ShellExecResult;
package/dist/lib/utils.js CHANGED
@@ -178,6 +178,52 @@ export const shx = {
178
178
  }
179
179
  fs.symlinkSync(target, link);
180
180
  },
181
+ ls: (arg1, arg2) => {
182
+ let options = '';
183
+ let paths = [];
184
+ // Rilevamento argomenti: ls('-R', path) vs ls(path)
185
+ if (typeof arg1 === 'string' && arg1.startsWith('-')) {
186
+ options = arg1;
187
+ // Se c'è arg2 lo usa, altrimenti default a '.'
188
+ paths = arg2 ? (Array.isArray(arg2) ? arg2 : [arg2]) : ['.'];
189
+ }
190
+ else {
191
+ // Nessuna opzione, arg1 sono i path. Se null, default a '.'
192
+ paths = arg1 ? (Array.isArray(arg1) ? arg1 : [arg1]) : ['.'];
193
+ }
194
+ const recursive = options.includes('R');
195
+ let results = [];
196
+ paths.forEach(p => {
197
+ if (!fs.existsSync(p))
198
+ return;
199
+ const stat = fs.statSync(p);
200
+ if (stat.isDirectory()) {
201
+ if (recursive) {
202
+ // Funzione ricorsiva interna
203
+ const walk = (dir) => {
204
+ const files = fs.readdirSync(dir);
205
+ files.forEach(f => {
206
+ const fullPath = path.join(dir, f);
207
+ results.push(fullPath); // Aggiunge il path completo
208
+ if (fs.statSync(fullPath).isDirectory()) {
209
+ walk(fullPath);
210
+ }
211
+ });
212
+ };
213
+ walk(p);
214
+ }
215
+ else {
216
+ // Comportamento standard: ritorna solo i nomi dei file nella cartella
217
+ results = results.concat(fs.readdirSync(p));
218
+ }
219
+ }
220
+ else {
221
+ // È un file singolo
222
+ results.push(p);
223
+ }
224
+ });
225
+ return results;
226
+ },
181
227
  exec: (command, options = {}) => {
182
228
  const env = getCleanEnv();
183
229
  const spawnOpts = {
Binary file
@@ -6,12 +6,12 @@
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1">
7
7
  </head>
8
8
  <body>
9
- <h1>eggs(1) -- the reproductive system of penguins: eggs v25.12.7</h1>
9
+ <h1>eggs(1) -- the reproductive system of penguins: eggs v25.12.8</h1>
10
10
  <h1>SYNOPSIS</h1>
11
11
  <p>eggs is a console utility, in active development, who let you to remaster your system and redistribuite it as live ISO image.</p>
12
12
  <h1>INSTALL</h1>
13
13
  <p>penguins-eggs as an AppImage, it can be installed on all supported distributions. Download it from https://github.com/pieroproietti/penguins-eggs/releases, then run the following commands:</p>
14
- <pre><code>$ chmod +x penguins-eggs_25.12.7-1_amd64-x86_64.AppImage
14
+ <pre><code>$ chmod +x penguins-eggs_25.12.8-1_amd64-x86_64.AppImage
15
15
  $ sudo mv /usr/local/bin
16
16
  $ sudo eggs setup
17
17
  </code></pre>
@@ -19,30 +19,30 @@ $ sudo eggs setup
19
19
  <pre><code>$ doas apk add penguins-eggs@testing
20
20
  </code></pre>
21
21
  <p>AlmaLinux/RockyLinux</p>
22
- <pre><code>$ sudo dnf install ./penguins-eggs_25.12.7-1_amd64-1rocky9.5..x86_64.rpm
22
+ <pre><code>$ sudo dnf install ./penguins-eggs_25.12.8-1_amd64-1rocky9.5..x86_64.rpm
23
23
 
24
24
  </code></pre>
25
25
  <p>Arch</p>
26
26
  <pre><code>$ sudo pacman -S penguins-eggs
27
- $ sudo pacman -U penguins-eggs_25.12.7-1_amd64-1-x86_64.pkg.tar.zst
27
+ $ sudo pacman -U penguins-eggs_25.12.8-1_amd64-1-x86_64.pkg.tar.zst
28
28
  </code></pre>
29
29
  <p>Debian/Devuan/Ubuntu</p>
30
30
  <pre><code>$ sudo apt install penguins-eggs
31
- $ sudo dpkg -i penguins-eggs_25.12.7-1_amd64.deb
31
+ $ sudo dpkg -i penguins-eggs_25.12.8-1_amd64.deb
32
32
  </code></pre>
33
33
  <p>Fedora</p>
34
- <pre><code>$ sudo dnf install ./penguins-eggs_25.12.7-1_amd64-1fedora.x86_64.rpm
34
+ <pre><code>$ sudo dnf install ./penguins-eggs_25.12.8-1_amd64-1fedora.x86_64.rpm
35
35
  </code></pre>
36
36
  <p>Manjaro</p>
37
37
  <pre><code>$ sudo pamac install penguins-eggs
38
38
  </code></pre>
39
39
  <p>OpenMamba</p>
40
- <pre><code>$ sudo dnf install ./penguins-eggs_25.12.7-1_amd64-1mamba.x86_64.rpm
40
+ <pre><code>$ sudo dnf install ./penguins-eggs_25.12.8-1_amd64-1mamba.x86_64.rpm
41
41
  </code></pre>
42
42
  <h1>USAGE</h1>
43
43
  <pre><code>$ eggs (-v|--version|version)
44
44
 
45
- penguins-eggs/25.12.7
45
+ penguins-eggs/25.12.8
46
46
  $ eggs --help [COMMAND]
47
47
 
48
48
  USAGE
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "penguins-eggs",
3
3
  "shortName": "eggs",
4
4
  "description": "A remaster system tool, compatible with Almalinux, Alpine, Arch, Debian, Devuan, Fedora, Manjaro, Opensuse, Ubuntu and derivatives",
5
- "version": "25.12.7",
5
+ "version": "25.12.15",
6
6
  "author": "Piero Proietti",
7
7
  "bin": {
8
8
  "eggs": "./bin/run.js"
@@ -56,7 +56,7 @@
56
56
  "eslint-config-prettier": "^10.1.8",
57
57
  "glob": "^13.0.0",
58
58
  "mocha": "^11.7.5",
59
- "oclif": "^4.22.54",
59
+ "oclif": "^4.22.55",
60
60
  "perrisbrewery": "^25.9.16",
61
61
  "prettier": "^3.7.4",
62
62
  "shx": "^0.4.0",