Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: change modules #4

Merged
merged 1 commit into from
Oct 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion @types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,18 @@ declare module 'consolidate';

interface ObjectValueType {
[key: string]: string | boolean | { [key: string]: any }
}
}

interface MacrosType {
scriptName: string,
placeholder: string,
download: string,
remaxRepo: string,
templateRepo: string,
templateTSRepo: string,
description: string,
descriptionTS: string,
tmpPathName: string,
templatePathName: string,
defaultPlatform: string
}
10 changes: 10 additions & 0 deletions src/create/clone.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import degit from 'degit';

export default (templateRepo: string, tmpPath: string) => {
const emitter = degit(templateRepo, {
cache: false,
force: true,
verbose: true,
});
return emitter.clone(tmpPath)
}
140 changes: 7 additions & 133 deletions src/create/index.ts
Original file line number Diff line number Diff line change
@@ -1,142 +1,16 @@
import ora from 'ora';
import degit from 'degit';
import path from 'path';
import Metalsmith from 'metalsmith';
import chalk from 'chalk';
import consolidate from 'consolidate';
import async from 'async';
import clone from './clone';
import render, { ArgvType, pathAndRepoUrlGenerator } from './render';

import { checkRepoVersion } from './check-version';
import { MacrosType } from '../utils/macros';
import { Arguments } from 'yargs';
import user from './git-user';
import ask, { CustomQuestionObjectType } from './ask';

interface GeneratorValues {
[key: string]: string
}

export interface ArgvType extends Arguments {
t: boolean,
projectDirectory: string,
}

