2015-11-16 11:21:57 -08: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.
2015-10-13 14:31:29 -07:00
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
2015-10-15 15:09:37 -07:00
using Microsoft.Extensions.JsonParser.Sources ;
2015-10-13 14:31:29 -07:00
2015-10-17 08:55:06 -07:00
namespace Microsoft.Extensions.ProjectModel.Files
2015-10-13 14:31:29 -07:00
{
internal static class PatternsCollectionHelper
{
private static readonly char [ ] PatternSeparator = new [ ] { ';' } ;
2015-10-15 15:09:37 -07:00
public static IEnumerable < string > GetPatternsCollection ( JsonObject rawProject ,
2015-10-13 14:31:29 -07:00
string projectDirectory ,
string projectFilePath ,
string propertyName ,
IEnumerable < string > defaultPatterns = null ,
bool literalPath = false )
{
defaultPatterns = defaultPatterns ? ? Enumerable . Empty < string > ( ) ;
try
{
2015-10-15 15:09:37 -07:00
if ( ! rawProject . Keys . Contains ( propertyName ) )
{
return CreateCollection ( projectDirectory , propertyName , defaultPatterns , literalPath ) ;
}
var valueInString = rawProject . ValueAsString ( propertyName ) ;
2015-10-13 14:31:29 -07:00
if ( valueInString ! = null )
{
return CreateCollection ( projectDirectory , propertyName , new string [ ] { valueInString } , literalPath ) ;
}
2015-10-15 15:09:37 -07:00
var valuesInArray = rawProject . ValueAsStringArray ( propertyName ) ;
2015-10-13 14:31:29 -07:00
if ( valuesInArray ! = null )
{
return CreateCollection ( projectDirectory , propertyName , valuesInArray . Select ( s = > s . ToString ( ) ) , literalPath ) ;
}
}
catch ( Exception ex )
{
2015-10-15 15:09:37 -07:00
throw FileFormatException . Create ( ex , rawProject . Value ( propertyName ) , projectFilePath ) ;
2015-10-13 14:31:29 -07:00
}
2015-10-15 15:09:37 -07:00
throw FileFormatException . Create ( "Value must be either string or array." , rawProject . Value ( propertyName ) , projectFilePath ) ;
2015-10-13 14:31:29 -07:00
}
private static IEnumerable < string > CreateCollection ( string projectDirectory , string propertyName , IEnumerable < string > patternsStrings , bool literalPath )
{
var patterns = patternsStrings . SelectMany ( patternsString = > GetSourcesSplit ( patternsString ) )
. Select ( patternString = > patternString . Replace ( '/' , Path . DirectorySeparatorChar ) . Replace ( '\\' , Path . DirectorySeparatorChar ) ) ;
foreach ( var pattern in patterns )
{
if ( Path . IsPathRooted ( pattern ) )
{
throw new InvalidOperationException ( $"The '{propertyName}' property cannot be a rooted path." ) ;
}
if ( literalPath & & pattern . Contains ( '*' ) )
{
throw new InvalidOperationException ( $"The '{propertyName}' property cannot contain wildcard characters." ) ;
}
}
return new List < string > ( patterns . Select ( pattern = > FolderToPattern ( pattern , projectDirectory ) ) ) ;
}
private static IEnumerable < string > GetSourcesSplit ( string sourceDescription )
{
if ( string . IsNullOrEmpty ( sourceDescription ) )
{
return Enumerable . Empty < string > ( ) ;
}
return sourceDescription . Split ( PatternSeparator , StringSplitOptions . RemoveEmptyEntries ) ;
}
private static string FolderToPattern ( string candidate , string projectDir )
{
// This conversion is needed to support current template
// If it's already a pattern, no change is needed
if ( candidate . Contains ( '*' ) )
{
return candidate ;
}
// If the given string ends with a path separator, or it is an existing directory
// we convert this folder name to a pattern matching all files in the folder
if ( candidate . EndsWith ( @"\" ) | |
candidate . EndsWith ( "/" ) | |
Directory . Exists ( Path . Combine ( projectDir , candidate ) ) )
{
return Path . Combine ( candidate , "**" , "*" ) ;
}
// Otherwise, it represents a single file
return candidate ;
}
}
}