带有 [System.Text.RegularExpressions.Regex]::Match(string,string) 参数的 xbuild 无法正常工作(MSBuild 很好)
xbuild with [System.Text.RegularExpressions.Regex]::Match(string,string) parameters doesn't work properly (MSBuild is fine)
我有一个目标,它使用 ReadLinesFromFile 读取 .proj 文件,然后尝试从包含的行中匹配版本号(例如 1.0.23),例如:
<Target Name="GetRevision">
<ReadLinesFromFile File="$(MyDir)GetStuff.Data.proj">
<Output TaskParameter="Lines" ItemName="GetStuffLines" />
</ReadLinesFromFile>
<PropertyGroup>
<In>@(GetStuffLines)</In>
<Out>$([System.Text.RegularExpressions.Regex]::Match($(In), "(\d+)\.(\d+)\.(\d+)"))</Out>
</PropertyGroup>
<Message Text="Revision number [$(Out)]" />
<CreateProperty Value="$(Out)">
<Output TaskParameter="Value" PropertyName="RevisionNumber" />
</CreateProperty>
</Target>
结果总是空的。即使我尝试做一个简单的 Match($(In), "somestring") 它在 linux/xbuild 中也不能正常工作。 在 windows/msbuild
上有效
有tricks/ideas吗?另一种方法是从第一个 .proj 文件中获取 属性 版本,而不是读取所有行并将数字与正则表达式匹配,但我什至不知道这是否可能。
我是运行版本:
XBuild Engine Version 12.0
Mono, Version 4.2.1.0
编辑:
我已经能够进一步追踪到进入 Match() 的参数,变量评估有问题。该函数实际上适用于 Match("foobar","bar")
我会得到 bar
但是其他输入会发生奇怪的事情,例如Match($(In), "Get")
将匹配 Get
因为它实际上匹配字符串“@(GetStuffLines)”
当我执行 Match($(In), "@..")
时,我将得到 @(G
的匹配项
但是,当我这样做时 Match($(In), "@.*")
我实际上得到了输入文件的全部内容 GetStuff.Data.proj
这表明变量在某处被正确扩展并且匹配匹配整个输入字符串。
我需要绕过 Match() 因为此时它似乎被窃听了。
我想出的丑陋的解决方案是使用 Exec 和 grep 模式,如:
<Exec Command="grep -o -P '[0-9]+[.][0-9]+[.][0-9]+' $(MyDir)GetStuff.Data.proj > extractedRevisionNumber.tmp" Condition="$(OSTYPE.Contains('linux'))"/>
<ReadLinesFromFile File="$(ComponentRootDir)extractedRevisionNumber.tmp" Condition="$(OSTYPE.Contains('linux'))">
<Output TaskParameter="Lines" ItemName="GetExtractedRevisionNumber" />
</ReadLinesFromFile>
我什至无法使用属性 ConsoleToMSBuild
和 ConsoleOutput
(https://msdn.microsoft.com/en-us/library/ms124731%28v=VS.110%29.aspx),因为 xbuild 无法识别这些属性。这就是为什么我 grep 模式并将其保存到一个临时文件,可以用 ReadLinesFromFile
读取到我稍后使用的 ItemName="GetExtractedRevisionNumber"
中。
我有一个目标,它使用 ReadLinesFromFile 读取 .proj 文件,然后尝试从包含的行中匹配版本号(例如 1.0.23),例如:
<Target Name="GetRevision">
<ReadLinesFromFile File="$(MyDir)GetStuff.Data.proj">
<Output TaskParameter="Lines" ItemName="GetStuffLines" />
</ReadLinesFromFile>
<PropertyGroup>
<In>@(GetStuffLines)</In>
<Out>$([System.Text.RegularExpressions.Regex]::Match($(In), "(\d+)\.(\d+)\.(\d+)"))</Out>
</PropertyGroup>
<Message Text="Revision number [$(Out)]" />
<CreateProperty Value="$(Out)">
<Output TaskParameter="Value" PropertyName="RevisionNumber" />
</CreateProperty>
</Target>
结果总是空的。即使我尝试做一个简单的 Match($(In), "somestring") 它在 linux/xbuild 中也不能正常工作。 在 windows/msbuild
上有效有tricks/ideas吗?另一种方法是从第一个 .proj 文件中获取 属性 版本,而不是读取所有行并将数字与正则表达式匹配,但我什至不知道这是否可能。
我是运行版本:
XBuild Engine Version 12.0
Mono, Version 4.2.1.0
编辑:
我已经能够进一步追踪到进入 Match() 的参数,变量评估有问题。该函数实际上适用于 Match("foobar","bar")
我会得到 bar
但是其他输入会发生奇怪的事情,例如Match($(In), "Get")
将匹配 Get
因为它实际上匹配字符串“@(GetStuffLines)”
当我执行 Match($(In), "@..")
时,我将得到 @(G
但是,当我这样做时 Match($(In), "@.*")
我实际上得到了输入文件的全部内容 GetStuff.Data.proj
这表明变量在某处被正确扩展并且匹配匹配整个输入字符串。
我需要绕过 Match() 因为此时它似乎被窃听了。 我想出的丑陋的解决方案是使用 Exec 和 grep 模式,如:
<Exec Command="grep -o -P '[0-9]+[.][0-9]+[.][0-9]+' $(MyDir)GetStuff.Data.proj > extractedRevisionNumber.tmp" Condition="$(OSTYPE.Contains('linux'))"/>
<ReadLinesFromFile File="$(ComponentRootDir)extractedRevisionNumber.tmp" Condition="$(OSTYPE.Contains('linux'))">
<Output TaskParameter="Lines" ItemName="GetExtractedRevisionNumber" />
</ReadLinesFromFile>
我什至无法使用属性 ConsoleToMSBuild
和 ConsoleOutput
(https://msdn.microsoft.com/en-us/library/ms124731%28v=VS.110%29.aspx),因为 xbuild 无法识别这些属性。这就是为什么我 grep 模式并将其保存到一个临时文件,可以用 ReadLinesFromFile
读取到我稍后使用的 ItemName="GetExtractedRevisionNumber"
中。