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
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="18.7.1" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="7.0.2" />
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="9.0.14" />
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="5.6.0" />
<PackageVersion Include="Microsoft.NET.StringTools" Version="18.7.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.7.0" />
<PackageVersion Include="MySqlConnector" Version="2.5.0" />
Expand Down
40 changes: 40 additions & 0 deletions build/PublicApi.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<Project>
<!--
Opt-in shared props for Microsoft.CodeAnalysis.PublicApiAnalyzers (issue #191:
PUBLIC-API-STABILITY). Import this explicitly from a project's .csproj - do NOT
import it via Directory.Build.props - so only the reusable, externally-consumable
library projects pick up the analyzer, not every project in the solution.

Multi-targeted projects (net472;net8.0;net9.0;net10.0) would otherwise need a
separate PublicAPI.Shipped.txt/.Unshipped.txt pair PER TargetFramework, because
net472 carries TFM-conditional polyfilled types and looser nullable annotations
that diverge from net8.0+, which would produce spurious per-TFM RS0016/RS0017
mismatches. To avoid that churn, the analyzer + AdditionalFiles are scoped to a
SINGLE canonical TFM via $(PublicApiAnalyzerTfm) - net10.0, the newest/most
complete TFM - which locks the real cross-consumer surface once.

Usage in an importing .csproj (multi-targeted project):
<PropertyGroup>
<PublicApiAnalyzerTfm>net10.0</PublicApiAnalyzerTfm>
</PropertyGroup>
<Import Project="..\..\build\PublicApi.props" />

Usage for a single-TFM project (e.g. netstandard2.0-only JD.Efcpt.Ide.Core, or
the net8.0-only JD.Efcpt.Cli): leave $(PublicApiAnalyzerTfm) unset. The analyzer
then applies unconditionally to that project's one TFM.
-->
<PropertyGroup>
<_PublicApiAnalyzerEnabled Condition="'$(PublicApiAnalyzerTfm)' == ''">true</_PublicApiAnalyzerEnabled>
<_PublicApiAnalyzerEnabled Condition="'$(PublicApiAnalyzerTfm)' != '' And '$(TargetFramework)' == '$(PublicApiAnalyzerTfm)'">true</_PublicApiAnalyzerEnabled>
<_PublicApiAnalyzerEnabled Condition="'$(_PublicApiAnalyzerEnabled)' == ''">false</_PublicApiAnalyzerEnabled>
</PropertyGroup>

<ItemGroup Condition="'$(_PublicApiAnalyzerEnabled)' == 'true'">
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime;build;native;contentfiles;analyzers</IncludeAssets>
</PackageReference>
<AdditionalFiles Include="PublicAPI.Shipped.txt" />
<AdditionalFiles Include="PublicAPI.Unshipped.txt" />
</ItemGroup>
</Project>
7 changes: 7 additions & 0 deletions ide/vs/JD.Efcpt.Ide.Core/JD.Efcpt.Ide.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
<LangVersion>latest</LangVersion>
</PropertyGroup>

<!--
PublicApiAnalyzers (#191: PUBLIC-API-STABILITY) locks this assembly's public surface.
Single-TFM project (netstandard2.0), so build/PublicApi.props applies unconditionally -
no PublicApiAnalyzerTfm needed.
-->
<Import Project="..\..\..\build\PublicApi.props" />

<ItemGroup>
<PackageReference Include="System.Text.Json" />
</ItemGroup>
Expand Down
138 changes: 138 additions & 0 deletions ide/vs/JD.Efcpt.Ide.Core/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#nullable enable
JD.Efcpt.Ide.Core.BuildProfile
JD.Efcpt.Ide.Core.BuildProfile.Artifacts.get -> System.Collections.Generic.IReadOnlyList<JD.Efcpt.Ide.Core.BuildProfileArtifact!>!
JD.Efcpt.Ide.Core.BuildProfile.Artifacts.set -> void
JD.Efcpt.Ide.Core.BuildProfile.BuildProfile() -> void
JD.Efcpt.Ide.Core.BuildProfile.Diagnostics.get -> System.Collections.Generic.IReadOnlyList<JD.Efcpt.Ide.Core.BuildProfileDiagnostic!>!
JD.Efcpt.Ide.Core.BuildProfile.Diagnostics.set -> void
JD.Efcpt.Ide.Core.BuildProfile.Duration.get -> System.TimeSpan?
JD.Efcpt.Ide.Core.BuildProfile.Duration.set -> void
JD.Efcpt.Ide.Core.BuildProfile.EndTime.get -> System.DateTimeOffset?
JD.Efcpt.Ide.Core.BuildProfile.EndTime.set -> void
JD.Efcpt.Ide.Core.BuildProfile.ModelCount.get -> int
JD.Efcpt.Ide.Core.BuildProfile.ModelCount.set -> void
JD.Efcpt.Ide.Core.BuildProfile.ProjectName.get -> string?
JD.Efcpt.Ide.Core.BuildProfile.ProjectName.set -> void
JD.Efcpt.Ide.Core.BuildProfile.RunId.get -> string?
JD.Efcpt.Ide.Core.BuildProfile.RunId.set -> void
JD.Efcpt.Ide.Core.BuildProfile.SchemaSupported.get -> bool
JD.Efcpt.Ide.Core.BuildProfile.SchemaSupported.set -> void
JD.Efcpt.Ide.Core.BuildProfile.SchemaVersion.get -> string!
JD.Efcpt.Ide.Core.BuildProfile.SchemaVersion.set -> void
JD.Efcpt.Ide.Core.BuildProfile.StartTime.get -> System.DateTimeOffset?
JD.Efcpt.Ide.Core.BuildProfile.StartTime.set -> void
JD.Efcpt.Ide.Core.BuildProfile.Status.get -> string!
JD.Efcpt.Ide.Core.BuildProfile.Status.set -> void
JD.Efcpt.Ide.Core.BuildProfile.StatusValue.get -> JD.Efcpt.Ide.Core.BuildProfileStatus
JD.Efcpt.Ide.Core.BuildProfile.StatusValue.set -> void
JD.Efcpt.Ide.Core.BuildProfileArtifact
JD.Efcpt.Ide.Core.BuildProfileArtifact.BuildProfileArtifact() -> void
JD.Efcpt.Ide.Core.BuildProfileArtifact.Path.get -> string!
JD.Efcpt.Ide.Core.BuildProfileArtifact.Path.set -> void
JD.Efcpt.Ide.Core.BuildProfileArtifact.Size.get -> long?
JD.Efcpt.Ide.Core.BuildProfileArtifact.Size.set -> void
JD.Efcpt.Ide.Core.BuildProfileArtifact.Type.get -> string!
JD.Efcpt.Ide.Core.BuildProfileArtifact.Type.set -> void
JD.Efcpt.Ide.Core.BuildProfileDiagnostic
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.BuildProfileDiagnostic() -> void
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.Code.get -> string?
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.Code.set -> void
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.Message.get -> string?
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.Message.set -> void
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.Severity.get -> string!
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.Severity.set -> void
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.Timestamp.get -> System.DateTimeOffset?
JD.Efcpt.Ide.Core.BuildProfileDiagnostic.Timestamp.set -> void
JD.Efcpt.Ide.Core.BuildProfileParseException
JD.Efcpt.Ide.Core.BuildProfileParseException.BuildProfileParseException(string! message) -> void
JD.Efcpt.Ide.Core.BuildProfileParseException.BuildProfileParseException(string! message, System.Exception! innerException) -> void
JD.Efcpt.Ide.Core.BuildProfileReader
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Artifacts.get -> System.Collections.Generic.List<JD.Efcpt.Ide.Core.BuildProfileArtifact!>?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Artifacts.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Diagnostics.get -> System.Collections.Generic.List<JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic!>?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Diagnostics.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Duration.get -> string?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Duration.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.EndTime.get -> System.DateTimeOffset?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.EndTime.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Project.get -> JD.Efcpt.Ide.Core.BuildProfileReader.RawProject?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Project.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.RawBuildProfile() -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.RunId.get -> string?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.RunId.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.SchemaVersion.get -> string?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.SchemaVersion.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.StartTime.get -> System.DateTimeOffset?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.StartTime.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Status.get -> string?
JD.Efcpt.Ide.Core.BuildProfileReader.RawBuildProfile.Status.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.Code.get -> string?
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.Code.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.Level.get -> string?
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.Level.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.Message.get -> string?
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.Message.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.RawDiagnostic() -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.Timestamp.get -> System.DateTimeOffset?
JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic.Timestamp.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawProject
JD.Efcpt.Ide.Core.BuildProfileReader.RawProject.Name.get -> string?
JD.Efcpt.Ide.Core.BuildProfileReader.RawProject.Name.set -> void
JD.Efcpt.Ide.Core.BuildProfileReader.RawProject.RawProject() -> void
JD.Efcpt.Ide.Core.BuildProfileStatus
JD.Efcpt.Ide.Core.BuildProfileStatus.Canceled = 4 -> JD.Efcpt.Ide.Core.BuildProfileStatus
JD.Efcpt.Ide.Core.BuildProfileStatus.Failed = 2 -> JD.Efcpt.Ide.Core.BuildProfileStatus
JD.Efcpt.Ide.Core.BuildProfileStatus.Skipped = 3 -> JD.Efcpt.Ide.Core.BuildProfileStatus
JD.Efcpt.Ide.Core.BuildProfileStatus.Success = 1 -> JD.Efcpt.Ide.Core.BuildProfileStatus
JD.Efcpt.Ide.Core.BuildProfileStatus.Unknown = 0 -> JD.Efcpt.Ide.Core.BuildProfileStatus
JD.Efcpt.Ide.Core.BuildStatusEvaluation
JD.Efcpt.Ide.Core.BuildStatusEvaluation.BannerMessage.get -> string?
JD.Efcpt.Ide.Core.BuildStatusEvaluation.BuildStatusEvaluation(JD.Efcpt.Ide.Core.BuildStatusFreshness freshness, string? bannerMessage) -> void
JD.Efcpt.Ide.Core.BuildStatusEvaluation.Freshness.get -> JD.Efcpt.Ide.Core.BuildStatusFreshness
JD.Efcpt.Ide.Core.BuildStatusEvaluator
JD.Efcpt.Ide.Core.BuildStatusFreshness
JD.Efcpt.Ide.Core.BuildStatusFreshness.Current = 1 -> JD.Efcpt.Ide.Core.BuildStatusFreshness
JD.Efcpt.Ide.Core.BuildStatusFreshness.NoProfile = 0 -> JD.Efcpt.Ide.Core.BuildStatusFreshness
JD.Efcpt.Ide.Core.BuildStatusFreshness.StaleAfterFailedRegenerate = 3 -> JD.Efcpt.Ide.Core.BuildStatusFreshness
JD.Efcpt.Ide.Core.BuildStatusFreshness.StaleFromEarlierRun = 2 -> JD.Efcpt.Ide.Core.BuildStatusFreshness
JD.Efcpt.Ide.Core.JdDiagnostic
JD.Efcpt.Ide.Core.JdDiagnostic.Code.get -> string!
JD.Efcpt.Ide.Core.JdDiagnostic.JdDiagnostic(JD.Efcpt.Ide.Core.JdDiagnosticSeverity severity, string! code, string! message) -> void
JD.Efcpt.Ide.Core.JdDiagnostic.Message.get -> string!
JD.Efcpt.Ide.Core.JdDiagnostic.Severity.get -> JD.Efcpt.Ide.Core.JdDiagnosticSeverity
JD.Efcpt.Ide.Core.JdDiagnosticParser
JD.Efcpt.Ide.Core.JdDiagnosticSeverity
JD.Efcpt.Ide.Core.JdDiagnosticSeverity.Error = 1 -> JD.Efcpt.Ide.Core.JdDiagnosticSeverity
JD.Efcpt.Ide.Core.JdDiagnosticSeverity.Warning = 0 -> JD.Efcpt.Ide.Core.JdDiagnosticSeverity
JD.Efcpt.Ide.Core.ProjectDiscovery
JD.Efcpt.Ide.Core.ProjectDiscoveryResult
JD.Efcpt.Ide.Core.ProjectDiscoveryResult.Matches.get -> System.Collections.Generic.IReadOnlyList<string!>!
JD.Efcpt.Ide.Core.ProjectDiscoveryResult.ProjectDiscoveryResult(System.Collections.Generic.IReadOnlyList<string!>! matches, System.Collections.Generic.IReadOnlyList<JD.Efcpt.Ide.Core.SkippedProject!>! skipped) -> void
JD.Efcpt.Ide.Core.ProjectDiscoveryResult.Skipped.get -> System.Collections.Generic.IReadOnlyList<JD.Efcpt.Ide.Core.SkippedProject!>!
JD.Efcpt.Ide.Core.RegenerateAttempt
JD.Efcpt.Ide.Core.RegenerateAttempt.ExitCode.get -> int
JD.Efcpt.Ide.Core.RegenerateAttempt.RegenerateAttempt(System.DateTimeOffset startedUtc, bool succeeded, int exitCode) -> void
JD.Efcpt.Ide.Core.RegenerateAttempt.StartedUtc.get -> System.DateTimeOffset
JD.Efcpt.Ide.Core.RegenerateAttempt.Succeeded.get -> bool
JD.Efcpt.Ide.Core.SecretRedaction
JD.Efcpt.Ide.Core.SkippedProject
JD.Efcpt.Ide.Core.SkippedProject.Path.get -> string!
JD.Efcpt.Ide.Core.SkippedProject.Reason.get -> string!
JD.Efcpt.Ide.Core.SkippedProject.SkippedProject(string! path, string! reason) -> void
const JD.Efcpt.Ide.Core.BuildProfileReader.SupportedSchemaMajor = 1 -> int
const JD.Efcpt.Ide.Core.SecretRedaction.ConnectionStringPlaceholder = "<connection-string redacted>" -> string!
static JD.Efcpt.Ide.Core.BuildProfileReader.IsSchemaSupported(string! schemaVersion) -> bool
static JD.Efcpt.Ide.Core.BuildProfileReader.NormalizeDiagnostic(JD.Efcpt.Ide.Core.BuildProfileReader.RawDiagnostic! raw) -> JD.Efcpt.Ide.Core.BuildProfileDiagnostic!
static JD.Efcpt.Ide.Core.BuildProfileReader.Parse(string! jsonText) -> JD.Efcpt.Ide.Core.BuildProfile!
static JD.Efcpt.Ide.Core.BuildProfileReader.ReadFile(string! path) -> JD.Efcpt.Ide.Core.BuildProfile!
static JD.Efcpt.Ide.Core.BuildStatusEvaluator.Evaluate(JD.Efcpt.Ide.Core.RegenerateAttempt? lastAttempt, JD.Efcpt.Ide.Core.BuildProfile? profile) -> JD.Efcpt.Ide.Core.BuildStatusEvaluation!
static JD.Efcpt.Ide.Core.JdDiagnosticParser.ParseLines(string! output) -> System.Collections.Generic.IReadOnlyList<JD.Efcpt.Ide.Core.JdDiagnostic!>!
static JD.Efcpt.Ide.Core.JdDiagnosticParser.TryParseLine(string! line) -> JD.Efcpt.Ide.Core.JdDiagnostic?
static JD.Efcpt.Ide.Core.ProjectDiscovery.DiscoverJdEfcptProjects(System.Collections.Generic.IReadOnlyList<string!>! csprojPaths, System.Func<string!, string!>! readFile) -> JD.Efcpt.Ide.Core.ProjectDiscoveryResult!
static JD.Efcpt.Ide.Core.ProjectDiscovery.HasJdEfcptPackageReference(string! csprojContent) -> bool
static JD.Efcpt.Ide.Core.SecretRedaction.MaskSecrets(string? text) -> string!
static JD.Efcpt.Ide.Core.SecretRedaction.RedactConnectionString(string? text, string? connectionString) -> string!
static readonly JD.Efcpt.Ide.Core.JdDiagnosticParser.DiagnosticPattern -> System.Text.RegularExpressions.Regex!
static readonly JD.Efcpt.Ide.Core.ProjectDiscovery.PackageReferencePattern -> System.Text.RegularExpressions.Regex!
1 change: 1 addition & 0 deletions ide/vs/JD.Efcpt.Ide.Core/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#nullable enable
9 changes: 9 additions & 0 deletions src/JD.Efcpt.Build.Core/JD.Efcpt.Build.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
-->
<TargetFrameworks>net472;net8.0;net9.0;net10.0</TargetFrameworks>

<!--
PublicApiAnalyzers (#191: PUBLIC-API-STABILITY) locks this assembly's public surface.
Scoped to net10.0 only; see build/PublicApi.props for why (avoids a per-TFM
PublicAPI.*.txt baseline for net472).
-->
<PublicApiAnalyzerTfm>net10.0</PublicApiAnalyzerTfm>

<!--
Not packed as its own NuGet package. This assembly is a build-time/runtime implementation
detail shared between JD.Efcpt.Build.Tasks and JD.Efcpt.Cli via ProjectReference; its output
Expand All @@ -29,6 +36,8 @@
<NoWarn Condition="'$(TargetFramework)' == 'net472'">$(NoWarn);CS8632</NoWarn>
</PropertyGroup>

<Import Project="..\..\build\PublicApi.props" />

<!-- Polyfills for net472: provides IsExternalInit, init accessors, etc. (records use these). -->
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<PackageReference Include="PolySharp">
Expand Down
Loading
Loading