[tools] Integrate NuGet (#8414)

* Integrate NuGet ask

* Update NuGet version. Rely on NuGet to filter TFM. And use asset.json to find entrypoint

* Update XML file to per TFM

* Add extra property to the fake project according to nuget

* Treat nuget fallback folder as offline cache for tool

* Require -g to install global tool

* Copy test asset during test project build

* Address code review on LockFileMatchChecker

* Get NETCorePlatformsImplicitPackageVersion from PackageDefinitions

* Edit and add missing loc

* Change LockFileMatchChecker to local function

* Adding comment

* Add to content instead of copy

* Download platform package instead

* disable SDK side implicit NuGetFallbackFolder

* merge loc

* Revert extra line

* use a prerelease platforms version that supports alpine
This commit is contained in:
William Lee 2018-01-19 17:15:34 -08:00 committed by GitHub
parent c7d44beca7
commit 02a98d4e63
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 640 additions and 109 deletions

View file

@ -99,6 +99,8 @@
<ItemGroup> <ItemGroup>
<_NETStandardLibraryVersions Include="@(PackageDefinitions->'%(Version)')" <_NETStandardLibraryVersions Include="@(PackageDefinitions->'%(Version)')"
Condition="%(PackageDefinitions.Name) == 'NetStandard.Library'" /> Condition="%(PackageDefinitions.Name) == 'NetStandard.Library'" />
<_NETCorePlatformsImplicitPackageVersion Include="@(PackageDefinitions->'%(Version)')"
Condition="%(PackageDefinitions.Name) == 'Microsoft.NETCore.Platforms'" />
</ItemGroup> </ItemGroup>
<Error Condition="@(_NETStandardLibraryVersions->Distinct()->Count()) != 1" <Error Condition="@(_NETStandardLibraryVersions->Distinct()->Count()) != 1"
@ -107,6 +109,7 @@
<PropertyGroup> <PropertyGroup>
<_NETCoreAppPackageVersion>$(MicrosoftNETCoreAppPackageVersion)</_NETCoreAppPackageVersion> <_NETCoreAppPackageVersion>$(MicrosoftNETCoreAppPackageVersion)</_NETCoreAppPackageVersion>
<_NETStandardPackageVersion>@(_NETStandardLibraryVersions->Distinct())</_NETStandardPackageVersion> <_NETStandardPackageVersion>@(_NETStandardLibraryVersions->Distinct())</_NETStandardPackageVersion>
<_NETCorePlatformsImplicitPackageVersion>@(_NETCorePlatformsImplicitPackageVersion->Distinct())</_NETCorePlatformsImplicitPackageVersion>
<!-- Use only major and minor in target framework version --> <!-- Use only major and minor in target framework version -->
<_NETCoreAppTargetFrameworkVersion>$(_NETCoreAppPackageVersion.Split('.')[0]).$(_NETCoreAppPackageVersion.Split('.')[1])</_NETCoreAppTargetFrameworkVersion> <_NETCoreAppTargetFrameworkVersion>$(_NETCoreAppPackageVersion.Split('.')[0]).$(_NETCoreAppPackageVersion.Split('.')[1])</_NETCoreAppTargetFrameworkVersion>
@ -131,6 +134,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<BundledNETCoreAppPackageVersion>$(_NETCoreAppPackageVersion)</BundledNETCoreAppPackageVersion> <BundledNETCoreAppPackageVersion>$(_NETCoreAppPackageVersion)</BundledNETCoreAppPackageVersion>
<BundledNETStandardTargetFrameworkVersion>$(_NETStandardTargetFrameworkVersion)</BundledNETStandardTargetFrameworkVersion> <BundledNETStandardTargetFrameworkVersion>$(_NETStandardTargetFrameworkVersion)</BundledNETStandardTargetFrameworkVersion>
<BundledNETStandardPackageVersion>$(_NETStandardPackageVersion)</BundledNETStandardPackageVersion> <BundledNETStandardPackageVersion>$(_NETStandardPackageVersion)</BundledNETStandardPackageVersion>
<NETCorePlatformsImplicitPackageVersion>$(_NETCorePlatformsImplicitPackageVersion)</NETCorePlatformsImplicitPackageVersion>
</PropertyGroup> </PropertyGroup>
</Project> </Project>
]]> ]]>

View file

@ -584,4 +584,10 @@ Output: {1}</value>
<data name="FailInstallToolSameName" xml:space="preserve"> <data name="FailInstallToolSameName" xml:space="preserve">
<value>Failed to install tool {0}. A command with the same name already exists.</value> <value>Failed to install tool {0}. A command with the same name already exists.</value>
</data> </data>
<data name="ToolPackageMissingEntryPointFile" xml:space="preserve">
<value>Package '{0}' is missing entry point file {1}.</value>
</data>
<data name="ToolPackageMissingSettingsFile" xml:space="preserve">
<value>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</value>
</data>
</root> </root>

View file

