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.
 
 
 

106 lines
2.7 KiB

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