Directory.Build.props 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <Project>
  2. <PropertyGroup>
  3. <!-- 支持 .NET 6 及以上所有版本 -->
  4. <TargetFrameworks>net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
  5. <!-- 公共设置 -->
  6. <ImplicitUsings>enable</ImplicitUsings>
  7. <Nullable>enable</Nullable>
  8. <LangVersion>latest</LangVersion>
  9. <!-- 生成文档 -->
  10. <GenerateDocumentationFile>true</GenerateDocumentationFile>
  11. <NoWarn>$(NoWarn);CS1591</NoWarn>
  12. <!-- 抑制 XML 注释警告 -->
  13. <NoWarn>$(NoWarn);CS1591;CS1570;CS1574</NoWarn>
  14. <!-- 抑制 TFM 不支持警告 -->
  15. <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
  16. </PropertyGroup>
  17. <!-- Apq.ChangeBubbling 特定的 NuGet 包元数据 -->
  18. <PropertyGroup>
  19. <Description>变更冒泡事件库,支持 Rx 响应式流、弱引用消息和可插拔调度环境</Description>
  20. <PackageTags>change-bubbling;reactive;rx;mvvm;messaging;event;observable</PackageTags>
  21. <PackageReadmeFile>README.md</PackageReadmeFile>
  22. </PropertyGroup>
  23. <!-- 从 versions 目录自动获取版本号(纯 MSBuild,跨平台兼容) -->
  24. <PropertyGroup>
  25. <VersionsDir>$([System.IO.Path]::Combine($(MSBuildThisFileDirectory), 'versions'))</VersionsDir>
  26. </PropertyGroup>
  27. <!-- 内联任务:获取最高版本号及其文件路径 -->
  28. <UsingTask TaskName="GetMaxVersion" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)/Microsoft.Build.Tasks.Core.dll">
  29. <ParameterGroup>
  30. <VersionFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
  31. <MaxVersion ParameterType="System.String" Output="true" />
  32. <MaxVersionCore ParameterType="System.String" Output="true" />
  33. <MaxVersionRevision ParameterType="System.String" Output="true" />
  34. <MaxVersionFile ParameterType="System.String" Output="true" />
  35. </ParameterGroup>
  36. <Task>
  37. <Using Namespace="System.Text.RegularExpressions" />
  38. <Code Type="Fragment" Language="cs"><![CDATA[
  39. MaxVersion = "1.0.0";
  40. MaxVersionCore = "1.0.0";
  41. MaxVersionRevision = "0";
  42. MaxVersionFile = "";
  43. Version maxVer = new Version(0, 0, 0);
  44. string maxPrerelease = "";
  45. if (VersionFiles != null) {
  46. foreach (var file in VersionFiles) {
  47. // 匹配完整版本号,包括预发布标签(如 v1.0.2-beta1)
  48. var match = Regex.Match(file.GetMetadata("Filename"), @"^v(\d+\.\d+\.\d+)(-[\w.]+)?");
  49. if (match.Success) {
  50. var coreVersion = match.Groups[1].Value;
  51. var prerelease = match.Groups[2].Success ? match.Groups[2].Value : "";
  52. var ver = new Version(coreVersion);
  53. // 比较:先比核心版本,再比预发布标签(空字符串 > 预发布标签,即正式版 > beta)
  54. bool isNewer = ver > maxVer ||
  55. (ver == maxVer && string.Compare(prerelease, maxPrerelease, StringComparison.Ordinal) > 0);
  56. if (isNewer) {
  57. maxVer = ver;
  58. maxPrerelease = prerelease;
  59. MaxVersionCore = coreVersion;
  60. MaxVersion = coreVersion + prerelease;
  61. MaxVersionFile = file.GetMetadata("FullPath");
  62. // 从预发布标签提取数字作为修订号(如 -beta2 -> 2, -rc.3 -> 3)
  63. var revMatch = Regex.Match(prerelease, @"(\d+)$");
  64. MaxVersionRevision = revMatch.Success ? revMatch.Groups[1].Value : "0";
  65. }
  66. }
  67. }
  68. }
  69. ]]></Code>
  70. </Task>
  71. </UsingTask>
  72. <!-- 内联任务:检查文件内容长度 -->
  73. <UsingTask TaskName="CheckFileLength" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)/Microsoft.Build.Tasks.Core.dll">
  74. <ParameterGroup>
  75. <FilePath ParameterType="System.String" Required="true" />
  76. <MinLength ParameterType="System.Int32" Required="true" />
  77. <IsLongEnough ParameterType="System.Boolean" Output="true" />
  78. </ParameterGroup>
  79. <Task>
  80. <Using Namespace="System.IO" />
  81. <Code Type="Fragment" Language="cs"><![CDATA[
  82. IsLongEnough = false;
  83. if (!string.IsNullOrEmpty(FilePath) && File.Exists(FilePath)) {
  84. var content = File.ReadAllText(FilePath);
  85. IsLongEnough = content.Length >= MinLength;
  86. }
  87. ]]></Code>
  88. </Task>
  89. </UsingTask>
  90. <!-- 扫描版本文件并提取最高版本 -->
  91. <Target Name="DetectVersionFromFiles" BeforeTargets="GetAssemblyVersion;GenerateNuspec;Pack;Build">
  92. <ItemGroup>
  93. <VersionFiles Include="$(VersionsDir)/v*.md" />
  94. </ItemGroup>
  95. <GetMaxVersion VersionFiles="@(VersionFiles)">
  96. <Output TaskParameter="MaxVersion" PropertyName="DetectedVersion" />
  97. <Output TaskParameter="MaxVersionCore" PropertyName="DetectedVersionCore" />
  98. <Output TaskParameter="MaxVersionRevision" PropertyName="DetectedVersionRevision" />
  99. <Output TaskParameter="MaxVersionFile" PropertyName="DetectedVersionFile" />
  100. </GetMaxVersion>
  101. <PropertyGroup>
  102. <!-- Version/PackageVersion 使用完整版本(含预发布标签) -->
  103. <Version>$(DetectedVersion)</Version>
  104. <PackageVersion>$(DetectedVersion)</PackageVersion>
  105. <!-- AssemblyVersion/FileVersion 使用数字版本,第四位为预发布序号 -->
  106. <AssemblyVersion>$(DetectedVersionCore).$(DetectedVersionRevision)</AssemblyVersion>
  107. <FileVersion>$(DetectedVersionCore).$(DetectedVersionRevision)</FileVersion>
  108. </PropertyGroup>
  109. <Message Text="检测到版本: $(DetectedVersion)" Importance="high" />
  110. </Target>
  111. <!-- 动态选择 README 文件:优先使用版本文件,内容不足5字符时回退到项目 README -->
  112. <Target Name="SelectReadmeFile" BeforeTargets="_GetPackageFiles" DependsOnTargets="DetectVersionFromFiles">
  113. <!-- 检查版本文件内容长度 -->
  114. <CheckFileLength FilePath="$(DetectedVersionFile)" MinLength="5">
  115. <Output TaskParameter="IsLongEnough" PropertyName="UseVersionFileAsReadme" />
  116. </CheckFileLength>
  117. <!-- 如果版本文件内容足够长,使用版本文件 -->
  118. <ItemGroup Condition="'$(UseVersionFileAsReadme)' == 'true'">
  119. <_PackageFiles Include="$(DetectedVersionFile)">
  120. <PackagePath>README.md</PackagePath>
  121. <BuildAction>None</BuildAction>
  122. </_PackageFiles>
  123. </ItemGroup>
  124. <!-- 否则使用项目目录下的 README.md -->
  125. <ItemGroup Condition="'$(UseVersionFileAsReadme)' != 'true'">
  126. <_PackageFiles Include="README.md">
  127. <PackagePath>README.md</PackagePath>
  128. <BuildAction>None</BuildAction>
  129. </_PackageFiles>
  130. </ItemGroup>
  131. <Message Text="README 来源: $(DetectedVersionFile) (版本文件)" Importance="high" Condition="'$(UseVersionFileAsReadme)' == 'true'" />
  132. <Message Text="README 来源: README.md (项目目录)" Importance="high" Condition="'$(UseVersionFileAsReadme)' != 'true'" />
  133. </Target>
  134. <!-- NuGet 包公共元数据 -->
  135. <PropertyGroup>
  136. <Authors>Apq</Authors>
  137. <Company>Apq</Company>
  138. <Copyright>Copyright © Apq $([System.DateTime]::Now.Year)</Copyright>
  139. <PackageLicenseExpression>MIT</PackageLicenseExpression>
  140. <!-- 启用包生成 -->
  141. <IsPackable>true</IsPackable>
  142. <!-- 源码链接支持 -->
  143. <PublishRepositoryUrl>true</PublishRepositoryUrl>
  144. <EmbedUntrackedSources>true</EmbedUntrackedSources>
  145. <IncludeSymbols>true</IncludeSymbols>
  146. <SymbolPackageFormat>snupkg</SymbolPackageFormat>
  147. </PropertyGroup>
  148. </Project>