Search code examples
regexlinuxmsbuildmonoxbuild

xbuild with [System.Text.RegularExpressions.Regex]::Match(string,string) parameters doesn't work properly (MSBuild is fine)


I have a target that reads a .proj file with ReadLinesFromFile and then try to match a version number (e.g. 1.0.23) from the contained lines like:

<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>

The result is always empty.. Even if I try to do a simple Match($(In), "somestring") its not working correctly in linux/xbuild. This does work on windows/msbuild

Any tricks/ideas? An alternative would be to get the property version out of the first .proj file, instead of reading all lines and matching the number with a regex, but I don't even know if that is possible.

I am running versions:

XBuild Engine Version 12.0
Mono, Version 4.2.1.0

EDIT: I've been able to trace it further down into the parameters that go into Match(), there is something wrong with the variables evaluation. The function actually works with for example Match("foobar","bar") I will get bar

But weird things happen with other inputs, e.g. Match($(In), "Get") will match Get because it is actually matching against the string "@(GetStuffLines)"

When I do Match($(In), "@..") I will get a match of @(G

But then, when I do Match($(In), "@.*") I actually get the entire content of the input file GetStuff.Data.proj which indicates that the variable was correctly expanded somewhere and the matching matched the entire input string.


Solution

  • I needed to circumvent Match() because it seems to be bugged at this point. The ugly solution I came up with was to use Exec and grep the pattern like:

     <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>
    

    I couldn't even use the properties ConsoleToMSBuild and ConsoleOutput (https://msdn.microsoft.com/en-us/library/ms124731%28v=VS.110%29.aspx) because xbuild didn't recognize those.. That's why I grep the pattern and save it into a temp file which can be read with ReadLinesFromFile into the ItemName="GetExtractedRevisionNumber" that I use later.