From 3dad02286668cbbd8094a747f61b785da136306a Mon Sep 17 00:00:00 2001 From: Paul Knopf Date: Fri, 12 Apr 2019 21:17:06 -0400 Subject: [PATCH] Ensuring the symlinks are created. --- src/net/Qml.Net.Tests/RuntimeManagerTests.cs | 9 ++++-- src/net/Qml.Net/Runtimes/Symlink.cs | 19 ++++++++++++ src/net/Qml.Net/Runtimes/Tar.cs | 31 +++++++++++++++----- 3 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 src/net/Qml.Net/Runtimes/Symlink.cs diff --git a/src/net/Qml.Net.Tests/RuntimeManagerTests.cs b/src/net/Qml.Net.Tests/RuntimeManagerTests.cs index 9b90fdb5..aa9b2517 100644 --- a/src/net/Qml.Net.Tests/RuntimeManagerTests.cs +++ b/src/net/Qml.Net.Tests/RuntimeManagerTests.cs @@ -19,7 +19,7 @@ namespace Qml.Net.Tests } [Fact] - public void Can_download_windows_untime() + public void Can_download_windows_runtime() { RuntimeManager.DownloadRuntimeToDirectory(QmlNetConfig.QtBuildVersion, RuntimeTarget.Windows64, _tempDirectory); File.ReadAllText(Path.Combine(_tempDirectory, "version.txt")).Should().Be($"{QmlNetConfig.QtBuildVersion}-win-x64"); @@ -40,6 +40,9 @@ namespace Qml.Net.Tests permissions.Should().Be(FileAccessPermissions.UserReadWriteExecute | FileAccessPermissions.GroupRead | FileAccessPermissions.GroupExecute | FileAccessPermissions.OtherRead | FileAccessPermissions.OtherExecute); + + // Make sure links are setup correctly. + File.Exists(Path.Combine(_tempDirectory, "qt", "lib", "libQt5Xml.so.5")).Should().BeTrue(); } } @@ -54,10 +57,12 @@ namespace Qml.Net.Tests var permissions = UnixFileInfo .GetFileSystemEntry(Path.Combine(_tempDirectory, "qt", "lib", "QtXml.framework", "Versions", "5", "QtXml")) .FileAccessPermissions; - permissions.Should().Be(FileAccessPermissions.UserReadWriteExecute | FileAccessPermissions.GroupRead | FileAccessPermissions.GroupExecute | FileAccessPermissions.OtherRead | FileAccessPermissions.OtherExecute); + + // Make sure links are setup correctly. + Directory.Exists(Path.Combine(_tempDirectory, "qt", "lib", "QtXml.framework", "Versions", "Current")).Should().BeTrue(); } } diff --git a/src/net/Qml.Net/Runtimes/Symlink.cs b/src/net/Qml.Net/Runtimes/Symlink.cs new file mode 100644 index 00000000..3d7eb661 --- /dev/null +++ b/src/net/Qml.Net/Runtimes/Symlink.cs @@ -0,0 +1,19 @@ +using System; +using System.Runtime.InteropServices; + +namespace Qml.Net.Runtimes +{ + internal class Symlink + { + [DllImport("libc")] + private static extern int symlink(string path1, string path2); + + public static void Create(string path1, string path2) + { + if (symlink(path1, path2) != 0) + { + throw new Exception($"Couldn't create symlink from {path1} to {path2}"); + } + } + } +} \ No newline at end of file diff --git a/src/net/Qml.Net/Runtimes/Tar.cs b/src/net/Qml.Net/Runtimes/Tar.cs index ba8f679f..71980199 100644 --- a/src/net/Qml.Net/Runtimes/Tar.cs +++ b/src/net/Qml.Net/Runtimes/Tar.cs @@ -12,7 +12,7 @@ namespace Qml.Net.Runtimes { internal class Tar { - internal enum EntryType : byte + public enum EntryType : byte { // ReSharper disable UnusedMember.Global File = 0, @@ -87,6 +87,9 @@ namespace Qml.Net.Runtimes { using (var gstream = new GZipStream(stream, CompressionMode.Decompress)) { + var isUnix = RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || + RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + var fileBuffer = new byte[1024 * 4]; while (true) @@ -98,10 +101,26 @@ namespace Qml.Net.Runtimes break; } + var output = Path.Combine(destinationDirectory, header.Name); + + if (header.EntryType == EntryType.SymLink) + { + if (!isUnix) + { + throw new Exception("Cannot extract symlink on current platform."); + } + + var parentDirectory = Path.GetDirectoryName(output); + if (!Directory.Exists(parentDirectory)) + { + Directory.CreateDirectory(parentDirectory); + } + + Symlink.Create(header.LinkName, output); + } + if (header.Size > 0) { - var output = Path.Combine(destinationDirectory, header.Name); - var parentDirectory = Path.GetDirectoryName(output); if (!Directory.Exists(parentDirectory)) { @@ -128,14 +147,10 @@ namespace Qml.Net.Runtimes } } - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (isUnix) { // This OS supports file modes. // Let's set them. - if (Path.GetFileName(output) == "libQt5Xml.so.5.12.2") - { - Debugger.Break(); - } Chmod.Set(output, header.Mode); }