From dd810453e21f62230e354b93e6e17d8b9ad181ba Mon Sep 17 00:00:00 2001 From: Chris Campbell Date: Fri, 19 Apr 2024 13:20:19 -0700 Subject: [PATCH] fix: replace degit with giget so that `create` package doesn't depend on Git being installed locally --- packages/create/package.json | 3 +- packages/create/src/step-git.ts | 14 ++- packages/create/src/step-template.ts | 112 ++++---------------- pnpm-lock.yaml | 153 ++++++++++++++++++++++++--- 4 files changed, 170 insertions(+), 112 deletions(-) diff --git a/packages/create/package.json b/packages/create/package.json index 860b81ea..4f82b177 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -26,9 +26,9 @@ }, "dependencies": { "@sdeverywhere/compile": "^0.7.15", - "degit": "^2.8.4", "execa": "^6.1.0", "fs-extra": "^10.1.0", + "giget": "^1.2.3", "kleur": "^4.1.5", "ora": "^6.1.2", "prompts": "^2.4.2", @@ -37,7 +37,6 @@ "yargs-parser": "^21.1.1" }, "devDependencies": { - "@types/degit": "^2.8.3", "@types/fs-extra": "^9.0.13", "@types/node": "^20.5.7", "@types/prompts": "^2.0.14", diff --git a/packages/create/src/step-git.ts b/packages/create/src/step-git.ts index ecfc2d20..3e95aa2c 100644 --- a/packages/create/src/step-git.ts +++ b/packages/create/src/step-git.ts @@ -1,7 +1,7 @@ // Copyright (c) 2022 Climate Interactive / New Venture Fund import { execaCommand } from 'execa' -import { cyan, dim, green, reset } from 'kleur/colors' +import { cyan, dim, green, reset, yellow } from 'kleur/colors' import ora from 'ora' import prompts from 'prompts' import type { Arguments } from 'yargs-parser' @@ -33,6 +33,14 @@ export async function chooseGitInit(projDir: string, args: Arguments): Promise { - // Enable verbose degit logging if the --verbose flag is used - const verbose = args.verbose - - // Set up degit (we will be writing to a temporary directory, so force is safe) - const emitter = degit(`${templateTarget}${hash}`, { - cache: false, - force: true, - verbose - }) - +async function copyTemplate(templateTarget: string, dstDir: string, spinner: Ora): Promise { try { - if (verbose) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - emitter.on('info', (info: any) => { - console.log(info.message) - }) - } - - // Make degit write to a temporary directory + // Make giget write to a temporary directory const tmpDir = mkdtempSync(joinPath(tmpdir(), 'sde-create-')) - await emitter.clone(tmpDir) - // degit does not return an error when an invalid template is provided, as such we - // need to handle this manually + // Use giget to download the template (we will be writing to a temporary directory, + // so `force` is safe) + await downloadTemplate(`github:${templateTarget}`, { + force: true, + provider: 'github', + dir: tmpDir + }) + + // In case giget doesn't return an error when an invalid template is provided, check + // that the temporary directory is non-empty if (!existsSync(tmpDir) || readdirSync(tmpDir).length === 0) { - throw new Error('The requested template failed to download') + throw new Error('Failed to download the requested template: the temporary directory is empty.') } // Copy files to destination without overwriting @@ -123,67 +102,16 @@ async function runDegit( // Remove the temporary directory rmSync(tmpDir, { recursive: true, force: true }) } catch (e) { + // The download failed; show an error message + // TODO: Handle common download issues; for now, just log the error message and exit spinner.fail() - - // degit is compiled, so the stacktrace is pretty noisy. Only report the stacktrace when using verbose mode. - // logger.debug(err) console.error(red(e.message)) - - // TODO: Handle common degit issues like below; for now, just log the error and exit - console.error(yellow('There was a problem copying the template.')) + console.error(yellow('\nThere was a problem copying the template.')) console.error( yellow( - 'Please file a new issue with the command output here: https://github.com/climateinteractive/sdeverywhere/issues' + 'Please start a new discussion thread and include the command output so that we can help:\n https://github.com/climateinteractive/SDEverywhere/discussions/categories/q-a\n' ) ) process.exit(0) - - // // Warning for issue #655 and other corrupted cache issue - // if (e.message === 'zlib: unexpected end of file' || e.message === 'TAR_BAD_ARCHIVE: Unrecognized archive format') { - // console.log( - // yellow( - // // 'Local degit cache seems to be corrupted.' - // // 'For more information check out this issue: https://github.com/withastro/astro/issues/655.' - // ) - // ) - // const cacheIssueResponse = await prompts({ - // type: 'confirm', - // name: 'cache', - // message: 'Would you like us to clear the cache and try again?', - // initial: true - // }) - // if (cacheIssueResponse.cache) { - // const homeDirectory = os.homedir() - // const cacheDir = joinPath(homeDirectory, '.degit', 'github', '@sdeverywhere') - // rmSync(cacheDir, { recursive: true, force: true, maxRetries: 3 }) - // spinner = ora('Copying project files...').start() - // try { - // await emitter.clone(dstDir) - // } catch (e) { - // // logger.debug(e) - // console.error(red(e.message)) - // } - // } else { - // console.log( - // "Okay, no worries! To fix this manually, remove the folder '~/.degit/github/withastro' and rerun the command." - // ) - // } - // } - - // // Helpful message when encountering the "could not find commit hash for ..." error - // if (e.code === 'MISSING_REF') { - // console.log( - // yellow( - // "This seems to be an issue with degit. Please check if you have 'git' installed on your system, and if you don't, go here to install: https://git-scm.com" - // ) - // ) - // console.log( - // yellow( - // "If you do have 'git' installed, please file a new issue with the command output here: https://github.com/climateinteractive/sdeverywhere/issues" - // ) - // ) - // } - - // process.exit(1) } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index af8e54f2..c61f8834 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -304,15 +304,15 @@ importers: '@sdeverywhere/compile': specifier: ^0.7.15 version: link:../compile - degit: - specifier: ^2.8.4 - version: 2.8.4 execa: specifier: ^6.1.0 version: 6.1.0 fs-extra: specifier: ^10.1.0 version: 10.1.0 + giget: + specifier: ^1.2.3 + version: 1.2.3 kleur: specifier: ^4.1.5 version: 4.1.5 @@ -332,9 +332,6 @@ importers: specifier: ^21.1.1 version: 21.1.1 devDependencies: - '@types/degit': - specifier: ^2.8.3 - version: 2.8.3 '@types/fs-extra': specifier: ^9.0.13 version: 9.0.13 @@ -1090,10 +1087,6 @@ packages: resolution: {integrity: sha512-EGlKlgMhnLt/cM4DbUSafFdrkeJoC9Mvnj0PUCU7tFmTjMjNRT957kXCx0wYm3JuEq4o4ZsS5vG+NlkM2DMd2A==} dev: true - /@types/degit@2.8.3: - resolution: {integrity: sha512-CL7y71j2zaDmtPLD5Xq5S1Gv2dFoHl0/GBZm6s39Mj/ls28L3NzAOqf7H4H0/2TNVMgMjMVf9CAFYSjmXhi3bw==} - dev: true - /@types/estree@0.0.39: resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} dev: false @@ -1650,6 +1643,17 @@ packages: optionalDependencies: fsevents: 2.3.3 + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: false + + /citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + dependencies: + consola: 3.2.3 + dev: false + /cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1700,6 +1704,11 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + /consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + dev: false + /constantinople@4.0.1: resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} dependencies: @@ -1785,10 +1794,8 @@ packages: object-keys: 1.1.1 dev: true - /degit@2.8.4: - resolution: {integrity: sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng==} - engines: {node: '>=8.0.0'} - hasBin: true + /defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} dev: false /detect-indent@6.1.0: @@ -2333,6 +2340,21 @@ packages: strip-final-newline: 3.0.0 dev: false + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: false + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2427,6 +2449,13 @@ packages: universalify: 2.0.0 dev: false + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: false + /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2475,6 +2504,11 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: false + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -2483,6 +2517,20 @@ packages: get-intrinsic: 1.1.1 dev: true + /giget@1.2.3: + resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==} + hasBin: true + dependencies: + citty: 0.1.6 + consola: 3.2.3 + defu: 6.1.4 + node-fetch-native: 1.6.4 + nypm: 0.3.8 + ohash: 1.1.3 + pathe: 1.1.2 + tar: 6.2.1 + dev: false + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2635,6 +2683,11 @@ packages: engines: {node: '>=12.20.0'} dev: false + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: false + /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false @@ -3096,6 +3149,26 @@ packages: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} dev: true + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: false + + /minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + dev: false + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: false + /mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -3103,6 +3176,12 @@ packages: minimist: 1.2.6 dev: true + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: false + /mlly@1.4.1: resolution: {integrity: sha512-SCDs78Q2o09jiZiE2WziwVBEqXQ02XkGdUy45cbJf+BpYRIjArXRJ1Wbowxkb+NaM9DWvS3UC9GiO/6eqvQ/pg==} dependencies: @@ -3156,6 +3235,10 @@ packages: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} dev: true + /node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + dev: false + /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -3199,6 +3282,18 @@ packages: path-key: 4.0.0 dev: false + /nypm@0.3.8: + resolution: {integrity: sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + dependencies: + citty: 0.1.6 + consola: 3.2.3 + execa: 8.0.1 + pathe: 1.1.2 + ufo: 1.5.3 + dev: false + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -3227,6 +3322,10 @@ packages: resolution: {integrity: sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==} dev: false + /ohash@1.1.3: + resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + dev: false + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -3365,6 +3464,10 @@ packages: resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} dev: true + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: false + /pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true @@ -3825,6 +3928,11 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: false + /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} dev: false @@ -4131,6 +4239,18 @@ packages: engines: {node: '>= 8'} dev: true + /tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: false + /temp@0.9.4: resolution: {integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==} engines: {node: '>=6.0.0'} @@ -4323,6 +4443,10 @@ packages: resolution: {integrity: sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==} dev: true + /ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + dev: false + /uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} @@ -4665,7 +4789,6 @@ packages: /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true /yaml@2.2.2: resolution: {integrity: sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==}