基于快应用开发问题的自动化命令行
Posted 米花儿团儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于快应用开发问题的自动化命令行相关的知识,希望对你有一定的参考价值。
Git
校验
你记得这次打包是不是当前调试的代码么?
const sh = require(\'shelljs\')
const chalk = require(\'chalk\')
const uncommit = sh.exec(\'git status --porcelain\').stdout
const lines = uncommit.toString().split(\'\\n\').filter(item => item).length
if (lines) {
console.log(chalk.red(\'note: 有代码未提交或缓存,请慎重发版!!!\'))
console.log(\'----------------------------------------------------\')
console.log(\'recommend: 使用git push提交 或 git stash缓存后再发版.\')
process.exit(1)
}
process.exit(0)
每次打包没有日志,强制开发者必须上传或缓存后才能打包,利用Git为打包做日志服务。
const sh = require(\'shelljs\')
const chalk = require(\'chalk\')
const inquirer = require(\'inquirer\')
const log = console.log
async function permission () {
const uncommit = sh.exec(\'git status --porcelain\').stdout
const lines = uncommit.toString().split(\'\\n\').filter(item => item).length
if (lines) {
log(chalk.redBright(chalk.bold(\'note: \') + \'有代码未提交或缓存,请慎重发版!!!\'))
log(\'----------------------------------------------------\')
log(chalk.blueBright(\'recommend: \') + \'使用git push提交 或 git stash缓存后再发版.\')
const { isSkip } = (await inquirer.prompt({
type: \'expand\',
name: \'isSkip\',
choices: [
{
key: \'y\',
name: \'Yes\',
value: true
},
{
key: \'n\',
name: \'No\',
value: false
}
],
message: \'是否一意孤行?\'
}))
if (isSkip) {
process.env.custom_uncommit_skip = isSkip
process.exit(0)
}
process.exit(1)
}
process.exit(0)
}
permission()
使用场景
"prerelease": "node bin/index.js"
自动版本号【简约版】
const fs = require(\'fs\')
const path = require(\'path\')
const handleFile = path.resolve(process.cwd(), \'src\', \'manifest.json\')
const rawText = fs.readFileSync(handleFile)
const manifestJson = JSON.parse(rawText)
console.log(manifestJson)
manifestJson.versionCode++
fs.writeFileSync(handleFile, JSON.stringify(manifestJson, \'\', 2))
JSON.stringify
的使用
JSON.stringify()
接受三个参数
- data:JSON数据
- function:序列化函数——执行序列化时,被序列化的每个属性都会经过该函数的转换和处理。
- Number | String:指定缩进用的空白字符串来美化输出——Number标识新行空格的个数;字符串标识
\\t
、\\n
之类
使用场景
"prerelease": "node bin/git-uncommit.js && node bin/auto-version.js",
完善自动版本号
参考lerna version
- 通过命令行交互选择版本更新级别
- 根据对应的版本级别借助
semver.inc
升级版本
const fs = require(\'fs\')
const path = require(\'path\')
const sh = require(\'shelljs\')
const chalk = require(\'chalk\')
const semver = require(\'semver\')
const inquirer = require(\'inquirer\')
const terminal = inquirer.prompt
const quickJSONFile = path.resolve(process.cwd(), \'src\', \'manifest.json\')
const manifestJson = JSON.parse(fs.readFileSync(quickJSONFile))
function customVersion(message, { filter, validate } = {}) {
return terminal([
{
type: "input",
name: "input",
message,
filter,
validate,
},
])
.then(answers => {
return answers.input;
});
}
/**
* @param {PackageGraphNode|Object} node The metadata to process
* @property {String} currentVersion
* @property {String} name (Only used in independent mode)
* @property {String} prereleaseId
*/
function promptVersion(currentVersion, name, prereleaseId) {
const patch = semver.inc(currentVersion, "patch");
const minor = semver.inc(currentVersion, "minor");
const major = semver.inc(currentVersion, "major");
const prepatch = semver.inc(currentVersion, "prepatch", prereleaseId);
const preminor = semver.inc(currentVersion, "preminor", prereleaseId);
const premajor = semver.inc(currentVersion, "premajor", prereleaseId);
const message = `Select a new version ${name ? `for ${name} ` : ""}(currently ${currentVersion})`;
return terminal({
type: \'list\',
message,
name: \'choice\',
choices: [
{ value: patch, name: `Patch (${patch})` },
{ value: minor, name: `Minor (${minor})` },
{ value: major, name: `Major (${major})` },
{ value: prepatch, name: `Prepatch (${prepatch})` },
{ value: preminor, name: `Preminor (${preminor})` },
{ value: premajor, name: `Premajor (${premajor})` },
{ value: "PRERELEASE", name: "Custom Prerelease" },
{ value: "CUSTOM", name: "Custom Version" },
]
}).then(({choice}) => {
if (choice === "CUSTOM") {
return customVersion("Enter a custom version", {
filter: semver.valid,
// semver.valid() always returns null with invalid input
validate: v => v !== null || "Must be a valid semver version",
});
}
if (choice === "PRERELEASE") {
const defaultVersion = semver.inc(currentVersion, "prerelease", prereleaseId);
const prompt = `(default: "${prereleaseId}", yielding ${defaultVersion})`;
return customVersion(`Enter a prerelease identifier ${prompt}`, {
filter: v => semver.inc(currentVersion, "prerelease", v || prereleaseId),
});
}
return choice;
});
}
promptVersion(manifestJson.versionName).then(nextVersion => {
try {
manifestJson.versionName = nextVersion
manifestJson.versionCode++
fs.writeFileSync(quickJSONFile, JSON.stringify(manifestJson, \'\', 2))
console.log(chalk.whiteBright(`--------------path:${quickJSONFile}--------------------`))
console.log(`${chalk.whiteBright(chalk.bold(\'Has been configured a new version:\'))}${chalk.blueBright(nextVersion)}`)
console.log(chalk.whiteBright(`--------------releasing-releasing-releasing------------------`))
if (!process.env.custom_uncommit_skip) {
sh.exec(\'git commit --amend --no-edit\')
}
process.exit(0)
} catch (e) {
console.log(chalk.redBright(JSON.stringify(e)))
process.exit(1)
}
})
自动生成更新日志
第三方工具
standard-version:
执行npx standard-version
,会进行以下步骤:
- 在
packageFiles
文件中查询当前版本号 - 基于当前版本号 &
commit
(的type
)升级bumpFiles & packageFiles
文件中的版本号 - 生成提交日志(底层借助
conventional-changelog
) - 生成新的commit
- 生成新的tag
bumpFiles vs. packageFiles概念介绍:可以借助文章后续的定制化理解,简单来说,packageFiles
是输入,packageFiles
+ bumpFiles
是输出
用法
基础用法
npx standard-version
指定Tag前缀
默认是\'v-*\'
standard-version -t <prefix>
首次提交
指定首次提交,不会自动升级版本号
npx standard-version --first-release
指定预发版及Tag前缀
格式
standard-version --prerelease <prefix>
示例
# npm run script
npm run release -- --prerelease alpha
指定版本号
忽略自动升级版本功能
# npm run script
npm run release -- --release-as minor
# Or
npm run release -- --release-as 1.1.0
忽略Git钩子校验
standard-version --no-verify
定制化
默认配置
在项目根目录下创建.versionrc | .versionrc.js | .versionrc.json
定制使用standard-version
。
在这之前,需要了解默认配置,默认项是以下的合集
standard-version
的default.js
- 本文使用
standard-version
时,引入的conventional-changelog^2.1.0
以package.json
文件为例:standard-version
默认修改的是顶层的version
字段,如果想要修改其它结构中的其它字段,除了配置bumpFiles & packageFiles
,还需要自定义updater
。
快应用场景示例:
// .versionrc.js
const handleFile = [
{
"filename": "src/manifest.json",
"type": "json",
"updater": require(\'./bin/custom-version-updater\')
}
]
module.exports = {
"packageFiles": handleFile,
"bumpFiles": handleFile
}
// bin/custom-version-updater.js
const stringifyPackage = require(\'stringify-package\')
const detectIndent = require(\'detect-indent\')
const detectNewline = require(\'detect-newline\')
module.exports.readVersion = function (contents) {
return JSON.parse(contents).versionName
}
module.exports.writeVersion = function (contents, version) {
const json = JSON.parse(contents)
let indent = detectIndent(contents).indent
let newline = detectNewline(contents)
json.versionCode++
json.versionName = version
return stringifyPackage(json, indent, newline)
}
自定义adapter官方文档
以上是关于基于快应用开发问题的自动化命令行的主要内容,如果未能解决你的问题,请参考以下文章
sql [SQL查询片段]用于在命令行或通过R和其他工具使用SQL的快速代码段#tags:sql,R,text processing,命令li
每当我运行我的片段时,这行代码 mapFragment.setRetainInstance(true);正在崩溃我的应用程序? [关闭]