2017-06-06 11:22:23 -07:00
|
|
|
// Copyright (c) .NET Foundation. All rights reserved.
|
2015-09-25 14:33:45 -07:00
|
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
|
|
2025-11-20 21:13:26 +10:30
|
|
|
#nullable disable
|
|
|
|
|
|
2015-09-25 14:33:45 -07:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using NuGet.Frameworks;
|
|
|
|
|
using NuGet.ProjectManagement;
|
2015-12-07 17:40:52 -08:00
|
|
|
using NuGet.Test.Utility;
|
2015-09-25 14:33:45 -07:00
|
|
|
|
|
|
|
|
namespace Test.Utility
|
|
|
|
|
{
|
2017-05-26 17:50:49 -07:00
|
|
|
public class TestMSBuildNuGetProjectSystem : IMSBuildProjectSystem
|
2015-09-25 14:33:45 -07:00
|
|
|
{
|
|
|
|
|
private const string TestProjectName = "TestProjectName";
|
2016-09-21 14:22:44 -07:00
|
|
|
|
2015-09-25 14:33:45 -07:00
|
|
|
public Dictionary<string, string> References { get; }
|
|
|
|
|
public HashSet<string> FrameworkReferences { get; }
|
|
|
|
|
public HashSet<string> Files { get; }
|
2025-08-15 03:29:41 +10:00
|
|
|
private HashSet<string> _filesInProcessing;
|
2015-09-25 14:33:45 -07:00
|
|
|
public HashSet<string> ProcessedFiles { get; private set; }
|
|
|
|
|
public HashSet<string> Imports { get; }
|
|
|
|
|
public int BindingRedirectsCallCount { get; private set; }
|
2017-05-26 17:50:49 -07:00
|
|
|
public INuGetProjectContext NuGetProjectContext { get; set; }
|
2016-09-27 09:29:31 -07:00
|
|
|
public int BatchCount { get; private set; }
|
|
|
|
|
public Action<string> AddReferenceAction { get; set; }
|
|
|
|
|
public Action<string> RemoveReferenceAction { get; set; }
|
2019-07-11 16:35:37 -07:00
|
|
|
private Dictionary<string, dynamic> KnownProperties { get; }
|
2015-09-25 14:33:45 -07:00
|
|
|
|
2016-09-21 14:22:44 -07:00
|
|
|
public TestMSBuildNuGetProjectSystem(
|
|
|
|
|
NuGetFramework targetFramework,
|
|
|
|
|
INuGetProjectContext nuGetProjectContext,
|
|
|
|
|
string projectFullPath = null,
|
|
|
|
|
string projectName = null,
|
|
|
|
|
string projectFileFullPath = null)
|
2015-09-25 14:33:45 -07:00
|
|
|
{
|
|
|
|
|
TargetFramework = targetFramework;
|
|
|
|
|
References = new Dictionary<string, string>();
|
|
|
|
|
FrameworkReferences = new HashSet<string>();
|
|
|
|
|
Files = new HashSet<string>();
|
|
|
|
|
Imports = new HashSet<string>();
|
|
|
|
|
NuGetProjectContext = nuGetProjectContext;
|
|
|
|
|
ProjectFullPath = string.IsNullOrEmpty(projectFullPath) ? Environment.CurrentDirectory : projectFullPath;
|
|
|
|
|
ProcessedFiles = new HashSet<string>();
|
|
|
|
|
ProjectName = projectName ?? TestProjectName;
|
2016-09-21 14:22:44 -07:00
|
|
|
ProjectFileFullPath = projectFileFullPath ?? Path.Combine(ProjectFullPath, ProjectName);
|
2016-09-27 09:29:31 -07:00
|
|
|
AddReferenceAction = AddReferenceImplementation;
|
|
|
|
|
RemoveReferenceAction = RemoveReferenceImplementation;
|
2019-07-11 16:35:37 -07:00
|
|
|
KnownProperties = new Dictionary<string, dynamic>()
|
|
|
|
|
{
|
|
|
|
|
{ "NuGetLockFilePath", null },
|
|
|
|
|
{ "RestorePackagesWithLockFile", "false" }
|
|
|
|
|
};
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddFile(string path, Stream stream)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(path)
|
|
|
|
|
|| string.IsNullOrEmpty(Path.GetFileName(path)))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using (var streamReader = new StreamReader(stream))
|
|
|
|
|
{
|
|
|
|
|
Files.Add(path);
|
|
|
|
|
var fullPath = Path.Combine(ProjectFullPath, path);
|
|
|
|
|
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
|
|
|
|
|
File.WriteAllText(fullPath, streamReader.ReadToEnd());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 17:50:49 -07:00
|
|
|
public Task AddFrameworkReferenceAsync(string name, string packageId)
|
2015-09-25 14:33:45 -07:00
|
|
|
{
|
|
|
|
|
if (FrameworkReferences.Contains(name))
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Cannot add existing reference. That would be a COMException in VS");
|
|
|
|
|
}
|
|
|
|
|
FrameworkReferences.Add(name);
|
2017-05-26 17:50:49 -07:00
|
|
|
return Task.CompletedTask;
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddImport(string targetFullPath, ImportLocation location)
|
|
|
|
|
{
|
|
|
|
|
Imports.Add(targetFullPath);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 17:50:49 -07:00
|
|
|
public Task AddReferenceAsync(string referencePath)
|
2015-09-25 14:33:45 -07:00
|
|
|
{
|
2016-09-27 09:29:31 -07:00
|
|
|
AddReferenceAction(referencePath);
|
2017-05-26 17:50:49 -07:00
|
|
|
return Task.CompletedTask;
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveFile(string path)
|
|
|
|
|
{
|
|
|
|
|
Files.Remove(path);
|
|
|
|
|
var fullPath = Path.Combine(ProjectFullPath, path);
|
|
|
|
|
if (File.Exists(fullPath))
|
|
|
|
|
{
|
|
|
|
|
File.Delete(fullPath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string ProjectFullPath { get; }
|
|
|
|
|
|
2016-09-21 14:22:44 -07:00
|
|
|
public string ProjectFileFullPath { get; }
|
|
|
|
|
|
2015-09-25 14:33:45 -07:00
|
|
|
public string ProjectName { get; }
|
|
|
|
|
|
|
|
|
|
public string ProjectUniqueName
|
|
|
|
|
{
|
|
|
|
|
get { return ProjectName; }
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 17:50:49 -07:00
|
|
|
public Task<bool> ReferenceExistsAsync(string name)
|
2015-09-25 14:33:45 -07:00
|
|
|
{
|
2017-05-26 17:50:49 -07:00
|
|
|
return Task.FromResult(References.ContainsKey(name) || FrameworkReferences.Contains(name));
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RemoveImport(string targetFullPath)
|
|
|
|
|
{
|
|
|
|
|
Imports.Remove(targetFullPath);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 17:50:49 -07:00
|
|
|
public Task RemoveReferenceAsync(string name)
|
2015-09-25 14:33:45 -07:00
|
|
|
{
|
2016-09-27 09:29:31 -07:00
|
|
|
RemoveReferenceAction(name);
|
2017-05-26 17:50:49 -07:00
|
|
|
return Task.CompletedTask;
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public NuGetFramework TargetFramework { get; }
|
|
|
|
|
|
|
|
|
|
public bool FileExistsInProject(string path)
|
|
|
|
|
{
|
2022-10-26 12:09:46 -04:00
|
|
|
return Files.Any(c => path.Equals(c, StringComparison.OrdinalIgnoreCase));
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
2019-07-11 16:35:37 -07:00
|
|
|
public void SetPropertyValue(string propertyName, dynamic value)
|
|
|
|
|
{
|
|
|
|
|
KnownProperties[propertyName] = value;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-25 14:33:45 -07:00
|
|
|
public dynamic GetPropertyValue(string propertyName)
|
|
|
|
|
{
|
2019-07-11 16:35:37 -07:00
|
|
|
if (KnownProperties.TryGetValue(propertyName, out var value))
|
|
|
|
|
{
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Real builds have lots of properties added by the project file and maybe the build system. Returning null here to
|
|
|
|
|
// signal an undefined property might not match real-world results of this method, so throw an exception so tests
|
|
|
|
|
// can't accidently rely on test-only behaviour.
|
2015-09-25 14:33:45 -07:00
|
|
|
throw new NotImplementedException();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string ResolvePath(string path)
|
|
|
|
|
{
|
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool IsSupportedFile(string path)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddExistingFile(string path)
|
|
|
|
|
{
|
|
|
|
|
Files.Add(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void AddBindingRedirects()
|
|
|
|
|
{
|
|
|
|
|
BindingRedirectsCallCount++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-06 11:22:23 -07:00
|
|
|
public Task BeginProcessingAsync()
|
2015-09-25 14:33:45 -07:00
|
|
|
{
|
2023-06-22 06:00:26 +10:00
|
|
|
return Task.CompletedTask;
|
2015-10-13 14:39:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RegisterProcessedFiles(IEnumerable<string> files)
|
|
|
|
|
{
|
2025-08-15 03:29:41 +10:00
|
|
|
if (_filesInProcessing == null)
|
2015-10-13 14:39:57 -07:00
|
|
|
{
|
2025-08-15 03:29:41 +10:00
|
|
|
_filesInProcessing = new HashSet<string>(files);
|
2015-10-13 14:39:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var file in files)
|
|
|
|
|
{
|
2025-08-15 03:29:41 +10:00
|
|
|
_filesInProcessing.Add(file);
|
2015-10-13 14:39:57 -07:00
|
|
|
}
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
2017-06-06 11:22:23 -07:00
|
|
|
public Task EndProcessingAsync()
|
2015-09-25 14:33:45 -07:00
|
|
|
{
|
2016-09-27 09:29:31 -07:00
|
|
|
++BatchCount;
|
2025-08-15 03:29:41 +10:00
|
|
|
ProcessedFiles = _filesInProcessing;
|
|
|
|
|
_filesInProcessing = null;
|
2017-06-06 11:22:23 -07:00
|
|
|
|
2023-06-22 06:00:26 +10:00
|
|
|
return Task.CompletedTask;
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void DeleteDirectory(string path, bool recursive)
|
|
|
|
|
{
|
2015-10-20 17:16:51 -07:00
|
|
|
var fullPath = Path.Combine(ProjectFullPath, path);
|
2015-12-07 17:40:52 -08:00
|
|
|
|
|
|
|
|
// this will delete recursive regadless of input, doesn't matter for testing
|
|
|
|
|
TestFileSystemUtility.DeleteRandomTestFolder(fullPath);
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<string> GetFiles(string path, string filter, bool recursive)
|
|
|
|
|
{
|
|
|
|
|
return Files.Where(f => f.StartsWith(path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<string> GetFullPaths(string fileName)
|
|
|
|
|
{
|
|
|
|
|
return Files.Where(f => f.Equals(fileName, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
.Select(f => Path.Combine(ProjectFullPath, f));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IEnumerable<string> GetDirectories(string path)
|
|
|
|
|
{
|
|
|
|
|
return GetFiles(path, "*.*", recursive: true);
|
|
|
|
|
}
|
2016-09-27 09:29:31 -07:00
|
|
|
|
|
|
|
|
private void AddReferenceImplementation(string referencePath)
|
|
|
|
|
{
|
|
|
|
|
var referenceAssemblyName = Path.GetFileName(referencePath);
|
|
|
|
|
if (References.ContainsKey(referenceAssemblyName))
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Cannot add existing reference. That would be a COMException in VS");
|
|
|
|
|
}
|
|
|
|
|
References.Add(referenceAssemblyName, referencePath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RemoveReferenceImplementation(string name)
|
|
|
|
|
{
|
|
|
|
|
if (References.ContainsKey(name))
|
|
|
|
|
{
|
|
|
|
|
References.Remove(name);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-09-25 14:33:45 -07:00
|
|
|
}
|
|
|
|
|
}
|