【发布时间】:2011-01-24 02:14:12
【问题描述】:
原来的问题
在构建我们的项目时,我希望将每个存储库的 mercurial id 嵌入到该存储库的产品(库、应用程序或测试应用程序)中。
我发现,如果您确切地知道构建客户正在使用的特定版本的应用程序的内容,那么调试由 8 个时区以外的客户运行的应用程序会变得非常容易。因此,我们系统中的每个项目(应用程序或库)都实现了一种获取相关修订信息的方法。
我还发现能够查看应用程序是否已使用存储库中的干净(未修改)变更集进行编译非常有用。当存储库中有未提交的更改时,'Hg id' 有用地将 + 附加到更改集 id,因此这使我们可以轻松查看人们是在运行代码的干净版本还是修改版本。
我目前的解决方案详述如下,并满足基本要求,但存在许多问题。
当前解决方案
目前,对于每个 Visual Studio 解决方案,我都添加了以下“预构建事件命令行”命令:
cd $(ProjectDir)
HgID
我还在项目目录中添加了一个 HgID.bat 文件:
@echo off
type HgId.pre > HgId.cs
For /F "delims=" %%a in ('hg id') Do <nul >>HgID.cs set /p = @"%%a"
echo ; >> HgId.cs
echo } >> HgId.cs
echo } >> HgId.cs
还有一个 HgId.pre 文件,定义为:
namespace My.Namespace {
/// <summary> Auto generated Mercurial ID class. </summary>
internal class HgID {
/// <summary> Mercurial version ID [+ is modified] [Named branch]</summary>
public const string Version =
当我构建我的应用程序时,会在所有库上触发预构建事件,创建一个新的 HgId.cs 文件(不受修订控制)并导致使用新的 ' 重新编译库'版本'中的 hg id' 字符串。
当前解决方案的问题
主要的问题是,由于每次预编译都会重新创建 HgId.cs,所以每次我们需要编译任何东西时,都会重新编译当前解决方案中的所有项目。由于我们希望能够轻松调试到我们的库中,因此我们通常会在我们的主要应用程序解决方案中保留许多引用的库。这可能会导致构建时间比我想要的要长得多。
理想情况下,我希望库仅在 HgId.cs 文件的内容实际发生更改时才编译,而不是使用完全相同的内容重新创建。
此方法的第二个问题是它依赖于 windows shell 的特定行为。我已经不得不多次修改批处理文件,因为原始版本在 XP 下工作而不是 Vista,下一个版本在 Vista 但不是 XP 下工作,最后我设法让它同时工作。但它是否适用于 Windows 7 尚有待商榷,随着时间的推移,我认为承包商更有可能希望能够在他们的 Windows 7 boxen 上构建我们的应用程序。
最后,我对这个解决方案有一个审美问题,批处理文件和模板文件混在一起感觉好像是错误的做法。
我的实际问题
你将如何解决/如何解决我试图解决的问题?
有什么比我目前正在做的更好的选择?
拒绝解决这些问题
在实施当前解决方案之前,我查看了 Mercurials 关键字扩展,因为它似乎是显而易见的解决方案。然而,我越看它和阅读人们的意见,我就越得出这样的结论:这样做是不对的。
我还记得在以前公司的项目中关键字替换给我带来的问题(只是想到必须再次使用 Source Safe 让我感到恐惧*8')。
另外,我并不特别希望启用 Mercurial 扩展来完成构建。我希望解决方案是自包含的,这样就不容易因为未启用扩展或未安装正确的帮助软件而在没有嵌入版本信息的情况下意外编译应用程序。
我也想过用一种更好的脚本语言来写这个,我只会写 HgId.cs 文件 如果内容确实发生了变化,但我能想到的所有选项都需要我的同事、承包商和可能的客户必须安装他们可能不需要的软件(例如 cygwin)。
人们能想到的任何其他选择将不胜感激。
更新
部分解决方案
玩了一段时间后,我设法让 HgId.bat 文件仅在 HgId.cs 文件发生更改时才覆盖它:
@echo off
type HgId.pre > HgId.cst
For /F "delims=" %%a in ('hg id') Do <nul >>HgId.cst set /p = @"%%a"
echo ; >> HgId.cst
echo } >> HgId.cst
echo } >> HgId.cst
fc HgId.cs HgId.cst >NUL
if %errorlevel%==0 goto :ok
copy HgId.cst HgId.cs
:ok
del HgId.cst
这个解决方案的问题
即使不再每次都重新创建 HgId.cs,Visual Studio 仍然坚持每次都编译所有内容。我已经尝试寻找解决方案并尝试在工具|选项|项目和解决方案|构建和运行中检查“仅构建启动项目和运行依赖项”,但没有任何区别。
第二个问题仍然存在,现在我无法测试它是否适用于 Vista,因为那个承包商不再和我们在一起了。
- 如果有人可以在 Windows 7 和/或 Vista 机器上测试此批处理文件,我将不胜感激。
最后,我对这个解决方案的审美问题比以前更严重,因为批处理文件更复杂,而且现在还有更多问题。
如果您能想到任何更好的解决方案,我很想听听。
【问题讨论】:
-
@Mark Booth:我首先想到的是你的“更好的脚本语言”,但你明确地排除了这一点:(啊微软商店的乐趣生态系统和供应商锁定;)
-
对不起,但我知道我的同事/客户是什么样的,并且任何使用当前 TortoiseHg+VS2008 安装无法完成的事情都不会成功。 *8'(
-
就“更好的脚本”而言——我想到了两件事:1)powershell——a)是一种更好的脚本语言,b)它比喜欢cygwin; 2) 编写一个 .exe 实用程序(您可以将其包含在您的项目中作为控制)以使用附加逻辑执行与批处理文件相同的操作。
-
您可以尝试 WSH 以获得更好的脚本。
-
Powershell 功能强大,但默认情况下不包含在 XP 中。 7中默认包含(不了解Vista)。
标签: c# visual-studio-2008 mercurial build