@ -0,0 +1,57 @@
// 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.Linq;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.ToolPackage
{
internal class LockFileMatcher
{
/// <summary>
/// Check if LockFileItem matches the targetRelativeFilePath.
/// The path in LockFileItem is in pattern tools/TFM/RID/my/tool.dll. Tools/TFM/RID is selected by NuGet.
/// And there will be only one TFM/RID combination.
/// When "my/tools.dll" part matches exactly with the targetRelativeFilePath, return true.
/// </summary>
/// <param name="lockFileItem">LockFileItem from asset.json restored from temp project</param>
/// <param name="targetRelativeFilePath">file path relative to tools/TFM/RID</param>
internal static bool MatchesFile(LockFileItem lockFileItem, string targetRelativeFilePath)
{
string[] pathInLockFilePathInArray = SplitPathByDirectorySeparator(lockFileItem.Path);
string[] entryPointPathInArray = SplitPathByDirectorySeparator(targetRelativeFilePath);
return entryPointPathInArray.Length >= 1
&& PathInLockFileDirectoriesStartWithToolsAndFollowsTwoSubFolder()
&& SubPathMatchesTargetFilePath();
bool SubPathMatchesTargetFilePath()
{
string[] pathAfterToolsTfmRid = pathInLockFilePathInArray.Skip(3).ToArray();
return !pathAfterToolsTfmRid
.Where((directoryOnEveryLevel, i) => directoryOnEveryLevel != entryPointPathInArray[i])
.Any();
}
bool PathInLockFileDirectoriesStartWithToolsAndFollowsTwoSubFolder()
{
if (pathInLockFilePathInArray.Length - entryPointPathInArray.Length != 3)
{
return false;
}
if (pathInLockFilePathInArray[0] != "tools")
{
return false;
}
return true;
}
string[] SplitPathByDirectorySeparator(string path)
{
return path.Split('\\', '/');
}
}
}
}

View file

@ -5,17 +5,18 @@ using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.DotNet.ToolPackage namespace Microsoft.DotNet.ToolPackage
{ {
internal class ToolConfigurationAndExecutableDirectory internal class ToolConfigurationAndExecutablePath
{ {
public ToolConfigurationAndExecutableDirectory( public ToolConfigurationAndExecutablePath(
ToolConfiguration toolConfiguration, ToolConfiguration toolConfiguration,
DirectoryPath executableDirectory) FilePath executable)
{ {
Configuration = toolConfiguration; Configuration = toolConfiguration;
ExecutableDirectory = executableDirectory; Executable = executable;
} }
public ToolConfiguration Configuration { get; } public ToolConfiguration Configuration { get; }
public DirectoryPath ExecutableDirectory { get; }
public FilePath Executable { get; }
} }
} }

View file

