Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/user-guide/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
11 changes: 10 additions & 1 deletion docs/user-guide/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<PropertyGroup>
<EfcptSdkVersionWarningLevel>Info</EfcptSdkVersionWarningLevel>
</PropertyGroup>
```

### Use global.json for Centralized Management

When you have multiple projects, use `global.json` to manage SDK versions in one place:
Expand Down
50 changes: 47 additions & 3 deletions docs/user-guide/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<PropertyGroup>
<!-- Valid values: None, Info, Warn, Error -->
<EfcptAutoDetectWarningLevel>Info</EfcptAutoDetectWarningLevel>
</PropertyGroup>
```

**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:**
```
Expand All @@ -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
<PropertyGroup>
<!-- Valid values: None, Info, Warn, Error -->
<EfcptSdkVersionWarningLevel>Warn</EfcptSdkVersionWarningLevel>
</PropertyGroup>
```

**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:
Expand All @@ -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

Expand Down
37 changes: 37 additions & 0 deletions src/JD.Efcpt.Build.Tasks/BuildLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ public interface IBuildLog
/// <param name="code">The error code.</param>
/// <param name="message">The error message.</param>
void Error(string code, string message);

/// <summary>
/// Logs a message at the specified severity level with an optional code.
/// </summary>
/// <param name="level">The message severity level.</param>
/// <param name="message">The message to log.</param>
/// <param name="code">Optional message code.</param>
void Log(MessageLevel level, string message, string? code = null);
}

/// <summary>
Expand Down Expand Up @@ -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);

/// <inheritdoc />
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;
}
}
}

/// <summary>
Expand Down Expand Up @@ -124,4 +158,7 @@ public void Error(string message) { }

/// <inheritdoc />
public void Error(string code, string message) { }

/// <inheritdoc />
public void Log(MessageLevel level, string message, string? code = null) { }
}
73 changes: 62 additions & 11 deletions src/JD.Efcpt.Build.Tasks/CheckSdkVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public class CheckSdkVersion : Microsoft.Build.Utilities.Task
/// </summary>
public bool ForceCheck { get; set; }

/// <summary>
/// Controls the severity level for SDK version update messages.
/// Valid values: "None", "Info", "Warn", "Error". Defaults to "Warn".
/// </summary>
public string WarningLevel { get; set; } = "Warn";

/// <summary>
/// The latest version available on NuGet (output).
/// </summary>
Expand Down Expand Up @@ -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();
}
}

/// <summary>
/// Emits the version update message at the configured severity level.
/// Protected virtual to allow testing without reflection.
/// </summary>
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;
}
}

Expand Down
27 changes: 27 additions & 0 deletions src/JD.Efcpt.Build.Tasks/MessageLevel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace JD.Efcpt.Build.Tasks;

/// <summary>
/// Defines the severity level for build messages.
/// </summary>
public enum MessageLevel
{
/// <summary>
/// No message is emitted.
/// </summary>
None,

/// <summary>
/// Message is emitted as informational (low priority).
/// </summary>
Info,

/// <summary>
/// Message is emitted as a warning.
/// </summary>
Warn,

/// <summary>
/// Message is emitted as an error.
/// </summary>
Error
}
52 changes: 52 additions & 0 deletions src/JD.Efcpt.Build.Tasks/MessageLevelHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace JD.Efcpt.Build.Tasks;

/// <summary>
/// Helper methods for working with <see cref="MessageLevel"/>.
/// </summary>
public static class MessageLevelHelpers
{
/// <summary>
/// Parses a string into a <see cref="MessageLevel"/>.
/// </summary>
/// <param name="value">The string value to parse (case-insensitive).</param>
/// <param name="defaultValue">The default value to return if parsing fails.</param>
/// <returns>The parsed <see cref="MessageLevel"/>.</returns>
public static MessageLevel Parse(string? value, MessageLevel defaultValue)
{
return TryParse(value, out var result) ? result : defaultValue;
}

/// <summary>
/// Tries to parse a string into a <see cref="MessageLevel"/>.
/// </summary>
/// <param name="value">The string value to parse (case-insensitive).</param>
/// <param name="result">The parsed <see cref="MessageLevel"/>.</param>
/// <returns><c>true</c> if parsing succeeded; otherwise, <c>false</c>.</returns>
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;
}
}
}
15 changes: 13 additions & 2 deletions src/JD.Efcpt.Build.Tasks/ResolveSqlProjAndInputs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@ public sealed class ResolveSqlProjAndInputs : Task
/// </value>
public string DumpResolvedInputs { get; set; } = "false";

/// <summary>
/// Controls the severity level for SQL project or connection string auto-detection messages.
/// </summary>
/// <value>
/// Valid values: "None", "Info", "Warn", "Error". Defaults to "Info".
/// </value>
public string AutoDetectWarningLevel { get; set; } = "Info";

/// <summary>
/// Resolved full path to the SQL project to use.
/// </summary>
Expand Down Expand Up @@ -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, "");
}

Expand Down Expand Up @@ -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);
}
}
Expand Down
12 changes: 12 additions & 0 deletions src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@
<EfcptLogVerbosity Condition="'$(EfcptLogVerbosity)'==''">minimal</EfcptLogVerbosity>
<EfcptDumpResolvedInputs Condition="'$(EfcptDumpResolvedInputs)'==''">false</EfcptDumpResolvedInputs>

<!--
Warning Level Configuration: Controls the severity of build-time diagnostic messages.

EfcptAutoDetectWarningLevel: Severity for SQL project or connection string auto-detection.
Valid values: "None", "Info", "Warn", "Error". Defaults to "Info".

EfcptSdkVersionWarningLevel: Severity for SDK version update notifications.
Valid values: "None", "Info", "Warn", "Error". Defaults to "Warn".
-->
<EfcptAutoDetectWarningLevel Condition="'$(EfcptAutoDetectWarningLevel)'==''">Info</EfcptAutoDetectWarningLevel>
<EfcptSdkVersionWarningLevel Condition="'$(EfcptSdkVersionWarningLevel)'==''">Warn</EfcptSdkVersionWarningLevel>

<!--
SDK Version Check: Opt-in feature to check for newer SDK versions on NuGet.
Enable with EfcptCheckForUpdates=true. Results are cached to avoid network
Expand Down
Loading
Loading