Skip to content

Commit

Permalink
feat: 优化template创建逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
taomas committed Feb 4, 2021
1 parent 5e13b5c commit ca6cf1c
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 223 deletions.
28 changes: 28 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint'
],
env: {
browser: true,
amd: true,
node: true
},
rules: {
// 0 = off, 1 = warn, 2 = error
// '@typescript-eslint/no-explicit-any': 1
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-this-alias': 0,
'no-empty': 0,
'no-prototype-builtins': 0,
'@typescript-eslint/ban-ts-ignore': 0,
'@typescript-eslint/explicit-module-boundary-types': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-unused-vars': 0
}
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@
"devDependencies": {
"@fbi-js/eslint-config-typescript": "^1.2.0",
"@fbi-js/tsconfig": "^1.2.0",
"@types/ejs": "^3.0.5",
"@types/node": "*",
"@types/semver": "^7",
"ejs": "^3.1.5",
"eslint": "^7",
"prettier": "^2.2.1",
"typescript": "^4"
Expand Down
152 changes: 70 additions & 82 deletions src/commands/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import { Template } from '../core/template'
import { basename, join, relative } from 'path'
import { groupBy, flatten, isValidArray } from '../utils'

interface createProjectArgs {
template: Template
subDirectory?: string
targetDir: string
flags: any
useSubTemplate: boolean
}

export default class CommandCreate extends Command {
id = 'create'
alias = ''
Expand All @@ -24,11 +32,11 @@ export default class CommandCreate extends Command {
'fbi create factory-node my-app -p yarn'
]

constructor (public factory: Fbi) {
constructor(public factory: Fbi) {
super()
}

async run (factoryOrTemplateName: any, projectName: any, flags: any) {
async run(factoryOrTemplateName: any, projectName: any, flags: any) {
this.debug(
`Running command "${this.id}" from factory "${this.factory.id}" with options:`,
{
Expand All @@ -45,6 +53,9 @@ export default class CommandCreate extends Command {

const cwd = process.cwd()
const usingFactory = this.context.get('config.factory')
this.debug(`usingFactory: ${usingFactory}`)
this.debug(`targetTemplate: ${targetTemplate}`)

if (usingFactory) {
const factory = this.factory.resolveFactory(usingFactory.id)
const template = factory?.resolveTemplate(usingFactory.template)
Expand All @@ -60,13 +71,13 @@ export default class CommandCreate extends Command {
useSubTemplate = true
}
} else if (isValidArray(subTemplates)) {
const { templateType } = (await this.prompt({
const { templateType } = await this.prompt<{ templateType: string }>({
type: 'select',
name: 'templateType',
hint: 'Use arrow-keys, <return> to submit',
message: 'Pick an action:',
choices: ['Use sub templates', 'Use other templates', 'Cancel']
})) as any
})

if (templateType === 'Cancel') {
this.exit()
Expand Down Expand Up @@ -155,47 +166,43 @@ export default class CommandCreate extends Command {
}
}

private async createProject ({
template,
subDirectory,
targetDir,
flags,
useSubTemplate = false
}: {
template: Template
subDirectory?: string
targetDir: string
flags: any
useSubTemplate: boolean
}) {
private async createProject(args: createProjectArgs) {
this.debug('createProjectArgs', args)
const {
template,
subDirectory,
targetDir,
flags,
useSubTemplate = false
} = args
if (!template) {
this.exit()
}

// get init data
const factory = template.factory
const storeInfo = this.store.get(factory.id)

const info: Record<string, any> = await template.run(
{
factory: {
id: factory.id,
path:
storeInfo?.version?.latest?.dir ||
storeInfo?.path ||
factory.baseDir ||
factory.options?.rootDir ||
join(process.cwd(), subDirectory || '', 'node_modules', factory.id),
version: storeInfo?.version?.latest?.short ?? '',
template: template.id
},
project: {
name: basename(targetDir)
},
subDirectory
this.debug('storeInfo', storeInfo)
const templateOptions = {
factory: {
id: factory.id,
path:
storeInfo?.version?.latest?.dir ||
storeInfo?.path ||
factory.baseDir ||
factory.options?.rootDir ||
join(process.cwd(), subDirectory || '', 'node_modules', factory.id),
version: storeInfo?.version?.latest?.short ?? '',
template: template.id
},
flags
)
project: {
name: basename(targetDir)
},
subDirectory
}

// render template
const info: Record<string, any> = await template.run(templateOptions, flags)

if (!info || !info.path) {
return
Expand All @@ -222,11 +229,14 @@ export default class CommandCreate extends Command {
)
}

private async selectTempate (
private async selectTempate(
templates: Template[],
factoryOrTemplateName?: string
) {
// console.log('selectTempate', templates)
this.debug(`factoryOrTemplateName: ${factoryOrTemplateName}`)
const _choices = groupBy(templates, 'factory.id')

const choices = flatten(
Object.entries(_choices).map(([key, val]: any) =>
[{ role: 'separator', message: `\n※ ${key}:` }].concat(
Expand All @@ -239,87 +249,65 @@ export default class CommandCreate extends Command {
)
)

const { selected } = (await this.prompt({
const { selected } = await this.prompt<{ selected: any }>({
type: 'select',
name: 'selected',
message: factoryOrTemplateName
? 'Confirm which template to use'
: 'Choose a template',
hint: 'Use arrow-keys, <return> to submit',
choices,
result (templateId: any) {
result(templateId: any) {
return {
templateId,
factoryId: (this as any).focused.value
} as any
}
})) as any
})

if (!selected) {
return null
}
this.debug('selected', selected)

return templates?.find(
const selectedTemplate = templates?.find(
(t: Template) =>
t.id === selected.templateId && t.factory.id === selected.factoryId
)
this.debug('selectedTemplate', selectedTemplate)
return selectedTemplate
}

private async getTargetDir (projectName?: string, cwd = process.cwd()) {
private async getTargetDir(projectName?: string, cwd = process.cwd()) {
if (projectName) {
return {
targetDir: cwd,
subDirectory: projectName
}
}

const { action } = await this.prompt<{ action: string }>({
type: 'select',
name: 'action',
hint: 'Use arrow-keys, <return> to submit',
message: 'Create project in:',
choices: [
{
message: 'Current directory',
name: 'current'
},
{
message: 'New subdirectory',
name: 'subDirectory'
},
{
message: 'Cancel',
name: 'cancel'
}
]
})
console.log(`\n${this.style.green('fbi will create a project !')}\n`)

switch (action) {
case 'subDirectory': {
const { subDirectory } = await this.prompt<{ subDirectory: string }>({
type: 'input',
name: 'subDirectory',
message: 'Subdirectory path'
})
const targetDir = join(cwd, subDirectory ?? '')
return {
targetDir,
subDirectory
const { subDirectory } = await this.prompt<{ subDirectory: string }>([
{
type: 'input',
name: 'subDirectory',
message: 'Please enter a directory name!',
initial () {
return 'my-app'
}
}
case 'cancel':
this.exit()
break
default:
break
}
])

const targetDir = join(cwd, subDirectory ?? '')
return {
targetDir: cwd
targetDir,
subDirectory
}

}

private async addFromRemote (name: string, flags: any) {
private async addFromRemote(name: string, flags: any) {
const commandAdd = this.factory.resolveCommand('add')
if (!commandAdd) {
return this.error(
Expand Down
2 changes: 1 addition & 1 deletion src/core/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export abstract class BaseClass {
return prompt
}

get exec () {
get exec (): any {
return execa
}

Expand Down
Loading

0 comments on commit ca6cf1c

Please sign in to comment.