From 75a57829c2546c7dc30f9284721a78e01f72da4e Mon Sep 17 00:00:00 2001 From: Felix Wiedenbach Date: Sat, 18 Sep 2021 03:50:53 +0200 Subject: [PATCH] fixed git helper async/await issues, template strings, clean up --- .../default/updatenotification/git_helper.js | 94 ++++++++++++------- 1 file changed, 58 insertions(+), 36 deletions(-) diff --git a/modules/default/updatenotification/git_helper.js b/modules/default/updatenotification/git_helper.js index b165e7bc..992a055b 100644 --- a/modules/default/updatenotification/git_helper.js +++ b/modules/default/updatenotification/git_helper.js @@ -4,10 +4,11 @@ const fs = require("fs"); const path = require("path"); const Log = require("logger"); -class gitHelper { +const BASE_DIR = path.normalize(`${__dirname}/../../../`); + +class GitHelper { constructor() { this.gitRepos = []; - this.baseDir = path.normalize(__dirname + "/../../../"); } getRefRegex(branch) { @@ -15,37 +16,41 @@ class gitHelper { } async execShell(command) { - let res = { stdout: "", stderr: "" }; - const { stdout, stderr } = await exec(command); + const { stdout = "", stderr = "" } = await exec(command); - res.stdout = stdout; - res.stderr = stderr; - return res; + return { stdout, stderr }; } 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) { - Log.error("Failed to fetch git data for " + moduleFolder + ": " + res.stderr); + Log.error(`Failed to fetch git data for ${moduleFolder}: ${res.stderr}`); + return false; - } else { - return true; } + + return true; } - add(moduleName) { - let moduleFolder = this.baseDir; + async add(moduleName) { + let moduleFolder = BASE_DIR; + if (moduleName !== "default") { - moduleFolder = moduleFolder + "modules/" + moduleName; + moduleFolder = `${moduleFolder}modules/${moduleName}`; } + try { - Log.info("Checking git for module: " + moduleName); + Log.info(`Checking git for module: ${moduleName}`); // Throws error if file doesn't exist fs.statSync(path.join(moduleFolder, ".git")); + // 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 - this.gitRepos.unshift({ module: moduleName, folder: moduleFolder }); + this.gitRepos.push({ module: moduleName, folder: moduleFolder }); } } catch (err) { // Error when directory .git doesn't exist or doesn't have any remotes @@ -56,36 +61,38 @@ class gitHelper { async getStatusInfo(repo) { let gitInfo = { module: repo.module, - // commits behind: - behind: 0, - // branch name: - current: "", - // current hash: - hash: "", - // remote branch: - tracking: "", + behind: 0, // commits behind + current: "", // branch name + hash: "", // current hash + tracking: "", // remote branch isBehindInStatus: false }; + let res; if (repo.module === "default") { // 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) { - 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; } + if (repo.res) { // mocking res = repo.res; } else { - res = await this.execShell("cd " + repo.folder + " && git status -sb"); + res = await this.execShell(`cd ${repo.folder} && git status -sb`); } + 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 return; } + // only the first line of stdout is evaluated let status = res.stdout.split("\n")[0]; // examples for status: @@ -101,60 +108,73 @@ class gitHelper { // [ 'origin/develop' ] // [ 'origin/master', '[behind', '8]' ] gitInfo.tracking = status[0].trim(); + if (status[2]) { // 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.isBehindInStatus = true; } + return gitInfo; } async getRepoInfo(repo) { let gitInfo; + if (repo.gitInfo) { // mocking gitInfo = repo.gitInfo; } else { gitInfo = await this.getStatusInfo(repo); } + if (!gitInfo) { return; } + if (gitInfo.isBehindInStatus) { return gitInfo; } + let res; + if (repo.res) { // mocking res = repo.res; } 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: // From https://github.com/MichMich/MagicMirror // e40ddd4..06389e3 develop -> origin/develop // here the result is in stderr (this is a git default, don't ask why ...) const matches = res.stderr.match(this.getRefRegex(gitInfo.current)); + if (!matches || !matches[0]) { // no refs found, nothing to do return; } + // get behind with refs 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); + return gitInfo; } 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() { const gitResultList = []; + for (let repo of this.gitRepos) { const gitInfo = await this.getStatusInfo(repo); + if (gitInfo) { - gitResultList.unshift(gitInfo); + gitResultList.push(gitInfo); } } @@ -163,10 +183,12 @@ class gitHelper { async getRepos() { const gitResultList = []; - for (let repo of this.gitRepos) { + + for (const repo of this.gitRepos) { const gitInfo = await this.getRepoInfo(repo); + if (gitInfo) { - gitResultList.unshift(gitInfo); + gitResultList.push(gitInfo); } } @@ -174,4 +196,4 @@ class gitHelper { } } -module.exports.gitHelper = gitHelper; +module.exports = GitHelper;