feat: git changes processing
This commit is contained in:
@@ -69,3 +69,7 @@ props:
|
||||
default: 'John Smith'
|
||||
hint: 'Used as fallback in case the author of the change is not present.'
|
||||
order: 21
|
||||
actions:
|
||||
- handler: syncUntracked
|
||||
label: Add Untracked Changes
|
||||
hint: Output all content from the DB to the Git repo to ensure all untracked content is saved. If you enabled Git after content was created or you temporarily disabled Git, you'll want to execute this action to add the missing untracked changes.
|
||||
|
@@ -3,6 +3,8 @@ const sgit = require('simple-git/promise')
|
||||
const fs = require('fs-extra')
|
||||
const _ = require('lodash')
|
||||
|
||||
const localeFolderRegex = /^([a-z]{2}(?:-[a-z]{2})?\/)?(.*)/i
|
||||
|
||||
/**
|
||||
* Get file extension based on content type
|
||||
*/
|
||||
@@ -17,6 +19,33 @@ const getFileExtension = (contentType) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getContenType = (filePath) => {
|
||||
const ext = _.last(filePath.split('.'))
|
||||
switch (ext) {
|
||||
case 'md':
|
||||
return 'markdown'
|
||||
case 'html':
|
||||
return 'html'
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const getPagePath = (filePath) => {
|
||||
let meta = {
|
||||
locale: 'en',
|
||||
path: _.initial(filePath.split('.')).join('')
|
||||
}
|
||||
const result = localeFolderRegex.exec(meta.path)
|
||||
if (result[1]) {
|
||||
meta = {
|
||||
locale: result[1],
|
||||
path: result[2]
|
||||
}
|
||||
}
|
||||
return meta
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
git: null,
|
||||
repoPath: path.join(process.cwd(), 'data/repo'),
|
||||
@@ -26,6 +55,9 @@ module.exports = {
|
||||
async deactivated() {
|
||||
// not used
|
||||
},
|
||||
/**
|
||||
* INIT
|
||||
*/
|
||||
async init() {
|
||||
WIKI.logger.info('(STORAGE/GIT) Initializing...')
|
||||
this.repoPath = path.resolve(WIKI.ROOTPATH, this.config.localRepoPath)
|
||||
@@ -87,7 +119,12 @@ module.exports = {
|
||||
|
||||
WIKI.logger.info('(STORAGE/GIT) Initialization completed.')
|
||||
},
|
||||
/**
|
||||
* SYNC
|
||||
*/
|
||||
async sync() {
|
||||
const currentCommitLog = _.get(await this.git.log(['-n', '1', this.config.branch]), 'latest', {})
|
||||
|
||||
// Pull rebase
|
||||
if (_.includes(['sync', 'pull'], this.mode)) {
|
||||
WIKI.logger.info(`(STORAGE/GIT) Performing pull rebase from origin on branch ${this.config.branch}...`)
|
||||
@@ -103,7 +140,83 @@ module.exports = {
|
||||
}
|
||||
await this.git.push('origin', this.config.branch, pushOpts)
|
||||
}
|
||||
|
||||
// Process Changes
|
||||
if (_.includes(['sync', 'pull'], this.mode)) {
|
||||
const latestCommitLog = _.get(await this.git.log(['-n', '1', this.config.branch]), 'latest', {})
|
||||
|
||||
const diff = await this.git.diffSummary([currentCommitLog.hash, latestCommitLog.hash])
|
||||
if (_.get(diff, 'files', []).length > 0) {
|
||||
for(const item of diff.files) {
|
||||
const contentType = getContenType(item.file)
|
||||
if (!contentType) {
|
||||
continue
|
||||
}
|
||||
const contentPath = getPagePath(item.file)
|
||||
|
||||
let itemContents = ''
|
||||
try {
|
||||
itemContents = await fs.readFile(path.join(this.repoPath, item.file), 'utf8')
|
||||
const pageData = WIKI.models.pages.parseMetadata(itemContents, contentType)
|
||||
const currentPage = await WIKI.models.pages.query().findOne({
|
||||
path: contentPath.path,
|
||||
localeCode: contentPath.locale
|
||||
})
|
||||
if (currentPage) {
|
||||
// Already in the DB, can mark as modified
|
||||
WIKI.logger.info(`(STORAGE/GIT) Page marked as modified: ${item.file}`)
|
||||
await WIKI.models.pages.updatePage({
|
||||
id: currentPage.id,
|
||||
title: _.get(pageData, 'title', currentPage.title),
|
||||
description: _.get(pageData, 'description', currentPage.description),
|
||||
isPublished: _.get(pageData, 'isPublished', currentPage.isPublished),
|
||||
isPrivate: false,
|
||||
content: pageData.content,
|
||||
authorId: 1,
|
||||
skipStorage: true
|
||||
})
|
||||
} else {
|
||||
// Not in the DB, can mark as new
|
||||
WIKI.logger.info(`(STORAGE/GIT) Page marked as new: ${item.file}`)
|
||||
const pageEditor = await WIKI.models.editors.getDefaultEditor(contentType)
|
||||
await WIKI.models.pages.createPage({
|
||||
path: contentPath.path,
|
||||
locale: contentPath.locale,
|
||||
title: _.get(pageData, 'title', _.last(contentPath.path.split('/'))),
|
||||
description: _.get(pageData, 'description', ''),
|
||||
isPublished: _.get(pageData, 'isPublished', true),
|
||||
isPrivate: false,
|
||||
content: pageData.content,
|
||||
authorId: 1,
|
||||
editor: pageEditor,
|
||||
skipStorage: true
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT' && item.deletions > 0 && item.insertions === 0) {
|
||||
// File was deleted by git, can safely mark as deleted in DB
|
||||
WIKI.logger.info(`(STORAGE/GIT) Page marked as deleted: ${item.file}`)
|
||||
|
||||
await WIKI.models.pages.deletePage({
|
||||
path: contentPath.path,
|
||||
locale: contentPath.locale,
|
||||
skipStorage: true
|
||||
})
|
||||
|
||||
} else {
|
||||
WIKI.logger.warn(`(STORAGE/GIT) Failed to open ${item.file}`)
|
||||
WIKI.logger.warn(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* CREATE
|
||||
*
|
||||
* @param {Object} page Page to create
|
||||
*/
|
||||
async created(page) {
|
||||
WIKI.logger.info(`(STORAGE/GIT) Committing new file ${page.path}...`)
|
||||
const fileName = `${page.path}.${getFileExtension(page.contentType)}`
|
||||
@@ -115,6 +228,11 @@ module.exports = {
|
||||
'--author': `"${page.authorName} <${page.authorEmail}>"`
|
||||
})
|
||||
},
|
||||
/**
|
||||
* UPDATE
|
||||
*
|
||||
* @param {Object} page Page to update
|
||||
*/
|
||||
async updated(page) {
|
||||
WIKI.logger.info(`(STORAGE/GIT) Committing updated file ${page.path}...`)
|
||||
const fileName = `${page.path}.${getFileExtension(page.contentType)}`
|
||||
@@ -126,6 +244,11 @@ module.exports = {
|
||||
'--author': `"${page.authorName} <${page.authorEmail}>"`
|
||||
})
|
||||
},
|
||||
/**
|
||||
* DELETE
|
||||
*
|
||||
* @param {Object} page Page to delete
|
||||
*/
|
||||
async deleted(page) {
|
||||
WIKI.logger.info(`(STORAGE/GIT) Committing removed file ${page.path}...`)
|
||||
const fileName = `${page.path}.${getFileExtension(page.contentType)}`
|
||||
@@ -135,6 +258,11 @@ module.exports = {
|
||||
'--author': `"${page.authorName} <${page.authorEmail}>"`
|
||||
})
|
||||
},
|
||||
/**
|
||||
* RENAME
|
||||
*
|
||||
* @param {Object} page Page to rename
|
||||
*/
|
||||
async renamed(page) {
|
||||
WIKI.logger.info(`(STORAGE/GIT) Committing file move from ${page.sourcePath} to ${page.destinationPath}...`)
|
||||
const sourceFilePath = `${page.sourcePath}.${getFileExtension(page.contentType)}`
|
||||
|
Reference in New Issue
Block a user