private bool TryGetPackagedShim( IReadOnlyList <FilePath> packagedShims, ToolCommandName commandName, out FilePath?packagedShim) { packagedShim = null; if (packagedShims != null && packagedShims.Count > 0) { FilePath[] candidatepackagedShim = packagedShims .Where(s => string.Equals( Path.GetFileName(s.Value), Path.GetFileName(GetShimPath(commandName).Value))).ToArray(); if (candidatepackagedShim.Length > 1) { throw new ShellShimException( string.Format( CommonLocalizableStrings.MoreThanOnePackagedShimAvailable, string.Join(';', candidatepackagedShim))); } if (candidatepackagedShim.Length == 1) { packagedShim = candidatepackagedShim.Single(); return(true); } } return(false); }
private (FilePath, LocalToolsCommandResolver) DefaultSetup(string toolCommand) { NuGetVersion packageVersionA = NuGetVersion.Parse("1.0.4"); _fileSystem.File.WriteAllText(Path.Combine(_testDirectoryRoot, ManifestFilename), _jsonContent.Replace("$TOOLCOMMAND$", toolCommand)); ToolManifestFinder toolManifest = new ToolManifestFinder(new DirectoryPath(_testDirectoryRoot), _fileSystem, new FakeDangerousFileDetector()); ToolCommandName toolCommandNameA = new ToolCommandName(toolCommand); FilePath fakeExecutable = _nugetGlobalPackagesFolder.WithFile("fakeExecutable.dll"); _fileSystem.Directory.CreateDirectory(_nugetGlobalPackagesFolder.Value); _fileSystem.File.CreateEmptyFile(fakeExecutable.Value); _localToolsResolverCache.Save( new Dictionary <RestoredCommandIdentifier, RestoredCommand> { [new RestoredCommandIdentifier( new PackageId("local.tool.console.a"), packageVersionA, NuGetFramework.Parse(BundledTargetFramework.GetTargetFrameworkMoniker()), Constants.AnyRid, toolCommandNameA)] = new RestoredCommand(toolCommandNameA, "dotnet", fakeExecutable) }); var localToolsCommandResolver = new LocalToolsCommandResolver( toolManifest, _localToolsResolverCache, _fileSystem); return(fakeExecutable, localToolsCommandResolver); }
public void CreateShim(FilePath targetExecutablePath, ToolCommandName commandName, IReadOnlyList <FilePath> packagedShims = null) { if (string.IsNullOrEmpty(targetExecutablePath.Value)) { throw new ShellShimException(CommonLocalizableStrings.CannotCreateShimForEmptyExecutablePath); } if (ShimExists(commandName)) { throw new ShellShimException( string.Format( CommonLocalizableStrings.ShellShimConflict, commandName)); } TransactionalAction.Run( action: () => { try { if (!_fileSystem.Directory.Exists(_shimsDirectory.Value)) { _fileSystem.Directory.CreateDirectory(_shimsDirectory.Value); } if (TryGetPackagedShim(packagedShims, commandName, out FilePath? packagedShim)) { _fileSystem.File.Copy(packagedShim.Value.Value, GetShimPath(commandName).Value); _filePermissionSetter.SetUserExecutionPermission(GetShimPath(commandName).Value); } else { _appHostShellShimMaker.CreateApphostShellShim( targetExecutablePath, GetShimPath(commandName)); } } catch (FilePermissionSettingException ex) { throw new ShellShimException( string.Format(CommonLocalizableStrings.FailedSettingShimPermissions, ex.Message)); } catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException) { throw new ShellShimException( string.Format( CommonLocalizableStrings.FailedToCreateShellShim, commandName, ex.Message ), ex); } }, rollback: () => { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { File.Delete(file.Value); } }); }
private CommandSpec GetPackageCommandSpecUsingMuxer(CommandResolverArguments arguments, ToolCommandName toolCommandName) { if (!_toolManifest.TryFind(toolCommandName, out var toolManifestPackage)) { return(null); } if (_localToolsResolverCache.TryLoad( new RestoredCommandIdentifier( toolManifestPackage.PackageId, toolManifestPackage.Version, NuGetFramework.Parse(BundledTargetFramework.GetTargetFrameworkMoniker()), Constants.AnyRid, toolCommandName), _nugetGlobalPackagesFolder, out var restoredCommand)) { if (!_fileSystem.File.Exists(restoredCommand.Executable.Value)) { throw new GracefulException(string.Format(LocalizableStrings.NeedRunToolRestore, toolCommandName.ToString())); } return(MuxerCommandSpecMaker.CreatePackageCommandSpecUsingMuxer( restoredCommand.Executable.Value, arguments.CommandArguments)); } return(null); }
public bool TryFind(ToolCommandName toolCommandName, out ToolManifestPackage toolManifestPackage) { toolManifestPackage = default(ToolManifestPackage); foreach (FilePath possibleManifest in EnumerateDefaultAllPossibleManifests()) { if (!_fileSystem.File.Exists(possibleManifest.Value)) { continue; } SerializableLocalToolsManifest deserializedManifest = DeserializeLocalToolsManifest(possibleManifest); List <ToolManifestPackage> toolManifestPackages = GetToolManifestPackageFromOneManifestFile(deserializedManifest, possibleManifest); foreach (var package in toolManifestPackages) { if (package.CommandNames.Contains(toolCommandName)) { toolManifestPackage = package; return(true); } } if (deserializedManifest.isRoot.Value) { return(false); } } return(false); }
public void ItShouldFailWhenPackageCommandNameDoesNotMatchManifestCommands() { ToolCommandName differentCommandNameA = new ToolCommandName("different-command-nameA"); ToolCommandName differentCommandNameB = new ToolCommandName("different-command-nameB"); IToolManifestFinder manifestFinder = new MockManifestFinder(new[] { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] { differentCommandNameA, differentCommandNameB }, new DirectoryPath(_temporaryDirectory)), }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_appliedCommand, _parseResult, _toolPackageInstallerMock, manifestFinder, _localToolsResolverCache, _fileSystem, _nugetGlobalPackagesFolder, _reporter ); toolRestoreCommand.Execute().Should().Be(1); _reporter.Lines.Should() .Contain(l => l.Contains( string.Format(LocalizableStrings.CommandsMismatch, "\"different-command-nameA\" \"different-command-nameB\"", _packageIdA, "\"a\""))); }
public RestoredCommand( ToolCommandName name, string runner, FilePath executable) { Name = name; Runner = runner ?? throw new ArgumentNullException(nameof(runner)); Executable = executable; }
private FilePath GetShimPath(ToolCommandName commandName) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return(_shimsDirectory.WithFile(commandName.Value + ".exe")); } else { return(_shimsDirectory.WithFile(commandName.Value)); } }
private FilePath GetShimPath(ToolCommandName commandName) { if (OperatingSystem.IsWindows()) { return(_shimsDirectory.WithFile(commandName.Value + ".exe")); } else { return(_shimsDirectory.WithFile(commandName.Value)); } }
public RestoredCommandIdentifierVersionRange( PackageId packageId, VersionRange versionRange, NuGetFramework targetFramework, string runtimeIdentifier, ToolCommandName commandName) { PackageId = packageId; VersionRange = versionRange ?? throw new ArgumentException(nameof(versionRange)); TargetFramework = targetFramework ?? throw new ArgumentException(nameof(targetFramework)); RuntimeIdentifier = runtimeIdentifier ?? throw new ArgumentException(nameof(runtimeIdentifier)); CommandName = commandName; }
public void ItCanFindToolExecutable() { var toolCommand = "a"; NuGetVersion packageVersionA = NuGetVersion.Parse("1.0.4"); _fileSystem.File.WriteAllText(Path.Combine(_testDirectoryRoot, ManifestFilename), _jsonContent.Replace("$TOOLCOMMAND$", toolCommand)); ToolManifestFinder toolManifest = new ToolManifestFinder(new DirectoryPath(_testDirectoryRoot), _fileSystem); ToolCommandName toolCommandNameA = new ToolCommandName(toolCommand); var fakeExecutable = _nugetGlobalPackagesFolder.WithFile("fakeExecutable.dll"); _fileSystem.Directory.CreateDirectory(_nugetGlobalPackagesFolder.Value); _fileSystem.File.CreateEmptyFile(fakeExecutable.Value); _localToolsResolverCache.Save( new Dictionary <RestoredCommandIdentifier, RestoredCommand> { [new RestoredCommandIdentifier( new PackageId("local.tool.console.a"), packageVersionA, NuGetFramework.Parse(BundledTargetFramework.GetTargetFrameworkMoniker()), Constants.AnyRid, toolCommandNameA)] = new RestoredCommand(toolCommandNameA, "dotnet", fakeExecutable) }, _nugetGlobalPackagesFolder); var localToolsCommandResolver = new LocalToolsCommandResolver( toolManifest, _localToolsResolverCache, _fileSystem, _nugetGlobalPackagesFolder); var result = localToolsCommandResolver.Resolve(new CommandResolverArguments() { CommandName = "dotnet-a", }); result.Should().NotBeNull(); var commandPath = result.Args.Trim('"'); _fileSystem.File.Exists(commandPath).Should().BeTrue("the following path exists: " + commandPath); commandPath.Should().Be(fakeExecutable.Value); }
public void WhenNuGetGlobalPackageLocationIsCleanedAfterRestoreItShowError() { ToolCommandName toolCommandNameA = new ToolCommandName("a"); NuGetVersion packageVersionA = NuGetVersion.Parse("1.0.4"); _fileSystem.File.WriteAllText(Path.Combine(_testDirectoryRoot, ManifestFilename), _jsonContent.Replace("$TOOLCOMMAND$", toolCommandNameA.Value)); ToolManifestFinder toolManifest = new ToolManifestFinder(new DirectoryPath(_testDirectoryRoot), _fileSystem); var fakeExecutable = _nugetGlobalPackagesFolder.WithFile("fakeExecutable.dll"); _fileSystem.Directory.CreateDirectory(_nugetGlobalPackagesFolder.Value); _fileSystem.File.CreateEmptyFile(fakeExecutable.Value); _localToolsResolverCache.Save( new Dictionary <RestoredCommandIdentifier, RestoredCommand> { [new RestoredCommandIdentifier( new PackageId("local.tool.console.a"), packageVersionA, NuGetFramework.Parse(BundledTargetFramework.GetTargetFrameworkMoniker()), Constants.AnyRid, toolCommandNameA)] = new RestoredCommand(toolCommandNameA, "dotnet", fakeExecutable) }, _nugetGlobalPackagesFolder); var localToolsCommandResolver = new LocalToolsCommandResolver( toolManifest, _localToolsResolverCache, _fileSystem, _nugetGlobalPackagesFolder); _fileSystem.File.Delete(fakeExecutable.Value); Action action = () => localToolsCommandResolver.Resolve(new CommandResolverArguments() { CommandName = $"dotnet-{toolCommandNameA.ToString()}", }); action.ShouldThrow <GracefulException>(string.Format(CommandFactory.LocalizableStrings.NeedRunToolRestore, toolCommandNameA.ToString())); }
public void RemoveShim(ToolCommandName commandName) { var files = new Dictionary <string, string>(); TransactionalAction.Run( action: () => { try { foreach (var file in GetShimFiles(commandName).Where(f => _fileSystem.File.Exists(f.Value))) { var tempPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(file.Value, tempPath)); files[file.Value] = tempPath; } } catch (Exception ex) when(ex is UnauthorizedAccessException || ex is IOException) { throw new ShellShimException( string.Format( CommonLocalizableStrings.FailedToRemoveShellShim, commandName.ToString(), ex.Message ), ex); } }, commit: () => { foreach (var value in files.Values) { _fileSystem.File.Delete(value); } }, rollback: () => { foreach (var kvp in files) { FileAccessRetrier.RetryOnMoveAccessFailure(() => _fileSystem.File.Move(kvp.Value, kvp.Key)); } }); }
public void WhenNuGetGlobalPackageLocationIsNotRestoredItThrowsGracefulException() { ToolCommandName toolCommandNameA = new ToolCommandName("a"); NuGetVersion packageVersionA = NuGetVersion.Parse("1.0.4"); _fileSystem.File.WriteAllText(Path.Combine(_testDirectoryRoot, ManifestFilename), _jsonContent.Replace("$TOOLCOMMAND$", toolCommandNameA.Value)); ToolManifestFinder toolManifest = new ToolManifestFinder(new DirectoryPath(_testDirectoryRoot), _fileSystem); var localToolsCommandResolver = new LocalToolsCommandResolver( toolManifest, _localToolsResolverCache, _fileSystem); Action action = () => localToolsCommandResolver.ResolveStrict(new CommandResolverArguments() { CommandName = $"dotnet-{toolCommandNameA.ToString()}", }); action.ShouldThrow <GracefulException>(string.Format(CommandFactory.LocalizableStrings.NeedRunToolRestore, toolCommandNameA.ToString())); }
private IEnumerable <FilePath> GetShimFiles(ToolCommandName commandName) { yield return(GetShimPath(commandName)); }
private List <ToolManifestPackage> GetToolManifestPackageFromOneManifestFile( SerializableLocalToolsManifest deserializedManifest, FilePath path) { List <ToolManifestPackage> result = new List <ToolManifestPackage>(); var errors = new List <string>(); if (deserializedManifest.version == 0) { errors.Add(string.Format(LocalizableStrings.ManifestVersion0, path.Value)); } if (deserializedManifest.version > SupportedVersion) { errors.Add( string.Format( LocalizableStrings.ManifestVersionHigherThanSupported, deserializedManifest.version, SupportedVersion, path.Value)); } foreach (KeyValuePair <string, SerializableLocalToolSinglePackage> tools in deserializedManifest.tools) { var packageLevelErrors = new List <string>(); var packageIdString = tools.Key; var packageId = new PackageId(packageIdString); string versionString = tools.Value.version; NuGetVersion version = null; if (versionString is null) { packageLevelErrors.Add(LocalizableStrings.ToolMissingVersion); } else { if (!NuGetVersion.TryParse(versionString, out version)) { packageLevelErrors.Add(string.Format(LocalizableStrings.VersionIsInvalid, versionString)); } } NuGetFramework targetFramework = null; var targetFrameworkString = tools.Value.targetFramework; if (targetFrameworkString != null) { targetFramework = NuGetFramework.Parse( targetFrameworkString); if (targetFramework.IsUnsupported) { packageLevelErrors.Add( string.Format(LocalizableStrings.TargetFrameworkIsUnsupported, targetFrameworkString)); } } if (tools.Value.commands == null || (tools.Value.commands != null && tools.Value.commands.Length == 0)) { packageLevelErrors.Add(LocalizableStrings.FieldCommandsIsMissing); } if (packageLevelErrors.Any()) { var joinedWithIndentation = string.Join(Environment.NewLine, packageLevelErrors.Select(e => "\t\t" + e)); errors.Add(string.Format(LocalizableStrings.InPackage, packageId.ToString(), joinedWithIndentation)); } else { result.Add(new ToolManifestPackage( packageId, version, ToolCommandName.Convert(tools.Value.commands))); } } if (errors.Any()) { throw new ToolManifestException( string.Format(LocalizableStrings.InvalidManifestFilePrefix, string.Join(Environment.NewLine, errors.Select(e => "\t" + e)))); } return(result); }
public IReadOnlyCollection <ToolManifestPackage> Find(FilePath?filePath = null) { var result = new List <ToolManifestPackage>(); IEnumerable <FilePath> allPossibleManifests = filePath != null ? new[] { filePath.Value } : EnumerateDefaultAllPossibleManifests(); foreach (FilePath possibleManifest in allPossibleManifests) { if (_fileSystem.File.Exists(possibleManifest.Value)) { SerializableLocalToolsManifest deserializedManifest = JsonConvert.DeserializeObject <SerializableLocalToolsManifest>( _fileSystem.File.ReadAllText(possibleManifest.Value), new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Ignore }); var errors = new List <string>(); if (!deserializedManifest.isRoot) { errors.Add("isRoot is false is not supported."); } if (deserializedManifest.version != 1) { errors.Add(string.Format("Tools manifest format version {0} is not supported.", deserializedManifest.version)); } foreach (var tools in deserializedManifest.tools) { var packageLevelErrors = new List <string>(); var packageIdString = tools.Key; var packageId = new PackageId(packageIdString); string versionString = tools.Value.version; NuGetVersion version = null; if (versionString is null) { packageLevelErrors.Add(LocalizableStrings.MissingVersion); } else { var versionParseResult = NuGetVersion.TryParse( versionString, out version); if (!versionParseResult) { packageLevelErrors.Add(string.Format(LocalizableStrings.VersionIsInvalid, versionString)); } } if (tools.Value.commands == null || (tools.Value.commands != null && tools.Value.commands.Length == 0)) { packageLevelErrors.Add(LocalizableStrings.FieldCommandsIsMissing); } if (packageLevelErrors.Any()) { var joined = string.Join(string.Empty, packageLevelErrors.Select(e => Environment.NewLine + " " + e)); errors.Add(string.Format(LocalizableStrings.InPackage, packageId.ToString()) + joined); } else { result.Add(new ToolManifestPackage( packageId, version, ToolCommandName.Convert(tools.Value.commands))); } } if (errors.Any()) { throw new ToolManifestException(LocalizableStrings.InvalidManifestFilePrefix + string.Join(string.Empty, errors.Select(e => Environment.NewLine + " " + e))); } return(result); } } throw new ToolManifestCannotFindException( string.Format(LocalizableStrings.CannotFindAnyManifestsFileSearched, string.Join(Environment.NewLine, allPossibleManifests.Select(f => f.Value)))); }
private List <ToolManifestPackage> GetToolManifestPackageFromOneManifestFile( SerializableLocalToolsManifest deserializedManifest, FilePath path, DirectoryPath correspondingDirectory) { List <ToolManifestPackage> result = new List <ToolManifestPackage>(); var errors = new List <string>(); ValidateVersion(deserializedManifest, errors); if (!deserializedManifest.IsRoot.HasValue) { errors.Add(string.Format(LocalizableStrings.ManifestMissingIsRoot, path.Value)); } foreach (KeyValuePair <string, SerializableLocalToolSinglePackage> tools in (deserializedManifest.Tools ?? new Dictionary <string, SerializableLocalToolSinglePackage>())) { var packageLevelErrors = new List <string>(); var packageIdString = tools.Key; var packageId = new PackageId(packageIdString); string versionString = tools.Value.Version; NuGetVersion version = null; if (versionString is null) { packageLevelErrors.Add(LocalizableStrings.ToolMissingVersion); } else { if (!NuGetVersion.TryParse(versionString, out version)) { packageLevelErrors.Add(string.Format(LocalizableStrings.VersionIsInvalid, versionString)); } } if (tools.Value.Commands == null || (tools.Value.Commands != null && tools.Value.Commands.Length == 0)) { packageLevelErrors.Add(LocalizableStrings.FieldCommandsIsMissing); } if (packageLevelErrors.Any()) { var joinedWithIndentation = string.Join(Environment.NewLine, packageLevelErrors.Select(e => "\t\t" + e)); errors.Add(string.Format(LocalizableStrings.InPackage, packageId.ToString(), joinedWithIndentation)); } else { result.Add(new ToolManifestPackage( packageId, version, ToolCommandName.Convert(tools.Value.Commands), correspondingDirectory)); } } if (errors.Any()) { throw new ToolManifestException( string.Format(LocalizableStrings.InvalidManifestFilePrefix, path.Value, string.Join(Environment.NewLine, errors.Select(e => "\t" + e)))); } return(result); }
private bool ShimExists(ToolCommandName commandName) { return(GetShimFiles(commandName).Any(p => _fileSystem.File.Exists(p.Value))); }