Files
vue-cli/packages/@vue/cli-ui/apollo-server/connectors/git.js
2018-08-23 02:20:24 +02:00

124 lines
3.0 KiB
JavaScript

const execa = require('execa')
const path = require('path')
const fs = require('fs-extra')
const parseDiff = require('../util/parse-diff')
// Connectors
const cwd = require('./cwd')
// Utils
const { hasProjectGit } = require('@vue/cli-shared-utils')
async function getNewFiles (context) {
if (!hasProjectGit(cwd.get())) return []
const { stdout } = await execa('git', [
'ls-files',
'-o',
'--exclude-standard',
'--full-name'
], {
cwd: cwd.get()
})
if (stdout.trim()) {
return stdout.split(/\r?\n/g)
}
return []
}
async function getDiffs (context) {
if (!hasProjectGit(cwd.get())) return []
const { highlightCode } = require('../util/highlight')
const newFiles = await getNewFiles(context)
await execa('git', ['add', '-N', '*'], {
cwd: cwd.get()
})
const { stdout } = await execa('git', ['diff'], {
cwd: cwd.get()
})
await reset(context)
let list = parseDiff(stdout)
for (const n in list) {
const fileDiff = list[n]
const isNew = newFiles.includes(fileDiff.to)
let fromContent
if (!isNew) {
const result = await execa('git', ['show', `HEAD:${fileDiff.from}`], {
cwd: cwd.get()
})
fromContent = result.stdout
}
const highlightedContentFrom = fromContent && highlightCode(fileDiff.from, fromContent).split('\n')
const highlightedContentTo = highlightCode(fileDiff.to, fs.readFileSync(path.resolve(cwd.get(), fileDiff.to), { encoding: 'utf8' })).split('\n')
for (const chunk of fileDiff.chunks) {
for (const change of chunk.changes) {
const firstChar = change.content.charAt(0)
let highlightedCode
if (change.normal) {
highlightedCode = highlightedContentFrom[change.ln1 - 1]
} else if (change.type === 'del') {
highlightedCode = highlightedContentFrom[change.ln - 1]
} else if (change.type === 'add') {
highlightedCode = highlightedContentTo[change.ln - 1]
}
if (highlightedCode) {
change.content = firstChar + highlightedCode
}
}
}
list[n] = {
id: fileDiff.index.join(' '),
...fileDiff,
new: isNew
}
}
return list
}
async function commit (message, context) {
if (!hasProjectGit(cwd.get())) return false
await execa('git', ['add', '*'], {
cwd: cwd.get()
})
await execa('git', ['commit', '-m', message.replace(/"/, '\\"')], {
cwd: cwd.get()
})
return true
}
async function reset (context) {
if (!hasProjectGit(cwd.get())) return false
await execa('git', ['reset'], {
cwd: cwd.get()
})
return true
}
async function getRoot (context) {
if (!hasProjectGit(cwd.get())) return cwd.get()
const { stdout } = await execa('git', [
'rev-parse',
'--show-toplevel'
], {
cwd: cwd.get()
})
return stdout
}
async function resolveFile (file, context) {
const root = await getRoot(context)
return path.resolve(root, file)
}
module.exports = {
getDiffs,
commit,
reset,
getRoot,
resolveFile
}