diff --git a/docs/user-guide/api-reference.md b/docs/user-guide/api-reference.md index 162f0ef..4f4870a 100644 --- a/docs/user-guide/api-reference.md +++ b/docs/user-guide/api-reference.md @@ -320,6 +320,8 @@ Applies MSBuild property overrides to the staged `efcpt-config.json` file. This | `EfcptFingerprintFile` | `$(EfcptOutput)fingerprint.txt` | Fingerprint cache location | | `EfcptStampFile` | `$(EfcptOutput).efcpt.stamp` | Generation stamp file | | `EfcptDetectGeneratedFileChanges` | `false` | Detect changes to generated `.g.cs` files and trigger regeneration. **Warning**: When enabled, manual edits to generated files will be overwritten. | +| `EfcptAutoDetectWarningLevel` | `Info` | Severity for SQL project/connection string auto-detection messages. Valid values: `None`, `Info`, `Warn`, `Error` | +| `EfcptSdkVersionWarningLevel` | `Warn` | Severity for SDK version update notifications. Valid values: `None`, `Info`, `Warn`, `Error` | ### Config Override Properties diff --git a/docs/user-guide/sdk.md b/docs/user-guide/sdk.md index ce82b0e..3b7e5d8 100644 --- a/docs/user-guide/sdk.md +++ b/docs/user-guide/sdk.md @@ -242,10 +242,19 @@ warning EFCPT002: A newer version of JD.Efcpt.Sdk is available: 1.1.0 (current: ``` Configuration options: -- `EfcptCheckForUpdates` - Enable/disable version checking (default: `false`) +- `EfcptCheckForUpdates` - Enable/disable version checking (default: `false` for package references, `true` for SDK references) +- `EfcptSdkVersionWarningLevel` - Control severity of update notifications: `None`, `Info`, `Warn` (default), or `Error` - `EfcptUpdateCheckCacheHours` - Hours to cache the result (default: `24`) - `EfcptForceUpdateCheck` - Bypass cache and always check (default: `false`) +Example: Make version updates informational instead of warnings: + +```xml + + Info + +``` + ### Use global.json for Centralized Management When you have multiple projects, use `global.json` to manage SDK versions in one place: diff --git a/docs/user-guide/troubleshooting.md b/docs/user-guide/troubleshooting.md index 005629b..4122eb3 100644 --- a/docs/user-guide/troubleshooting.md +++ b/docs/user-guide/troubleshooting.md @@ -354,9 +354,41 @@ JD.Efcpt.Build task assemblies target .NET 8.0+ and cannot run on the .NET Frame 2. Build from command line with `dotnet build` 3. Set `EfcptEnabled=false` to disable code generation if you only need to compile the project +### EFCPT001: Auto-Detection Informational Message + +**Type:** Informational (configurable) + +**Message:** +``` +EFCPT001: No SQL project references found in project; using SQL project detected from solution: path/to/project.sqlproj +``` +or +``` +EFCPT001: No .sqlproj found. Using auto-discovered connection string. +``` + +**Cause:** +The build automatically detected a SQL project from the solution or a connection string from configuration files when no explicit reference was provided. This is expected behavior in zero-config scenarios. + +**Severity Control:** +Control the message severity using `EfcptAutoDetectWarningLevel`: +```xml + + + Info + +``` + +**Default:** `Info` (informational message) + +**Solutions:** +- If you want to suppress this message entirely, set `EfcptAutoDetectWarningLevel=None` +- If you want to make it a warning, set `EfcptAutoDetectWarningLevel=Warn` +- To be explicit about your SQL project or connection string, configure `EfcptSqlProj`, `EfcptConnectionString`, or other relevant properties + ### EFCPT002: Newer SDK Version Available -**Type:** Warning (opt-in) +**Type:** Warning (opt-in, configurable) **Message:** ``` @@ -366,6 +398,17 @@ EFCPT002: A newer version of JD.Efcpt.Sdk is available: X.Y.Z (current: A.B.C) **Cause:** When `EfcptCheckForUpdates` is enabled, the build checks NuGet for newer SDK versions. This warning indicates an update is available. +**Severity Control:** +Control the message severity using `EfcptSdkVersionWarningLevel`: +```xml + + + Warn + +``` + +**Default:** `Warn` (warning message) + **Solutions:** 1. Update your project's `Sdk` attribute: `Sdk="JD.Efcpt.Sdk/X.Y.Z"` 2. Or update `global.json` if using centralized version management: @@ -376,9 +419,10 @@ When `EfcptCheckForUpdates` is enabled, the build checks NuGet for newer SDK ver } } ``` -3. To suppress this warning, set `EfcptCheckForUpdates=false` +3. To change the severity level, set `EfcptSdkVersionWarningLevel` to `None`, `Info`, `Warn`, or `Error` +4. To disable version checking entirely, set `EfcptCheckForUpdates=false` -**Note:** This check is opt-in and disabled by default. Results are cached for 24 hours to minimize network calls. +**Note:** This check is opt-in for package references and opt-out for SDK references. Results are cached for 24 hours to minimize network calls. ## Error Messages diff --git a/src/JD.Efcpt.Build.Tasks/BuildLog.cs b/src/JD.Efcpt.Build.Tasks/BuildLog.cs index c1dc2a8..70a58ef 100644 --- a/src/JD.Efcpt.Build.Tasks/BuildLog.cs +++ b/src/JD.Efcpt.Build.Tasks/BuildLog.cs @@ -50,6 +50,14 @@ public interface IBuildLog /// The error code. /// The error message. void Error(string code, string message); + + /// + /// Logs a message at the specified severity level with an optional code. + /// + /// The message severity level. + /// The message to log. + /// Optional message code. + void Log(MessageLevel level, string message, string? code = null); } /// @@ -89,6 +97,32 @@ public void Error(string code, string message) => log.LogError(subcategory: null, code, helpKeyword: null, file: null, lineNumber: 0, columnNumber: 0, endLineNumber: 0, endColumnNumber: 0, message); + + /// + public void Log(MessageLevel level, string message, string? code = null) + { + switch (level) + { + case MessageLevel.None: + // Do nothing + break; + case MessageLevel.Info: + log.LogMessage(MessageImportance.High, message); + break; + case MessageLevel.Warn: + if (!string.IsNullOrEmpty(code)) + Warn(code, message); + else + Warn(message); + break; + case MessageLevel.Error: + if (!string.IsNullOrEmpty(code)) + Error(code, message); + else + Error(message); + break; + } + } } /// @@ -124,4 +158,7 @@ public void Error(string message) { } /// public void Error(string code, string message) { } + + /// + public void Log(MessageLevel level, string message, string? code = null) { } } diff --git a/src/JD.Efcpt.Build.Tasks/CheckSdkVersion.cs b/src/JD.Efcpt.Build.Tasks/CheckSdkVersion.cs index 4e33a46..6d9c230 100644 --- a/src/JD.Efcpt.Build.Tasks/CheckSdkVersion.cs +++ b/src/JD.Efcpt.Build.Tasks/CheckSdkVersion.cs @@ -46,6 +46,12 @@ public class CheckSdkVersion : Microsoft.Build.Utilities.Task /// public bool ForceCheck { get; set; } + /// + /// Controls the severity level for SDK version update messages. + /// Valid values: "None", "Info", "Warn", "Error". Defaults to "Warn". + /// + public string WarningLevel { get; set; } = "Warn"; + /// /// The latest version available on NuGet (output). /// @@ -103,17 +109,62 @@ private void CheckAndWarn() latest > current) { UpdateAvailable = true; - Log.LogWarning( - subcategory: null, - warningCode: "EFCPT002", - helpKeyword: null, - file: null, - lineNumber: 0, - columnNumber: 0, - endLineNumber: 0, - endColumnNumber: 0, - message: $"A newer version of JD.Efcpt.Sdk is available: {LatestVersion} (current: {CurrentVersion}). " + - $"Update your project's Sdk attribute or global.json to use the latest version."); + EmitVersionUpdateMessage(); + } + } + + /// + /// Emits the version update message at the configured severity level. + /// Protected virtual to allow testing without reflection. + /// + protected virtual void EmitVersionUpdateMessage() + { + var level = MessageLevelHelpers.Parse(WarningLevel, MessageLevel.Warn); + var message = $"A newer version of JD.Efcpt.Sdk is available: {LatestVersion} (current: {CurrentVersion}). " + + $"Update your project's Sdk attribute or global.json to use the latest version."; + + switch (level) + { + case MessageLevel.None: + // Do nothing + break; + case MessageLevel.Info: + Log.LogMessage( + subcategory: null, + code: "EFCPT002", + helpKeyword: null, + file: null, + lineNumber: 0, + columnNumber: 0, + endLineNumber: 0, + endColumnNumber: 0, + importance: MessageImportance.High, + message: message); + break; + case MessageLevel.Warn: + Log.LogWarning( + subcategory: null, + warningCode: "EFCPT002", + helpKeyword: null, + file: null, + lineNumber: 0, + columnNumber: 0, + endLineNumber: 0, + endColumnNumber: 0, + message: message); + break; + case MessageLevel.Error: + Log.LogError( + subcategory: null, + errorCode: "EFCPT002", + helpKeyword: null, + file: null, + lineNumber: 0, + columnNumber: 0, + endLineNumber: 0, + endColumnNumber: 0, + message: message); + break; } } diff --git a/src/JD.Efcpt.Build.Tasks/MessageLevel.cs b/src/JD.Efcpt.Build.Tasks/MessageLevel.cs new file mode 100644 index 0000000..951b2e8 --- /dev/null +++ b/src/JD.Efcpt.Build.Tasks/MessageLevel.cs @@ -0,0 +1,27 @@ +namespace JD.Efcpt.Build.Tasks; + +/// +/// Defines the severity level for build messages. +/// +public enum MessageLevel +{ + /// + /// No message is emitted. + /// + None, + + /// + /// Message is emitted as informational (low priority). + /// + Info, + + /// + /// Message is emitted as a warning. + /// + Warn, + + /// + /// Message is emitted as an error. + /// + Error +} diff --git a/src/JD.Efcpt.Build.Tasks/MessageLevelHelpers.cs b/src/JD.Efcpt.Build.Tasks/MessageLevelHelpers.cs new file mode 100644 index 0000000..50a5fce --- /dev/null +++ b/src/JD.Efcpt.Build.Tasks/MessageLevelHelpers.cs @@ -0,0 +1,52 @@ +namespace JD.Efcpt.Build.Tasks; + +/// +/// Helper methods for working with . +/// +public static class MessageLevelHelpers +{ + /// + /// Parses a string into a . + /// + /// The string value to parse (case-insensitive). + /// The default value to return if parsing fails. + /// The parsed . + public static MessageLevel Parse(string? value, MessageLevel defaultValue) + { + return TryParse(value, out var result) ? result : defaultValue; + } + + /// + /// Tries to parse a string into a . + /// + /// The string value to parse (case-insensitive). + /// The parsed . + /// true if parsing succeeded; otherwise, false. + public static bool TryParse(string? value, out MessageLevel result) + { + result = MessageLevel.None; + + if (string.IsNullOrWhiteSpace(value)) + return false; + + var normalized = value.Trim().ToLowerInvariant(); + switch (normalized) + { + case "none": + result = MessageLevel.None; + return true; + case "info": + result = MessageLevel.Info; + return true; + case "warn": + case "warning": + result = MessageLevel.Warn; + return true; + case "error": + result = MessageLevel.Error; + return true; + default: + return false; + } + } +} diff --git a/src/JD.Efcpt.Build.Tasks/ResolveSqlProjAndInputs.cs b/src/JD.Efcpt.Build.Tasks/ResolveSqlProjAndInputs.cs index d012400..d9d938f 100644 --- a/src/JD.Efcpt.Build.Tasks/ResolveSqlProjAndInputs.cs +++ b/src/JD.Efcpt.Build.Tasks/ResolveSqlProjAndInputs.cs @@ -170,6 +170,14 @@ public sealed class ResolveSqlProjAndInputs : Task /// public string DumpResolvedInputs { get; set; } = "false"; + /// + /// Controls the severity level for SQL project or connection string auto-detection messages. + /// + /// + /// Valid values: "None", "Info", "Warn", "Error". Defaults to "Info". + /// + public string AutoDetectWarningLevel { get; set; } = "Info"; + /// /// Resolved full path to the SQL project to use. /// @@ -384,7 +392,8 @@ private TargetContext DetermineMode(BuildLog log) if (string.IsNullOrWhiteSpace(connectionString)) return null; - log.Info("No .sqlproj found. Using auto-discovered connection string."); + var level = MessageLevelHelpers.Parse(AutoDetectWarningLevel, MessageLevel.Info); + log.Log(level, "No .sqlproj found. Using auto-discovered connection string.", "EFCPT001"); return new(true, connectionString, ""); } @@ -531,7 +540,9 @@ private string ResolveSqlProjWithValidation(BuildLog log) var fallback = TryResolveFromSolution(); if (!string.IsNullOrWhiteSpace(fallback)) { - log.Warn("No SQL project references found in project; using SQL project detected from solution: " + fallback); + var level = MessageLevelHelpers.Parse(AutoDetectWarningLevel, MessageLevel.Info); + var message = "No SQL project references found in project; using SQL project detected from solution: " + fallback; + log.Log(level, message, "EFCPT001"); sqlRefs.Add(fallback); } } diff --git a/src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.props b/src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.props index baebb6c..349905b 100644 --- a/src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.props +++ b/src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.props @@ -60,6 +60,18 @@ minimal false + + Info + Warn +