@ -1,10 +1,12 @@
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
using Microsoft.DotNet.Tools; using Microsoft.DotNet.Tools;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Configurer;
using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.Extensions.EnvironmentAbstractions;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.ToolPackage namespace Microsoft.DotNet.ToolPackage
{ {
@ -15,9 +17,11 @@ namespace Microsoft.DotNet.ToolPackage
private readonly IPackageToProjectFileAdder _packageToProjectFileAdder; private readonly IPackageToProjectFileAdder _packageToProjectFileAdder;
private readonly IProjectRestorer _projectRestorer; private readonly IProjectRestorer _projectRestorer;
private readonly DirectoryPath _toolsPath; private readonly DirectoryPath _toolsPath;
private readonly DirectoryPath _offlineFeedPath;
public ToolPackageObtainer( public ToolPackageObtainer(
DirectoryPath toolsPath, DirectoryPath toolsPath,
DirectoryPath offlineFeedPath,
Func<FilePath> getTempProjectPath, Func<FilePath> getTempProjectPath,
Lazy<string> bundledTargetFrameworkMoniker, Lazy<string> bundledTargetFrameworkMoniker,
IPackageToProjectFileAdder packageToProjectFileAdder, IPackageToProjectFileAdder packageToProjectFileAdder,
@ -30,9 +34,10 @@ namespace Microsoft.DotNet.ToolPackage
_packageToProjectFileAdder = packageToProjectFileAdder ?? _packageToProjectFileAdder = packageToProjectFileAdder ??
throw new ArgumentNullException(nameof(packageToProjectFileAdder)); throw new ArgumentNullException(nameof(packageToProjectFileAdder));
_toolsPath = toolsPath; _toolsPath = toolsPath;
_offlineFeedPath = offlineFeedPath;
} }
public ToolConfigurationAndExecutableDirectory ObtainAndReturnExecutablePath( public ToolConfigurationAndExecutablePath ObtainAndReturnExecutablePath(
string packageId, string packageId,
string packageVersion = null, string packageVersion = null,
FilePath? nugetconfig = null, FilePath? nugetconfig = null,
@ -50,7 +55,7 @@ namespace Microsoft.DotNet.ToolPackage
{ {
throw new PackageObtainException( throw new PackageObtainException(
string.Format(CommonLocalizableStrings.NuGetConfigurationFileDoesNotExist, string.Format(CommonLocalizableStrings.NuGetConfigurationFileDoesNotExist,
Path.GetFullPath(nugetconfig.Value.Value))); Path.GetFullPath(nugetconfig.Value.Value)));
} }
} }
@ -95,16 +100,52 @@ namespace Microsoft.DotNet.ToolPackage
packageVersion = concreteVersion; packageVersion = concreteVersion;
} }
ToolConfiguration toolConfiguration = GetConfiguration(packageId: packageId, packageVersion: packageVersion, individualToolVersion: toolDirectory); LockFile lockFile = new LockFileFormat()
.ReadWithLock(toolDirectory.WithFile("project.assets.json").Value)
.Result;
return new ToolConfigurationAndExecutableDirectory( LockFileItem dotnetToolSettings = FindAssetInLockFile(lockFile, "DotnetToolSettings.xml", packageId);
if (dotnetToolSettings == null)
{
throw new PackageObtainException(
string.Format(CommonLocalizableStrings.ToolPackageMissingSettingsFile, packageId));
}
FilePath toolConfigurationPath =
toolDirectory
.WithSubDirectories(packageId, packageVersion)
.WithFile(dotnetToolSettings.Path);
ToolConfiguration toolConfiguration =
ToolConfigurationDeserializer.Deserialize(toolConfigurationPath.Value);
var entryPointFromLockFile =
FindAssetInLockFile(lockFile, toolConfiguration.ToolAssemblyEntryPoint, packageId);
if (entryPointFromLockFile == null)
{
throw new PackageObtainException(string.Format(CommonLocalizableStrings.ToolPackageMissingEntryPointFile,
packageId, toolConfiguration.ToolAssemblyEntryPoint));
}
return new ToolConfigurationAndExecutablePath(
toolConfiguration, toolConfiguration,
toolDirectory.WithSubDirectories( toolDirectory.WithSubDirectories(
packageId, packageId,
packageVersion, packageVersion)
"tools", .WithFile(entryPointFromLockFile.Path));
targetframework, }
"any"));
private static LockFileItem FindAssetInLockFile(
LockFile lockFile,
string targetRelativeFilePath, string packageId)
{
return lockFile
.Targets?.SingleOrDefault(t => t.RuntimeIdentifier != null)
?.Libraries?.SingleOrDefault(l => l.Name == packageId)
?.ToolsAssemblies
?.SingleOrDefault(t => LockFileMatcher.MatchesFile(t, targetRelativeFilePath));
} }
private static void MoveToVersionedDirectory( private static void MoveToVersionedDirectory(
@ -119,22 +160,6 @@ namespace Microsoft.DotNet.ToolPackage
Directory.Move(temporary.Value, versioned.Value); Directory.Move(temporary.Value, versioned.Value);
} }
private static ToolConfiguration GetConfiguration(
string packageId,
string packageVersion,
DirectoryPath individualToolVersion)
{
FilePath toolConfigurationPath =
individualToolVersion
.WithSubDirectories(packageId, packageVersion, "tools")
.WithFile("DotnetToolSettings.xml");
ToolConfiguration toolConfiguration =
ToolConfigurationDeserializer.Deserialize(toolConfigurationPath.Value);
return toolConfiguration;
}
private FilePath CreateTempProject( private FilePath CreateTempProject(
string packageId, string packageId,
PackageVersion packageVersion, PackageVersion packageVersion,
@ -153,9 +178,16 @@ namespace Microsoft.DotNet.ToolPackage
new XAttribute("Sdk", "Microsoft.NET.Sdk"), new XAttribute("Sdk", "Microsoft.NET.Sdk"),
new XElement("PropertyGroup", new XElement("PropertyGroup",
new XElement("TargetFramework", targetframework), new XElement("TargetFramework", targetframework),
new XElement("RestorePackagesPath", individualToolVersion.Value), new XElement("RestorePackagesPath", individualToolVersion.Value), // tool package will restore to tool folder
new XElement("RestoreSolutionDirectory", Directory.GetCurrentDirectory()), // https://github.com/NuGet/Home/issues/6199 new XElement("RestoreProjectStyle", "DotnetToolReference"), // without it, project cannot reference tool package
new XElement("DisableImplicitFrameworkReferences", "true") new XElement("RestoreRootConfigDirectory", Directory.GetCurrentDirectory()), // config file probing start directory
new XElement("DisableImplicitFrameworkReferences", "true"), // no Microsoft.NETCore.App in tool folder
new XElement("RestoreFallbackFolders", "clear"), // do not use fallbackfolder, tool package need to be copied to tool folder
new XElement("RestoreAdditionalProjectSources", // use fallbackfolder as feed to enable offline
Directory.Exists(_offlineFeedPath.Value) ? _offlineFeedPath.Value : string.Empty),
new XElement("RestoreAdditionalProjectFallbackFolders", string.Empty), // block other
new XElement("RestoreAdditionalProjectFallbackFoldersExcludes", string.Empty), // block other
new XElement("DisableImplicitNuGetFallbackFolder","true") // disable SDK side implicit NuGetFallbackFolder
), ),
packageVersion.IsConcreteValue packageVersion.IsConcreteValue
? new XElement("ItemGroup", ? new XElement("ItemGroup",

View file

@ -6,9 +6,7 @@ using System.Collections.Generic;
using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.Add;
using Microsoft.DotNet.Tools.Install.Tool; using Microsoft.DotNet.Tools.Install.Tool;
using LocalizableStrings = Microsoft.DotNet.Tools.Install.LocalizableStrings;
namespace Microsoft.DotNet.Tools.Install namespace Microsoft.DotNet.Tools.Install
{ {

View file

@ -21,6 +21,7 @@ namespace Microsoft.DotNet.Tools.Install.Tool
private static string _configFilePath; private static string _configFilePath;
private static string _framework; private static string _framework;
private static string _source; private static string _source;
private static bool _global;
public InstallToolCommand( public InstallToolCommand(
AppliedOption appliedCommand, AppliedOption appliedCommand,
@ -37,27 +38,28 @@ namespace Microsoft.DotNet.Tools.Install.Tool
_configFilePath = appliedCommand.ValueOrDefault<string>("configfile"); _configFilePath = appliedCommand.ValueOrDefault<string>("configfile");
_framework = appliedCommand.ValueOrDefault<string>("framework"); _framework = appliedCommand.ValueOrDefault<string>("framework");
_source = appliedCommand.ValueOrDefault<string>("source"); _source = appliedCommand.ValueOrDefault<string>("source");
_global = appliedCommand.ValueOrDefault<bool>("global");
} }
public override int Execute() public override int Execute()
{ {
var executablePackagePath = new DirectoryPath(new CliFolderPathCalculator().ExecutablePackagesPath); if (!_global)
{
throw new GracefulException(LocalizableStrings.InstallToolCommandOnlySupportGlobal);
}
var toolConfigurationAndExecutableDirectory = ObtainPackage(executablePackagePath); var cliFolderPathCalculator = new CliFolderPathCalculator();
var executablePackagePath = new DirectoryPath(cliFolderPathCalculator.ExecutablePackagesPath);
var offlineFeedPath = new DirectoryPath(cliFolderPathCalculator.CliFallbackFolderPath);
DirectoryPath executable = toolConfigurationAndExecutableDirectory var toolConfigurationAndExecutablePath = ObtainPackage(executablePackagePath, offlineFeedPath);
.ExecutableDirectory
.WithSubDirectories(
toolConfigurationAndExecutableDirectory
.Configuration
.ToolAssemblyEntryPoint);
var shellShimMaker = new ShellShimMaker(executablePackagePath.Value); var shellShimMaker = new ShellShimMaker(executablePackagePath.Value);
var commandName = toolConfigurationAndExecutableDirectory.Configuration.CommandName; var commandName = toolConfigurationAndExecutablePath.Configuration.CommandName;
shellShimMaker.EnsureCommandNameUniqueness(commandName); shellShimMaker.EnsureCommandNameUniqueness(commandName);
shellShimMaker.CreateShim( shellShimMaker.CreateShim(
executable.Value, toolConfigurationAndExecutablePath.Executable.Value,
commandName); commandName);
EnvironmentPathFactory EnvironmentPathFactory
@ -70,7 +72,9 @@ namespace Microsoft.DotNet.Tools.Install.Tool
return 0; return 0;
} }
private static ToolConfigurationAndExecutableDirectory ObtainPackage(DirectoryPath executablePackagePath) private static ToolConfigurationAndExecutablePath ObtainPackage(
DirectoryPath executablePackagePath,
DirectoryPath offlineFeedPath)
{ {
try try
{ {
@ -83,6 +87,7 @@ namespace Microsoft.DotNet.Tools.Install.Tool
var toolPackageObtainer = var toolPackageObtainer =
new ToolPackageObtainer( new ToolPackageObtainer(
executablePackagePath, executablePackagePath,
offlineFeedPath,
() => new DirectoryPath(Path.GetTempPath()) () => new DirectoryPath(Path.GetTempPath())
.WithSubDirectories(Path.GetRandomFileName()) .WithSubDirectories(Path.GetRandomFileName())
.WithFile(Path.GetRandomFileName() + ".csproj"), .WithFile(Path.GetRandomFileName() + ".csproj"),
@ -97,6 +102,7 @@ namespace Microsoft.DotNet.Tools.Install.Tool
targetframework: _framework, targetframework: _framework,
source: _source); source: _source);
} }
catch (PackageObtainException ex) catch (PackageObtainException ex)
{ {
throw new GracefulException( throw new GracefulException(

View file

@ -15,6 +15,10 @@ namespace Microsoft.DotNet.Cli
Accept.ExactlyOneArgument(errorMessage: o => LocalizableStrings.SpecifyExactlyOnePackageId) Accept.ExactlyOneArgument(errorMessage: o => LocalizableStrings.SpecifyExactlyOnePackageId)
.With(name: LocalizableStrings.PackageIdArgumentName, .With(name: LocalizableStrings.PackageIdArgumentName,
description: LocalizableStrings.PackageIdArgumentDescription), description: LocalizableStrings.PackageIdArgumentDescription),
Create.Option(
"-g|--global",
LocalizableStrings.GlobalOptionDescription,
Accept.NoArguments()),
Create.Option( Create.Option(
"--version", "--version",
LocalizableStrings.VersionOptionDescription, LocalizableStrings.VersionOptionDescription,

View file

@ -129,13 +129,13 @@
<data name="VersionOptionDescription" xml:space="preserve"> <data name="VersionOptionDescription" xml:space="preserve">
<value>Version of the tool package in NuGet.</value> <value>Version of the tool package in NuGet.</value>
</data> </data>
<data name="SourceOptionDescription" xml:space="preserve"> <data name="SourceOptionDescription" xml:space="preserve">
<value>Specifies a NuGet package source to use during installation.</value> <value>Specifies a NuGet package source to use during installation.</value>
</data> </data>
<data name="SourceOptionName" xml:space="preserve"> <data name="SourceOptionName" xml:space="preserve">
<value>SOURCE</value> <value>SOURCE</value>
</data> </data>
<data name="CommandDescription" xml:space="preserve"> <data name="CommandDescription" xml:space="preserve">
<value>Installs a tool for use on the command line.</value> <value>Installs a tool for use on the command line.</value>
</data> </data>
<data name="ConfigFileOptionDescription" xml:space="preserve"> <data name="ConfigFileOptionDescription" xml:space="preserve">
@ -172,4 +172,13 @@ The error was:
<value> <value>
The installation succeeded. If there are no further instructions, you can type the following command in shell directly to invoke: {0}</value> The installation succeeded. If there are no further instructions, you can type the following command in shell directly to invoke: {0}</value>
</data> </data>
<data name="GlobalOptionDescription" xml:space="preserve">
<value>Install user wide.</value>
</data>
<data name="InstallFullCommandNameLocalized" xml:space="preserve">
<value>.NET Install Command</value>
</data>
<data name="InstallToolCommandOnlySupportGlobal" xml:space="preserve">
<value>The --global switch (-g) is currently required because only user wide tools are supported.</value>
</data>
</root> </root>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -98,6 +98,21 @@ The error was:
<target state="new">Please specify one tool Package Id to install.</target> <target state="new">Please specify one tool Package Id to install.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="GlobalOptionDescription">
<source>Install user wide.</source>
<target state="new">Install user wide.</target>
<note />
</trans-unit>
<trans-unit id="InstallFullCommandNameLocalized">
<source>.NET Install Command</source>
<target state="new">.NET Install Command</target>
<note />
</trans-unit>
<trans-unit id="InstallToolCommandOnlySupportGlobal">
<source>The --global switch (-g) is currently required because only user wide tools are supported.</source>
<target state="new">The --global switch (-g) is currently required because only user wide tools are supported.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View file

@ -787,6 +787,16 @@ You can do this by running the following command:
setx PATH "%PATH%;{1}"</target> setx PATH "%PATH%;{1}"</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ToolPackageMissingEntryPointFile">
<source>Package '{0}' is missing entry point file {1}.</source>
<target state="new">Package '{0}' is missing entry point file {1}.</target>
<note />
</trans-unit>
<trans-unit id="ToolPackageMissingSettingsFile">
<source>Package '{0}' is missing tool settings file DotnetToolSettings.xml.</source>
<target state="new">Package '{0}' is missing tool settings file DotnetToolSettings.xml.</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View 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 FluentAssertions;
using Microsoft.DotNet.Tools.Test.Utilities;
using NuGet.ProjectModel;
using Xunit;
namespace Microsoft.DotNet.ToolPackage.Tests
{
public class LockFileMatcherTests : TestBase
{
[Theory]
[InlineData("tools/netcoreapp1.1/any/tool.dll", "tool.dll", true)]
[InlineData(@"tools\netcoreapp1.1\any\subDirectory\tool.dll", "subDirectory/tool.dll", true)]
[InlineData("tools/netcoreapp1.1/win-x64/tool.dll", "tool.dll", true)]
[InlineData("tools/netcoreapp1.1/any/subDirectory/tool.dll", "subDirectory/tool.dll", true)]
[InlineData("libs/netcoreapp1.1/any/tool.dll", "tool.dll", false)]
[InlineData("tools/netcoreapp1.1/any/subDirectory/tool.dll", "tool.dll", false)]
[InlineData("tools/netcoreapp1.1/any/subDirectory/tool.dll", "subDirectory/subDirectory/subDirectory/subDirectory/subDirectory/tool.dll", false)]
public void MatchesEntryPointTests(string pathInLockFileItem, string targetRelativeFilePath, bool shouldMatch)
{
LockFileMatcher.MatchesFile(new LockFileItem(pathInLockFileItem), targetRelativeFilePath)
.Should().Be(shouldMatch);
}
}
}

View file

@ -33,16 +33,15 @@
<None Update="DotnetToolSettingsGolden.xml"> <None Update="DotnetToolSettingsGolden.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Update="TestAssetLocalNugetFeed/*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Compile Remove="SampleGlobalTool/**" /> <Compile Remove="SampleGlobalTool/**" />
<Content Remove="SampleGlobalTool/**" /> <Content Remove="SampleGlobalTool/**" />
<EmbeddedResource Remove="SampleGlobalTool/**" /> <EmbeddedResource Remove="SampleGlobalTool/**" />
<None Remove="SampleGlobalTool/**" /> <None Remove="SampleGlobalTool/**" />
</ItemGroup> </ItemGroup>
<UsingTask TaskName="DownloadFile" AssemblyFile="$(CLIBuildDll)" />
<Target Name="CreateNupkgFromSource" BeforeTargets="Build"> <Target Name="CreateNupkgFromSource" BeforeTargets="Build">
<PropertyGroup> <PropertyGroup>
<testAssetSourceRoot>$(BaseOutputPath)/TestAsset/SampleGlobalTool</testAssetSourceRoot> <testAssetSourceRoot>$(BaseOutputPath)/TestAsset/SampleGlobalTool</testAssetSourceRoot>
@ -53,4 +52,16 @@
<MSBuild BuildInParallel="False" Projects="SampleGlobalTool/consoledemo.csproj" Targets="pack" Properties="Configuration=Release;NuspecFile=includepublish.nuspec;NuspecBasePath=$(testAssetSourceRoot);PackageOutputPath=$(OutputPath)/TestAssetLocalNugetFeed"> <MSBuild BuildInParallel="False" Projects="SampleGlobalTool/consoledemo.csproj" Targets="pack" Properties="Configuration=Release;NuspecFile=includepublish.nuspec;NuspecBasePath=$(testAssetSourceRoot);PackageOutputPath=$(OutputPath)/TestAssetLocalNugetFeed">
</MSBuild> </MSBuild>
</Target> </Target>
<Target Name="DownloadTestAssetPackages" BeforeTargets="Build">
<PropertyGroup>
<!-- use a prerelease version that supports alpine -->
<PlatformsNupkgFileName>microsoft.netcore.platforms.2.1.0-preview1-26115-04.nupkg</PlatformsNupkgFileName>
<PlatformsNupkgUri>https://dotnet.myget.org/F/dotnet-core/api/v2/package/Microsoft.NETCore.Platforms/2.1.0-preview1-26115-04</PlatformsNupkgUri>
</PropertyGroup>
<DownloadFile Uri="$(PlatformsNupkgUri)"
DestinationPath="$(OutputPath)/TestAssetLocalNugetFeed/$(PlatformsNupkgFileName)" />
</Target>
</Project> </Project>

View file

@ -5,9 +5,15 @@
<version>1.0.4</version> <version>1.0.4</version>
<description>test app</description> <description>test app</description>
<authors>testauthor</authors> <authors>testauthor</authors>
<packageTypes>
<packageType name="DotnetTool" />
</packageTypes>
<dependencies>
<dependency id="Microsoft.NETCore.Platforms" version="2.1.0-preview1-26115-04" />
</dependencies>
</metadata> </metadata>
<files> <files>
<file src="bin\Release\netcoreapp2.1\publish\*.*" target="tools\netcoreapp2.1\any\" /> <file src="bin\Release\netcoreapp2.1\publish\*.*" target="tools\netcoreapp2.1\any\" />
<file src="DotnetToolSettings.xml" target="tools\DotnetToolSettings.xml" /> <file src="DotnetToolSettings.xml" target="tools\netcoreapp2.1\any\DotnetToolSettings.xml" />
</files> </files>
</package> </package>

View file

@ -23,24 +23,67 @@ namespace Microsoft.DotNet.ToolPackage.Tests
var packageObtainer = var packageObtainer =
ConstructDefaultPackageObtainer(toolsPath); ConstructDefaultPackageObtainer(toolsPath);
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory = packageObtainer.ObtainAndReturnExecutablePath( ToolConfigurationAndExecutablePath toolConfigurationAndExecutablePath = packageObtainer.ObtainAndReturnExecutablePath(
packageId: TestPackageId, packageId: TestPackageId,
packageVersion: TestPackageVersion, packageVersion: TestPackageVersion,
nugetconfig: nugetConfigPath, nugetconfig: nugetConfigPath,
targetframework: _testTargetframework); targetframework: _testTargetframework);
var executable = toolConfigurationAndExecutableDirectory var executable = toolConfigurationAndExecutablePath
.ExecutableDirectory .Executable;
.WithFile(
toolConfigurationAndExecutableDirectory
.Configuration
.ToolAssemblyEntryPoint);
File.Exists(executable.Value) File.Exists(executable.Value)
.Should() .Should()
.BeTrue(executable + " should have the executable"); .BeTrue(executable + " should have the executable");
} }
[Fact]
public void GivenNoFeedItThrows()
{
var toolsPath = Path.Combine(Directory.GetCurrentDirectory(), Path.GetRandomFileName());
ToolPackageObtainer packageObtainer =
ConstructDefaultPackageObtainer(toolsPath);
Action a = () => packageObtainer.ObtainAndReturnExecutablePath(
packageId: TestPackageId,
packageVersion: TestPackageVersion,
targetframework: _testTargetframework);
a.ShouldThrow<PackageObtainException>();
}
[Fact]
public void GivenOfflineFeedWhenCallItCanDownloadThePackage()
{
var toolsPath = Path.Combine(Directory.GetCurrentDirectory(), Path.GetRandomFileName());
ToolPackageObtainer packageObtainer =
new ToolPackageObtainer(
toolsPath: new DirectoryPath(toolsPath),
offlineFeedPath: new DirectoryPath(GetTestLocalFeedPath()),
getTempProjectPath: GetUniqueTempProjectPathEachTest,
bundledTargetFrameworkMoniker: new Lazy<string>(),
packageToProjectFileAdder: new PackageToProjectFileAdder(),
projectRestorer: new ProjectRestorer());
ToolConfigurationAndExecutablePath toolConfigurationAndExecutablePath =
packageObtainer.ObtainAndReturnExecutablePath(
packageId: TestPackageId,
packageVersion: TestPackageVersion,
targetframework: _testTargetframework);
var executable = toolConfigurationAndExecutablePath
.Executable;
File.Exists(executable.Value)
.Should()
.BeTrue(executable + " should have the executable");
executable.Value.Should().NotContain(GetTestLocalFeedPath(), "Executalbe should not be still in fallbackfolder");
executable.Value.Should().Contain(toolsPath, "Executalbe should be copied to tools Path");
}
[Fact] [Fact]
public void GivenNugetConfigAndPackageNameAndVersionAndTargetFrameworkWhenCallItCreateAssetFile() public void GivenNugetConfigAndPackageNameAndVersionAndTargetFrameworkWhenCallItCreateAssetFile()
{ {
@ -49,15 +92,23 @@ namespace Microsoft.DotNet.ToolPackage.Tests
var packageObtainer = var packageObtainer =
ConstructDefaultPackageObtainer(toolsPath); ConstructDefaultPackageObtainer(toolsPath);
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory =
packageObtainer.ObtainAndReturnExecutablePath(
packageId: TestPackageId,
packageVersion: TestPackageVersion,
nugetconfig: nugetConfigPath,
targetframework: _testTargetframework);
var assetJsonPath = toolConfigurationAndExecutableDirectory ToolConfigurationAndExecutablePath toolConfigurationAndExecutablePath = packageObtainer.ObtainAndReturnExecutablePath(
.ExecutableDirectory packageId: TestPackageId,
packageVersion: TestPackageVersion,
nugetconfig: nugetConfigPath,
targetframework: _testTargetframework);
/*
From mytool.dll to project.assets.json
.dotnet/.tools/packageid/version/packageid/version/mytool.dll
/dependency1 package id/
/dependency2 package id/
/project.assets.json
*/
var assetJsonPath = toolConfigurationAndExecutablePath
.Executable
.GetDirectoryPath()
.GetParentPath() .GetParentPath()
.GetParentPath() .GetParentPath()
.GetParentPath() .GetParentPath()
@ -89,21 +140,18 @@ namespace Microsoft.DotNet.ToolPackage.Tests
var packageObtainer = var packageObtainer =
new ToolPackageObtainer( new ToolPackageObtainer(
new DirectoryPath(toolsPath), new DirectoryPath(toolsPath),
new DirectoryPath("no such path"),
() => uniqueTempProjectPath, () => uniqueTempProjectPath,
new Lazy<string>(), new Lazy<string>(),
new PackageToProjectFileAdder(), new PackageToProjectFileAdder(),
new ProjectRestorer()); new ProjectRestorer());
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory = packageObtainer.ObtainAndReturnExecutablePath( ToolConfigurationAndExecutablePath toolConfigurationAndExecutablePath =
packageId: TestPackageId, packageObtainer.ObtainAndReturnExecutablePath(
packageVersion: TestPackageVersion, packageId: TestPackageId,
targetframework: _testTargetframework); packageVersion: TestPackageVersion,
targetframework: _testTargetframework);
var executable = toolConfigurationAndExecutableDirectory var executable = toolConfigurationAndExecutablePath.Executable;
.ExecutableDirectory
.WithFile(
toolConfigurationAndExecutableDirectory
.Configuration
.ToolAssemblyEntryPoint);
File.Exists(executable.Value) File.Exists(executable.Value)
.Should() .Should()
@ -118,17 +166,13 @@ namespace Microsoft.DotNet.ToolPackage.Tests
var packageObtainer = var packageObtainer =
ConstructDefaultPackageObtainer(toolsPath); ConstructDefaultPackageObtainer(toolsPath);
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory = packageObtainer.ObtainAndReturnExecutablePath( ToolConfigurationAndExecutablePath toolConfigurationAndExecutablePath = packageObtainer.ObtainAndReturnExecutablePath(
packageId: TestPackageId, packageId: TestPackageId,
packageVersion: TestPackageVersion,
nugetconfig: nugetConfigPath, nugetconfig: nugetConfigPath,
targetframework: _testTargetframework); targetframework: _testTargetframework);
var executable = toolConfigurationAndExecutableDirectory var executable = toolConfigurationAndExecutablePath.Executable;
.ExecutableDirectory
.WithFile(
toolConfigurationAndExecutableDirectory
.Configuration
.ToolAssemblyEntryPoint);
File.Exists(executable.Value) File.Exists(executable.Value)
.Should() .Should()
@ -167,22 +211,18 @@ namespace Microsoft.DotNet.ToolPackage.Tests
var packageObtainer = var packageObtainer =
new ToolPackageObtainer( new ToolPackageObtainer(
new DirectoryPath(toolsPath), new DirectoryPath(toolsPath),
new DirectoryPath("no such path"),
GetUniqueTempProjectPathEachTest, GetUniqueTempProjectPathEachTest,
new Lazy<string>(() => BundledTargetFramework.GetTargetFrameworkMoniker()), new Lazy<string>(() => BundledTargetFramework.GetTargetFrameworkMoniker()),
new PackageToProjectFileAdder(), new PackageToProjectFileAdder(),
new ProjectRestorer()); new ProjectRestorer());
ToolConfigurationAndExecutableDirectory toolConfigurationAndExecutableDirectory = ToolConfigurationAndExecutablePath toolConfigurationAndExecutablePath =
packageObtainer.ObtainAndReturnExecutablePath( packageObtainer.ObtainAndReturnExecutablePath(
packageId: TestPackageId, packageId: TestPackageId,
packageVersion: TestPackageVersion, packageVersion: TestPackageVersion,
nugetconfig: nugetConfigPath); nugetconfig: nugetConfigPath);
var executable = toolConfigurationAndExecutableDirectory var executable = toolConfigurationAndExecutablePath.Executable;
.ExecutableDirectory
.WithFile(
toolConfigurationAndExecutableDirectory
.Configuration
.ToolAssemblyEntryPoint);
File.Exists(executable.Value) File.Exists(executable.Value)
.Should() .Should()
@ -205,7 +245,6 @@ namespace Microsoft.DotNet.ToolPackage.Tests
a.ShouldThrow<PackageObtainException>() a.ShouldThrow<PackageObtainException>()
.And .And
.Message.Should().Contain("does not exist"); .Message.Should().Contain("does not exist");
} }
[Fact] [Fact]
@ -218,16 +257,9 @@ namespace Microsoft.DotNet.ToolPackage.Tests
packageId: TestPackageId, packageId: TestPackageId,
packageVersion: TestPackageVersion, packageVersion: TestPackageVersion,
targetframework: _testTargetframework, targetframework: _testTargetframework,
source: Path.Combine( source: GetTestLocalFeedPath());
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"TestAssetLocalNugetFeed"));
var executable = toolConfigurationAndExecutableDirectory var executable = toolConfigurationAndExecutableDirectory.Executable;
.ExecutableDirectory
.WithFile(
toolConfigurationAndExecutableDirectory
.Configuration
.ToolAssemblyEntryPoint);
File.Exists(executable.Value) File.Exists(executable.Value)
.Should() .Should()
@ -247,6 +279,7 @@ namespace Microsoft.DotNet.ToolPackage.Tests
{ {
return new ToolPackageObtainer( return new ToolPackageObtainer(
new DirectoryPath(toolsPath), new DirectoryPath(toolsPath),
new DirectoryPath("no such path"),
GetUniqueTempProjectPathEachTest, GetUniqueTempProjectPathEachTest,
new Lazy<string>(), new Lazy<string>(),
new PackageToProjectFileAdder(), new PackageToProjectFileAdder(),
@ -256,7 +289,6 @@ namespace Microsoft.DotNet.ToolPackage.Tests
private static FilePath WriteNugetConfigFileToPointToTheFeed() private static FilePath WriteNugetConfigFileToPointToTheFeed()
{ {
var nugetConfigName = "nuget.config"; var nugetConfigName = "nuget.config";
var executeDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var tempPathForNugetConfigWithWhiteSpace = var tempPathForNugetConfigWithWhiteSpace =
Path.Combine(Path.GetTempPath(), Path.Combine(Path.GetTempPath(),
@ -266,10 +298,13 @@ namespace Microsoft.DotNet.ToolPackage.Tests
NuGetConfig.Write( NuGetConfig.Write(
directory: tempPathForNugetConfigWithWhiteSpace, directory: tempPathForNugetConfigWithWhiteSpace,
configname: nugetConfigName, configname: nugetConfigName,
localFeedPath: Path.Combine(executeDirectory, "TestAssetLocalNugetFeed")); localFeedPath: GetTestLocalFeedPath());
return new FilePath(Path.GetFullPath(Path.Combine(tempPathForNugetConfigWithWhiteSpace, nugetConfigName))); return new FilePath(Path.GetFullPath(Path.Combine(tempPathForNugetConfigWithWhiteSpace, nugetConfigName)));
} }
private static string GetTestLocalFeedPath() => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestAssetLocalNugetFeed");
private readonly string _testTargetframework = BundledTargetFramework.GetTargetFrameworkMoniker(); private readonly string _testTargetframework = BundledTargetFramework.GetTargetFrameworkMoniker();
private const string TestPackageVersion = "1.0.4"; private const string TestPackageVersion = "1.0.4";
private const string TestPackageId = "global.tool.console.demo"; private const string TestPackageId = "global.tool.console.demo";

View file

@ -24,7 +24,7 @@ namespace Microsoft.DotNet.Tests.ParserTests
public void InstallGlobaltoolParserCanGetPackageIdAndPackageVersion() public void InstallGlobaltoolParserCanGetPackageIdAndPackageVersion()
{ {
var command = Parser.Instance; var command = Parser.Instance;
var result = command.Parse("dotnet install tool console.test.app --version 1.0.1"); var result = command.Parse("dotnet install tool -g console.test.app --version 1.0.1");
var parseResult = result["dotnet"]["install"]["tool"]; var parseResult = result["dotnet"]["install"]["tool"];
@ -41,7 +41,7 @@ namespace Microsoft.DotNet.Tests.ParserTests
var command = Parser.Instance; var command = Parser.Instance;
var result = var result =
command.Parse( command.Parse(
@"dotnet install tool console.test.app --version 1.0.1 --framework netcoreapp2.0 --configfile C:\TestAssetLocalNugetFeed"); @"dotnet install tool -g console.test.app --version 1.0.1 --framework netcoreapp2.0 --configfile C:\TestAssetLocalNugetFeed");
var parseResult = result["dotnet"]["install"]["tool"]; var parseResult = result["dotnet"]["install"]["tool"];
@ -54,10 +54,19 @@ namespace Microsoft.DotNet.Tests.ParserTests
{ {
const string expectedSourceValue = "TestSourceValue"; const string expectedSourceValue = "TestSourceValue";
var result = Parser.Instance.Parse($"dotnet install tool --source {expectedSourceValue} console.test.app"); var result = Parser.Instance.Parse($"dotnet install tool -g --source {expectedSourceValue} console.test.app");
var appliedOptions = result["dotnet"]["install"]["tool"]; var appliedOptions = result["dotnet"]["install"]["tool"];
appliedOptions.ValueOrDefault<string>("source").Should().Be(expectedSourceValue); appliedOptions.ValueOrDefault<string>("source").Should().Be(expectedSourceValue);
} }
[Fact]
public void InstallToolParserCanGetGlobalOption()
{
var result = Parser.Instance.Parse("dotnet install tool -g console.test.app");
var appliedOptions = result["dotnet"]["install"]["tool"];
appliedOptions.ValueOrDefault<bool>("global").Should().Be(true);
}
} }
} }