打开 DeterministicSourcePaths 获取源文件位置

时间:2021-05-28 19:33:12

标签: c# .net msbuild deterministic

问题: 有没有办法在不使用 CallerFilePath 属性的情况下获取调用者或当前帧源代码位置?

背景:

我定义了这个助手:

public class PathHelper
{
    public static string GetThisFilePath([CallerFilePath] string path = null)
    {
        return path;
    }
}

可以按如下方式调用以获取用于构建二进制文件的源代码的位置:

var currentSourceFilePath = PathHelper.GetThisFilePath();

这很好用,除非我打开了 DeterministicSourcePaths(通常通过 ContinuousIntegrationBuild msbuild 属性)。在这种情况下,返回的路径被修剪为类似:

/_/MyRelativeSourcePath

因此似乎确定性路径被注入到支持 CallerFilePath 的编译器功能中,从而产生这种行为。

我需要源代码位置以便能够对产品特定功能进行单元测试(这与检查构建过程有关),同时我仍然希望在 CI 机器上支持完全确定性构建。

1 个答案:

答案 0 :(得分:0)

您可以尝试以下操作。请注意

  • 这只是一个想法,具体的实现取决于你的环境

  • 如果您仅使用“默认构建输出路径”,这将起作用

  • 我没有测试过

      public static string GetThisFilePath([CallerFilePath] string path = null)
      {
          const string determenisticRoot = "/_/";
    
          if(!path.StartsWith(determenisticRoot))
          {
              return path;
          }
    
          // callerBinPath would be something like $(SolutionRoot)/.../MyProject.Tests/bin/Debug/net5.0
          var callerBinPath = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
    
          // Traverse to $(TestProjectRoot) - testProjectRoot would be something like $(SolutionRoot)/.../MyProject.Tests
          var testProjectRoot = Path.Combine(callerExecutablePath, "../../..");
    
          // Combine projectRoot root with relative path from [CallerFilePath]
          return Path.Combine(testProjectRoot, path.Substring(determenisticRoot.Length));
      }
    
相关问题