在Linux上使用类Unix的换行符,在Windows上使用Windows风格的换行符

3

我有一段C#代码能够在Linux和Windows上运行。在自动化构建过程中,团队城市(TeamCity)构建服务器会运行单元/集成测试。如果代码发生更改,它将触发Linux和Windows的构建,并且相同的单元测试将在Linux和Windows上执行。

这些构建代理使用git来下载源码、构建和进行测试。

期望的行为是,在Linux代理上使用Linux风格的(LF)换行符的源代码,而Windows代理的代码则使用Windows风格的(CR LF)换行符。原因是该代码将多行字符串字面量作为某些单元测试的输入,并且被测试的代码使用Environment.NewLine

var example = @"This is a really,
really long string";

我想在Linux和Windows系统中将系统定义的Environment.NewLine出现在字符串中,但是考虑到我的限制,我无法实现这一点。

我无法访问构建代理。任何它需要完成其工作的设置或值都需要捕获在我的源代码中,而不是机器上的某个本地值。 我有一些有限的了解告诉我应该依赖于 .gitattributes 文件,并且虽然我已经看到并且稍微了解了可以在.gitattributes文件中使用的各种行结束设置。

我不能只配置Windows机器使用core.autocrlf=true,Linux机器使用core.autocrlf=false或某些变体,除非我只能通过添加或修改包含在我的存储库中的文件来完成。

考虑到我的限制,是否有一种使用Git来实现这一点的方法?

2个回答

2
我不能仅仅配置Windows机器使用core.autocrlf=true,而Linux机器使用core.autocrlf=false
完美,core.autocrlf一般都应该设置为false
代码本身应该只使用LF:无论在Windows还是Linux上,它都将被IDE正确解释。
至于字符串,在单元测试代码中应该:
  • 检测操作系统
  • 根据操作系统将测试中使用的字符串转换为LF或CRLF
这意味着Git与单元测试如何运行无关。
所述单元测试不应依赖于外部工具(此处为版本控制工具)是否正确配置。 它们应该独立于任何.gitattributes正确运行:它们的代码应负责构建预期的结果。

所以,如果我理解你的意思正确的话;在跨平台开发方面,使用多行字符串文字是一种反模式,因为 git 确实关注该字符串的内容,对吗? - Rob P.
1
@RobP。git 不应该关心那个字符串的内容。你的单元测试代码应该关心那个多行字符串的内容,而不管版本控制工具在检出期间对其进行了什么操作。这将确保单元测试在各个平台上都是健壮的。 - VonC

1
Git默认会对文本文件执行行结束符转换。如果您想要将文件的行结束符进行转换,可以在您的 .gitattributes 文件中标记这些文件为文本类型:
*.cs text

如果您希望Git自动猜测哪些文件是文本文件,那么您应该编写类似于以下内容的代码:
* text=auto

假设您的构建代理没有自定义的Git配置覆盖行尾,这应该足以使Git将行尾转换为本地行尾。如果您想要明确指定,可以使用core.eol设置为native执行克隆,如下所示:git -c core.eol=native clone URL
然而,话虽如此,在代码中做出关于行尾的假设通常不是一个好主意。如果您的用户正在使用Windows子系统来运行Linux,则他们可能会使用Unix Git并在其工作树中使用Unix行尾,并且这不应影响您单元测试的正确性。行尾应明确设置为LF或CRLF,因为存在功能原因(例如,任何平台上都无法使用CRLF行尾的shell脚本),或者根据用户的开发环境留给用户的意愿。
如果您需要在测试中明确使用平台的本机行尾,则应编写一个将根据平台适当解析的显式字符串,或者将测试字符串包装在根据平台进行转换的辅助函数中。

我非常感谢这个答案。我同意,我做了很多错误的事情 - 没有统一的构建代理配置,代码/测试依赖于行尾是本地行尾,可能还有很多其他问题。但是,听起来在克隆期间指定core.eol=native将实现我正在寻找的确切功能,即使它只是对更严重问题的一种权宜之计。 - Rob P.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接