Skip to content

Commit

Permalink
fix: replace degit with giget so that create package doesn't depend…
Browse files Browse the repository at this point in the history
… on Git being installed locally
  • Loading branch information
chrispcampbell committed Apr 19, 2024
1 parent 8d06b81 commit dd81045
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 112 deletions.
3 changes: 1 addition & 2 deletions packages/create/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
14 changes: 11 additions & 3 deletions packages/create/src/step-git.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -33,6 +33,14 @@ export async function chooseGitInit(projDir: string, args: Arguments): Promise<v
}

// Init git repo
await execaCommand('git init', { cwd: projDir })
ora().succeed(green('Git repository initialized!'))
try {
await execaCommand('git init', { cwd: projDir })
ora().succeed(green('Git repository initialized!'))
} catch (e) {
ora().warn(
yellow(
`There was a problem initializing the Git repository, but no problem, you can run ${cyan(`git init`)} later.`
)
)
}
}
112 changes: 20 additions & 92 deletions packages/create/src/step-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { copy } from 'fs-extra'
import { tmpdir } from 'os'
import { join as joinPath } from 'path'

import degit from 'degit'
import { downloadTemplate } from 'giget'
import { dim, green, red, yellow } from 'kleur/colors'
import type { Ora } from 'ora'
import ora from 'ora'
Expand Down Expand Up @@ -56,10 +56,9 @@ export async function chooseTemplate(projDir: string, args: Arguments, pkgManage
const commit = args.commit || defaultRev

// Copy the template files to the project directory
const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}`
const hash = `#${commit}`
const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}#${commit}`
const templateSpinner = ora('Copying project files...').start()
await runDegit(templateTarget, hash, projDir, args, templateSpinner)
await copyTemplate(templateTarget, projDir, templateSpinner)
templateSpinner.text = green('Template copied!')
templateSpinner.succeed()

Expand All @@ -75,43 +74,23 @@ export async function chooseTemplate(projDir: string, args: Arguments, pkgManage
return options.template
}

// XXX: This is mostly copied from Astro's create package:
// https://github.com/withastro/astro/blob/main/packages/create-astro/src/index.ts
// It contains workarounds for degit issues that may or may not be relevant for SDE,
// so this should be re-evaluated later.
async function runDegit(
templateTarget: string,
hash: string,
dstDir: string,
args: Arguments,
spinner: Ora
): Promise<void> {
// 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<void> {
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
Expand All @@ -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)
}
}
Loading

0 comments on commit dd81045

Please sign in to comment.