dotnet-installer/src/dotnet/ShellShim/ShellShimMaker.cs

119 lines
4.3 KiB
C#
Raw Normal View History

// 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.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml.Linq;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools;
using Microsoft.Extensions.EnvironmentAbstractions;
namespace Microsoft.DotNet.ShellShim
{
public class ShellShimMaker : IShellShimMaker
{
private const string LauncherExeResourceName = "Microsoft.DotNet.Tools.Launcher.Executable";
private const string LauncherConfigResourceName = "Microsoft.DotNet.Tools.Launcher.Config";
private readonly string _pathToPlaceShim;
public ShellShimMaker(string pathToPlaceShim)
{
_pathToPlaceShim =
pathToPlaceShim ?? throw new ArgumentNullException(nameof(pathToPlaceShim));
}
2018-01-30 15:41:39 -08:00
public void CreateShim(FilePath packageExecutable, string shellCommandName)
{
FilePath shimPath = GetShimPath(shellCommandName);
if (!Directory.Exists(shimPath.GetDirectoryPath().Value))
{
Directory.CreateDirectory(shimPath.GetDirectoryPath().Value);
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
2018-01-30 15:41:39 -08:00
CreateConfigFile(shimPath.Value + ".config", entryPoint: packageExecutable, runner: "dotnet");
using (var shim = File.Create(shimPath.Value))
using (var exe = typeof(ShellShimMaker).Assembly.GetManifestResourceStream(LauncherExeResourceName))
{
exe.CopyTo(shim);
}
}
else
{
var script = new StringBuilder();
script.AppendLine("#!/bin/sh");
script.AppendLine($"dotnet {packageExecutable.ToQuotedString()} \"$@\"");
File.WriteAllText(shimPath.Value, script.ToString());
SetUserExecutionPermissionToShimFile(shimPath);
}
}
public void EnsureCommandNameUniqueness(string shellCommandName)
{
if (File.Exists(Path.Combine(_pathToPlaceShim, shellCommandName)))
{
throw new GracefulException(
string.Format(CommonLocalizableStrings.FailInstallToolSameName,
shellCommandName));
}
}
2018-01-30 15:41:39 -08:00
internal void CreateConfigFile(string outputPath, FilePath entryPoint, string runner)
{
XDocument config;
using (var resource = typeof(ShellShimMaker).Assembly.GetManifestResourceStream(LauncherConfigResourceName))
{
config = XDocument.Load(resource);
}
var appSettings = config.Descendants("appSettings").First();
2018-01-30 15:41:39 -08:00
appSettings.Add(new XElement("add", new XAttribute("key", "entryPoint"), new XAttribute("value", entryPoint.Value)));
appSettings.Add(new XElement("add", new XAttribute("key", "runner"), new XAttribute("value", runner ?? string.Empty)));
config.Save(outputPath);
}
public void Remove(string shellCommandName)
{
File.Delete(GetShimPath(shellCommandName).Value);
}
private FilePath GetShimPath(string shellCommandName)
{
var scriptPath = Path.Combine(_pathToPlaceShim, shellCommandName);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
scriptPath += ".exe";
}
return new FilePath(scriptPath);
}
private static void SetUserExecutionPermissionToShimFile(FilePath scriptPath)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return;
CommandResult result = new CommandFactory()
.Create("chmod", new[] { "u+x", scriptPath.Value })
.CaptureStdOut()
.CaptureStdErr()
.Execute();
if (result.ExitCode != 0)
{
throw new GracefulException(
string.Format(CommonLocalizableStrings.FailInstallToolPermission, result.StdErr,
result.StdOut));
}
}
}
}