Skip to content

Commit a8d9ae7

Browse files
authored
chore: Add configurable warning levels for auto-detection and SDK version checks (#50)
1 parent c9845f7 commit a8d9ae7

13 files changed

Lines changed: 528 additions & 52 deletions

File tree

docs/user-guide/api-reference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ Applies MSBuild property overrides to the staged `efcpt-config.json` file. This
320320
| `EfcptFingerprintFile` | `$(EfcptOutput)fingerprint.txt` | Fingerprint cache location |
321321
| `EfcptStampFile` | `$(EfcptOutput).efcpt.stamp` | Generation stamp file |
322322
| `EfcptDetectGeneratedFileChanges` | `false` | Detect changes to generated `.g.cs` files and trigger regeneration. **Warning**: When enabled, manual edits to generated files will be overwritten. |
323+
| `EfcptAutoDetectWarningLevel` | `Info` | Severity for SQL project/connection string auto-detection messages. Valid values: `None`, `Info`, `Warn`, `Error` |
324+
| `EfcptSdkVersionWarningLevel` | `Warn` | Severity for SDK version update notifications. Valid values: `None`, `Info`, `Warn`, `Error` |
323325

324326
### Config Override Properties
325327

docs/user-guide/sdk.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,19 @@ warning EFCPT002: A newer version of JD.Efcpt.Sdk is available: 1.1.0 (current:
242242
```
243243

244244
Configuration options:
245-
- `EfcptCheckForUpdates` - Enable/disable version checking (default: `false`)
245+
- `EfcptCheckForUpdates` - Enable/disable version checking (default: `false` for package references, `true` for SDK references)
246+
- `EfcptSdkVersionWarningLevel` - Control severity of update notifications: `None`, `Info`, `Warn` (default), or `Error`
246247
- `EfcptUpdateCheckCacheHours` - Hours to cache the result (default: `24`)
247248
- `EfcptForceUpdateCheck` - Bypass cache and always check (default: `false`)
248249

250+
Example: Make version updates informational instead of warnings:
251+
252+
```xml
253+
<PropertyGroup>
254+
<EfcptSdkVersionWarningLevel>Info</EfcptSdkVersionWarningLevel>
255+
</PropertyGroup>
256+
```
257+
249258
### Use global.json for Centralized Management
250259

251260
When you have multiple projects, use `global.json` to manage SDK versions in one place:

docs/user-guide/troubleshooting.md

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,41 @@ JD.Efcpt.Build task assemblies target .NET 8.0+ and cannot run on the .NET Frame
354354
2. Build from command line with `dotnet build`
355355
3. Set `EfcptEnabled=false` to disable code generation if you only need to compile the project
356356

357+
### EFCPT001: Auto-Detection Informational Message
358+
359+
**Type:** Informational (configurable)
360+
361+
**Message:**
362+
```
363+
EFCPT001: No SQL project references found in project; using SQL project detected from solution: path/to/project.sqlproj
364+
```
365+
or
366+
```
367+
EFCPT001: No .sqlproj found. Using auto-discovered connection string.
368+
```
369+
370+
**Cause:**
371+
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.
372+
373+
**Severity Control:**
374+
Control the message severity using `EfcptAutoDetectWarningLevel`:
375+
```xml
376+
<PropertyGroup>
377+
<!-- Valid values: None, Info, Warn, Error -->
378+
<EfcptAutoDetectWarningLevel>Info</EfcptAutoDetectWarningLevel>
379+
</PropertyGroup>
380+
```
381+
382+
**Default:** `Info` (informational message)
383+
384+
**Solutions:**
385+
- If you want to suppress this message entirely, set `EfcptAutoDetectWarningLevel=None`
386+
- If you want to make it a warning, set `EfcptAutoDetectWarningLevel=Warn`
387+
- To be explicit about your SQL project or connection string, configure `EfcptSqlProj`, `EfcptConnectionString`, or other relevant properties
388+
357389
### EFCPT002: Newer SDK Version Available
358390

359-
**Type:** Warning (opt-in)
391+
**Type:** Warning (opt-in, configurable)
360392

361393
**Message:**
362394
```
@@ -366,6 +398,17 @@ EFCPT002: A newer version of JD.Efcpt.Sdk is available: X.Y.Z (current: A.B.C)
366398
**Cause:**
367399
When `EfcptCheckForUpdates` is enabled, the build checks NuGet for newer SDK versions. This warning indicates an update is available.
368400

401+
**Severity Control:**
402+
Control the message severity using `EfcptSdkVersionWarningLevel`:
403+
```xml
404+
<PropertyGroup>
405+
<!-- Valid values: None, Info, Warn, Error -->
406+
<EfcptSdkVersionWarningLevel>Warn</EfcptSdkVersionWarningLevel>
407+
</PropertyGroup>
408+
```
409+
410+
**Default:** `Warn` (warning message)
411+
369412
**Solutions:**
370413
1. Update your project's `Sdk` attribute: `Sdk="JD.Efcpt.Sdk/X.Y.Z"`
371414
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
376419
}
377420
}
378421
```
379-
3. To suppress this warning, set `EfcptCheckForUpdates=false`
422+
3. To change the severity level, set `EfcptSdkVersionWarningLevel` to `None`, `Info`, `Warn`, or `Error`
423+
4. To disable version checking entirely, set `EfcptCheckForUpdates=false`
380424

381-
**Note:** This check is opt-in and disabled by default. Results are cached for 24 hours to minimize network calls.
425+
**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.
382426

383427
## Error Messages
384428

src/JD.Efcpt.Build.Tasks/BuildLog.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public interface IBuildLog
5050
/// <param name="code">The error code.</param>
5151
/// <param name="message">The error message.</param>
5252
void Error(string code, string message);
53+
54+
/// <summary>
55+
/// Logs a message at the specified severity level with an optional code.
56+
/// </summary>
57+
/// <param name="level">The message severity level.</param>
58+
/// <param name="message">The message to log.</param>
59+
/// <param name="code">Optional message code.</param>
60+
void Log(MessageLevel level, string message, string? code = null);
5361
}
5462

5563
/// <summary>
@@ -89,6 +97,32 @@ public void Error(string code, string message)
8997
=> log.LogError(subcategory: null, code, helpKeyword: null,
9098
file: null, lineNumber: 0, columnNumber: 0,
9199
endLineNumber: 0, endColumnNumber: 0, message);
100+
101+
/// <inheritdoc />
102+
public void Log(MessageLevel level, string message, string? code = null)
103+
{
104+
switch (level)
105+
{
106+
case MessageLevel.None:
107+
// Do nothing
108+
break;
109+
case MessageLevel.Info:
110+
log.LogMessage(MessageImportance.High, message);
111+
break;
112+
case MessageLevel.Warn:
113+
if (!string.IsNullOrEmpty(code))
114+
Warn(code, message);
115+
else
116+
Warn(message);
117+
break;
118+
case MessageLevel.Error:
119+
if (!string.IsNullOrEmpty(code))
120+
Error(code, message);
121+
else
122+
Error(message);
123+
break;
124+
}
125+
}
92126
}
93127

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

125159
/// <inheritdoc />
126160
public void Error(string code, string message) { }
161+
162+
/// <inheritdoc />
163+
public void Log(MessageLevel level, string message, string? code = null) { }
127164
}

src/JD.Efcpt.Build.Tasks/CheckSdkVersion.cs

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ public class CheckSdkVersion : Microsoft.Build.Utilities.Task
4646
/// </summary>
4747
public bool ForceCheck { get; set; }
4848

49+
/// <summary>
50+
/// Controls the severity level for SDK version update messages.
51+
/// Valid values: "None", "Info", "Warn", "Error". Defaults to "Warn".
52+
/// </summary>
53+
public string WarningLevel { get; set; } = "Warn";
54+
4955
/// <summary>
5056
/// The latest version available on NuGet (output).
5157
/// </summary>
@@ -103,17 +109,62 @@ private void CheckAndWarn()
103109
latest > current)
104110
{
105111
UpdateAvailable = true;
106-
Log.LogWarning(
107-
subcategory: null,
108-
warningCode: "EFCPT002",
109-
helpKeyword: null,
110-
file: null,
111-
lineNumber: 0,
112-
columnNumber: 0,
113-
endLineNumber: 0,
114-
endColumnNumber: 0,
115-
message: $"A newer version of JD.Efcpt.Sdk is available: {LatestVersion} (current: {CurrentVersion}). " +
116-
$"Update your project's Sdk attribute or global.json to use the latest version.");
112+
EmitVersionUpdateMessage();
113+
}
114+
}
115+
116+
/// <summary>
117+
/// Emits the version update message at the configured severity level.
118+
/// Protected virtual to allow testing without reflection.
119+
/// </summary>
120+
protected virtual void EmitVersionUpdateMessage()
121+
{
122+
var level = MessageLevelHelpers.Parse(WarningLevel, MessageLevel.Warn);
123+
var message = $"A newer version of JD.Efcpt.Sdk is available: {LatestVersion} (current: {CurrentVersion}). " +
124+
$"Update your project's Sdk attribute or global.json to use the latest version.";
125+
126+
switch (level)
127+
{
128+
case MessageLevel.None:
129+
// Do nothing
130+
break;
131+
case MessageLevel.Info:
132+
Log.LogMessage(
133+
subcategory: null,
134+
code: "EFCPT002",
135+
helpKeyword: null,
136+
file: null,
137+
lineNumber: 0,
138+
columnNumber: 0,
139+
endLineNumber: 0,
140+
endColumnNumber: 0,
141+
importance: MessageImportance.High,
142+
message: message);
143+
break;
144+
case MessageLevel.Warn:
145+
Log.LogWarning(
146+
subcategory: null,
147+
warningCode: "EFCPT002",
148+
helpKeyword: null,
149+
file: null,
150+
lineNumber: 0,
151+
columnNumber: 0,
152+
endLineNumber: 0,
153+
endColumnNumber: 0,
154+
message: message);
155+
break;
156+
case MessageLevel.Error:
157+
Log.LogError(
158+
subcategory: null,
159+
errorCode: "EFCPT002",
160+
helpKeyword: null,
161+
file: null,
162+
lineNumber: 0,
163+
columnNumber: 0,
164+
endLineNumber: 0,
165+
endColumnNumber: 0,
166+
message: message);
167+
break;
117168
}
118169
}
119170

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace JD.Efcpt.Build.Tasks;
2+
3+
/// <summary>
4+
/// Defines the severity level for build messages.
5+
/// </summary>
6+
public enum MessageLevel
7+
{
8+
/// <summary>
9+
/// No message is emitted.
10+
/// </summary>
11+
None,
12+
13+
/// <summary>
14+
/// Message is emitted as informational (low priority).
15+
/// </summary>
16+
Info,
17+
18+
/// <summary>
19+
/// Message is emitted as a warning.
20+
/// </summary>
21+
Warn,
22+
23+
/// <summary>
24+
/// Message is emitted as an error.
25+
/// </summary>
26+
Error
27+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
namespace JD.Efcpt.Build.Tasks;
2+
3+
/// <summary>
4+
/// Helper methods for working with <see cref="MessageLevel"/>.
5+
/// </summary>
6+
public static class MessageLevelHelpers
7+
{
8+
/// <summary>
9+
/// Parses a string into a <see cref="MessageLevel"/>.
10+
/// </summary>
11+
/// <param name="value">The string value to parse (case-insensitive).</param>
12+
/// <param name="defaultValue">The default value to return if parsing fails.</param>
13+
/// <returns>The parsed <see cref="MessageLevel"/>.</returns>
14+
public static MessageLevel Parse(string? value, MessageLevel defaultValue)
15+
{
16+
return TryParse(value, out var result) ? result : defaultValue;
17+
}
18+
19+
/// <summary>
20+
/// Tries to parse a string into a <see cref="MessageLevel"/>.
21+
/// </summary>
22+
/// <param name="value">The string value to parse (case-insensitive).</param>
23+
/// <param name="result">The parsed <see cref="MessageLevel"/>.</param>
24+
/// <returns><c>true</c> if parsing succeeded; otherwise, <c>false</c>.</returns>
25+
public static bool TryParse(string? value, out MessageLevel result)
26+
{
27+
result = MessageLevel.None;
28+
29+
if (string.IsNullOrWhiteSpace(value))
30+
return false;
31+
32+
var normalized = value.Trim().ToLowerInvariant();
33+
switch (normalized)
34+
{
35+
case "none":
36+
result = MessageLevel.None;
37+
return true;
38+
case "info":
39+
result = MessageLevel.Info;
40+
return true;
41+
case "warn":
42+
case "warning":
43+
result = MessageLevel.Warn;
44+
return true;
45+
case "error":
46+
result = MessageLevel.Error;
47+
return true;
48+
default:
49+
return false;
50+
}
51+
}
52+
}

src/JD.Efcpt.Build.Tasks/ResolveSqlProjAndInputs.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,14 @@ public sealed class ResolveSqlProjAndInputs : Task
170170
/// </value>
171171
public string DumpResolvedInputs { get; set; } = "false";
172172

173+
/// <summary>
174+
/// Controls the severity level for SQL project or connection string auto-detection messages.
175+
/// </summary>
176+
/// <value>
177+
/// Valid values: "None", "Info", "Warn", "Error". Defaults to "Info".
178+
/// </value>
179+
public string AutoDetectWarningLevel { get; set; } = "Info";
180+
173181
/// <summary>
174182
/// Resolved full path to the SQL project to use.
175183
/// </summary>
@@ -384,7 +392,8 @@ private TargetContext DetermineMode(BuildLog log)
384392
if (string.IsNullOrWhiteSpace(connectionString))
385393
return null;
386394

387-
log.Info("No .sqlproj found. Using auto-discovered connection string.");
395+
var level = MessageLevelHelpers.Parse(AutoDetectWarningLevel, MessageLevel.Info);
396+
log.Log(level, "No .sqlproj found. Using auto-discovered connection string.", "EFCPT001");
388397
return new(true, connectionString, "");
389398
}
390399

@@ -531,7 +540,9 @@ private string ResolveSqlProjWithValidation(BuildLog log)
531540
var fallback = TryResolveFromSolution();
532541
if (!string.IsNullOrWhiteSpace(fallback))
533542
{
534-
log.Warn("No SQL project references found in project; using SQL project detected from solution: " + fallback);
543+
var level = MessageLevelHelpers.Parse(AutoDetectWarningLevel, MessageLevel.Info);
544+
var message = "No SQL project references found in project; using SQL project detected from solution: " + fallback;
545+
log.Log(level, message, "EFCPT001");
535546
sqlRefs.Add(fallback);
536547
}
537548
}

src/JD.Efcpt.Build/buildTransitive/JD.Efcpt.Build.props

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@
6060
<EfcptLogVerbosity Condition="'$(EfcptLogVerbosity)'==''">minimal</EfcptLogVerbosity>
6161
<EfcptDumpResolvedInputs Condition="'$(EfcptDumpResolvedInputs)'==''">false</EfcptDumpResolvedInputs>
6262

63+
<!--
64+
Warning Level Configuration: Controls the severity of build-time diagnostic messages.
65+
66+
EfcptAutoDetectWarningLevel: Severity for SQL project or connection string auto-detection.
67+
Valid values: "None", "Info", "Warn", "Error". Defaults to "Info".
68+
69+
EfcptSdkVersionWarningLevel: Severity for SDK version update notifications.
70+
Valid values: "None", "Info", "Warn", "Error". Defaults to "Warn".
71+
-->
72+
<EfcptAutoDetectWarningLevel Condition="'$(EfcptAutoDetectWarningLevel)'==''">Info</EfcptAutoDetectWarningLevel>
73+
<EfcptSdkVersionWarningLevel Condition="'$(EfcptSdkVersionWarningLevel)'==''">Warn</EfcptSdkVersionWarningLevel>
74+
6375
<!--
6476
SDK Version Check: Opt-in feature to check for newer SDK versions on NuGet.
6577
Enable with EfcptCheckForUpdates=true. Results are cached to avoid network

0 commit comments

Comments
 (0)