我认为这个问题一般适用于CMS。
我正在使用CMS,Kentico,用于特定的Web应用程序。 CMS安装程序生成自己的样板项目,包含10,000多个文件,该项目相当于一个可运行的Web应用程序。很少有CMS提供的文件可供修改。然而,标准做法是将自定义代码添加到项目中,并将整个项目检查为源代码控制。
我不喜欢检查整个CMS的想法。我更喜欢我的存储库只包含项目特有的代码,而供应商文件则自动从其他地方“拉入”。例如,Visual Studio可以将NuGet包恢复到项目中的固定位置,版本控制可以忽略此位置。
在某种程度上,使用CMS进行开发比使用典型供应商库时更脏。通常,您自己的代码依赖于库,而库独立于您的代码。但是,CMS希望 您的应用程序,并且您自己的代码交织在一起。 CMS需要自定义其自己提供的文件。您不能只是将CMS文件“拉入”固定位置,然后忽略该位置。
鉴于这种情况,我仍然希望尽可能多地省略CMS文件。到目前为止,我已经确定了这个策略:
这种策略在理论上听起来不错,但在实践中却更为复杂。以下是一些并发症:
将10,000多个文件路径更改为外部文件中的“链接”,结果不仅仅是查找替换操作。需要更复杂的映射来保留原始项目的目录结构。
Web服务器要求所有文件位于同一目录中。使用项目文件链接到外部文件可以进行编译,但是您已将Web根分成两部分。
对于后一个问题,似乎最好的解决方法是执行构建后复制操作。这本身比起初看起来更复杂。
在我写这篇文章时,我开始觉得我应该继续将整个工作CMS转储到我的存储库中。感觉很脏,但这简直太难了。在我这样做之前,有没有人对我如何实现目标有任何经验或想法?
重述我的问题:如何从我的版本控制存储库中排除CMS提供的文件,同时仍然将它们包含在我的项目/构建脚本和我的Web应用程序根目录中?
答案 0 :(得分:1)
以下是如何实现这一目标的另一个想法:
以下是KenticoBuilder.csproj脚本的作用:
这很复杂,但我认为它可能会起作用。思绪,有人吗?
答案 1 :(得分:0)
Kentico应该很快就会解决这个问题,你可以参考预先构建的dll而不是每次修改C#时重建整个CMS。
在此之前,您是否考虑使用Symbolic Links来引用原始文件?然后在需要时用你的修改过的文件覆盖链接?
如果您之前没有使用过,请参阅this other question。 mklink附带了更新的Windows版本(命令行),但也有一堆基于第三方GUI的应用程序。
答案 2 :(得分:0)
我提出了一个理想的策略:
link
元素使这一点复杂化,因此我编写了一个小的控制台应用程序来解析XML并生成必要的元素。我还在属性中存储库的路径。此时,您有一个可编辑的项目。这些文件都只是指向只读,基线,CMS提供的文件的链接,但IDE显示了一个很好的目录结构,就好像文件实际上在您的存储库中一样。在自定义时,您可以使用自己的实际文件替换链接。
但是,您的网站文件现在分为两个完全不同的位置。 Web服务器需要它们实际位于同一目录中。这是一些脚本派上用场的地方。
使用构建脚本工具,插入构建后事件,将链接文件复制到项目目录中。当然,您可以省略已编译的文件。这是我用MSBuild做的方式(感谢这个blog post):
<Target Name="AfterBuild">
<ItemGroup>
<LinkedKenticoFiles Include="@(None);@(EmbeddedResource);@(Content)"
Condition="$([System.String]::new('%(FullPath)').StartsWith('$(MY_LIBRARY_BASE_PATH)'))" />
</ItemGroup>
<Copy SourceFiles="%(LinkedKenticoFiles.Identity)"
DestinationFiles="%(LinkedKenticoFiles.Link)"
SkipUnchangedFiles='true' />
</Target>
(可选)插入清除事件以删除这些文件。我使用类似的MSBuild语法删除文件,因为它留下了空目录,我也删除了空目录。 (感谢this answer。)
<Target Name="BeforeClean">
<ItemGroup>
<LinkedKenticoFiles Include="@(None);@(EmbeddedResource);@(Content)"
Condition="$([System.String]::new('%(FullPath)').StartsWith('$(MY_LIBRARY_BASE_PATH)'))" />
</ItemGroup>
<Delete Files="%(LinkedKenticoFiles.Link)" />
<ItemGroup>
<Directories Include="$([System.IO.Directory]::GetDirectories($(MSBuildProjectDirectory), '*', System.IO.SearchOption.AllDirectories))" />
<Directories>
<Files>$([System.IO.Directory]::GetFiles("%(Directories.Identity)", "*", System.IO.SearchOption.AllDirectories).get_Length())</Files>
</Directories>
</ItemGroup>
<RemoveDir Directories="@(Directories)" Condition="%(Files)=='0'" />
</Target>
(可选)使源控件忽略站点/项目文件夹,以避免签入临时复制的站点文件。