mirror of
https://github.com/qmlnet/qmlnet.git
synced 2026-05-21 06:45:32 -06:00
Added unit test for extracting runtime.
This commit is contained in:
parent
89d0bc3bee
commit
4bd92651ef
9 changed files with 282 additions and 4 deletions
|
|
@ -1,6 +1,6 @@
|
|||
image: Visual Studio 2017
|
||||
before_build:
|
||||
- ps: Invoke-WebRequest -Uri https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-de3f7b1-win-x64-dev.tar.gz -OutFile C:\qmlnet-qt.tar.gz
|
||||
- ps: Invoke-WebRequest -Uri https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-877b810-win-x64-dev.tar.gz -OutFile C:\qmlnet-qt.tar.gz
|
||||
- cmd: 7z x C:\qmlnet-qt.tar.gz -oC:\
|
||||
- cmd: 7z x C:\qmlnet-qt.tar -oC:\qmlnet-qt
|
||||
- cmd: rm -r C:\Tools\GitVersion\
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ QT_DIR=$SCRIPT_DIR/Qt
|
|||
sudo apt-get install -y libgl1-mesa-dev
|
||||
|
||||
mkdir -p $QT_DIR
|
||||
wget -O- -q https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-de3f7b1-linux-x64-dev.tar.gz | tar xpz -C $QT_DIR
|
||||
wget -O- -q https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-877b810-linux-x64-dev.tar.gz | tar xpz -C $QT_DIR
|
||||
|
||||
export PATH=$QT_DIR/qt/bin:$PATH
|
||||
export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/src/native/output:$QT_DIR/qt/lib
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
|||
QT_DIR=$SCRIPT_DIR/Qt
|
||||
|
||||
mkdir -p $QT_DIR
|
||||
wget -O- -q https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-de3f7b1-osx-x64-dev.tar.gz | tar xpz -C $QT_DIR
|
||||
wget -O- -q https://github.com/qmlnet/qt-runtimes/releases/download/releases/qt-5.12.2-877b810-osx-x64-dev.tar.gz | tar xpz -C $QT_DIR
|
||||
|
||||
export PATH=$QT_DIR/qt/bin:$PATH
|
||||
export DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/src/native/output:$QT_DIR/qt/lib
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="5.6.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
|
||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.10.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.23.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
|
|
|
|||
70
src/net/Qml.Net.Tests/RuntimeManagerTests.cs
Normal file
70
src/net/Qml.Net.Tests/RuntimeManagerTests.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using FluentAssertions;
|
||||
using Qml.Net.Runtimes;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Readers;
|
||||
using Xunit;
|
||||
|
||||
namespace Qml.Net.Tests
|
||||
{
|
||||
public class RuntimeManagerTests : IDisposable
|
||||
{
|
||||
private readonly string _tempDirectory;
|
||||
|
||||
public RuntimeManagerTests()
|
||||
{
|
||||
_tempDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString().Replace("-", ""));
|
||||
Directory.CreateDirectory(_tempDirectory);
|
||||
|
||||
RuntimeManager.ExtractTarGZStream = (stream, directory) =>
|
||||
{
|
||||
using (var reader = ReaderFactory.Open(stream, new ReaderOptions()))
|
||||
{
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
{
|
||||
reader.WriteEntryToDirectory(directory, new ExtractionOptions()
|
||||
{
|
||||
ExtractFullPath = true,
|
||||
Overwrite = true,
|
||||
WriteSymbolicLink = (sourcePath, targetPath) =>
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
throw new Exception("File links aren't supported.");
|
||||
}
|
||||
|
||||
var link = new Mono.Unix.UnixSymbolicLinkInfo(sourcePath);
|
||||
if (File.Exists(sourcePath))
|
||||
{
|
||||
link.Delete(); // equivalent to ln -s -f
|
||||
}
|
||||
|
||||
link.CreateSymbolicLinkTo(targetPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Can_download_runtime()
|
||||
{
|
||||
RuntimeManager.DownloadRuntimeToDirectory(QmlNetConfig.QtBuildVersion, RuntimeTarget.Windows64, _tempDirectory);
|
||||
File.ReadAllText(Path.Combine(_tempDirectory, "version.txt")).Should().Be($"{QmlNetConfig.QtBuildVersion}-win-x64");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Directory.Exists(_tempDirectory))
|
||||
{
|
||||
Directory.Delete(_tempDirectory, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GC/@EntryIndexedValue">GC</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OSX/@EntryIndexedValue">OSX</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OSX/@EntryIndexedValue">OSX</s:String>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Runtimes/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
|
|
@ -4,6 +4,8 @@ namespace Qml.Net
|
|||
{
|
||||
public class QmlNetConfig
|
||||
{
|
||||
public static string QtBuildVersion => "qt-5.12.2-877b810";
|
||||
|
||||
public static bool ListenForExceptionsWhenInvokingTasks { get; set; }
|
||||
|
||||
public static event Action<AggregateException> UnhandledTaskException;
|
||||
|
|
|
|||
9
src/net/Qml.Net/Runtimes/RuntimeArchitecture.cs
Normal file
9
src/net/Qml.Net/Runtimes/RuntimeArchitecture.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace Qml.Net.Runtimes
|
||||
{
|
||||
public enum RuntimeTarget
|
||||
{
|
||||
LinuxX64,
|
||||
OSX64,
|
||||
Windows64
|
||||
}
|
||||
}
|
||||
194
src/net/Qml.Net/Runtimes/RuntimeManager.cs
Normal file
194
src/net/Qml.Net/Runtimes/RuntimeManager.cs
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Qml.Net.Runtimes
|
||||
{
|
||||
public static class RuntimeManager
|
||||
{
|
||||
public delegate string BuildRuntimeUrlDelegate(string qtVersion, RuntimeTarget target);
|
||||
|
||||
// ReSharper disable once MemberCanBePrivate.Global
|
||||
// ReSharper disable once FieldCanBeMadeReadOnly.Global
|
||||
public static BuildRuntimeUrlDelegate BuildRuntimeUrl = (qtVersion, target) =>
|
||||
{
|
||||
var url = $"https://github.com/qmlnet/qt-runtimes/releases/download/releases/{qtVersion}-{{target}}-runtime.tar.gz";
|
||||
switch (target)
|
||||
{
|
||||
case RuntimeTarget.Windows64:
|
||||
return url.Replace("{target}", "win-x64");
|
||||
case RuntimeTarget.LinuxX64:
|
||||
return url.Replace("{target}", "linux-x64");
|
||||
case RuntimeTarget.OSX64:
|
||||
return url.Replace("{target}", "osx-64");
|
||||
default:
|
||||
throw new Exception($"Unknown target {target}");
|
||||
}
|
||||
};
|
||||
|
||||
public delegate void ExtractTarGZStreamDelegate(Stream stream, string destinationDirectory);
|
||||
|
||||
public static ExtractTarGZStreamDelegate ExtractTarGZStream;
|
||||
|
||||
public static RuntimeTarget GetCurrentRuntimeTarget()
|
||||
{
|
||||
if (IntPtr.Size != 8)
|
||||
{
|
||||
throw new Exception("Only 64bit supported");
|
||||
}
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return RuntimeTarget.Windows64;
|
||||
}
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return RuntimeTarget.LinuxX64;
|
||||
}
|
||||
|
||||
if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
return RuntimeTarget.OSX64;
|
||||
}
|
||||
|
||||
throw new Exception("Unknown OS platform");
|
||||
}
|
||||
|
||||
public static void DownloadRuntimeToDirectory(string qtVersion,
|
||||
RuntimeTarget runtimeTarget,
|
||||
string destinationDirectory)
|
||||
{
|
||||
var extractTarGZStreamDel = ExtractTarGZStream;
|
||||
if (extractTarGZStreamDel == null)
|
||||
{
|
||||
throw new Exception("You must set RuntimeManager.ExtractTarGZStream to properly extract a tar file.");
|
||||
}
|
||||
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
{
|
||||
throw new Exception($"The directory \"{destinationDirectory}\" doesn't exist.");
|
||||
}
|
||||
|
||||
if (Directory.GetFiles(destinationDirectory).Length > 0)
|
||||
{
|
||||
throw new Exception("The directory is not empty");
|
||||
}
|
||||
|
||||
if (Directory.GetDirectories(destinationDirectory).Length > 0)
|
||||
{
|
||||
throw new Exception("The directory is not empty");
|
||||
}
|
||||
|
||||
var url = BuildRuntimeUrl(qtVersion, runtimeTarget);
|
||||
|
||||
GetUrlStream(url, stream =>
|
||||
{
|
||||
extractTarGZStreamDel(stream, destinationDirectory);
|
||||
});
|
||||
}
|
||||
|
||||
public static void GetUrlStream(string url, Action<Stream> action)
|
||||
{
|
||||
var syncContext = SynchronizationContext.Current;
|
||||
try
|
||||
{
|
||||
SynchronizationContext.SetSynchronizationContext(null);
|
||||
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
action(httpClient.GetStreamAsync(url).GetAwaiter().GetResult());
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
SynchronizationContext.SetSynchronizationContext(syncContext);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// private static string GetRuntimeContainerDirectory()
|
||||
// {
|
||||
// var homeDirectory = (Environment.OSVersion.Platform == PlatformID.Unix ||
|
||||
// Environment.OSVersion.Platform == PlatformID.MacOSX)
|
||||
// ? Environment.GetEnvironmentVariable("HOME")
|
||||
// : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
|
||||
// var runtimeDirector = Path.Combine(homeDirectory, ".qmlnet-runtimes");
|
||||
// if (!Directory.Exists(runtimeDirector))
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static string GetRuntimeDirectory()
|
||||
// {
|
||||
// var runtimePath = Environment.GetEnvironmentVariable("QMLNET_QT_RUNTIME_DIR");
|
||||
// if (!string.IsNullOrEmpty(runtimePath))
|
||||
// {
|
||||
// // There is already one ready for us to start using!
|
||||
// return runtimePath;
|
||||
// }
|
||||
//
|
||||
// // We must now detect the proper version, download it, and return it's path.
|
||||
// var url = $"https://github.com/qmlnet/qt-runtimes/releases/download/releases/{QmlNetConfig.QtBuildVersion}-{GetPlatformIdentifier()}-runtime.tar.gz";
|
||||
// }
|
||||
|
||||
public static void ConfigureRuntimeDirectory(string directory)
|
||||
{
|
||||
if (string.IsNullOrEmpty(directory))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(directory));
|
||||
}
|
||||
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
throw new Exception("The directory doesn't exist.");
|
||||
}
|
||||
|
||||
var versionFile = Path.Combine(directory, "version.txt");
|
||||
|
||||
if (!File.Exists(versionFile))
|
||||
{
|
||||
throw new Exception("The version.txt file doesn't exist in the directory.");
|
||||
}
|
||||
|
||||
var version = File.ReadAllText(versionFile).TrimEnd(Environment.NewLine.ToCharArray());
|
||||
var expectedVersion = $"{QmlNetConfig.QtBuildVersion}-{GetCurrentRuntimeTarget()}";
|
||||
|
||||
if (version != expectedVersion)
|
||||
{
|
||||
throw new Exception($"The version of the runtime directory was {versionFile}, but expected {expectedVersion}");
|
||||
}
|
||||
|
||||
var pluginsDirectory = Path.Combine(directory, "plugins");
|
||||
if (!Directory.Exists(pluginsDirectory))
|
||||
{
|
||||
throw new Exception($"Plugins directory didn't exist: {pluginsDirectory}");
|
||||
}
|
||||
Environment.SetEnvironmentVariable("QT_PLUGIN_PATH", pluginsDirectory);
|
||||
|
||||
var qmlDirectory = Path.Combine(directory, "qml");
|
||||
if (!Directory.Exists(qmlDirectory))
|
||||
{
|
||||
throw new Exception($"QML directory didn't exist: {qmlDirectory}");
|
||||
}
|
||||
Environment.SetEnvironmentVariable("QML2_IMPORT_PATH", qmlDirectory);
|
||||
|
||||
/*if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(libDirectory) && Directory.Exists(libDirectory))
|
||||
{
|
||||
// Even though we opened up the native dll correctly, we need to add
|
||||
// the folder to the path. The reason is because QML plugins aren't
|
||||
// in the same directory and have trouble finding dependencies
|
||||
// that are within our lib folder.
|
||||
Environment.SetEnvironmentVariable(
|
||||
"PATH",
|
||||
Environment.GetEnvironmentVariable("PATH") + $";{libDirectory}");
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue