mora-scripts
Version:
Some collection scripts by myself
157 lines (136 loc) • 4.93 kB
JavaScript
var fs = require('fs')
var path = require('path')
var cp = require('child_process')
var resolve = require('path').resolve
var findup = require('../../libs/fs/findup')
// var warn = require('../../libs/sys/warn')
var shell = require('../../libs/tty/shell')
var exists = require('../../libs/fs/exists')
// console.log('Working directory ' + process.cwd()) // 就是当前项目(mora-scripts)的根目录
var ROOT = resolve(process.cwd(), '..', '..') // 用户项目的根目录
var config = require('./config')
var template = process.platform === 'win32'
? fs.readFileSync(resolve(__dirname, 'template.js')).toString()
: fs.readFileSync(resolve(__dirname, 'template.sh')).toString()
.replace('{node}', path.relative(ROOT, path.join(ROOT, 'node_modules', '.bin', 'run-node')))
.replace('{script}', path.relative(ROOT, require.resolve('./pre-runner.js')))
var reTemplate = /Generated by mora-scripts\. Do not edit this file\./
var args = process.argv.slice(2).join(',')
function main() {
// INIT_CWD holds the full path you were in when you ran npm install (supported also by yarn and pnpm)
// See https://docs.npmjs.com/cli/run-script
if (process.env.INIT_CWD) {
if (process.env.INIT_CWD.indexOf('node_modules') > 0) return
}
var gitDir = findup.git()
if (ROOT !== path.dirname(gitDir)) return
var pkg = require(path.join(ROOT, 'package.json'))
if (
pkg.config && pkg.config.hooks && Object.keys(pkg.config.hooks).length
&& (pkg.dependencies && pkg.dependencies['mora-scripts'] || pkg.devDependencies && pkg.devDependencies['mora-scripts'])
) {
if (/reverse|uninstall/.test(args)) {
uninstall(gitDir)
} else {
install(gitDir)
}
}
}
try {
main()
} catch (e) {}
function install(gitDir) {
try {
console.log('Install hooks in ' + gitDir)
var hooksDir = resolve(gitDir, 'hooks')
if (!exists.directory(hooksDir)) fs.mkdirSync(hooksDir)
config.hooks.forEach(installHook.bind(null, hooksDir))
installGitMessage(gitDir)
} catch (e) {
warnAboutGit()
}
}
function uninstall(gitDir) {
try {
config.hooks.forEach(uninstallHook.bind(null, resolve(gitDir, 'hooks')))
uninstallGitMessage(path.join(path.dirname(gitDir), '.gitmessage'))
} catch (e) {}
}
function installHook(dir, file) {
var filepath = resolve(dir, file)
if (!isHookTemplateFile(filepath)) {
// console.log(' install hook ' + file)
backup(filepath)
fs.writeFileSync(filepath, template)
fs.chmodSync(filepath, '755')
} else {
// console.log(' update hook ' + file)
fs.writeFileSync(filepath, template) // 更新原来的文件
}
}
function uninstallHook(dir, file) {
var filepath = resolve(dir, file)
if (isHookTemplateFile(filepath)) {
// console.log(' uninstall hook ' + file)
restore(filepath)
}
}
function installGitMessage(dotGitDir) {
if (tryExecCmdSync('git config --local commit.template', '') !== '.gitmessage') {
var messageFile = path.join(path.dirname(dotGitDir), '.gitmessage')
// console.log('\n set git commit.template')
if (!exists.file(messageFile)) {
// 文件不存在,使用模板
fs.writeFileSync(messageFile, fs.readFileSync(resolve(__dirname, '..', 'gitmessage')).toString())
}
shell('git config --local commit.template .gitmessage')
}
}
function uninstallGitMessage(messageFile) {
if (tryExecCmdSync('git config --local commit.template', '') === '.gitmessage') {
shell('git config --local --unset commit.template')
}
// if (exists.file(messageFile)) {
// warn(
// '\ngit config commit.template has already unset.\n'
// + 'so file ' + messageFile + ' not in use.\n'
// + 'you can delete it anytime.\n'
// )
// }
}
function tryExecCmdSync(cmd, fallback) {
try {
return cp.execSync(cmd).toString()
} catch (e) {
return fallback
}
}
function isHookTemplateFile(filepath) {
try {
return reTemplate.test(fs.readFileSync(filepath).toString())
} catch (e) { return false }
}
function warnAboutGit() {
// 不出醒目的提醒,此包不只是 hooks,还有很多功能函数
console.log('Hooks not installed, because not a git project')
// warn(
// '\nThis does not seem to be a git project.\n'
// + '===========================================================\n\n'
// + 'Although mora-scripts was installed, the actual hooks have not.\n'
// + 'Please run the following command manually:\n\n'
// + '\tgit init\n'
// + '\tnpm explore mora-scripts -- npm run postinstall\n\n'
// + 'Please ignore this message if you are not using mora-scripts/hooks directly.\n'
// )
}
function backup(filepath) {
rename(filepath, filepath + '.bkp')
}
function restore(filepath) {
rename(filepath + '.bkp', filepath)
}
function rename(from, to) {
if (exists.file(to)) fs.unlinkSync(to)
if (exists.file(from)) fs.renameSync(from, to)
}