これは非常に奇妙です。私たちはしばらくそれを理解しようとしてきましたが、実際には意味がありません。
この Web プロジェクトは、次のようなターゲットを持つターゲット ファイルをインポートします。
<Target Name="CSSCheckInternal">
<ItemGroup>
<CSSFiles Include="$(MSBuildProjectDirectory)\**\*.css" />
</ItemGroup>
<CSSChecker Files="@(CSSFiles)" />
</Target>
現時点では、1 つのブランチが完全に構築されており、必要に応じてタスクを実行しています。しかし、他のブランチは上記のターゲットで失敗しています。
失敗は、@(CSSFiles)
アイテムがタスクによって受信されたときに、ITaskItem
配列に展開されていないように見えるためです。
タスクは次のように記述されます (FullPath メタデータを取得するところまで):
public class CSSChecker : Task
{
[Required]
public ITaskItem[] Files
{
get;
set;
}
public override bool Execute()
{
string fullFilePath = null;
if (Files != null)
{
foreach (var item in Files)
{
fullFilePath = item.GetMetadata("FullPath");
if(!File.Exists(fullFilePath))
throw new InvalidOperationException(
string.Format("{0} does not exist", fullFilePath));
//rest of the code elided
失敗しているビルドは、次のInvalidOperationException
ように最後の行にスローされます。
ファイルが存在しません: C:\Code\Project\**\*.css
したがって、MSBuild は、Include
属性でワイルドカードを展開する代わりに、単に文字列を渡しているように見えるためITaskItem
、タスクには 1 つしか作成されません。
ターゲット フォルダーはディスク上に存在し、破損したプロジェクト ファイルと動作中のプロジェクト ファイルの唯一の違いは、プロジェクト ファイルのかなり前に含まれる単一のファイルです。
アップデート
私は Twitter で Sayed Hashimi に尋ねました( MSBuild の本を書きました)。それを通じて、フォルダーのワイルドカードを取り出してみたところ、**
今では機能し始めています。タスクはプロジェクト間で再利用できるようになっているため、これはあまり適していません。しかし、それはこれと関係があるように見えます。
更新終了
MSBuild がワイルドカードを正しく展開しない状況を誰かが知っていれば、それは大きな助けになるでしょう!