From 30df5c623370daf43946b8d0844e0b03a6e00bda Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Thu, 30 Mar 2023 11:50:22 +0200 Subject: [PATCH] #549 - Added the folder name --- package.json | 5 + src/commands/Folders.ts | 20 ++++ src/constants/settings.ts | 1 + src/listeners/general/GitListener.ts | 132 +++++++++++++++++++-------- 4 files changed, 118 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index 8a137164..a0e56189 100644 --- a/package.json +++ b/package.json @@ -784,6 +784,11 @@ "markdownDescription": "Specify the submodule branch to checkout. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.git.submodule.branch)", "default": "" }, + "frontMatter.git.submodule.folder": { + "type": "string", + "markdownDescription": "Specify the submodule folder of your content, this can be handy when you are using multiple submodules. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.git.submodule.folder)", + "default": "" + }, "frontMatter.global.activeMode": { "type": [ "string", diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index 6bd6c776..2564bf98 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -431,6 +431,26 @@ export class Folders { return parseWinPath(absPath); } + /** + * Retrieve the absolute folder path + * @param filePath + * @returns + */ + public static getAbsFolderPath(folderPath: string): string { + const wsFolder = Folders.getWorkspaceFolder(); + const isWindows = process.platform === 'win32'; + + let absPath = ''; + if (folderPath.includes(WORKSPACE_PLACEHOLDER)) { + absPath = folderPath.replace(WORKSPACE_PLACEHOLDER, parseWinPath(wsFolder?.fsPath || '')); + } else { + absPath = join(parseWinPath(wsFolder?.fsPath || ''), folderPath); + } + + absPath = isWindows ? absPath.split('/').join('\\') : absPath; + return parseWinPath(absPath); + } + /** * Generate the absolute URL for the workspace * @param folder diff --git a/src/constants/settings.ts b/src/constants/settings.ts index 6dd4da54..3b6005e3 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -92,6 +92,7 @@ export const SETTING_GIT_COMMIT_MSG = 'git.commitMessage'; export const SETTING_GIT_SUBMODULE_PULL = 'git.submodule.pull'; export const SETTING_GIT_SUBMODULE_PUSH = 'git.submodule.push'; export const SETTING_GIT_SUBMODULE_BRANCH = 'git.submodule.branch'; +export const SETTING_GIT_SUBMODULE_FOLDER = 'git.submodule.folder'; /** * Sponsors only settings diff --git a/src/listeners/general/GitListener.ts b/src/listeners/general/GitListener.ts index 7c676449..1651ecd6 100644 --- a/src/listeners/general/GitListener.ts +++ b/src/listeners/general/GitListener.ts @@ -1,5 +1,6 @@ import { SETTING_GIT_SUBMODULE_BRANCH, + SETTING_GIT_SUBMODULE_FOLDER, SETTING_GIT_SUBMODULE_PULL, SETTING_GIT_SUBMODULE_PUSH } from './../../constants/settings'; @@ -31,7 +32,11 @@ import { PostMessageData } from '../../models'; export class GitListener { private static isRegistered: boolean = false; private static client: SimpleGit | null = null; + private static subClient: SimpleGit | null = null; + /** + * Initialize the listener + */ public static async init() { let isEnabled = false; const gitEnabled = Settings.get(SETTING_GIT_ENABLED); @@ -64,6 +69,9 @@ export class GitListener { } } + /** + * Run the sync + */ public static async sync() { try { this.sendMsg(GeneralCommands.toWebview.gitSyncingStart, {}); @@ -80,6 +88,10 @@ export class GitListener { } } + /** + * Check if the current workspace is a git repository + * @returns + */ public static async isGitRepository() { const git = this.getClient(); if (!git) { @@ -105,12 +117,21 @@ export class GitListener { return; } + const submoduleFolder = Settings.get(SETTING_GIT_SUBMODULE_FOLDER); const submoduleBranch = Settings.get(SETTING_GIT_SUBMODULE_BRANCH); const submodulePull = Settings.get(SETTING_GIT_SUBMODULE_PULL); - if (submoduleBranch) { - Logger.info(`Checking out the branch ${submoduleBranch} for submodules`); - await git.subModule(['foreach', 'git', 'checkout', submoduleBranch]); + if (submoduleFolder) { + const absFolderPath = Folders.getAbsFolderPath(submoduleFolder); + const subGit = this.getClient(absFolderPath); + if (subGit && submoduleBranch) { + await subGit.checkout(submoduleBranch); + } + } else { + if (submoduleBranch) { + Logger.info(`Checking out the branch ${submoduleBranch} for submodules`); + await git.subModule(['foreach', 'git', 'checkout', submoduleBranch]); + } } if (submodulePull) { @@ -140,31 +161,52 @@ export class GitListener { return; } + const submoduleFolder = Settings.get(SETTING_GIT_SUBMODULE_FOLDER); const submodulePush = Settings.get(SETTING_GIT_SUBMODULE_PUSH); - if (submodulePush) { - Logger.info(`Pushing to remote with submodules`); - - try { - const status = await git.subModule(['foreach', 'git', 'status', '--porcelain', '-u']); - const lines = status.split('\n').filter((line) => line.trim() !== ''); - - // First line is the submodule folder name - if (lines.length > 1) { - await git.subModule(['foreach', 'git', 'add', '.', '-A']); - await git.subModule([ - 'foreach', - 'git', - 'commit', - '-m', - commitMsg || 'Synced by Front Matter' - ]); - await git.subModule(['foreach', 'git', 'push']); + if (submoduleFolder) { + const absFolderPath = Folders.getAbsFolderPath(submoduleFolder); + const subGit = this.getClient(absFolderPath); + if (subGit && submodulePush) { + try { + const status = await subGit.status(); + // Check if anything changed + if (status.files.length > 0) { + await subGit.raw(['add', '.', '-A']); + await subGit.commit(commitMsg || 'Synced by Front Matter'); + } + await subGit.push(); + } catch (e) { + Notifications.error(`Failed to push submodules. Please check the logs for more details.`); + Logger.error((e as Error).message); + return; + } + } + } else { + if (submodulePush) { + Logger.info(`Pushing to remote with submodules`); + + try { + const status = await git.subModule(['foreach', 'git', 'status', '--porcelain', '-u']); + const lines = status.split('\n').filter((line) => line.trim() !== ''); + + // First line is the submodule folder name + if (lines.length > 1) { + await git.subModule(['foreach', 'git', 'add', '.', '-A']); + await git.subModule([ + 'foreach', + 'git', + 'commit', + '-m', + commitMsg || 'Synced by Front Matter' + ]); + await git.subModule(['foreach', 'git', 'push']); + } + } catch (e) { + Notifications.error(`Failed to push submodules. Please check the logs for more details.`); + Logger.error((e as Error).message); + return; } - } catch (e) { - Notifications.error(`Failed to push submodules. Please check the logs for more details.`); - Logger.error((e as Error).message); - return; } } @@ -172,38 +214,48 @@ export class GitListener { const status = await git.status(); - for (const file of status.not_added) { - await git.add(file); + if (status.files.length > 0) { + await git.raw(['add', '.', '-A']); + await git.commit(commitMsg || 'Synced by Front Matter'); } - for (const file of status.modified) { - await git.add(file); - } - for (const file of status.deleted) { - await git.add(file); - } - - await git.commit(commitMsg || 'Synced by Front Matter'); await git.push(); } - private static getClient() { - if (this.client) { + /** + * Get the git client + * @param submoduleFolder + * @returns + */ + private static getClient(submoduleFolder: string = ''): SimpleGit | null { + if (!submoduleFolder && this.client) { return this.client; + } else if (submoduleFolder && this.subClient) { + return this.subClient; } const wsFolder = Folders.getWorkspaceFolder(); const options = { - baseDir: wsFolder?.fsPath || '', + baseDir: submoduleFolder || wsFolder?.fsPath || '', binary: 'git', maxConcurrentProcesses: 6 }; - this.client = simpleGit(options); - return this.client; + if (submoduleFolder) { + this.subClient = simpleGit(options); + return this.subClient; + } else { + this.client = simpleGit(options); + return this.client; + } } + /** + * Send the message to the webview + * @param command + * @param payload + */ private static sendMsg(command: string, payload: any) { const extPath = Extension.getInstance().extensionPath; const panel = ExplorerView.getInstance(extPath);