2016-07-15 15:31:50 +00:00
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System ;
2016-06-29 23:21:46 +00:00
using System.IO ;
2018-04-05 03:57:45 +00:00
using System.Linq ;
2017-06-08 22:51:27 +00:00
using System.Text.RegularExpressions ;
2016-06-29 23:21:46 +00:00
using Microsoft.Build.Utilities ;
using Microsoft.Build.Framework ;
namespace Microsoft.DotNet.Cli.Build
{
/// <summary>
2017-02-23 21:24:21 +00:00
/// Reads contents of an input file, and searches for each replacement passed in.
///
/// When ReplacementItems is matched, it will replace the Include/ItemSpec with the corresponding
/// ReplacementString metadata value. This can be useful if the ReplacementString is a value that
/// cannot be represented by ITaskItem.ItemSpec (like string.Empty).
///
2016-06-29 23:21:46 +00:00
/// When a ReplacementPattern is matched it will replace it with the string of the corresponding (by index)
/// item in ReplacementStrings.
///
/// For example, if 2 ReplacementPatterns are passed in, 2 ReplacementStrings must also passed in and the first
/// pattern will be replaced with the first string, and the second pattern replaced with the second string.
///
/// ReplacementPattern could easily be a regex, but it isn't needed for current use cases, so leaving this
/// as just a string that will be replaced.
/// </summary>
public class ReplaceFileContents : Task
{
[Required]
2018-04-05 03:57:45 +00:00
public ITaskItem [ ] InputFiles { get ; set ; }
2016-06-29 23:21:46 +00:00
[Required]
2018-04-05 03:57:45 +00:00
public ITaskItem [ ] DestinationFiles { get ; set ; }
2016-06-29 23:21:46 +00:00
2017-02-23 21:24:21 +00:00
public ITaskItem [ ] ReplacementItems { get ; set ; }
2016-06-29 23:21:46 +00:00
public ITaskItem [ ] ReplacementPatterns { get ; set ; }
public ITaskItem [ ] ReplacementStrings { get ; set ; }
public override bool Execute ( )
{
2017-02-23 21:24:21 +00:00
if ( ReplacementItems = = null & & ReplacementPatterns = = null & & ReplacementStrings = = null )
{
throw new Exception ( $"ReplaceFileContents was called with no replacement values. Either pass ReplacementItems or ReplacementPatterns/ReplacementStrings properties." ) ;
}
ReplacementItems = ReplacementItems ? ? Array . Empty < ITaskItem > ( ) ;
ReplacementPatterns = ReplacementPatterns ? ? Array . Empty < ITaskItem > ( ) ;
ReplacementStrings = ReplacementStrings ? ? Array . Empty < ITaskItem > ( ) ;
2016-06-29 23:21:46 +00:00
if ( ReplacementPatterns . Length ! = ReplacementStrings . Length )
{
throw new Exception ( $"Expected {nameof(ReplacementPatterns)} (length {ReplacementPatterns.Length}) and {nameof(ReplacementStrings)} (length {ReplacementStrings.Length}) to have the same length." ) ;
}
2018-04-05 03:57:45 +00:00
if ( InputFiles . Length ! = DestinationFiles . Length )
2016-06-29 23:21:46 +00:00
{
2018-04-05 03:57:45 +00:00
throw new Exception ( $"Expected {nameof(InputFiles)} (length {InputFiles.Length}) and {nameof(DestinationFiles)} (length {DestinationFiles.Length}) to have the same length." ) ;
2016-06-29 23:21:46 +00:00
}
2018-04-05 03:57:45 +00:00
var filesNotFound = InputFiles . Where ( i = > ! File . Exists ( i . ItemSpec ) ) . Select ( i = > i . ItemSpec ) ;
if ( filesNotFound . Any ( ) )
{
var filesNotFoundString = string . Join ( "," , filesNotFound ) ;
throw new FileNotFoundException ( $"Expected files where not found: {filesNotFoundString}" ) ;
}
2016-06-29 23:21:46 +00:00
2018-04-05 03:57:45 +00:00
Log . LogMessage ( MessageImportance . High , $"ReplacingContents for `{InputFiles.Length}` files." ) ;
for ( var i = 0 ; i < InputFiles . Length ; i + + )
{
ReplaceContents ( InputFiles [ i ] . ItemSpec , DestinationFiles [ i ] . ItemSpec ) ;
}
2016-06-29 23:21:46 +00:00
return true ;
}
2018-04-05 03:57:45 +00:00
public void ReplaceContents ( string inputFile , string destinationFile )
{
string inputFileText = File . ReadAllText ( inputFile ) ;
string outputFileText = ReplacePatterns ( inputFileText ) ;
WriteOutputFile ( destinationFile , outputFileText ) ;
}
2016-06-29 23:21:46 +00:00
public string ReplacePatterns ( string inputFileText )
{
var outText = inputFileText ;
2017-02-23 21:24:21 +00:00
foreach ( var replacementItem in ReplacementItems )
{
var replacementPattern = replacementItem . ItemSpec ;
var replacementString = replacementItem . GetMetadata ( "ReplacementString" ) ;
outText = outText . Replace ( replacementPattern , replacementString ) ;
}
2016-06-29 23:21:46 +00:00
for ( int i = 0 ; i < ReplacementPatterns . Length ; + + i )
{
var replacementPattern = ReplacementPatterns [ i ] . ItemSpec ;
var replacementString = ReplacementStrings [ i ] . ItemSpec ;
2017-06-08 22:51:27 +00:00
var regex = new Regex ( replacementPattern ) ;
outText = regex . Replace ( outText , replacementString ) ;
2016-06-29 23:21:46 +00:00
}
return outText ;
}
2018-04-05 03:57:45 +00:00
public void WriteOutputFile ( string destinationFile , string outputFileText )
2016-06-29 23:21:46 +00:00
{
2018-04-05 03:57:45 +00:00
var destinationDirectory = Path . GetDirectoryName ( destinationFile ) ;
Log . LogMessage ( MessageImportance . High , $"Destination Directory: {destinationDirectory}" ) ;
2016-06-29 23:21:46 +00:00
if ( ! Directory . Exists ( destinationDirectory ) )
{
2018-04-05 03:57:45 +00:00
Log . LogMessage ( MessageImportance . High , $"Destination Directory `{destinationDirectory}` does not exist. Creating..." ) ;
2016-06-29 23:21:46 +00:00
Directory . CreateDirectory ( destinationDirectory ) ;
}
2018-04-05 03:57:45 +00:00
Log . LogMessage ( MessageImportance . High , $"Writing file: {destinationFile}" ) ;
File . WriteAllText ( destinationFile , outputFileText ) ;
2016-06-29 23:21:46 +00:00
}
}
}