diff --git a/extensions/git/package.json b/extensions/git/package.json index 82b8a93a27c..8170e22f3c0 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -3298,31 +3298,36 @@ "markdownDescription": "%config.commitShortHashLength%", "scope": "resource" }, - "git.diagnosticsCommitHook.Severity": { - "type": "string", - "enum": [ - "error", - "warning", - "information", - "hint" - ], - "enumDescriptions": [ - "%config.diagnosticsCommitHook.Severity.error%", - "%config.diagnosticsCommitHook.Severity.warning%", - "%config.diagnosticsCommitHook.Severity.information%", - "%config.diagnosticsCommitHook.Severity.hint%" - ], - "default": "error", - "markdownDescription": "%config.diagnosticsCommitHook.Severity%", + "git.diagnosticsCommitHook.Enabled": { + "type": "boolean", + "default": false, + "markdownDescription": "%config.diagnosticsCommitHook.Enabled%", "scope": "resource" }, - "git.diagnosticsCommitHook.Source": { + "git.diagnosticsCommitHook.Sources": { + "type": "object", + "additionalProperties": { + "type": "string", + "enum": [ + "error", + "warning", + "information", + "hint" + ] + }, + "default": { + "*": "error" + }, + "markdownDescription": "%config.diagnosticsCommitHook.Sources%", + "scope": "resource" + }, + "git.diagnosticsCommitHook.IgnoredSources": { "type": "array", "items": { "type": "string" }, "default": [], - "markdownDescription": "%config.diagnosticsCommitHook.Source%", + "markdownDescription": "%config.diagnosticsCommitHook.IgnoredSources%", "scope": "resource" }, "git.untrackedChangesSoftDelete": { diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 93d159bde07..9e01f5c8753 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -286,12 +286,9 @@ "config.blameStatusBarItem.enabled": "Controls whether to show blame information in the status bar.", "config.blameStatusBarItem.template": "Template for the blame information status bar item. Supported variables:\n\n* `hash`: Commit hash\n\n* `hashShort`: First N characters of the commit hash according to `#git.commitShortHashLength#`\n\n* `subject`: First line of the commit message\n\n* `authorName`: Author name\n\n* `authorEmail`: Author email\n\n* `authorDate`: Author date\n\n* `authorDateAgo`: Time difference between now and the author date\n\n", "config.commitShortHashLength": "Controls the length of the commit short hash.", - "config.diagnosticsCommitHook.Severity": "Controls the minimum diagnostics severity for which Git should check before committing.", - "config.diagnosticsCommitHook.Severity.error": "Errors only", - "config.diagnosticsCommitHook.Severity.warning": "Errors and warnings", - "config.diagnosticsCommitHook.Severity.information": "Errors, warnings, and information", - "config.diagnosticsCommitHook.Severity.hint": "Errors, warnings, information, and hints", - "config.diagnosticsCommitHook.Source": "Controls the list of diagnostics sources for which Git should check before committing.", + "config.diagnosticsCommitHook.Enabled": "Controls whether Git should check for unresolved diagnostic information before committing.", + "config.diagnosticsCommitHook.IgnoredSources": "List of diagnostic information sources that should be ignored. **Note:** Ignored diagnostic information sources take precedence over the diagnostic information sources listed in `#git.diagnosticsCommitHook.Sources#`.", + "config.diagnosticsCommitHook.Sources": "Controls the list of diagnostic information sources (**Item**) and the minimum diagnostic information severity (**Value**) to be considered before committing.", "config.untrackedChangesSoftDelete": "Controls whether discarding untracked changes moves the file(s) to the Recycle Bin (Windows), Trash (macOS, Linux) instead of deleting them.", "submenu.explorer": "Git", "submenu.commit": "Commit", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index f058de45122..e330c38f24d 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -619,11 +619,11 @@ class CommandErrorOutputTextDocumentContentProvider implements TextDocumentConte async function evaluateDiagnosticsCommitHook(repository: Repository, options: CommitOptions): Promise { const config = workspace.getConfiguration('git', Uri.file(repository.root)); - const diagnosticSource = config.get('diagnosticsCommitHook.Source', []); - const diagnosticSeveritySetting = config.get('diagnosticsCommitHook.Severity', 'error'); - const diagnosticSeverity = toDiagnosticSeverity(diagnosticSeveritySetting); + const enabled = config.get('diagnosticsCommitHook.Enabled', false) === true; + const ignoredSources = config.get('diagnosticsCommitHook.IgnoredSources', []); + const sourceSeverity = config.get>('diagnosticsCommitHook.Sources', { '*': 'error' }); - if (diagnosticSource.length === 0) { + if (!enabled) { return true; } @@ -643,12 +643,34 @@ async function evaluateDiagnosticsCommitHook(repository: Repository, options: Co } const diagnostics = languages.getDiagnostics(); - const changesDiagnostics = diagnostics.filter(([uri, diags]) => + const changesDiagnostics = diagnostics.filter(([uri, diags]) => { // File - changes.some(u => uri.scheme === 'file' && pathEquals(u.fsPath, uri.fsPath)) && - // Severity - diags.some(d => d.source && diagnosticSource.includes(d.source) && d.severity <= diagnosticSeverity) - ); + if (uri.scheme !== 'file' || !changes.find(c => pathEquals(c.fsPath, uri.fsPath))) { + return false; + } + + // Diagnostics + return diags.find(d => { + // No source or ignored source + if (!d.source || ignoredSources.includes(d.source)) { + return false; + } + + // Source severity + if (Object.keys(sourceSeverity).includes(d.source) && + d.severity <= toDiagnosticSeverity(sourceSeverity[d.source])) { + return true; + } + + // Wildcard severity + if (Object.keys(sourceSeverity).includes('*') && + d.severity <= toDiagnosticSeverity(sourceSeverity['*'])) { + return true; + } + + return false; + }); + }); if (changesDiagnostics.length === 0) { return true; @@ -659,7 +681,7 @@ async function evaluateDiagnosticsCommitHook(repository: Repository, options: Co const view = l10n.t('View Problems'); const message = changesDiagnostics.length === 1 - ? l10n.t('The following file has unresolved diagnostic information: {0}.\n\nHow would you like to proceed?', path.basename(changesDiagnostics[0][0].fsPath)) + ? l10n.t('The following file has unresolved diagnostic information: \'{0}\'.\n\nHow would you like to proceed?', path.basename(changesDiagnostics[0][0].fsPath)) : l10n.t('There are {0} files that have unresolved diagnostic information.\n\nHow would you like to proceed?', changesDiagnostics.length); const choice = await window.showWarningMessage(message, { modal: true }, commit, view);