我有一个我正在使用steal编译的Web应用程序,然后我只想复制生产所需的文件,但我需要保留目录结构。例如,在运行steal的构建(将js / css编译为production.js / css文件)之后,目录看起来像这样:
\WebApp\index.html
\WebApp\app\img\a.png
\WebApp\app\img\b.png
\WebApp\app\js\foo.js
\WebApp\app\js\bar.js
\WebApp\app\css\base.css
\WebApp\app\css\app.css
\WebApp\app\css\widget1.css
\WebApp\app\production.js
\WebApp\app\production.css
\WebApp\steal\steal.js
\WebApp\steal\README.md
\WebApp\steal\build\build.js
除此之外,我想只将一些特定文件复制到同一个目录结构中:
\artifacts\staging\www\index.html
\artifacts\staging\www\app\img\a.png
\artifacts\staging\www\app\img\b.png
\artifacts\staging\www\app\production.js
\artifacts\staging\www\app\production.css
\artifacts\staging\www\steal\steal.js
理想情况下,我会有这样的事情:
<PropertyGroup>
<WorkingDir>WebApp\</WorkingDir>
<OutputDir>artifacts\staging\www\</OutputDir>
</PropertyGroup>
...
<ItemGroup>
<CopyFiles Remove="@(CopyFiles)" /> <!-- clean existing items -->
<CopyFiles Condition="'$(Configuration)'=='Debug'"
Include="$(WorkingDir)\**\*.*"
Exclude="$(WorkingDir)\**\.svn\**" />
<CopyFiles Condition="'$(Configuration)'=='Release'"
Include="$(WorkingDir)\index.html;$(WorkingDir)\app\img\**\*.*;$(WorkingDir)\app\production.*;$(WorkingDir)\steal\steal.js;"
Exclude="$(WorkingDir)\**\.svn\**" />
</ItemGroup>
<Copy SourceFiles="@(CopyFiles)"
DestinationFolder="@(CopyFiles->'$(OutputDir)\%(RecursiveDir)%(Filename)%(Extension)')" />
问题当然没有保留目录结构,实际上我只是将所有文件都放到没有子目录的$(OutputDir)
中。 %(RecursiveDir)
是**
的扩展,但由于我明确指定了大多数路径,因此它实际上并未生效。
现在我知道我可以用一堆copy
任务和itemgroup
来强制执行此操作,但除了丑陋之外,它还引入了自己的问题。首先,它容易出错,因为如果有人想要添加项目,他们必须确保使用唯一的项目组名称(此构建脚本很大并且执行许多其他任务),并确保多条线路都同步。
必须有比这更好的方法吗?
<ItemGroup>
<IndexFiles Include="$(WorkingDir)\index.html" />
<ImgFiles Include="$(WorkingDir)\app\img\**\*.*" />
<AppFiles Include="$(WorkingDir)\app\production.*" />
...
</ItemGroup>
<Copy SourceFiles="@(IndexFiles)"
DestinationFolder="@(IndexFiles->'$(OutputDir)\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(ImgFiles)"
DestinationFolder="@(ImgFiles->'$(OutputDir)\app\img\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(AppFiles)"
DestinationFolder="@(AppFiles->'$(OutputDir)\app\%(RecursiveDir)%(Filename)%(Extension)')" />
....
答案 0 :(得分:2)
我遇到了同样的问题,经过一番挣扎,我成功了。关键是在“**”之后指定要包含的文件夹。
<ItemGroup>
<CopyFiles Include="$(WorkingDir)\index.html" />
<CopyFiles Include="$(WorkingDir)\**\app\img\**\*.*" />
<CopyFiles Include="$(WorkingDir)\**\app\production.*" />
...
</ItemGroup>
因此,输出目录将包含所有子目录为“img”的app文件夹,以及名为“production”的所有文件。
作为注释 - “RecursiveDir”部分保持不变。
答案 1 :(得分:1)
只是添加到底池。
您还可以使用“排除某些文件”策略。
以下内容将获取所有* .txt和* .doc文件...但也会排除特定名称的文件。
问题是.....你是否更感兴趣包括某些文件......或.....不包括某些文件。
不时需要两种“技巧”。
<ItemGroup>
<MyExcludeFiles Include="$(WorkingDir)\**\SuperSecretStuff.txt" />
<MyExcludeFiles Include="$(WorkingDir)\**\SuperSecretStuff.doc" />
</ItemGroup>
<ItemGroup>
<MyIncludeFiles Include="$(WorkingDir)\**\*.txt" Exclude="@(MyExcludeFiles)"/>
<MyIncludeFiles Include="$(WorkingDir)\**\*.doc" Exclude="@(MyExcludeFiles)"/>
</ItemGroup>
<Copy
SourceFiles="@(MyIncludeFiles)"
DestinationFiles="@(MyIncludeFiles->'$(OutputDir)\%(RecursiveDir)%(Filename)%(Extension)')"
/>
答案 2 :(得分:0)
您可以稍微改变逻辑并使用{{1}}包含所有内容,然后排除您不需要的文件:
**
然后,您可以使用 <CopyFiles Condition="'$(Configuration)'=='Debug'"
Include="$(WorkingDir)\**\*.*"
Exclude="$(WorkingDir)\**\.svn\**" />
<CopyFiles Condition="'$(Configuration)'=='Release'"
Include="$(WorkingDir)\**\*.*"
Exclude="$(WorkingDir)\**\.svn\**;$(WorkingDir)\app\css\*.*;$(WorkingDir)\app\js\*.*;$(WorkingDir)\steal\README.md;$(WorkingDir)\steal\build\*.*" />
属性。