Design system.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

103 line
2.6 KiB

  1. import { cp } from 'fs/promises';
  2. import { Argv } from 'yargs';
  3. import { useInternalPath } from '../mixins/internal-path';
  4. import { CommandError } from '../utils/error';
  5. export enum InitReturnCode {
  6. SUCCESS = 0,
  7. COULD_NOT_COPY_FILES = -2,
  8. COULD_NOT_INSTALL_DEPENDENCIES = -3,
  9. }
  10. const copyFiles = async () => {
  11. try {
  12. const srcPath = await useInternalPath('src', 'next');
  13. const destPath = await useInternalPath('.amanuensis', 'next');
  14. await cp(srcPath, destPath, { recursive: true });
  15. } catch (errRaw) {
  16. const err = errRaw as NodeJS.ErrnoException;
  17. throw new CommandError(
  18. InitReturnCode.COULD_NOT_COPY_FILES,
  19. `Could not copy files: ${err.message}`,
  20. );
  21. }
  22. };
  23. interface PackageManager {
  24. name: string;
  25. testCmd: [string, string[]];
  26. installCmd: [string, string[]];
  27. }
  28. const packageManagers: PackageManager[] = [
  29. {
  30. name: 'pnpm',
  31. testCmd: ['pnpm', ['--version']],
  32. installCmd: ['pnpm', ['install', '--ignore-workspace']],
  33. },
  34. {
  35. name: 'yarn',
  36. testCmd: ['yarn', ['--version']],
  37. installCmd: ['yarn', ['install']],
  38. },
  39. {
  40. name: 'npm',
  41. testCmd: ['npm', ['--version']],
  42. installCmd: ['npm', ['install']],
  43. },
  44. ];
  45. const installDependencies = async () => {
  46. const { execa } = await import('execa');
  47. const selectedPackageManagerIndex = await packageManagers.reduce(
  48. async (prevPmPromise, pkgm, i) => {
  49. const prevPm = await prevPmPromise;
  50. const { testCmd } = pkgm;
  51. const testPm = await execa(...testCmd);
  52. if (testPm.exitCode === 0 && prevPm === -1) {
  53. return i;
  54. }
  55. return prevPm;
  56. },
  57. Promise.resolve(-1),
  58. );
  59. if (selectedPackageManagerIndex < 0) {
  60. process.stderr.write('No package manager found\n');
  61. process.exit(-1);
  62. }
  63. const { [selectedPackageManagerIndex]: selectedPackageManager } = packageManagers;
  64. const cwd = await useInternalPath('.amanuensis', 'next');
  65. process.stdout.write(`In path: ${cwd}\n`);
  66. process.stdout.write(`Installing dependencies with ${selectedPackageManager.name}\n`);
  67. const result = await execa(
  68. selectedPackageManager.installCmd[0],
  69. selectedPackageManager.installCmd[1],
  70. { cwd },
  71. );
  72. if (result.exitCode !== 0) {
  73. throw new CommandError(InitReturnCode.COULD_NOT_INSTALL_DEPENDENCIES, 'Could not install dependencies');
  74. }
  75. };
  76. export const description = 'Initialize a new Amanuensis project' as const;
  77. export const builder = (yargsBuilder: Argv) => yargsBuilder;
  78. const init = async () => {
  79. try {
  80. await copyFiles();
  81. await installDependencies();
  82. } catch (errRaw) {
  83. const err = errRaw as CommandError;
  84. process.stderr.write(`${err.message}\n`);
  85. return err.exitCode;
  86. }
  87. return InitReturnCode.SUCCESS;
  88. };
  89. export default init;