UNPKG

git-gallery

Version:

A gallery app for showing work based on Git commits.

189 lines (163 loc) 4.54 kB
const simpleGit = require('simple-git'); const path = require("path"); const fs = require('fs-extra'); const hbs = require('hbs'); const repoPath = path.resolve(process.cwd()); var git; function getRepo() { return new Promise(function(fulfill, reject) { if (git) { fulfill(git); } else { try { git = simpleGit(repoPath); fulfill(git); } catch (error) { logError("Unable to open Git repo: " + repoPath, error); reject(error); } } }); } function getCommit(ref) { if (ref === 'HEAD') { return getHeadCommit(); } // For simple compatibility, just return the ref if it's a valid commit hash // The repo.js route only needs the commit reference, not the full commit object return Promise.resolve(ref); } function getHeadCommit() { return getRepo().then(git => { return git.log({ maxCount: 1 }).then(log => { const commit = log.latest; return { sha: commit.hash, author: { name: commit.author_name, email: commit.author_email }, date: new Date(commit.date), message: commit.message }; }); }); } function getCommits(maxCount) { return getRepo() .then(git => { return git.log({ maxCount: maxCount || 1000 }); }).then(log => { return log.all.map(commit => ({ sha: commit.hash, author: { name: commit.author_name, email: commit.author_email }, date: new Date(commit.date), message: commit.message })); }); } function getAllCommits() { return getCommits(1000); } function getLatestCommit() { return getCommits(1).then(commits => commits[0]); } function isWorkingDirClean() { return getRepo().then(git => { return git.status() }) .then(status => { return status.files.length === 0; }); } function isHeadDetached() { return getRepo().then(git => { return git.revparse(['--abbrev-ref', 'HEAD']).then(branch => { return branch.trim() === 'HEAD'; }); }); } function headStatus() { return isWorkingDirClean().then(isClean => { return isHeadDetached().then(isDetached => { return { isClean: isClean, isDetached: isDetached }; }); }); } function repoStatus() { let git; let status; return headStatus().then(_status => { status = _status; return getRepo(); }) .then(_git => { git = _git; return git.revparse(['--abbrev-ref', 'HEAD']); }) .then(branch => { status.branch = branch.trim(); return git.status(); }) .then(gitStatus => { gitStatus.files.forEach((file, index) => { gitStatus.files[index].description = statusToText(file); }); status.status = gitStatus.files; return status; }); } function statusToText(file) { var words = []; if (file.index === '?') { words.push("NEW"); } if (file.index === 'M' || file.working_dir === 'M') { words.push("MODIFIED"); } if (file.index === 'R' || file.working_dir === 'R') { words.push("RENAMED"); } if (file.index === 'D' || file.working_dir === 'D') { words.push("DELETED"); } if (file.index === 'U' || file.working_dir === 'U') { words.push("CONFLICTED"); } return words.join(" "); } function commitAllChanges(message) { return getRepo() .then(git => { return git.add('.') .then(() => git.commit(message)); }); } function restoreCommit(ref, dir, filter) { return getRepo() .then(git => { return git.raw(['ls-tree', '-r', '--name-only', ref]) .then(output => { const files = output.trim().split('\n').filter(f => f); const promises = files.map(filePath => { if (filter && !filter(filePath)) return Promise.resolve(); const fullPath = path.join(dir, filePath); return git.show([ref + ':' + filePath]) .then(content => { fs.ensureDirSync(path.dirname(fullPath)); return fs.writeFile(fullPath, content); }); }); return Promise.all(promises); }); }); } function logError(message, error) { console.log(message); console.log(error); } exports.getRepo = getRepo; exports.getCommit = getCommit; exports.getHeadCommit = getHeadCommit; exports.getCommits = getCommits; exports.getAllCommits = getAllCommits; exports.getLatestCommit = getLatestCommit; exports.isWorkingDirClean = isWorkingDirClean; exports.isHeadDetached = isHeadDetached; exports.headStatus = headStatus; exports.repoStatus = repoStatus; exports.commitAllChanges = commitAllChanges; exports.restoreCommit = restoreCommit;