dotnet-installer/src/dotnet/ProjectGlobbingResolver.cs
Andrew Stanton-Nurse ef0ca39da1 Memory usage improvements in build (#2626)
* Use a WorkspaceContext in dotnet-build to cache project data across
multiple compilations in a single build action
* Dramatically reduce string and object duplication by introducing a
"Symbol Table" that shares instances of NuGetVersion, NuGetFramework,
VersionRange and string across multiple lock-file parses

Test Results:
* Testing was done by compiling Microsoft.AspNetCore.Mvc (and it's
dependencies) and taking memory snapshots after each compilation in
dotMemory
* We used to allocate ~3MB and deallocate ~2.5MB on EACH compilation in
a single build action. This has been reduced to ~120KB
allocated/deallocated
* After introducing WorkspaceContext, total memory usage spiked from 6MB
across the whole build action to about 13MB, introducing the symbol
table dropped it back to about 5-6MB.
2016-04-22 15:01:56 -07:00

70 lines
No EOL
2.5 KiB
C#

// 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;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
using Microsoft.DotNet.ProjectModel;
namespace Microsoft.DotNet.Tools.Compiler
{
internal class ProjectGlobbingResolver
{
internal IEnumerable<string> Resolve(IEnumerable<string> values)
{
var currentDirectory = Directory.GetCurrentDirectory();
if (!values.Any())
{
var fileName = Path.Combine(currentDirectory, Project.FileName);
if (!File.Exists(fileName))
{
throw new InvalidOperationException($"Couldn't find '{Project.FileName}' in current directory");
}
yield return fileName;
yield break;
}
foreach (var value in values)
{
var fileName = Path.Combine(currentDirectory, value);
if (File.Exists(fileName))
{
yield return value;
continue;
}
fileName = Path.Combine(currentDirectory, value, Project.FileName);
if (File.Exists(fileName))
{
yield return fileName;
continue;
}
var matcher = new Matcher();
matcher.AddInclude(value);
var result = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(currentDirectory)));
if (result.Files.Any())
{
foreach (var filePatternMatch in result.Files)
{
yield return filePatternMatch.Path;
}
}
else if (value.Contains("*"))
{
throw new InvalidOperationException($"Globbing pattern '{value}' did not match any files");
}
else if (value.EndsWith(Project.FileName))
{
throw new InvalidOperationException($"Could not find project file '{value}'");
}
else
{
throw new InvalidOperationException($"Couldn't find '{Project.FileName}' in '{value}'");
}
}
}
}
}