Search code examples
visual-studiomsbuildpublishingslowcheetah

Replacing with values read from file or generated from code?


In SlowCheetah, I would like to transform some elements of my config file not with hard-coded values in a transform file, but either with the contents of another file or (preferably) a value generated from code. For example, in the case of generating a value from code, instead of this:

{
    "someSettings": {
        "@jdt.replace": {
            "timeTokenAtBuild": "1f3ac2"
        }
    }
}

... I want something like this:

{
    "someSettings": {
        "@jdt.replace": {
            "timeTokenAtBuild": [MyUtilitiesLibrary.GetCurrentTimeToken()]
        }
    }
}

Getting the value from something like a PowerShell script would be fine too. Can I do this with SlowCheetah currently? If not how hard would it be to extend it to allow this functionality?

Alternatively, is there some other NuGet package or msbuild mechanism I can use to achieve this behaviour?


Solution

  • Replacing with values read from file or generated from code?

    Not know about SlowCheetah. But for MSBuild, you can define a custom replace task to do that:

    <UsingTask TaskName="ReplaceFileText" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
      <ParameterGroup>
        <InputFilename ParameterType="System.String" Required="true" />
        <OutputFilename ParameterType="System.String" Required="true" />
        <MatchExpression ParameterType="System.String" Required="true" />
        <ReplacementText ParameterType="System.String" Required="true" />
      </ParameterGroup>
      <Task>
        <Reference Include="System.Core" />
        <Using Namespace="System" />
        <Using Namespace="System.IO" />
        <Using Namespace="System.Text.RegularExpressions" />
        <Code Type="Fragment" Language="cs">
          <![CDATA[
                File.WriteAllText(
                    OutputFilename,
                    Regex.Replace(File.ReadAllText(InputFilename), MatchExpression, ReplacementText)
                    );
              ]]>
        </Code>
      </Task>
    </UsingTask>
    

    Then you can use this task to replace elements of config file:

    <Target Name="BeforeBuild">
      <ReplaceFileText 
        InputFilename="$(YouConfigFilePath)YourConfigFile.config" 
        OutputFilename="$(YouConfigFilePath)YourConfigFile.config" 
        MatchExpression="1f3ac2" 
        ReplacementText="$(Value)" />
    </Target>
    

    Note, since the replace value is generated from code, you may need use PowerShell script or other scripts to set value for msbuild property:

    How to set value for msbuild property using powershell?

    Hope this helps.