Commit 4d245098 authored by lipengcheng 's avatar lipengcheng

download ander compile gitlab

parent eabe3e95
File added
......@@ -9,6 +9,14 @@
- [ ] vuecli中对ora(spinner)使用的封装
- [ ] vuecli中对log的封装(logger)
- [ ] command <list> 显示模板列表
- [ ] 全局捕获creator错误 -- vuecli
- [ ] 编译复制的时候去掉不需要的文件
- [ ] 动态生成package.json、readme文件内容
- [ ] 拼接package.json内容的方式
- [ ] 初始化项目时端口防重
- [ ] 通过删除模板文件中带插值的文件定位ejs报错信息
- [ ] 脚手架版本提示:"New version available 4.5.11 → 4.5.12";提示信息以方框的形式展示
- [ ] 删除生成的项目的git目录
#### Q
metalsmith是什么?
handlerbar?
......
......@@ -4,15 +4,17 @@ const { wrapLoading } = require('./utils')
const downlodRepo = require('download-git-repo') //不支持promise
const util = require('util')
const path = require('path')
const { generate } = require('./generate')
const fse = require('fs-extra');
const ORG = 'zhu-cli'
// const ORG = 'vuejs'
module.exports = class Creator {
constructor(projectname, targetDir) {
this.name = projectname
this.target = targetDir
this.tmpTarget = path.resolve(targetDir, '.tmp')
constructor(targetDir, meta, repo) {
this.targetDir = targetDir
this.meta = meta
this.repo = repo
this.tmpTarget = path.resolve(targetDir, '.lhfe-cli')
this.downlodRepo = util.promisify(downlodRepo)
}
......@@ -81,6 +83,7 @@ module.exports = class Creator {
async createFromGithub() {
const repo = await this.fetchRepo()
const tag = await this.fetchTag(repo)
// 拉取仓库
await this.exeDownload(repo, tag)
// 进入目录安装依赖
......@@ -89,23 +92,25 @@ module.exports = class Creator {
async createFromGitlab() {
// const url = `direct:https://gitlab.ilaihua.com/laihua-web/laihua-webh5.git` // 会报错git checkout,是git仓库
const url = `direct:https://gitlab.ilaihua.com/laihua-web/laihua-webh5.git#develop` // 没报错,不是git仓库
// const url = `direct:https://gitlab.ilaihua.com/laihua-web/laihua-webh5.git#develop` // 没报错,不是git仓库,可以拉取到指定分支
// const url = `direct:https://gitlab.ilaihua.com/laihua-web/laihua-webh5` // 会报错 是git仓库
// const url = `direct:https://gitlab.ilaihua.com/laihua-web/laihua-webh5#uat` // 没报错,不是git仓库
// const url = `direct:https://gitlab.ilaihua.com/laihua-web/laihua-webh5#uat` // 没报错,不是git仓库,可以拉取到指定分支
// const url = `https://gitlab.ilaihua.com:laihua-web/laihua-webh5` // 报错,是git仓库
// const url = `https://gitlab.ilaihua.com:laihua-web/laihua-webh5#uat` // 没报错 不是git仓库
// const url = `https://gitlab.ilaihua.com:laihua-web/laihua-webh5#uat` // 没报错 不是git仓库,可以拉取到指定分支
// const url = `direct:https://gitlab.ilaihua.com/lhfe/mould-vuecli3#feature/tpl`
const url = `direct:https://gitlab.ilaihua.com/lhfe/${this.repo}.git#feature/tpl`
// const url = `direct:https://gitlab.ilaihua.com/lhfe/mould-nuxt-h5.git#feature/tpl`
// download(
// url,
// path.resolve(process.cwd(), `aaaa`),
// {
// clone: true,
// // headers: { 'PRIVATE-TOKEN': key }
// },
// function (err) {
// console.log(err || 'Success')
// })
await wrapLoading(this.downlodRepo, 'Waitting for download。。。', url, this.tmpTarget, { clone: true })
await wrapLoading(this.downlodRepo, 'Waitting for download...', url, this.tmpTarget, { clone: true })
// 编译模板
// const source = path.resolve(__dirname, '../../aa/bbbb/.lhfe-cli')
// const source = path.resolve(__dirname, '../tpl/testgit')
await generate(this.tmpTarget, this.targetDir, this.meta)
// 移除临时目录
await fse.remove(this.tmpTarget)
// 进入项目初始化git
// 。。
}
}
\ No newline at end of file
......@@ -2,8 +2,11 @@
const path = require('path')
const fs = require('fs-extra');
const inquirer = require('inquirer');
const prompts = require('./prompts')
const Creator = require('./Creator')
const { validatePkgName } = require('../lib/utils')
const chalk = require('chalk')
// ======
module.exports = async function(projectname, options){
const cwd = process.cwd()
......@@ -12,28 +15,16 @@ module.exports = async function(projectname, options){
let inCurrent = false
if (projectname === basename) {
const { ok } = await inquirer.prompt([
{
name: 'ok',
type: 'confirm',
message: `项目名称与当前工作目录名称一样,是否直接在工作目录初始化项目?`
}
])
const { ok } = await inquirer.prompt(prompts.sameName)
inCurrent = ok
} else if (projectname === '.') {
const { ok } = await inquirer.prompt([
{
name: 'ok',
type: 'confirm',
message: `Generate project in current directory?`
}
])
const { ok } = await inquirer.prompt(prompts.initCurrent)
inCurrent = ok
}
const pkbName = inCurrent ? basename : projectname
const pkgName = inCurrent ? basename : projectname
const targetDir = path.resolve(cwd, inCurrent ? '' : projectname)
validatePkgName(pkbName)
validatePkgName(pkgName)
// 已存在同名目录
if (!inCurrent && fs.existsSync(targetDir)){
......@@ -45,17 +36,7 @@ module.exports = async function(projectname, options){
await fs.remove(targetDir)
} else {
// 提示是否要覆盖
const answers = await inquirer.prompt([
{
name: 'action',
type: 'list',
message: `Target dir has exists`,
choices: [
{ name: 'Overwrite', value: 'overwrite' },
{ name: 'Cncel', value: false },
]
}
])
const answers = await inquirer.prompt(prompts.overwrite)
const { action } = answers
if (!action) {
......@@ -66,22 +47,14 @@ module.exports = async function(projectname, options){
}
}
}
console.log(`pkbName:`, pkbName);
console.log(`targetDir:`, targetDir);
const { sourceType } = await inquirer.prompt([
{
name: 'sourceType',
type: 'list',
message: `Do u want to create project from Github or Gitlab?`,
choices:[
{name: 'Github', value: 'github'},
{name: 'Gitlab', value: 'gitlab'}
]
}
])
const { sourceType } = await inquirer.prompt(prompts.source)
let repo = 'mould-nuxt-h5'
if (sourceType === 'gitlab'){
repo = (await inquirer.prompt(prompts.repos)).repo
}
const meta = await inquirer.prompt(prompts.initMetaPrompts(projectname))
console.log('开始创建:',);
const creator = new Creator(pkbName, targetDir)
const creator = new Creator(targetDir, meta, repo)
creator.create(sourceType)
}
\ No newline at end of file
const Metalsmith = require('metalsmith')
const Handlebars = require('handlebars')
const path = require('path');
const { promisify } = require('util');
const render = require('consolidate').ejs.render; // 统一所有的模板引擎
const renderPro = promisify(render);
const ncp = require('ncp');
const ncpPro = promisify(ncp);
async function generate(source, target, meta) {
console.log(`source==:`,source);
console.log(`target:`,target);
console.log(`meta:`,meta);
let result = await new Promise((resolve, reject) => {
Metalsmith(source)
.metadata(meta)
.source(source)
.destination(target)
.use(async (files, metal, done) => {
const m = metal.metadata();
Object.assign(m, {email: 'xxxxx', description:'this is an extra attr' });
const excludeFiles = ['CHANGELOG.md']
excludeFiles.forEach(file => delete files[file])
done()
})
.use(async (files, metal, done) => {
const meta = metal.metadata();
Object.keys(files).forEach(async (file) => {
let content = files[file].contents.toString();
// 判断是否是模板 可用正则匹配
if (content.includes('<%')) {
content = await renderPro(content, meta);
files[file].contents = Buffer.from(content);
}
})
done()
})
.build((err) => {
err ? reject(false) : resolve(true)
})
}).catch(err => console.log(`err:`, err))
return result
}
module.exports = {
generate
}
const { execSync } = require('child_process')
module.exports.source = [
{
name: 'sourceType',
type: 'list',
message: `Do u want to create project from Github or Gitlab?`,
choices: [
{ name: 'Gitlab', value: 'gitlab' },
{ name: 'Github', value: 'github' },
]
}
]
module.exports.sameName = [
{
name: 'ok',
type: 'confirm',
message: `项目名称与当前工作目录名称一样,是否直接在工作目录初始化项目?`
}
]
module.exports.initCurrent = [
{
name: 'ok',
type: 'confirm',
message: `Generate project in current directory?`
}
]
module.exports.overwrite = [
{
name: 'action',
type: 'list',
message: `Target dir has exists`,
choices: [
{ name: 'Overwrite', value: 'overwrite' },
{ name: 'Cncel', value: false },
]
}
]
module.exports.repos = [
{
name: 'repo',
type: 'list',
message: `选择要拉取的仓库`,
choices: [
{ name: 'mould-nuxt', value: 'mould-nuxt' },
{ name: 'mould-nuxt-h5', value: 'mould-nuxt-h5' },
{ name: 'mould-vuecli3', value: 'mould-vuecli3' },
]
}
]
module.exports.initMetaPrompts = function (pkgName='') {
let user = execSync('git config --global user.name', { encoding: 'utf-8' });
let email = execSync('git config --global user.email', { encoding: 'utf-8' });
user = user.trim();
email = email.trim();
return [
{
type: 'confirm',
name: 'private',
message: 'Is the project private ?'
},
{
type: 'input',
name: 'pkgName',
message: 'package name',
default: pkgName,
// validate(input) {
// if (input.trim().length === 0) {
// return;
// }
// }
},
{
type: 'input',
name: 'port',
message: 'project port',
// validate(input) {
// if (input.trim().length === 0) {
// return;
// }
// }
},
{
type: 'input',
name: 'description',
message: 'description'
},
// {
// type: 'list',
// name: 'license',
// message: 'license',
// choices: ['MIT', "BSD 2-clause 'Simplified'", 'Apache 2.0', 'GNU General Public v3.0', 'BSD 3-clause', 'Eclipse Public 1.0', 'GNU Affero General Public v3.0', 'GNU General Public v2.0', 'GNU Lesser General Public v2.1', 'GNU Lesser General Public v3.0', 'Mozilla Public 2.0', 'The Unlicense']
// },
{
type: 'input',
name: 'author',
message: 'author',
default: `${user} ${email}`
},
];
}
module.exports = [
{
name: 'ok',
type: 'confirm',
message: `xxxxxx`
}
]
\ No newline at end of file
/*
* @Date: 2021-03-31 17:53:31
* @LastEditors: OBKoro1
* @LastEditTime: 2021-03-31 17:53:31
* @FilePath: /lib/ask.js
* @Description: 描述
* @Author: huacong
*
*/
const { execSync } = require('child_process')
module.exports = function askCreator(template = '') {
let user = execSync('git config --global user.name', { encoding: 'utf-8' });
let email = execSync('git config --global user.email', { encoding: 'utf-8' });
console.log(`user:`,user);
user = user.trim();
email = email.trim();
console.log(`user:`,user);
return [
{
type: 'confirm',
name: 'private',
message: 'Is the project private ?'
},
{
type: 'input',
name: 'pkgName',
message: 'package name',
default: 'default pkgName',
// validate(input) {
// if (input.trim().length === 0) {
// return;
// }
// }
},
{
type: 'input',
name: 'port',
message: 'project port',
// validate(input) {
// if (input.trim().length === 0) {
// return;
// }
// }
},
{
type: 'input',
name: 'description',
message: 'description'
},
// {
// type: 'list',
// name: 'license',
// message: 'license',
// choices: ['MIT', "BSD 2-clause 'Simplified'", 'Apache 2.0', 'GNU General Public v3.0', 'BSD 3-clause', 'Eclipse Public 1.0', 'GNU Affero General Public v3.0', 'GNU General Public v2.0', 'GNU Lesser General Public v2.1', 'GNU Lesser General Public v3.0', 'Mozilla Public 2.0', 'The Unlicense']
// },
{
type: 'input',
name: 'author',
message: 'author',
default: user
},
];
}
项目模板目录
\ No newline at end of file
const descriptions = {
build: 'Compiles and minifies for production',
serve: 'Compiles and hot-reloads for development',
lint: 'Lints and fixes files',
'test:e2e': 'Run your end-to-end tests',
'test:unit': 'Run your unit tests'
}
function printScripts(pkg, packageManager) {
return Object.keys(pkg.scripts || {}).map(key => {
if (!descriptions[key]) return ''
return [
`\n### ${descriptions[key]}`,
'```',
`${packageManager} ${packageManager !== 'yarn' ? 'run ' : ''}${key}`,
'```',
''
].join('\n')
}).join('')
}
module.exports = function generateReadme(pkg, packageManager) {
return [
`# ${pkg.name}\n`,
'## Project setup',
'```',
`${packageManager} install`,
'```',
printScripts(pkg, packageManager),
'### Customize configuration',
'See [Configuration Reference](https://cli.vuejs.org/config/).',
''
].join('\n')
}
const fs = require('fs-extra')
const path = require('path')
function deleteRemovedFiles(directory, newFiles, previousFiles) {
// get all files that are not in the new filesystem and are still existing
const filesToDelete = Object.keys(previousFiles)
.filter(filename => !newFiles[filename])
// delete each of these files
return Promise.all(filesToDelete.map(filename => {
return fs.unlink(path.join(directory, filename))
}))
}
/**
*
* @param {string} dir
* @param {Record<string,string|Buffer>} files
* @param {Record<string,string|Buffer>} [previousFiles]
* @param {Set<string>} [include]
*/
module.exports = async function writeFileTree(dir, files, previousFiles, include) {
if (process.env.VUE_CLI_SKIP_WRITE) {
return
}
if (previousFiles) {
await deleteRemovedFiles(dir, files, previousFiles)
}
Object.keys(files).forEach((name) => {
if (include && !include.has(name)) return
const filePath = path.join(dir, name)
fs.ensureDirSync(path.dirname(filePath))
fs.writeFileSync(filePath, files[name])
})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment