使用SVN与Delphi Visual Component软件包的最佳实践?

7
希望能够重现使用第三方可视化组件包的项目中给定版本的内容,那么在 SVN 中应该放什么,以及实施/构建 SVN 存储库的最佳方法是什么?
对于非可视化组件,规则似乎很简单,确保不依赖外部存储库 - “不允许 svn-externals 引用任何外部存储库”。我有一个共享存储库,我控制着它,这是唯一允许的“svn-externals”引用。这使得在不同 SVN 项目中实施和共享这些类型的运行时项与源代码变得容易。对此内部共享存储库的任何引用都是通过特定修订号的“svn-externals”进行的。
可视化包似乎与易于进行版本控制相矛盾,因为它们可能需要在每个版本中重新安装。如何创建最佳的 SVN 项目,以便稍后可以在特定修订号上重新创建...是否有推荐的解决方案?
以前,我们不担心第三方组件,因为它们不经常更改,而且我们从来没有找到真正好的解决方案。我想知道其他人是否已经找到了处理此问题的最佳方法,因为我正在进行春季清理 / 内部重新组织,并希望比以前做得更好。
从技术上讲,RTL / VCL 源代码也应该在 SVN 存储库中(如果发布了 Delphi 热修复/服务包)。
我的解决方案可能是创建一个具有特定版本的 Delphi 环境和所有可视化控件的虚拟机。随着我们添加/更新可视化控件,或者使用热修补程序/服务包更新 Delphi,然后我们创建虚拟机的新版本。然后,我们将此 VM 修订版的映像存储在某个架子上。你是这样做的吗?Delphi 激活/许可是否在此情况下有效(或根本有效)?
谢谢,
Darian

2
在我看来,第三方组件包(无论是可视化的还是非可视化的)与必须安装在IDE中才能工作的东西是一样的。例如INDY或JCL甚至JVCL(可视化和非可视化混合),这只是提到几个流行的非可视化组件包而已。 - jachguate
如果您没有使用运行时包并且具有源代码,则只需简单地指向源代码路径即可解决问题。因此,在这种情况下,带有源代码的运行时包要容易处理得多。 - Darian Miller
这并没有解决从svn(或任何版本管理)中检索特定版本的问题,包括第三方组件。 - Leonardo Herrera
我和jachguate的想法类似。也许更合适的区分是设计时和纯运行时包。 - Disillusioned
@Leonardo,如果你指的是VM不能从SVN检索特定版本,那么你是正确的。目前我没有其他可行的想法。这比我们目前拥有的更好,但肯定不是“理想”的。理想情况可能是VMWare LabManager,但那需要很高的费用。 - Darian Miller
3个回答

7
您可以为您的项目准备“启动IDE”(以及可能的“构建”)脚本,并随着项目在存储库中的发展而进行维护。
无论您决定将组件保留在单独的存储库中并使用外部引用,还是将它们包含在一个单一的存储库中并可能分支,您都应该为每个组件构建和为特定Delphi版本准备的每个分支包括已编译的bpl文件。
您应该尽量保持大多数(如果不是全部)路径相对,最坏情况下使用环境变量指向您的根项目目录。
启动IDE脚本允许您在单个Windows安装上单独配置每个项目和Delphi版本环境。
它应该包括您的项目和Delphi所需的必要注册表键。
Windows Registry Editor Version 5.00

[-${DelphiRegKey}\Disabled Packages]
[-${DelphiRegKey}\Known Packages]
[-${DelphiRegKey}\Library]

[${DelphiRegKey}\Known Packages]
"$(BDS)\\Bin\\dclstd${CompilerVersion}.bpl"="Borland Standard Components"
"$(BDS)\\Bin\\dclie${CompilerVersion}.bpl"="Internet Explorer Components"
"$(BDS)\\Bin\\dcldb${CompilerVersion}.bpl"="Borland Database Components"
(...)
"${CustomComponentPack}"="Custom Components"

[${DelphiRegKey}\Library]
"Search Path"="${YourLibrarySourceFolder1};${YourLibrarySourceFolder2}"
(...)

您可以准备批处理文件:
regedit /s project.reg
%DelphiPath%\bin\bds -rProjectRegKey Project.dpr

其中${DelphiRegKey}HKEY_CURRENT_USER\Software\Borland(或新版本中的CodeGear)\ProjectRegKey

基本上,从注册表中转储当前工作配置,去除不必要的键,将路径更改为相对路径,然后进行适应以使其与您的项目配合使用会更容易。

在这种配置中,只需检出存储库并运行脚本,即可在具有不同组件集(和/或可能使用不同Delphi版本)的项目和分支之间切换。


我使用类似这样的东西。至少它可以让你轻松地重新配置Delphi以适应各种目的。 - Frederik Slijkerman
你今天使用这种设置吗?听起来很有趣。'环境'将成为一个项目(reg脚本+bpls),并且也会被版本化...这可以是一个'svn-external',指向使用它们的项目中特定环境修订版。然后,随着环境的更改(Delphi服务包、组件添加或更新),环境将单独提交,并根据需要升级引用的项目。(svn-external始终引用特定的rev #)嗯...这确实打开了很多东西!需要一段时间来消化...谢谢。 - Darian Miller
我在很多项目中都使用这个设置,构建脚本是按照每个项目的基础准备的。不幸的是,它没有考虑到 Delphi 补丁 - 然而 Delphi 是唯一需要安装在机器上的依赖项,除了 TortoiseSVN(或者可能是 TortoiseGIT)和一些受版权保护的库之外,Woll2Woll 的 InfoPower 是唯一一个在使用安装程序时抱怨未被安装在系统中的库... 在加载时挂起 IDE。真可惜。 - too
1
您的解决方案,再加上此帖子http://www.dummzeuch.de/delphi/subversion/english.html中的一些附加逻辑。 - Darian Miller
我喜欢根据项目自定义IDE这个想法。不幸的是,这些更改是永久性的。也许有人可以提供一个工具来将注册表访问重定向到文件,然后这个文件将成为项目的一部分?我对挂钩Delphi 2007 IDE注册表访问的示例代码有些了解,但我不知道它是否还适用于更新版本。 - dummzeuch
这些更改是永久性的,直到您删除项目注册表键。删除 HKEY_CURRENT_USER\Software\Borland\Project 键将从您的系统中删除该项目的所有痕迹。 - too

3
幸运的是,我们不必担心热修复/服务包;我们仍在使用Delphi 5。:D
叹气,曾经整个应用程序(包括设置)都存在于单个目录中,这使得这个问题不存在。但是,世界已经发生了变化,我们的应用程序的各个部分散落在各个地方:
- 注册表 - Windows\System - Program Files - 有时甚至在“应用程序数据”或“本地设置”的用户文件夹中
您考虑到热修复/服务包的影响是完全正确的。不仅RTL/VCL可能会受到影响,编译器本身也可能会稍微改变。请注意,即使在升级Delphi版本时,您也需要使用正确的版本进行构建。不可否认,这可能会更容易一些,因为您可以同时运行不同的Delphi版本。
然而,我建议您不要花费太多精力。请记住,使用旧版本始终比使用当前版本更昂贵。
  • 理想情况下,您希望所有开发都在主分支代码上进行,尽可能减少对旧版本的补丁。
  • 因此,尽可能让大多数用户使用最新版本。
  • 不可否认,这并非总是可能的。
  • 在任何情况下,您都不会希望立即跳转到“新版本”而没有进行测试。
  • 某些敏捷流程确实会使此过程更加容易。
  • 通过使用单独的构建机器或虚拟机,您已经具有一定的控制能力。
  • 提示:我还建议构建过程自动将生成的输出复制到另一台机器,或者至少复制到另一个硬盘驱动器。
  • 一旦您对服务包满意,就可以计划何时将其升级到构建机器上。
  • 非常重要的是保留更改构建配置的标签的记录。(以防万一。)
  • 如果您的构建脚本也保存在源代码控制中,则会自动发生这种情况。
  • 在推出热修补/服务包后,应积极阻止对旧版本的修复。
  • 当然,它们可能无法消除,但如果它足够罕见,甚至手动重新配置也是可行的。
  • 您可以考虑驱动器映像而不是VM选项来保留旧配置。
  • 为了节省VMWare LabManager的$$$,请寻找一个基于命令行的VM Player。
  • 您可能需要保留2个“活动”机器/虚拟机,但永远不需要更多。
  • 自动构建脚本失败因为所需配置不可用是可以的。这将提醒您手动设置它。
  • 记住,使用旧版本始终比使用当前版本更加昂贵。

第三方包

我们在这里做了更多的努力。其中一个主要动机是我们使用约8个第三方包。因此,对其进行标准化的工作本身就是有意义的。我们还决定运行8个安装程序很麻烦,因此我们设计了一种从源代码控制中手动安装所有所需包的简单方法。

关键考虑因素

  • 构建环境不需要安装任何软件包,只要对象和/或源文件可访问即可。
  • 如果必要,开发人员能够相当容易地确保他们正在使用相同版本的第三方库。
  • 但是,开发环境通常必须将软件包安装到IDE中。
    • 这有时会导致源代码兼容性问题。
    • 例如,写入IDE维护文件的新属性。
    • 这当然又将我们带回了第二点。
  • 由于第三方软件包很少更新,因此它们放置在源代码控制的稍微不同的区域内。
  • 但是,NB仍然必须通过相对路径引用。
我们创建了以下文件夹结构:
...\ThirdParty\_DesignTimePackages //The actual package files only are copied here
...\ThirdParty\_RunTimePackages //As above, for any packages "required" by those above
...\ThirdParty\Suite1
...\ThirdParty\Suite2
...\ThirdParty\Suite3

由此可以很容易地配置新的环境:
  • 获取所有第三方文件的最新版本。
  • 将_DesignTimePackages和_RunTimePackages添加到Windows Path中。
  • 打开Delphi。
  • 选择安装组件。
  • 从_DesignTimePackages中选择所有包。
  • 完成!

编辑: Darian担心在切换设计包版本时可能会出现错误。然而,这种方法避免了这些问题。
  • 通过将_DesignTimePackages和_RunTimePackages添加到Windows Path中,Delphi将始终在相同的位置找到所需的包。
  • 因此,您更不可能遇到不兼容版本的“包噩梦”。
  • 当然,如果您做了一些愚蠢的事情,比如重建某些包并检入新版本,无论采取什么方法,都可能会遇到问题。

我深知 Delphi 5 的痛楚!感谢你详细的回复。 - Darian Miller
你切换版本时,之前装载的设计包会不会出现错误? - Darian Miller

2
我通常会在SVN中按照以下方式组织我的代码库:
/trunk/app1
/trunk/comp/thirdparty1
/trunk/comp/thirdparty2
/trunk/comp/thirdparty3...

我的根文件夹(trunk)中有一个项目组(.groupproj或旧版delphi的.bpg),其中包含所有我的组件(allcomponents.groupproj)。

在新机器上安装意味着打开该包并安装设计时组件。在Delphi 2010及其以上版本中,这是非常方便的功能,您可以一目了然地看到哪些组件是设计时组件。

有时,我也会通过制作build.bat文件和regcomponents.bat文件来避免手动安装这些组件。regcomponents只需运行regedit,并导入注册所有这些组件所需的键,而在build.bat构建它们和其他所有内容之后。

当您从一个Delphi版本升级到另一个版本时,拥有批处理和reg文件以及组项目将对您有很大帮助。尤其是如果您必须逐个打开项目/软件包并将它们保存为MyComponent3.dpk而不是MyComponent2.dpk,或者更新软件包扩展名从150到160,或者其他您的软件包要做的任何事情。


那么,对于使用不同版本的第三方库thirdparty3的app2,你也有卸载批处理文件吗?(卸载版本x,安装版本y) - Darian Miller
1
通常不需要卸载,因为“卸载”只是指清除我的第三方组件文件夹,然后启动Delphi,并多次点击“否”,或者是“是”。 - Warren P

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