使用MSBuild批量重命名

使用MSBuild批量重命名,msbuild,continuous-integration,batch-rename,Msbuild,Continuous Integration,Batch Rename,我刚刚加入了一个没有CI流程(甚至不是一夜之间构建)和一些粗略的开发实践的团队。人们希望改变这一点,所以我现在的任务是创建一个通宵构建。我跟随了大量的文章:创建一个包含我们所有项目的主解决方案(一些web应用程序、一个web服务、一些Windows服务,以及编译为命令行可执行文件的耦合工具);创建了一个MSBuild脚本来自动生成、打包和部署我们的产品;并创建了一个.cmd文件,一次单击即可完成所有操作。作为这一切的一部分,我现在正努力完成一项任务: 该团队目前的做法是将web.config和a

我刚刚加入了一个没有CI流程(甚至不是一夜之间构建)和一些粗略的开发实践的团队。人们希望改变这一点,所以我现在的任务是创建一个通宵构建。我跟随了大量的文章:创建一个包含我们所有项目的主解决方案(一些web应用程序、一个web服务、一些Windows服务,以及编译为命令行可执行文件的耦合工具);创建了一个MSBuild脚本来自动生成、打包和部署我们的产品;并创建了一个.cmd文件,一次单击即可完成所有操作。作为这一切的一部分,我现在正努力完成一项任务:

该团队目前的做法是将web.config和app.config文件置于源代码管理之外,并将其放入名为web.template.config和app.template.config的源代码管理文件中。其目的是开发人员将.template.config文件复制到.config,以获取所有标准配置值,然后能够将.config文件中的值编辑为本地开发/测试所需的任何值。出于显而易见的原因,我希望将.template.config文件重命名为.config的过程自动化。最好的方法是什么

是否可以在构建脚本本身中执行此操作,而不必在脚本中规定需要重命名的每个单独文件(这需要在向解决方案中添加新项目时对脚本进行维护)?或者我可能需要编写一些仅从脚本运行的批处理文件


此外,是否有更好的开发解决方案可以让整个过程变得不必要?

简短回答:
是的,您可以(而且应该)自动执行此操作。您应该能够使用重命名文件

长答案:
这是伟大的,有一个愿望,改变从手动过程到自动的。通常很少有真正的理由不自动化。构建脚本将作为构建和部署实际工作方式的活文档。在我看来,一个好的构建脚本比静态文档更有价值(尽管我不是说你不应该有文档——它们毕竟不是相互排斥的)。让我们逐一回答您的问题

最好的方法是什么?

我不完全了解您在这些文件中存储的配置,但我怀疑很多配置可以在整个开发团队中共享

我建议提出以下问题:

  • 哪些设置是特定于开发人员的
  • 有没有办法标准化本地开发人员机器,以便共享设置
是否可以在构建脚本本身中执行此操作,而不必在脚本中规定每个需要重命名的文件?

是的,看一看。您应该能够使用它来重命名文件

…在向解决方案中添加新项目时,需要对脚本进行哪些维护?

这是不可避免的-您的构建脚本必须与您的解决方案一起发展。接受这一事实,并将更改构建脚本的时间包括在您的估计中

此外,是否有更好的开发解决方案可以让整个过程变得不必要?

我不知道所有的要求,所以很难推荐非常具体的东西。我可以这样说:

  • 为您的解决方案创建共享构建脚本
  • 尽可能地自动化手动任务(在合理范围内)
  • 如果你正在努力实现自动化,它可能是一个需要重新思考/重新设计的领域的指标
  • 确保您的团队成员了解构建是如何工作的,并且能够自己对其进行更改-不要“拥有”构建而成为瓶颈
请记住,从无构建脚本到完全自动化不是一个一朝一夕的过程。要有耐心,首先要把注意力放在使疼痛最严重的区域自动化上


如果我误解了你的任何问题,请告诉我,我会更新答案。

在阅读了大量关于项目组、目标和复制任务的内容后,我已经找到了如何做我需要的事情

<ItemGroup>
    <FilesToCopy Include="..\**\app.template.config">
        <NewFilename>app.config</NewFilename>
    </FilesToCopy>
    <FilesToCopy Include="..\**\web.template.config">
        <NewFilename>web.config</NewFilename>
    </FilesToCopy>
    <FilesToCopy Include"..\Hibernate\hibernate.cfg.template.xml">
        <NewFilename>hibernate.cfg.xml</NewFilename>
    </FilesToCopy>
</ItemGroup>

<Target Name="CopyFiles"
        Inputs="@(FilesToCopy)"
        Outputs="@(FilesToCopy->'%(RootDir)%(Directory)%(NewFilename)')">
    <Message Text="Copying *.template.config files to *.config"/>
<Copy SourceFiles="@(FilesToCopy)"
      DestinationFiles="@(FilesToCopy->'%(RootDir)%(Directory)%(NewFilename)')"/>

app.config
web.config
hibernate.cfg.xml


我创建一个包含要复制的文件的项目组。**操作符告诉它递归整个目录树,以查找具有指定名称的每个文件。然后,我向这些文件中的每个文件添加一段元数据,称为“NewFilename”。这就是我将重命名每个文件的目的

此代码段将添加名为app.template.config的目录结构中的每个文件,并指定我将命名新文件app.config:

<FilesToCopy Include="..\**\app.template.config">
    <NewFilename>app.config</NewFilename>
</FilesToCopy>

app.config
然后我创建一个目标来复制所有文件。这个目标最初非常简单,只调用复制任务,以便始终复制和覆盖文件。我将FilesToCopy项目组作为复制操作的源传递。我使用以指定输出文件名,以及我的NewFilename元数据和众所周知的项元数据

例如,以下代码段将文件c:\Project\Subdir\app.template.config转换为c:\Project\Subdir\app.config,并将前者复制到后者:

<Target Name="CopyFiles">
    <Copy SourceFiles="@(FilesToCopy)"
          DestinationFiles="@(FilesToCopy->'%(RootDir)%(Directory)%(NewFileName)')"/>
</Target>

但是后来我注意到,开发人员可能不喜欢在每次运行脚本时都重写自定义的web.config文件。但是,如果存储库的web.template.config已被修改,并且其中包含代码所需的新值,那么开发人员可能应该重写其本地文件。我试着做这件事
<Target Name="CopyFiles"
        Input="@(FilesToCopy)"
        Output="@(FilesToCopy->'%(RootDir)%(Directory)%(NewFileName)')">
      ...
</Target>