fixed git helper async/await issues, template strings, clean up

This commit is contained in:
Felix Wiedenbach 2021-09-18 03:50:53 +02:00
parent 60e03777f3
commit 75a57829c2

View File

@ -4,10 +4,11 @@ const fs = require("fs");
const path = require("path"); const path = require("path");
const Log = require("logger"); const Log = require("logger");
class gitHelper { const BASE_DIR = path.normalize(`${__dirname}/../../../`);
class GitHelper {
constructor() { constructor() {
this.gitRepos = []; this.gitRepos = [];
this.baseDir = path.normalize(__dirname + "/../../../");
} }
getRefRegex(branch) { getRefRegex(branch) {
@ -15,37 +16,41 @@ class gitHelper {
} }
async execShell(command) { async execShell(command) {
let res = { stdout: "", stderr: "" }; const { stdout = "", stderr = "" } = await exec(command);
const { stdout, stderr } = await exec(command);
res.stdout = stdout; return { stdout, stderr };
res.stderr = stderr;
return res;
} }
async isGitRepo(moduleFolder) { async isGitRepo(moduleFolder) {
let res = await this.execShell("cd " + moduleFolder + " && git remote -v"); const res = await this.execShell(`cd ${moduleFolder} && git remote -v`);
if (res.stderr) { if (res.stderr) {
Log.error("Failed to fetch git data for " + moduleFolder + ": " + res.stderr); Log.error(`Failed to fetch git data for ${moduleFolder}: ${res.stderr}`);
return false; return false;
} else {
return true;
}
} }
add(moduleName) { return true;
let moduleFolder = this.baseDir;
if (moduleName !== "default") {
moduleFolder = moduleFolder + "modules/" + moduleName;
} }
async add(moduleName) {
let moduleFolder = BASE_DIR;
if (moduleName !== "default") {
moduleFolder = `${moduleFolder}modules/${moduleName}`;
}
try { try {
Log.info("Checking git for module: " + moduleName); Log.info(`Checking git for module: ${moduleName}`);
// Throws error if file doesn't exist // Throws error if file doesn't exist
fs.statSync(path.join(moduleFolder, ".git")); fs.statSync(path.join(moduleFolder, ".git"));
// Fetch the git or throw error if no remotes // Fetch the git or throw error if no remotes
if (this.isGitRepo(moduleFolder)) { const isGitRepo = await this.isGitRepo(moduleFolder);
if (isGitRepo) {
// Folder has .git and has at least one git remote, watch this folder // Folder has .git and has at least one git remote, watch this folder
this.gitRepos.unshift({ module: moduleName, folder: moduleFolder }); this.gitRepos.push({ module: moduleName, folder: moduleFolder });
} }
} catch (err) { } catch (err) {
// Error when directory .git doesn't exist or doesn't have any remotes // Error when directory .git doesn't exist or doesn't have any remotes
@ -56,36 +61,38 @@ class gitHelper {
async getStatusInfo(repo) { async getStatusInfo(repo) {
let gitInfo = { let gitInfo = {
module: repo.module, module: repo.module,
// commits behind: behind: 0, // commits behind
behind: 0, current: "", // branch name
// branch name: hash: "", // current hash
current: "", tracking: "", // remote branch
// current hash:
hash: "",
// remote branch:
tracking: "",
isBehindInStatus: false isBehindInStatus: false
}; };
let res; let res;
if (repo.module === "default") { if (repo.module === "default") {
// the hash is only needed for the mm repo // the hash is only needed for the mm repo
res = await this.execShell("cd " + repo.folder + " && git rev-parse HEAD"); res = await this.execShell(`cd ${repo.folder} && git rev-parse HEAD`);
if (res.stderr) { if (res.stderr) {
Log.error("Failed to get current commit hash for " + repo.module + ": " + res.stderr); Log.error(`Failed to get current commit hash for ${repo.module}: ${res.stderr}`);
} }
gitInfo.hash = res.stdout; gitInfo.hash = res.stdout;
} }
if (repo.res) { if (repo.res) {
// mocking // mocking
res = repo.res; res = repo.res;
} else { } else {
res = await this.execShell("cd " + repo.folder + " && git status -sb"); res = await this.execShell(`cd ${repo.folder} && git status -sb`);
} }
if (res.stderr) { if (res.stderr) {
Log.error("Failed to get git status for " + repo.module + ": " + res.stderr); Log.error(`Failed to get git status for ${repo.module}: ${res.stderr}`);
// exit without git status info // exit without git status info
return; return;
} }
// only the first line of stdout is evaluated // only the first line of stdout is evaluated
let status = res.stdout.split("\n")[0]; let status = res.stdout.split("\n")[0];
// examples for status: // examples for status:
@ -101,60 +108,73 @@ class gitHelper {
// [ 'origin/develop' ] // [ 'origin/develop' ]
// [ 'origin/master', '[behind', '8]' ] // [ 'origin/master', '[behind', '8]' ]
gitInfo.tracking = status[0].trim(); gitInfo.tracking = status[0].trim();
if (status[2]) { if (status[2]) {
// git fetch was already called before so `git status -sb` delivers already the behind number // git fetch was already called before so `git status -sb` delivers already the behind number
gitInfo.behind = parseInt(status[2].substring(0, status[2].length - 1)); gitInfo.behind = parseInt(status[2].substring(0, status[2].length - 1));
gitInfo.isBehindInStatus = true; gitInfo.isBehindInStatus = true;
} }
return gitInfo; return gitInfo;
} }
async getRepoInfo(repo) { async getRepoInfo(repo) {
let gitInfo; let gitInfo;
if (repo.gitInfo) { if (repo.gitInfo) {
// mocking // mocking
gitInfo = repo.gitInfo; gitInfo = repo.gitInfo;
} else { } else {
gitInfo = await this.getStatusInfo(repo); gitInfo = await this.getStatusInfo(repo);
} }
if (!gitInfo) { if (!gitInfo) {
return; return;
} }
if (gitInfo.isBehindInStatus) { if (gitInfo.isBehindInStatus) {
return gitInfo; return gitInfo;
} }
let res; let res;
if (repo.res) { if (repo.res) {
// mocking // mocking
res = repo.res; res = repo.res;
} else { } else {
res = await this.execShell("cd " + repo.folder + " && git fetch --dry-run"); res = await this.execShell(`cd ${repo.folder} && git fetch --dry-run`);
} }
// example output: // example output:
// From https://github.com/MichMich/MagicMirror // From https://github.com/MichMich/MagicMirror
// e40ddd4..06389e3 develop -> origin/develop // e40ddd4..06389e3 develop -> origin/develop
// here the result is in stderr (this is a git default, don't ask why ...) // here the result is in stderr (this is a git default, don't ask why ...)
const matches = res.stderr.match(this.getRefRegex(gitInfo.current)); const matches = res.stderr.match(this.getRefRegex(gitInfo.current));
if (!matches || !matches[0]) { if (!matches || !matches[0]) {
// no refs found, nothing to do // no refs found, nothing to do
return; return;
} }
// get behind with refs // get behind with refs
try { try {
res = await this.execShell("cd " + repo.folder + " && git rev-list --ancestry-path --count " + matches[0]); res = await this.execShell(`cd ${repo.folder} && git rev-list --ancestry-path --count ${matches[0]}`);
gitInfo.behind = parseInt(res.stdout); gitInfo.behind = parseInt(res.stdout);
return gitInfo; return gitInfo;
} catch (err) { } catch (err) {
Log.error("Failed to get git revisions for " + repo.module + ": " + err); Log.error(`Failed to get git revisions for ${repo.module}: ${err}`);
} }
} }
async getStatus() { async getStatus() {
const gitResultList = []; const gitResultList = [];
for (let repo of this.gitRepos) { for (let repo of this.gitRepos) {
const gitInfo = await this.getStatusInfo(repo); const gitInfo = await this.getStatusInfo(repo);
if (gitInfo) { if (gitInfo) {
gitResultList.unshift(gitInfo); gitResultList.push(gitInfo);
} }
} }
@ -163,10 +183,12 @@ class gitHelper {
async getRepos() { async getRepos() {
const gitResultList = []; const gitResultList = [];
for (let repo of this.gitRepos) {
for (const repo of this.gitRepos) {
const gitInfo = await this.getRepoInfo(repo); const gitInfo = await this.getRepoInfo(repo);
if (gitInfo) { if (gitInfo) {
gitResultList.unshift(gitInfo); gitResultList.push(gitInfo);
} }
} }
@ -174,4 +196,4 @@ class gitHelper {
} }
} }
module.exports.gitHelper = gitHelper; module.exports = GitHelper;