export default async (argv: ArgvType, macros: MacrosType) => {
export default (argv: ArgvType, macros: MacrosType) => {
const spinner = ora(macros.download).start();
const generatorValues = pathAndRepoUrlGenerator(argv, macros);
const {
templatePath,
tmpPath,
destPath,
templateRepo,
description,
projectDirectory
} = pathAndRepoUrlGenerator(argv, macros)
// 初始化下载
const emitter = degit(templateRepo, {
cache: false,
force: true,
verbose: true,
});
// 获取 remax 版本
const remaxTagName = await checkRepoVersion(macros.remaxRepo);
// 下载并进行数据处理
emitter.clone(tmpPath).then(() => {
} = generatorValues
clone(templateRepo, tmpPath).then(() => {
spinner.stop();
Metalsmith(process.cwd())
.metadata({
name: projectDirectory,
description: description,
remaxVersion: `^${remaxTagName.replace(/^./, '')}`,
})
.source(templatePath)
.destination(destPath)
.clean(false)
.use(askQuestions({
name: { default: projectDirectory, type: 'string' },
author: { default: user(), type: 'string' },
description: { default: description, type: 'string' },
platform: {
default: 'wechat',
type: 'list',
choices: [
'wechat',
'alipay',
'toutiao'
]
}
}))
.use(filterPlatform())
.use(renderTemplateFiles())
.build(function (err: Error) {
if (!err) {
console.log(chalk.green('create project success!'))
}
})
render(generatorValues, macros)
});
}

const pathAndRepoUrlGenerator = (argv: ArgvType, macros: MacrosType): GeneratorValues => {
const { projectDirectory, t } = argv;
const destPath = path.join(process.cwd(), projectDirectory)
let tmpPath = path.join(__dirname, '../..', macros.tmpPathName)
let templateRepo = macros.templateRepo
let description = macros.description
// 判断是否是 ts
if (t) {
templateRepo = macros.templateTSRepo
description = macros.descriptionTS
tmpPath = path.join(tmpPath, 'ts')
} else {
tmpPath = path.join(tmpPath, 'js')
}
const templatePath = path.join(tmpPath, macros.templatePathName)
return {
templatePath,
tmpPath,
destPath,
templateRepo,
description,
projectDirectory
}
}

const filterPlatform = () => {
return (_: any, metalsmith: any, done: () => void): void => {
const { platform } = metalsmith._metadata;
metalsmith._metadata.platformTitle = firstUpperCase(platform)
done()
}
}

const firstUpperCase = (str: string) => {
return str.toLowerCase().replace(/^./, (s: string): string => {
return s.toUpperCase()
})
}

const askQuestions = (prompts: CustomQuestionObjectType) => {
return (_: any, metalsmith: any, done: () => void): void => {
ask(prompts, metalsmith.metadata(), done)
}
}

const renderTemplateFiles = () => {
return (files: any, metalsmith: any, done: () => void): void => {
const keys = Object.keys(files)
const metalsmithMetadata = metalsmith.metadata()
async.each(keys, (file, next) => {
const str = files[file].contents.toString()
if (!/{{([^{}]+)}}/g.test(str)) {
return next()
}
consolidate.handlebars.render(str, metalsmithMetadata, (err: Error, res: string) => {
if (err) {
err.message = `[${file}] ${err.message}`
return next(err)
}
files[file].contents = Buffer.from(res, 'utf-8')
next()
})
}, done)
}
}
121 changes: 121 additions & 0 deletions src/create/render.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import Metalsmith from 'metalsmith';
import chalk from 'chalk';
import consolidate from 'consolidate';
import async from 'async';
import path from 'path';
import { Arguments } from 'yargs';

import { checkRepoVersion } from './check-version';
import user from './git-user';
import { firstUpperCase } from '../utils/utils';
import ask, { CustomQuestionObjectType } from './ask';


export interface GeneratorValues {
[key: string]: string
}

export interface ArgvType extends Arguments {
t: boolean,
projectDirectory: string,
}

export default async (renderObj: GeneratorValues, macros: MacrosType) => {
const remaxTagName = await checkRepoVersion(macros.remaxRepo);
const {
templatePath,
destPath,
description,
projectDirectory
} = renderObj
Metalsmith(process.cwd())
.metadata({
name: projectDirectory,
description: description,
remaxVersion: `^${remaxTagName.replace(/^./, '')}`,
})
.source(templatePath)
.destination(destPath)
.clean(false)
.use(askQuestions({
name: { default: projectDirectory, type: 'string' },
author: { default: user(), type: 'string' },
description: { default: description, type: 'string' },
platform: {
default: 'wechat',
type: 'list',
choices: [
'wechat',
'alipay',
'toutiao'
]
}
}))
.use(filterPlatform())
.use(renderTemplateFiles())
.build((err: Error) => {
if (!err) {
console.log(chalk.green('create project success!'))
}
})
}

const filterPlatform = () => {
return (_: any, metalsmith: any, done: () => void): void => {
const { platform } = metalsmith._metadata;
metalsmith._metadata.platformTitle = firstUpperCase(platform)
done()
}
}

const askQuestions = (prompts: CustomQuestionObjectType) => {
return (_: any, metalsmith: any, done: () => void): void => {
ask(prompts, metalsmith.metadata(), done)
}
}

const renderTemplateFiles = () => {
return (files: any, metalsmith: any, done: () => void): void => {
const keys = Object.keys(files)
const metalsmithMetadata = metalsmith.metadata()
async.each(keys, (file, next) => {
const str = files[file].contents.toString()
if (!/{{([^{}]+)}}/g.test(str)) {
return next()
}
consolidate.handlebars.render(str, metalsmithMetadata, (err: Error, res: string) => {
if (err) {
err.message = `[${file}] ${err.message}`
return next(err)
}
files[file].contents = Buffer.from(res, 'utf-8')
next()
})
}, done)
}
}


export const pathAndRepoUrlGenerator = (argv: ArgvType, macros: MacrosType): GeneratorValues => {
const { projectDirectory, t } = argv;
const destPath = path.join(process.cwd(), projectDirectory)
let tmpPath = path.join(__dirname, '../..', macros.tmpPathName)
let templateRepo = macros.templateRepo
let description = macros.description
if (t) {
templateRepo = macros.templateTSRepo
description = macros.descriptionTS
tmpPath = path.join(tmpPath, 'ts')
} else {
tmpPath = path.join(tmpPath, 'js')
}
const templatePath = path.join(tmpPath, macros.templatePathName)
return {
templatePath,
tmpPath,
destPath,
templateRepo,
description,
projectDirectory
}
}
14 changes: 0 additions & 14 deletions src/utils/macros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,4 @@ const macros = {
defaultPlatform: 'wechat'
}

export interface MacrosType {
scriptName: string,
placeholder: string,
download: string,
remaxRepo: string,
templateRepo: string,
templateTSRepo: string,
description: string,
descriptionTS: string,
tmpPathName: string,
templatePathName: string,
defaultPlatform: string
}

export default macros;
5 changes: 5 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const firstUpperCase = (str: string) => {
return str.toLowerCase().replace(/^./, (s: string): string => {
return s.toUpperCase()
})
}