refactor(new-design): Make some changes to lib/utils.js
* Support `.mustache` template files in `packages/new-design/shared/`, just as in `packages/new-design/templates/*/`. * Only render files with an explicit `.mustache` suffix. * In `downloadLabFiles`: * Don't try to write response failures into the destination file. This was failing because it wasn't wrapping the error in `{data: ...}` to imitate a successful axios response. * Actually wait for `writeFile` to finish. Don't try to add to `promises` after they've already been collected with `Promise.all`. * General refactoring (really leaning into Promises here...)
This commit is contained in:
parent
c959858e6c
commit
332541bac5
1 changed files with 67 additions and 53 deletions
|
@ -1,6 +1,6 @@
|
||||||
import { config } from './config.mjs'
|
import { config } from './config.mjs'
|
||||||
import { mkdir, readFile, writeFile, copyFile } from 'node:fs/promises'
|
import { mkdir, readFile, writeFile, copyFile } from 'node:fs/promises'
|
||||||
import { join, dirname } from 'path'
|
import { join, dirname, relative } from 'path'
|
||||||
import mustache from 'mustache'
|
import mustache from 'mustache'
|
||||||
import rdir from 'recursive-readdir'
|
import rdir from 'recursive-readdir'
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
|
@ -11,12 +11,13 @@ import axios from 'axios'
|
||||||
import { fileURLToPath } from 'url'
|
import { fileURLToPath } from 'url'
|
||||||
|
|
||||||
// Current working directory
|
// Current working directory
|
||||||
let cwd
|
let filename
|
||||||
try {
|
try {
|
||||||
cwd = __dirname
|
filename = __filename
|
||||||
} catch {
|
} catch {
|
||||||
cwd = dirname(fileURLToPath(import.meta.url))
|
filename = fileURLToPath(import.meta.url)
|
||||||
}
|
}
|
||||||
|
const newDesignDir = join(filename, '../..')
|
||||||
|
|
||||||
const nl = '\n'
|
const nl = '\n'
|
||||||
const tab = ' '
|
const tab = ' '
|
||||||
|
@ -114,41 +115,49 @@ export const getChoices = async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep track of directories that need to be created
|
// Keep track of directories that need to be created
|
||||||
const dirs = {}
|
const dirPromises = {}
|
||||||
const ensureDir = async (file, suppress = false) => {
|
const ensureDir = async (file, suppress = false) => {
|
||||||
const dir = suppress ? dirname(file.replace(suppress)) : dirname(file)
|
const dir = suppress ? dirname(file.replace(suppress)) : dirname(file)
|
||||||
if (!dirs[dir]) {
|
if (!dirPromises[dir]) {
|
||||||
await mkdir(dir, { recursive: true })
|
dirPromises[dir] = mkdir(dir, { recursive: true })
|
||||||
dirs[dir] = true
|
}
|
||||||
|
await dirPromises[dir]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method to copy template files
|
||||||
|
const copyFileOrTemplate = async (fromRoot, toRoot, relativeFile, templateVars) => {
|
||||||
|
const from = join(fromRoot, relativeFile)
|
||||||
|
const to = join(
|
||||||
|
toRoot,
|
||||||
|
relativeFile.endsWith('.mustache') ? relativeFile.slice(0, -9) : relativeFile
|
||||||
|
)
|
||||||
|
|
||||||
|
await ensureDir(to)
|
||||||
|
|
||||||
|
if (relativeFile.endsWith('.mustache')) {
|
||||||
|
const template = await readFile(from, 'utf-8')
|
||||||
|
const rendered = mustache.render(template, templateVars)
|
||||||
|
await writeFile(to, rendered)
|
||||||
|
} else {
|
||||||
|
await copyFile(from, to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to copy template files
|
// Helper method to copy template files
|
||||||
const copyTemplate = async (config, choices) => {
|
const copyAll = async (config, templateVars) => {
|
||||||
// Copy files in parallel rather than using await
|
|
||||||
const promises = []
|
|
||||||
|
|
||||||
// Copy shared files
|
// Copy shared files
|
||||||
for (const from of config.files.shared) {
|
await Promise.all(
|
||||||
// FIXME: Explain the -7
|
config.relativeFiles.shared.map((from) => {
|
||||||
const to = join(config.dest, from.slice(config.source.shared.length - 7))
|
copyFileOrTemplate(config.source.shared, config.dest, from, templateVars)
|
||||||
if (!dirs[to]) await ensureDir(to)
|
})
|
||||||
promises.push(copyFile(from, to))
|
)
|
||||||
}
|
|
||||||
|
|
||||||
// Template files
|
// Template files
|
||||||
for (const from of config.files.template) {
|
await Promise.all(
|
||||||
let to = join(config.dest, from.slice(config.source.template.length - 7))
|
config.relativeFiles.template.map((from) => {
|
||||||
if (to.slice(-9) === '.mustache') to = to.slice(0, -9)
|
copyFileOrTemplate(config.source.template, config.dest, from, templateVars)
|
||||||
if (!dirs[to]) await ensureDir(to)
|
})
|
||||||
// Template out file
|
)
|
||||||
const src = await readFile(from, 'utf-8')
|
|
||||||
promises.push(writeFile(to, mustache.render(src, { name: choices.name, tag: config.tag })))
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(promises)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to run [yarn|npm] install
|
// Helper method to run [yarn|npm] install
|
||||||
|
@ -162,25 +171,25 @@ const installDependencies = async (config, choices) =>
|
||||||
const downloadLabFiles = async (config) => {
|
const downloadLabFiles = async (config) => {
|
||||||
const promises = []
|
const promises = []
|
||||||
for (const dir in config.fetch) {
|
for (const dir in config.fetch) {
|
||||||
for (const file of config.fetch[dir]) {
|
|
||||||
const to = typeof file === 'string' ? join(config.dest, file) : join(config.dest, file.to)
|
|
||||||
if (!dirs[to]) await ensureDir(to)
|
|
||||||
promises.push(
|
promises.push(
|
||||||
axios
|
...config.fetch[dir].map(async (file) => {
|
||||||
.get(
|
const to = typeof file === 'string' ? join(config.dest, file) : join(config.dest, file.to)
|
||||||
|
await ensureDir(to)
|
||||||
|
try {
|
||||||
|
const res = await axios.get(
|
||||||
`${config.fileUri}/${config.repo}/${config.branch}/${dir}/${
|
`${config.fileUri}/${config.repo}/${config.branch}/${dir}/${
|
||||||
typeof file === 'string' ? file : file.from
|
typeof file === 'string' ? file : file.from
|
||||||
}`
|
}`
|
||||||
)
|
)
|
||||||
.catch((err) => console.log(err))
|
await writeFile(to, res.data)
|
||||||
.then((res) => promises.push(writeFile(to, res.data)))
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(promises)
|
return Promise.all(promises)
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to initialize a git repository
|
// Helper method to initialize a git repository
|
||||||
|
@ -253,21 +262,21 @@ const showTips = (config, choices) => {
|
||||||
// Creates the environment based on the user's choices
|
// Creates the environment based on the user's choices
|
||||||
export const createEnvironment = async (choices) => {
|
export const createEnvironment = async (choices) => {
|
||||||
// Store directories for re-use
|
// Store directories for re-use
|
||||||
;(config.cwd = cwd),
|
config.source = {
|
||||||
(config.source = {
|
template: `${newDesignDir}/templates/from-${choices.template}`,
|
||||||
root: cwd,
|
shared: `${newDesignDir}/shared`,
|
||||||
template: cwd + `/../templates/from-${choices.template}`,
|
}
|
||||||
shared: cwd + `/../shared`,
|
|
||||||
})
|
|
||||||
config.dest = join(process.cwd(), choices.name)
|
config.dest = join(process.cwd(), choices.name)
|
||||||
|
|
||||||
// Create target directory
|
// Create target directory
|
||||||
await mkdir(config.dest, { recursive: true })
|
await mkdir(config.dest, { recursive: true })
|
||||||
|
|
||||||
// Find files
|
// Find files
|
||||||
config.files = {
|
config.relativeFiles = {
|
||||||
template: await rdir(config.source.template),
|
template: (await rdir(config.source.template)).map((file) =>
|
||||||
shared: await rdir(config.source.shared),
|
relative(config.source.template, file)
|
||||||
|
),
|
||||||
|
shared: (await rdir(config.source.shared)).map((file) => relative(config.source.shared, file)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a linebreak
|
// Output a linebreak
|
||||||
|
@ -275,7 +284,12 @@ export const createEnvironment = async (choices) => {
|
||||||
|
|
||||||
// Copy/Template files
|
// Copy/Template files
|
||||||
try {
|
try {
|
||||||
await oraPromise(copyTemplate(config, choices), {
|
const templateVars = {
|
||||||
|
template: choices.template,
|
||||||
|
name: choices.name,
|
||||||
|
tag: config.tag,
|
||||||
|
}
|
||||||
|
await oraPromise(copyAll(config, templateVars), {
|
||||||
text:
|
text:
|
||||||
chalk.white.bold('🟨⬜⬜⬜ Copying template files') +
|
chalk.white.bold('🟨⬜⬜⬜ Copying template files') +
|
||||||
chalk.white.dim(' | Just a moment'),
|
chalk.white.dim(' | Just a moment'),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue