Global tools package obtain (#8035)
Add ExeutablePackageObtainer Given a tools package id, it can create a fake project and restore to correct folder - DI, aka no circular dependency of commands - Parser of config XML - I try to create test nupkg at build time, so I can run test and debug easily with VSCode. The code is in test csproj.
This commit is contained in:
parent
2fc86b6d01
commit
584d3f0502
32 changed files with 1169 additions and 29 deletions
|
@ -1,6 +1,6 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.0
|
||||
VisualStudioVersion = 15.0.27004.2008
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{ED2FE3E2-F7E7-4389-8231-B65123F2076F}"
|
||||
EndProject
|
||||
|
@ -230,6 +230,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.TestFramew
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Msbuild.Tests.Utilities", "test\Msbuild.Tests.Utilities\Msbuild.Tests.Utilities.csproj", "{E7C72EF2-8480-48B4-AAE8-A596F1A6048E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.ToolPackageObtainer.Tests", "test\Microsoft.DotNet.ToolPackageObtainer.Tests\Microsoft.DotNet.ToolPackageObtainer.Tests.csproj", "{F0D50831-9468-4ACB-8FD8-E9883DD553FB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -1614,6 +1616,30 @@ Global
|
|||
{E7C72EF2-8480-48B4-AAE8-A596F1A6048E}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{E7C72EF2-8480-48B4-AAE8-A596F1A6048E}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
|
||||
{E7C72EF2-8480-48B4-AAE8-A596F1A6048E}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.MinSizeRel|x64.Build.0 = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.MinSizeRel|x86.ActiveCfg = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.MinSizeRel|x86.Build.0 = Debug|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.RelWithDebInfo|x64.Build.0 = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.RelWithDebInfo|x86.ActiveCfg = Release|Any CPU
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB}.RelWithDebInfo|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -1686,6 +1712,7 @@ Global
|
|||
{B4EE3671-C103-4A37-8DEB-C74E0134104E} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
{44759218-B558-4AF0-8991-515F1100DCF5} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
{E7C72EF2-8480-48B4-AAE8-A596F1A6048E} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
{F0D50831-9468-4ACB-8FD8-E9883DD553FB} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B526D2CE-EE2D-4AD4-93EF-1867D90FF1F5}
|
||||
|
|
47
src/Microsoft.DotNet.InternalAbstractions/DirectoryPath.cs
Normal file
47
src/Microsoft.DotNet.InternalAbstractions/DirectoryPath.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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.IO;
|
||||
|
||||
namespace Microsoft.Extensions.EnvironmentAbstractions
|
||||
{
|
||||
public struct DirectoryPath
|
||||
{
|
||||
public string Value { get; }
|
||||
|
||||
public DirectoryPath(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public DirectoryPath WithSubDirectories(params string[] paths)
|
||||
{
|
||||
string[] insertValueInFront = new string[paths.Length + 1];
|
||||
insertValueInFront[0] = Value;
|
||||
Array.Copy(paths, 0, insertValueInFront, 1, paths.Length);
|
||||
|
||||
return new DirectoryPath(Path.Combine(insertValueInFront));
|
||||
}
|
||||
|
||||
public FilePath WithFile(string fileName)
|
||||
{
|
||||
return new FilePath(Path.Combine(Value, fileName));
|
||||
}
|
||||
|
||||
public string ToQuotedString()
|
||||
{
|
||||
return $"\"{Value}\"";
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToQuotedString();
|
||||
}
|
||||
|
||||
public DirectoryPath GetParentPath()
|
||||
{
|
||||
return new DirectoryPath(Directory.GetParent(Path.GetFullPath(Value)).FullName);
|
||||
}
|
||||
}
|
||||
}
|
32
src/Microsoft.DotNet.InternalAbstractions/FilePath.cs
Normal file
32
src/Microsoft.DotNet.InternalAbstractions/FilePath.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
// 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.IO;
|
||||
|
||||
namespace Microsoft.Extensions.EnvironmentAbstractions
|
||||
{
|
||||
public struct FilePath
|
||||
{
|
||||
public string Value { get; }
|
||||
|
||||
public FilePath(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string ToQuotedString()
|
||||
{
|
||||
return $"\"{Value}\"";
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToQuotedString();
|
||||
}
|
||||
|
||||
public DirectoryPath GetDirectoryPath()
|
||||
{
|
||||
return new DirectoryPath(Path.GetDirectoryName(Value));
|
||||
}
|
||||
}
|
||||
}
|
21
src/dotnet/BundledTargetFramework.cs
Normal file
21
src/dotnet/BundledTargetFramework.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.Versioning;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.Cli
|
||||
{
|
||||
internal static class BundledTargetFramework
|
||||
{
|
||||
public static string GetTargetFrameworkMoniker()
|
||||
{
|
||||
TargetFrameworkAttribute targetFrameworkAttribute = typeof(BundledTargetFramework)
|
||||
.GetTypeInfo()
|
||||
.Assembly
|
||||
.GetCustomAttribute<TargetFrameworkAttribute>();
|
||||
|
||||
return NuGetFramework
|
||||
.Parse(targetFrameworkAttribute.FrameworkName)
|
||||
.GetShortFolderName();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,3 +17,4 @@ using System.Runtime.CompilerServices;
|
|||
[assembly: InternalsVisibleTo("dotnet-sln-remove.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("dotnet-msbuild.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("dotnet-run.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.DotNet.ToolPackageObtainer.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
12
src/dotnet/ToolPackageObtainer/IPackageToProjectFileAdder.cs
Normal file
12
src/dotnet/ToolPackageObtainer/IPackageToProjectFileAdder.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// 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 Microsoft.Extensions.EnvironmentAbstractions;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal interface IPackageToProjectFileAdder
|
||||
{
|
||||
void Add(FilePath projectPath, string packageId);
|
||||
}
|
||||
}
|
15
src/dotnet/ToolPackageObtainer/IProjectRestorer.cs
Normal file
15
src/dotnet/ToolPackageObtainer/IProjectRestorer.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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 Microsoft.Extensions.EnvironmentAbstractions;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal interface IProjectRestorer
|
||||
{
|
||||
void Restore(
|
||||
FilePath projectPath,
|
||||
DirectoryPath assetJsonOutput,
|
||||
FilePath? nugetconfig);
|
||||
}
|
||||
}
|
22
src/dotnet/ToolPackageObtainer/PackageObtainException.cs
Normal file
22
src/dotnet/ToolPackageObtainer/PackageObtainException.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal class PackageObtainException : Exception
|
||||
{
|
||||
public PackageObtainException()
|
||||
{
|
||||
}
|
||||
|
||||
public PackageObtainException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PackageObtainException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
28
src/dotnet/ToolPackageObtainer/PackageVersion.cs
Normal file
28
src/dotnet/ToolPackageObtainer/PackageVersion.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// 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.IO;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal class PackageVersion
|
||||
{
|
||||
public PackageVersion(string packageVersion)
|
||||
{
|
||||
if (packageVersion == null)
|
||||
{
|
||||
Value = Path.GetRandomFileName();
|
||||
IsPlaceholder = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = packageVersion;
|
||||
IsPlaceholder = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPlaceholder { get; }
|
||||
public string Value { get; }
|
||||
public bool IsConcreteValue => !IsPlaceholder;
|
||||
}
|
||||
}
|
46
src/dotnet/ToolPackageObtainer/ToolConfiguration.cs
Normal file
46
src/dotnet/ToolPackageObtainer/ToolConfiguration.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal class ToolConfiguration
|
||||
{
|
||||
public ToolConfiguration(
|
||||
string commandName,
|
||||
string toolAssemblyEntryPoint)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(commandName))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(commandName), "Cannot be null or whitespace");
|
||||
}
|
||||
|
||||
EnsureNoInvalidFilenameCharacters(commandName, nameof(toolAssemblyEntryPoint));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(toolAssemblyEntryPoint))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(toolAssemblyEntryPoint), "Cannot be null or whitespace");
|
||||
}
|
||||
|
||||
CommandName = commandName;
|
||||
ToolAssemblyEntryPoint = toolAssemblyEntryPoint;
|
||||
}
|
||||
|
||||
private void EnsureNoInvalidFilenameCharacters(string commandName, string nameOfParam)
|
||||
{
|
||||
// https://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names
|
||||
char[] invalidCharactors = {'/', '<', '>', ':', '"', '/', '\\', '|', '?', '*'};
|
||||
if (commandName.IndexOfAny(invalidCharactors) != -1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
paramName: nameof(nameOfParam),
|
||||
message: "Cannot contain following character " + new string(invalidCharactors));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string CommandName { get; }
|
||||
public string ToolAssemblyEntryPoint { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// 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 Microsoft.Extensions.EnvironmentAbstractions;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal class ToolConfigurationAndExecutableDirectory
|
||||
{
|
||||
public ToolConfigurationAndExecutableDirectory(
|
||||
ToolConfiguration toolConfiguration,
|
||||
DirectoryPath executableDirectory)
|
||||
{
|
||||
Configuration = toolConfiguration;
|
||||
ExecutableDirectory = executableDirectory;
|
||||
}
|
||||
|
||||
public ToolConfiguration Configuration { get; }
|
||||
public DirectoryPath ExecutableDirectory { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer.ToolConfigurationDeserialization
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
[XmlRoot(Namespace = "", IsNullable = false)]
|
||||
public class DotNetCliTool
|
||||
{
|
||||
[XmlArrayItem("Command", IsNullable = false)]
|
||||
public DotNetCliToolCommand[] Commands { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer.ToolConfigurationDeserialization
|
||||
{
|
||||
[Serializable]
|
||||
[DebuggerStepThrough]
|
||||
[XmlType(AnonymousType = true)]
|
||||
public class DotNetCliToolCommand
|
||||
{
|
||||
[XmlAttribute]
|
||||
public string Name { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public string EntryPoint { get; set; }
|
||||
|
||||
[XmlAttribute]
|
||||
public string Runner { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// 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.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using Microsoft.DotNet.ToolPackageObtainer.ToolConfigurationDeserialization;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal static class ToolConfigurationDeserializer
|
||||
{
|
||||
public static ToolConfiguration Deserialize(string pathToXml)
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(DotNetCliTool));
|
||||
|
||||
DotNetCliTool dotNetCliTool;
|
||||
|
||||
using (var fs = new FileStream(pathToXml, FileMode.Open))
|
||||
{
|
||||
var reader = XmlReader.Create(fs);
|
||||
|
||||
try
|
||||
{
|
||||
dotNetCliTool = (DotNetCliTool)serializer.Deserialize(reader);
|
||||
}
|
||||
catch (InvalidOperationException e) when (e.InnerException is XmlException)
|
||||
{
|
||||
throw new ToolConfigurationException(
|
||||
"Failed to retrive tool configuration exception, configuration is malformed xml. " +
|
||||
e.InnerException.Message);
|
||||
}
|
||||
}
|
||||
|
||||
if (dotNetCliTool.Commands.Length != 1)
|
||||
{
|
||||
throw new ToolConfigurationException(
|
||||
"Failed to retrive tool configuration exception, one and only one command is supported.");
|
||||
}
|
||||
|
||||
if (dotNetCliTool.Commands[0].Runner != "dotnet")
|
||||
{
|
||||
throw new ToolConfigurationException(
|
||||
"Failed to retrive tool configuration exception, only dotnet as runner is supported.");
|
||||
}
|
||||
|
||||
var commandName = dotNetCliTool.Commands[0].Name;
|
||||
var toolAssemblyEntryPoint = dotNetCliTool.Commands[0].EntryPoint;
|
||||
|
||||
try
|
||||
{
|
||||
return new ToolConfiguration(commandName, toolAssemblyEntryPoint);
|
||||
}
|
||||
catch (ArgumentException e)
|
||||
{
|
||||
throw new ToolConfigurationException("Configuration content error. " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
src/dotnet/ToolPackageObtainer/ToolConfigurationException.cs
Normal file
14
src/dotnet/ToolPackageObtainer/ToolConfigurationException.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal class ToolConfigurationException : ArgumentException
|
||||
{
|
||||
public ToolConfigurationException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
190
src/dotnet/ToolPackageObtainer/ToolPackageObtainer.cs
Normal file
190
src/dotnet/ToolPackageObtainer/ToolPackageObtainer.cs
Normal file
|
@ -0,0 +1,190 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Extensions.EnvironmentAbstractions;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer
|
||||
{
|
||||
internal class ToolPackageObtainer
|
||||
{
|
||||
private readonly Lazy<string> _bundledTargetFrameworkMoniker;
|
||||
private readonly Func<FilePath> _getTempProjectPath;
|
||||
private readonly IPackageToProjectFileAdder _packageToProjectFileAdder;
|
||||
private readonly IProjectRestorer _projectRestorer;
|
||||
private readonly DirectoryPath _toolsPath;
|
||||
|
||||
public ToolPackageObtainer(
|
||||
DirectoryPath toolsPath,
|
||||
Func<FilePath> getTempProjectPath,
|
||||
Lazy<string> bundledTargetFrameworkMoniker,
|
||||
IPackageToProjectFileAdder packageToProjectFileAdder,
|
||||
IProjectRestorer projectRestorer
|
||||
)
|
||||
{
|
||||
_getTempProjectPath = getTempProjectPath;
|
||||
_bundledTargetFrameworkMoniker = bundledTargetFrameworkMoniker;
|
||||
_projectRestorer = projectRestorer ?? throw new ArgumentNullException(nameof(projectRestorer));
|
||||
_packageToProjectFileAdder = packageToProjectFileAdder ??
|
||||
throw new ArgumentNullException(nameof(packageToProjectFileAdder));
|
||||
_toolsPath = toolsPath;
|
||||
}
|
||||
|
||||
public ToolConfigurationAndExecutableDirectory ObtainAndReturnExecutablePath(
|
||||
string packageId,
|
||||
string packageVersion = null,
|
||||
FilePath? nugetconfig = null,
|
||||
string targetframework = null)
|
||||
{
|
||||
if (packageId == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(packageId));
|
||||
}
|
||||
|
||||
if (targetframework == null)
|
||||
{
|
||||
targetframework = _bundledTargetFrameworkMoniker.Value;
|
||||
}
|
||||
|
||||
var packageVersionOrPlaceHolder = new PackageVersion(packageVersion);
|
||||
|
||||
DirectoryPath individualToolVersion =
|
||||
CreateIndividualToolVersionDirectory(packageId, packageVersionOrPlaceHolder);
|
||||
|
||||
FilePath tempProjectPath = CreateTempProject(
|
||||
packageId,
|
||||
packageVersionOrPlaceHolder,
|
||||
targetframework,
|
||||
individualToolVersion);
|
||||
|
||||
if (packageVersionOrPlaceHolder.IsPlaceholder)
|
||||
{
|
||||
InvokeAddPackageRestore(
|
||||
nugetconfig,
|
||||
tempProjectPath,
|
||||
packageId);
|
||||
}
|
||||
|
||||
InvokeRestore(nugetconfig, tempProjectPath, individualToolVersion);
|
||||
|
||||
if (packageVersionOrPlaceHolder.IsPlaceholder)
|
||||
{
|
||||
var concreteVersion =
|
||||
new DirectoryInfo(
|
||||
Directory.GetDirectories(
|
||||
individualToolVersion.WithSubDirectories(packageId).Value).Single()).Name;
|
||||
DirectoryPath concreteVersionIndividualToolVersion =
|
||||
individualToolVersion.GetParentPath().WithSubDirectories(concreteVersion);
|
||||
Directory.Move(individualToolVersion.Value, concreteVersionIndividualToolVersion.Value);
|
||||
|
||||
individualToolVersion = concreteVersionIndividualToolVersion;
|
||||
packageVersion = concreteVersion;
|
||||
}
|
||||
|
||||
ToolConfiguration toolConfiguration = GetConfiguration(packageId, packageVersion, individualToolVersion);
|
||||
|
||||
return new ToolConfigurationAndExecutableDirectory(
|
||||
toolConfiguration,
|
||||
individualToolVersion.WithSubDirectories(
|
||||
packageId,
|
||||
packageVersion,
|
||||
"tools",
|
||||
targetframework));
|
||||
}
|
||||
|
||||
private static ToolConfiguration GetConfiguration(
|
||||
string packageId,
|
||||
string packageVersion,
|
||||
DirectoryPath individualToolVersion)
|
||||
{
|
||||
FilePath toolConfigurationPath =
|
||||
individualToolVersion
|
||||
.WithSubDirectories(packageId, packageVersion, "tools")
|
||||
.WithFile("DotnetToolsConfig.xml");
|
||||
|
||||
ToolConfiguration toolConfiguration =
|
||||
ToolConfigurationDeserializer.Deserialize(toolConfigurationPath.Value);
|
||||
|
||||
return toolConfiguration;
|
||||
}
|
||||
|
||||
private void InvokeRestore(
|
||||
FilePath? nugetconfig,
|
||||
FilePath tempProjectPath,
|
||||
DirectoryPath individualToolVersion)
|
||||
{
|
||||
_projectRestorer.Restore(tempProjectPath, individualToolVersion, nugetconfig);
|
||||
}
|
||||
|
||||
private FilePath CreateTempProject(
|
||||
string packageId,
|
||||
PackageVersion packageVersion,
|
||||
string targetframework,
|
||||
DirectoryPath individualToolVersion)
|
||||
{
|
||||
FilePath tempProjectPath = _getTempProjectPath();
|
||||
if (Path.GetExtension(tempProjectPath.Value) != "csproj")
|
||||
{
|
||||
tempProjectPath = new FilePath(Path.ChangeExtension(tempProjectPath.Value, "csproj"));
|
||||
}
|
||||
|
||||
EnsureDirectoryExists(tempProjectPath.GetDirectoryPath());
|
||||
var tempProjectContent = new XDocument(
|
||||
new XElement("Project",
|
||||
new XAttribute("Sdk", "Microsoft.NET.Sdk"),
|
||||
new XElement("PropertyGroup",
|
||||
new XElement("TargetFramework", targetframework),
|
||||
new XElement("RestorePackagesPath", individualToolVersion.Value),
|
||||
new XElement("DisableImplicitFrameworkReferences", "true")
|
||||
),
|
||||
packageVersion.IsConcreteValue
|
||||
? new XElement("ItemGroup",
|
||||
new XElement("PackageReference",
|
||||
new XAttribute("Include", packageId),
|
||||
new XAttribute("Version", packageVersion.Value)
|
||||
))
|
||||
: null));
|
||||
|
||||
File.WriteAllText(tempProjectPath.Value,
|
||||
tempProjectContent.ToString());
|
||||
|
||||
return tempProjectPath;
|
||||
}
|
||||
|
||||
private void InvokeAddPackageRestore(
|
||||
FilePath? nugetconfig,
|
||||
FilePath tempProjectPath,
|
||||
string packageId)
|
||||
{
|
||||
if (nugetconfig != null)
|
||||
{
|
||||
File.Copy(
|
||||
nugetconfig.Value.Value,
|
||||
tempProjectPath
|
||||
.GetDirectoryPath()
|
||||
.WithFile("nuget.config")
|
||||
.Value);
|
||||
}
|
||||
|
||||
_packageToProjectFileAdder.Add(tempProjectPath, packageId);
|
||||
}
|
||||
|
||||
private DirectoryPath CreateIndividualToolVersionDirectory(
|
||||
string packageId,
|
||||
PackageVersion packageVersion)
|
||||
{
|
||||
DirectoryPath individualTool = _toolsPath.WithSubDirectories(packageId);
|
||||
DirectoryPath individualToolVersion = individualTool.WithSubDirectories(packageVersion.Value);
|
||||
EnsureDirectoryExists(individualToolVersion);
|
||||
return individualToolVersion;
|
||||
}
|
||||
|
||||
private static void EnsureDirectoryExists(DirectoryPath path)
|
||||
{
|
||||
if (!Directory.Exists(path.Value))
|
||||
{
|
||||
Directory.CreateDirectory(path.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// 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 Microsoft.DotNet.ToolPackageObtainer;
|
||||
using Microsoft.Extensions.EnvironmentAbstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Cli
|
||||
{
|
||||
|
||||
internal class PackageToProjectFileAdder : IPackageToProjectFileAdder
|
||||
{
|
||||
public void Add(FilePath projectPath, string packageId)
|
||||
{
|
||||
if (packageId == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(packageId));
|
||||
}
|
||||
|
||||
var argsToPassToRestore = new List<string>
|
||||
{
|
||||
projectPath.Value,
|
||||
"package",
|
||||
packageId,
|
||||
"--no-restore"
|
||||
};
|
||||
|
||||
var command = new DotNetCommandFactory(alwaysRunOutOfProc: true)
|
||||
.Create(
|
||||
"add",
|
||||
argsToPassToRestore)
|
||||
.CaptureStdOut()
|
||||
.CaptureStdErr();
|
||||
|
||||
var result = command.Execute();
|
||||
if (result.ExitCode != 0)
|
||||
{
|
||||
throw new PackageObtainException("Failed to add package. " +
|
||||
$"{Environment.NewLine}WorkingDirectory: " +
|
||||
result.StartInfo.WorkingDirectory +
|
||||
$"{Environment.NewLine}Arguments: " +
|
||||
result.StartInfo.Arguments +
|
||||
$"{Environment.NewLine}Output: " +
|
||||
result.StdErr + result.StdOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
55
src/dotnet/commands/dotnet-install/ProjectRestorer.cs
Normal file
55
src/dotnet/commands/dotnet-install/ProjectRestorer.cs
Normal file
|
@ -0,0 +1,55 @@
|
|||
// 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 Microsoft.DotNet.ToolPackageObtainer;
|
||||
using Microsoft.DotNet.PlatformAbstractions;
|
||||
using Microsoft.Extensions.EnvironmentAbstractions;
|
||||
|
||||
namespace Microsoft.DotNet.Cli
|
||||
{
|
||||
internal class ProjectRestorer : IProjectRestorer
|
||||
{
|
||||
public void Restore(
|
||||
FilePath projectPath,
|
||||
DirectoryPath assetJsonOutput,
|
||||
FilePath? nugetconfig)
|
||||
{
|
||||
var argsToPassToRestore = new List<string>();
|
||||
|
||||
argsToPassToRestore.Add(projectPath.ToQuotedString());
|
||||
if (nugetconfig != null)
|
||||
{
|
||||
argsToPassToRestore.Add("--configfile");
|
||||
argsToPassToRestore.Add(nugetconfig.Value.ToQuotedString());
|
||||
}
|
||||
|
||||
argsToPassToRestore.AddRange(new List<string>
|
||||
{
|
||||
"--runtime",
|
||||
RuntimeEnvironment.GetRuntimeIdentifier(),
|
||||
$"/p:BaseIntermediateOutputPath={assetJsonOutput.ToQuotedString()}"
|
||||
});
|
||||
|
||||
var command = new DotNetCommandFactory(alwaysRunOutOfProc: true)
|
||||
.Create(
|
||||
"restore",
|
||||
argsToPassToRestore)
|
||||
.CaptureStdOut()
|
||||
.CaptureStdErr();
|
||||
|
||||
var result = command.Execute();
|
||||
if (result.ExitCode != 0)
|
||||
{
|
||||
throw new PackageObtainException("Failed to restore package. " +
|
||||
$"{Environment.NewLine}WorkingDirectory: " +
|
||||
result.StartInfo.WorkingDirectory +
|
||||
$"{Environment.NewLine}Arguments: " +
|
||||
result.StartInfo.Arguments +
|
||||
$"{Environment.NewLine}Output: " +
|
||||
result.StdErr + result.StdOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26419.0
|
||||
VisualStudioVersion = 15.0.27004.2008
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "dotnet-add-reference.Tests", "dotnet-add-reference.Tests\dotnet-add-reference.Tests.csproj", "{AB63A3E5-76A3-4EE9-A380-8E0C7B7644DC}"
|
||||
EndProject
|
||||
|
@ -74,13 +74,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-store.Tests", "dotne
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-back-compat.Tests", "dotnet-back-compat.Tests\dotnet-back-compat.Tests.csproj", "{27351B2F-325B-4843-9F4C-BC53FD06A7B5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-remove-package.Tests", "dotnet-remove-package.Tests\dotnet-remove-package.Tests.csproj", "{CF517B15-B307-4660-87D5-CC036ADECD4B}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-remove-package.Tests", "dotnet-remove-package.Tests\dotnet-remove-package.Tests.csproj", "{CF517B15-B307-4660-87D5-CC036ADECD4B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.MSBuildSdkResolver.Tests", "Microsoft.DotNet.MSBuildSdkResolver.Tests\Microsoft.DotNet.MSBuildSdkResolver.Tests.csproj", "{42A0CAB4-FFAD-47D4-9880-C0F4EDCF93DE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnet-clean.Tests", "dotnet-clean.Tests\dotnet-clean.Tests.csproj", "{D9A582B8-1FE2-45D5-B139-0BA828FE3691}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-clean.Tests", "dotnet-clean.Tests\dotnet-clean.Tests.csproj", "{D9A582B8-1FE2-45D5-B139-0BA828FE3691}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.DotNet.TestFramework", "Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj", "{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.TestFramework", "Microsoft.DotNet.TestFramework\Microsoft.DotNet.TestFramework.csproj", "{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.ToolPackageObtainer.Tests", "Microsoft.DotNet.ToolPackageObtainer.Tests\Microsoft.DotNet.ToolPackageObtainer.Tests.csproj", "{C2A907A3-677B-4C73-9AA4-E53613E13C78}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -490,16 +492,16 @@ Global
|
|||
{27351B2F-325B-4843-9F4C-BC53FD06A7B5}.Release|x86.Build.0 = Release|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|x64.Build.0 = Debug|x64
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|x86.Build.0 = Debug|x86
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|x64.ActiveCfg = Release|x64
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|x64.Build.0 = Release|x64
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|x86.ActiveCfg = Release|x86
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|x86.Build.0 = Release|x86
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CF517B15-B307-4660-87D5-CC036ADECD4B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{42A0CAB4-FFAD-47D4-9880-C0F4EDCF93DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{42A0CAB4-FFAD-47D4-9880-C0F4EDCF93DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{42A0CAB4-FFAD-47D4-9880-C0F4EDCF93DE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
@ -514,28 +516,40 @@ Global
|
|||
{42A0CAB4-FFAD-47D4-9880-C0F4EDCF93DE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|x64.Build.0 = Debug|x64
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|x86.Build.0 = Debug|x86
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|x64.ActiveCfg = Release|x64
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|x64.Build.0 = Release|x64
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|x86.ActiveCfg = Release|x86
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|x86.Build.0 = Release|x86
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D9A582B8-1FE2-45D5-B139-0BA828FE3691}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|x64.Build.0 = Debug|x64
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|x86.Build.0 = Debug|x86
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|x64.ActiveCfg = Release|x64
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|x64.Build.0 = Release|x64
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|x86.ActiveCfg = Release|x86
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|x86.Build.0 = Release|x86
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D23AFC9C-8FD5-45DD-A84C-0E6528C42F0E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C2A907A3-677B-4C73-9AA4-E53613E13C78}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -545,4 +559,7 @@ Global
|
|||
{5767D8F0-4ED9-4083-8BDC-ED9E65AA86EF} = {15DDC326-69C3-4081-8AA1-B578B2BDE2C6}
|
||||
{92BA9F90-E25B-4A1C-9598-2295D3DFC12F} = {BB393A93-1770-4753-B7D6-56F0DD378177}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {7AF6777A-0133-453A-B302-FDD974B8F39C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<DotNetCliTool>
|
||||
<Commands>
|
||||
<Command Name="sayhello" EntryPoint="console.dll" Runner="dotnet" />
|
||||
</Commands>
|
||||
</DotNetCliTool>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<DotNetCliTool>
|
||||
<Commands Malformed=""
|
||||
<Command Name="sayhello" EntryPoint="console.dll" Runner="dotnet" />
|
||||
</Commands>
|
||||
</DotNetCliTool>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<DotNetCliTool>
|
||||
<Commands>
|
||||
<Command EntryPoint="console.dll" Runner="dotnet" />
|
||||
</Commands>
|
||||
</DotNetCliTool>
|
|
@ -0,0 +1,56 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(CliTargetFramework)</TargetFramework>
|
||||
<RuntimeFrameworkVersion>$(CLI_SharedFrameworkVersion)</RuntimeFrameworkVersion>
|
||||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||
<AssemblyOriginatorKeyFile>../../tools/Key.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
<AssetTargetFallback>$(AssetTargetFallback);dotnet5.4;portable-net451+win8</AssetTargetFallback>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\dotnet\dotnet.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.DotNet.Configurer\Microsoft.DotNet.Configurer.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.DotNet.InternalAbstractions\Microsoft.DotNet.InternalAbstractions.csproj" />
|
||||
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
|
||||
<ProjectReference Include="..\..\src\Microsoft.DotNet.Cli.Utils\Microsoft.DotNet.Cli.Utils.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="4.18.0" />
|
||||
<PackageReference Include="Moq" Version="4.7.25" />
|
||||
<PackageReference Include="xunit" Version="2.2.0" />
|
||||
<PackageReference Include="System.ComponentModel.TypeConverter" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="DotnetToolsConfigMissing.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="DotnetToolsConfigMalformed.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="DotnetToolsConfigGolden.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="TestAssetLocalNugetFeed/*.*">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
<Compile Remove="SampleGlobalTool/**" />
|
||||
<Content Remove="SampleGlobalTool/**" />
|
||||
<EmbeddedResource Remove="SampleGlobalTool/**" />
|
||||
<None Remove="SampleGlobalTool/**" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CreateNupkgFromSource" BeforeTargets="Build">
|
||||
<PropertyGroup>
|
||||
<testAssetSourceRoot>$(BaseOutputPath)/TestAsset/SampleGlobalTool</testAssetSourceRoot>
|
||||
</PropertyGroup>
|
||||
<Copy SourceFiles="SampleGlobalTool/DotnetToolsConfig.xml" DestinationFolder="$(testAssetSourceRoot)" />
|
||||
<MSBuild BuildInParallel="False" Projects="SampleGlobalTool/consoledemo.csproj" Targets="Restore;Build;Publish" Properties="Configuration=Release;BaseOutputPath=$(testAssetSourceRoot)/bin/">
|
||||
</MSBuild>
|
||||
<MSBuild BuildInParallel="False" Projects="SampleGlobalTool/consoledemo.csproj" Targets="pack" Properties="Configuration=Release;NuspecFile=includepublish.nuspec;NuspecBasePath=$(testAssetSourceRoot);PackageOutputPath=$(OutputPath)/TestAssetLocalNugetFeed">
|
||||
</MSBuild>
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<DotNetCliTool>
|
||||
<Commands>
|
||||
<Command Name="demo" EntryPoint="consoledemo.dll" Runner="dotnet" />
|
||||
</Commands>
|
||||
</DotNetCliTool>
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace consoledemo
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var greeting = "Hello World from Global Tool";
|
||||
Console.WriteLine(greeting);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<AssemblyName>consoledemo</AssemblyName>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>global.tool.console.demo</id>
|
||||
<version>1.0.4</version>
|
||||
<description>test app</description>
|
||||
<authors>testauthor</authors>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="bin\Release\netcoreapp2.1\publish\*.*" target="tools\netcoreapp2.1\" />
|
||||
<file src="DotnetToolsConfig.xml" target="tools\DotnetToolsConfig.xml" />
|
||||
</files>
|
||||
</package>
|
|
@ -0,0 +1,52 @@
|
|||
// 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 FluentAssertions;
|
||||
using NuGet.Protocol.Core.Types;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer.Tests
|
||||
{
|
||||
public class ToolConfigurationDeserializerTests
|
||||
{
|
||||
[Fact]
|
||||
public void GivenXmlPathItShouldGetToolConfiguration()
|
||||
{
|
||||
ToolConfiguration toolConfiguration = ToolConfigurationDeserializer.Deserialize("DotnetToolsConfigGolden.xml");
|
||||
|
||||
toolConfiguration.CommandName.Should().Be("sayhello");
|
||||
toolConfiguration.ToolAssemblyEntryPoint.Should().Be("console.dll");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GivenMalformedPathItThrows()
|
||||
{
|
||||
Action a = () => ToolConfigurationDeserializer.Deserialize("DotnetToolsConfigMalformed.xml");
|
||||
a.ShouldThrow<ToolConfigurationException>()
|
||||
.And.Message.Should()
|
||||
.Contain("Failed to retrive tool configuration exception, configuration is malformed xml");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GivenMissingContentItThrows()
|
||||
{
|
||||
Action a = () => ToolConfigurationDeserializer.Deserialize("DotnetToolsConfigMissing.xml");
|
||||
a.ShouldThrow<ToolConfigurationException>()
|
||||
.And.Message.Should()
|
||||
.Contain("Configuration content error");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GivenInvalidCharAsFileNameItThrows()
|
||||
{
|
||||
Action a = () => new ToolConfiguration("na***me", "my.dll");
|
||||
a.ShouldThrow<ArgumentException>()
|
||||
.And.Message.Should()
|
||||
.Contain("Cannot contain following character");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
// 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.IO;
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||
using Microsoft.Extensions.EnvironmentAbstractions;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DotNet.ToolPackageObtainer.Tests
|
||||
{
|
||||
public class ToolPackageObtainerTests : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public void GivenNugetConfigAndPackageNameAndVersionAndTargetFrameworkWhenCallItCanDownloadThePackage()
|
||||
{
|
||||
FilePath nugetConfigPath = WriteNugetConfigFileToPointToTheFeed();
|
||||
var toolsPath = Path.Combine(Directory.GetCurrentDirectory(), Path.GetRandomFileName());
|
||||
|
||||
var packageObtainer =
|
||||
ConstructDefaultPackageObtainer(toolsPath);
|
||||
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory = packageObtainer.ObtainAndReturnExecutablePath(
|
||||
packageId: TestPackageId,
|
||||
packageVersion: TestPackageVersion,
|
||||
nugetconfig: nugetConfigPath,
|
||||
targetframework: _testTargetframework);
|
||||
|
||||
var executable = toolConfigurationAndExecutableDirectory
|
||||
.ExecutableDirectory
|
||||
.WithFile(
|
||||
toolConfigurationAndExecutableDirectory
|
||||
.Configuration
|
||||
.ToolAssemblyEntryPoint);
|
||||
|
||||
File.Exists(executable.Value)
|
||||
.Should()
|
||||
.BeTrue(executable + " should have the executable");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GivenNugetConfigAndPackageNameAndVersionAndTargetFrameworkWhenCallItCreateAssetFile()
|
||||
{
|
||||
var nugetConfigPath = WriteNugetConfigFileToPointToTheFeed();
|
||||
var toolsPath = Path.Combine(Directory.GetCurrentDirectory(), Path.GetRandomFileName());
|
||||
|
||||
var packageObtainer =
|
||||
ConstructDefaultPackageObtainer(toolsPath);
|
||||
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory =
|
||||
packageObtainer.ObtainAndReturnExecutablePath(
|
||||
packageId: TestPackageId,
|
||||
packageVersion: TestPackageVersion,
|
||||
nugetconfig: nugetConfigPath,
|
||||
targetframework: _testTargetframework);
|
||||
|
||||
var assetJsonPath = toolConfigurationAndExecutableDirectory
|
||||
.ExecutableDirectory
|
||||
.GetParentPath()
|
||||
.GetParentPath()
|
||||
.GetParentPath()
|
||||
.GetParentPath()
|
||||
.WithFile("project.assets.json").Value;
|
||||
|
||||
File.Exists(assetJsonPath)
|
||||
.Should()
|
||||
.BeTrue(assetJsonPath + " should be created");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GivenAllButNoNugetConfigFilePathItCanDownloadThePackage()
|
||||
{
|
||||
var uniqueTempProjectPath = GetUniqueTempProjectPathEachTest();
|
||||
var tempProjectDirectory = uniqueTempProjectPath.GetDirectoryPath();
|
||||
var nugetConfigPath = WriteNugetConfigFileToPointToTheFeed();
|
||||
var toolsPath = Path.Combine(Directory.GetCurrentDirectory(), Path.GetRandomFileName());
|
||||
|
||||
Directory.CreateDirectory(tempProjectDirectory.Value);
|
||||
|
||||
/*
|
||||
* No nuget config means you don't need nuget config passed in during call
|
||||
* NuGet needs a way to find the package, in production, it will keep look up folders for Nuget.Config
|
||||
* and use the feed there.
|
||||
* In test, we don't want NuGet to keep look up, so we just copy paste beside the project.
|
||||
*/
|
||||
File.Copy(nugetConfigPath.Value,
|
||||
tempProjectDirectory.WithFile("nuget.config").Value);
|
||||
|
||||
var packageObtainer =
|
||||
new ToolPackageObtainer(
|
||||
new DirectoryPath(toolsPath),
|
||||
() => uniqueTempProjectPath,
|
||||
new Lazy<string>(),
|
||||
new PackageToProjectFileAdder(),
|
||||
new ProjectRestorer());
|
||||
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory = packageObtainer.ObtainAndReturnExecutablePath(
|
||||
packageId: TestPackageId,
|
||||
packageVersion: TestPackageVersion,
|
||||
targetframework: _testTargetframework);
|
||||
|
||||
var executable = toolConfigurationAndExecutableDirectory
|
||||
.ExecutableDirectory
|
||||
.WithFile(
|
||||
toolConfigurationAndExecutableDirectory
|
||||
.Configuration
|
||||
.ToolAssemblyEntryPoint);
|
||||
|
||||
File.Exists(executable.Value)
|
||||
.Should()
|
||||
.BeTrue(executable + " should have the executable");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GivenAllButNoPackageVersionItCanDownloadThePackage()
|
||||
{
|
||||
var nugetConfigPath = WriteNugetConfigFileToPointToTheFeed();
|
||||
var toolsPath = Path.Combine(Directory.GetCurrentDirectory(), Path.GetRandomFileName());
|
||||
|
||||
var packageObtainer =
|
||||
ConstructDefaultPackageObtainer(toolsPath);
|
||||
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory = packageObtainer.ObtainAndReturnExecutablePath(
|
||||
packageId: TestPackageId,
|
||||
nugetconfig: nugetConfigPath,
|
||||
targetframework: _testTargetframework);
|
||||
|
||||
var executable = toolConfigurationAndExecutableDirectory
|
||||
.ExecutableDirectory
|
||||
.WithFile(
|
||||
toolConfigurationAndExecutableDirectory
|
||||
.Configuration
|
||||
.ToolAssemblyEntryPoint);
|
||||
|
||||
File.Exists(executable.Value)
|
||||
.Should()
|
||||
.BeTrue(executable + " should have the executable");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GivenAllButNoTargetFrameworkItCanDownloadThePackage()
|
||||
{
|
||||
var nugetConfigPath = WriteNugetConfigFileToPointToTheFeed();
|
||||
var toolsPath = Path.Combine(Directory.GetCurrentDirectory(), Path.GetRandomFileName());
|
||||
|
||||
var packageObtainer =
|
||||
new ToolPackageObtainer(
|
||||
new DirectoryPath(toolsPath),
|
||||
GetUniqueTempProjectPathEachTest,
|
||||
new Lazy<string>(() => BundledTargetFramework.GetTargetFrameworkMoniker()),
|
||||
new PackageToProjectFileAdder(),
|
||||
new ProjectRestorer());
|
||||
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory =
|
||||
packageObtainer.ObtainAndReturnExecutablePath(
|
||||
packageId: TestPackageId,
|
||||
packageVersion: TestPackageVersion,
|
||||
nugetconfig: nugetConfigPath);
|
||||
|
||||
var executable = toolConfigurationAndExecutableDirectory
|
||||
.ExecutableDirectory
|
||||
.WithFile(
|
||||
toolConfigurationAndExecutableDirectory
|
||||
.Configuration
|
||||
.ToolAssemblyEntryPoint);
|
||||
|
||||
File.Exists(executable.Value)
|
||||
.Should()
|
||||
.BeTrue(executable + " should have the executable");
|
||||
}
|
||||
|
||||
private static readonly Func<FilePath> GetUniqueTempProjectPathEachTest = () =>
|
||||
{
|
||||
var tempProjectDirectory =
|
||||
new DirectoryPath(Path.GetTempPath()).WithSubDirectories(Path.GetRandomFileName());
|
||||
var tempProjectPath =
|
||||
tempProjectDirectory.WithFile(Path.GetRandomFileName() + ".csproj");
|
||||
return tempProjectPath;
|
||||
};
|
||||
|
||||
private static ToolPackageObtainer ConstructDefaultPackageObtainer(string toolsPath)
|
||||
{
|
||||
return new ToolPackageObtainer(
|
||||
new DirectoryPath(toolsPath),
|
||||
GetUniqueTempProjectPathEachTest,
|
||||
new Lazy<string>(),
|
||||
new PackageToProjectFileAdder(),
|
||||
new ProjectRestorer());
|
||||
}
|
||||
|
||||
private static FilePath WriteNugetConfigFileToPointToTheFeed()
|
||||
{
|
||||
var nugetConfigName = Path.GetRandomFileName() + ".config";
|
||||
var executeDirectory =
|
||||
Path.GetDirectoryName(
|
||||
System.Reflection
|
||||
.Assembly
|
||||
.GetExecutingAssembly()
|
||||
.Location);
|
||||
NuGetConfig.Write(
|
||||
directory: executeDirectory,
|
||||
configname: nugetConfigName,
|
||||
localFeedPath: Path.Combine(executeDirectory, "TestAssetLocalNugetFeed"));
|
||||
return new FilePath(Path.GetFullPath(nugetConfigName));
|
||||
}
|
||||
|
||||
private readonly string _testTargetframework = BundledTargetFramework.GetTargetFrameworkMoniker();
|
||||
private const string TestPackageVersion = "1.0.4";
|
||||
private const string TestPackageId = "global.tool.console.demo";
|
||||
}
|
||||
}
|
|
@ -23,5 +23,23 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
|
|||
|
||||
File.WriteAllText(path, contents);
|
||||
}
|
||||
|
||||
public static void Write(string directory, string configname, string localFeedPath)
|
||||
{
|
||||
const string template = @"<?xml version=""1.0"" encoding=""utf-8""?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
|
||||
<clear />
|
||||
<add key=""Test Source"" value=""{0}"" />
|
||||
<add key=""api.nuget.org"" value=""https://api.nuget.org/v3/index.json"" />
|
||||
<add key=""dotnet-core"" value=""https://dotnet.myget.org/F/dotnet-core/api/v3/index.json"" />
|
||||
</packageSources>
|
||||
</configuration>";
|
||||
|
||||
var path = Path.Combine(directory, configname);
|
||||
|
||||
File.WriteAllText(path, string.Format(template, localFeedPath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
39
test/dotnet.Tests/BundledTargetFramworkTests.cs
Normal file
39
test/dotnet.Tests/BundledTargetFramworkTests.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
// 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.IO;
|
||||
using Microsoft.DotNet.Cli;
|
||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||
using Xunit;
|
||||
using FluentAssertions;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.Tests
|
||||
{
|
||||
public class BundledTargetFrameworkTests : TestBase
|
||||
{
|
||||
[Fact]
|
||||
public void VersionCommandDisplaysCorrectVersion()
|
||||
{
|
||||
var filePath = Path.Combine(
|
||||
AppContext.BaseDirectory,
|
||||
"ExpectedTargetFrameworkMoniker.txt");
|
||||
var targetFrameworkMoniker = GetTargetFrameworkMonikerFromFile(filePath);
|
||||
var shortFolderName = NuGetFramework
|
||||
.Parse(targetFrameworkMoniker)
|
||||
.GetShortFolderName();
|
||||
BundledTargetFramework
|
||||
.GetTargetFrameworkMoniker()
|
||||
.Should().Be(shortFolderName);
|
||||
}
|
||||
|
||||
private static string GetTargetFrameworkMonikerFromFile(string versionFilePath)
|
||||
{
|
||||
using (var reader = new StreamReader(File.OpenRead(versionFilePath)))
|
||||
{
|
||||
return reader.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -52,6 +52,23 @@
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="WriteExpectedTargetFrameworkMoniker" BeforeTargets="BeforeBuild" DependsOnTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ExpectedTargetFrameworkMonikerFileInIntermediateFolder>$(IntermediateOutputPath)ExpectedTargetFrameworkMoniker.txt</ExpectedTargetFrameworkMonikerFileInIntermediateFolder>
|
||||
<VersionFileContent>$(TargetFrameworkMoniker)</VersionFileContent>
|
||||
<ExistingVersionFileContent Condition=" Exists('$(ExpectedTargetFrameworkMonikerFileInIntermediateFolder)') ">
|
||||
$([System.IO.File]::ReadAllText($(ExpectedTargetFrameworkMonikerFileInIntermediateFolder)))
|
||||
</ExistingVersionFileContent>
|
||||
<ShouldOverwriteVersionFile>false</ShouldOverwriteVersionFile>
|
||||
<ShouldOverwriteVersionFile Condition=" '$(ExistingVersionFileContent.Trim())' != '$(VersionFileContent.Trim())' ">true</ShouldOverwriteVersionFile>
|
||||
</PropertyGroup>
|
||||
<WriteLinesToFile File="$(ExpectedTargetFrameworkMonikerFileInIntermediateFolder)" Lines="$(VersionFileContent)" Condition=" '$(ShouldOverwriteVersionFile)' == 'true' " Overwrite="true" />
|
||||
<ItemGroup>
|
||||
<Content Include="$(ExpectedTargetFrameworkMonikerFileInIntermediateFolder)" CopyToOutputDirectory="PreserveNewest" />
|
||||
<FileWrites Include="$(ExpectedTargetFrameworkMonikerFileInIntermediateFolder)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.DotNet.Tools.Tests.Utilities\Microsoft.DotNet.Tools.Tests.Utilities.csproj" />
|
||||
<ProjectReference Include="..\..\src\dotnet\dotnet.csproj" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue