diff --git a/.gitignore b/.gitignore index 64a922a868..a510c4e49f 100644 --- a/.gitignore +++ b/.gitignore @@ -152,3 +152,11 @@ $RECYCLE.BIN/ ################# *.userprefs *.nugetreferenceswitcher + +################# +## Cake +################# +tools/ +.nuget +artifacts/ +nuget diff --git a/.travis.yml b/.travis.yml index efa277ef1b..af7d5dbebf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,17 +4,8 @@ os: - osx mono: - latest -solution: Avalonia.travis-mono.sln -before_install: - - mkdir -p .nuget - - wget -O .nuget/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe -install: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y gtk-sharp2 ; fi - - mono .nuget/nuget.exe restore Avalonia.sln - - mono .nuget/nuget.exe install xunit.runner.console -Version 2.1.0 -OutputDirectory testrunner script: - - xbuild /p:Platform=Mono /p:Configuration=Release Avalonia.sln - - ./tests/run-tests.sh + - ./build.sh --target "Travis" --platform "Mono" --configuration "Release" notifications: email: false webhooks: diff --git a/Avalonia.sln b/Avalonia.sln index 5c0ee85216..1878d07234 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -168,6 +168,7 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInteropTest", "samples\interop\WindowsInteropTest\WindowsInteropTest.csproj", "{C7A69145-60B6-4882-97D6-A3921DD43978}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GtkInteropDemo", "samples\interop\GtkInteropDemo\GtkInteropDemo.csproj", "{BD7F352C-6DC1-4740-BAF2-2D34A038728C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DotNetFrameworkRuntime", "src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj", "{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution @@ -178,11 +179,9 @@ Global src\Shared\RenderHelpers\RenderHelpers.projitems*{47be08a7-5985-410b-9ffc-2264b8ea595f}*SharedItemsImports = 4 src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{47be08a7-5985-410b-9ffc-2264b8ea595f}*SharedItemsImports = 4 tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{48840edd-24bf-495d-911e-2eb12ae75d3b}*SharedItemsImports = 13 - src\Shared\PlatformSupport\PlatformSupport.projitems*{54f237d5-a70a-4752-9656-0c70b1a7b047}*SharedItemsImports = 4 + src\Shared\PlatformSupport\PlatformSupport.projitems*{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}*SharedItemsImports = 4 samples\TestApplicationShared\TestApplicationShared.projitems*{78345174-5b52-4a14-b9fd-d5f2428137f0}*SharedItemsImports = 13 src\Shared\PlatformSupport\PlatformSupport.projitems*{7b92af71-6287-4693-9dcb-bd5b6e927e23}*SharedItemsImports = 4 - src\Shared\PlatformSupport\PlatformSupport.projitems*{811a76cf-1cf6-440f-963b-bbe31bd72a82}*SharedItemsImports = 4 - src\Shared\PlatformSupport\PlatformSupport.projitems*{88060192-33d5-4932-b0f9-8bd2763e857d}*SharedItemsImports = 4 samples\TestApplicationShared\TestApplicationShared.projitems*{8c923867-8a8f-4f6b-8b80-47d9e8436166}*SharedItemsImports = 4 src\Shared\RenderHelpers\RenderHelpers.projitems*{925dd807-b651-475f-9f7c-cbeb974ce43d}*SharedItemsImports = 4 src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{925dd807-b651-475f-9f7c-cbeb974ce43d}*SharedItemsImports = 4 @@ -190,9 +189,7 @@ Global src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{bd43f7c0-396b-4aa1-bad9-dfde54d51298}*SharedItemsImports = 4 tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{d35a9f3d-8bb0-496e-bf72-444038a7debb}*SharedItemsImports = 4 tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{dabfd304-d6a4-4752-8123-c2ccf7ac7831}*SharedItemsImports = 4 - src\Shared\PlatformSupport\PlatformSupport.projitems*{db070a10-bf39-4752-8456-86e9d5928478}*SharedItemsImports = 4 tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{e106cf37-4066-4615-b684-172a6d30b058}*SharedItemsImports = 4 - src\Shared\PlatformSupport\PlatformSupport.projitems*{e1aa3dbf-9056-4530-9376-18119a7a3ffe}*SharedItemsImports = 4 samples\TestApplicationShared\TestApplicationShared.projitems*{e3a1060b-50d0-44e8-88b6-f44ef2e5bd72}*SharedItemsImports = 4 src\Shared\PlatformSupport\PlatformSupport.projitems*{e4d9629c-f168-4224-3f51-a5e482ffbc42}*SharedItemsImports = 13 src\Shared\RenderHelpers\RenderHelpers.projitems*{fb05ac90-89ba-4f2f-a924-f37875fb547c}*SharedItemsImports = 4 @@ -2328,6 +2325,46 @@ Global {BD7F352C-6DC1-4740-BAF2-2D34A038728C}.Release|Mono.Build.0 = Release|Any CPU {BD7F352C-6DC1-4740-BAF2-2D34A038728C}.Release|x86.ActiveCfg = Release|Any CPU {BD7F352C-6DC1-4740-BAF2-2D34A038728C}.Release|x86.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Mono.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|Mono.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Ad-Hoc|x86.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Any CPU.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Any CPU.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhone.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhone.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Mono.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|Mono.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|x86.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.AppStore|x86.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhone.Build.0 = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Mono.ActiveCfg = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|Mono.Build.0 = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|x86.ActiveCfg = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Debug|x86.Build.0 = Debug|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Any CPU.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhone.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhone.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Mono.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|Mono.Build.0 = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|x86.ActiveCfg = Release|Any CPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 0000000000..2a1e0af74d --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/appveyor.yml b/appveyor.yml index 5b7be0823d..eaa384fac3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,31 +1,27 @@ -version: 1.0.{build} os: Visual Studio 2015 -before_build: -- git submodule update --init -- nuget restore Avalonia.sln - +platform: +- Any CPU +configuration: +- Release environment: - myget_key: - secure: XOgD5bJUKNOS2kDDgb+affS4pDcslxALh+xvvnr1Koy0PjXlhILsBdNhxRe0KcNm - + NUGET_API_KEY: + secure: Xv89dlP2MSBZKhl1nrWSxqcDgCXB0HRhOd4SWQ+jRJ7QoLxQel5mLTipXM++J3G5 + NUGET_API_URL: https://www.nuget.org/api/v2/package + MYGET_API_KEY: + secure: OtVfyN3ErqQrDTnWH2HDfJDlCiu/i4/X4wFmK3ZXXP7HmCiXYPSbTjMPwwdOxRaK + MYGET_API_URL: https://www.myget.org/F/avalonia-ci/api/v2/package install: - if not exist gtk-sharp-2.12.26.msi appveyor DownloadFile http://download.xamarin.com/GTKforWindows/Windows/gtk-sharp-2.12.26.msi - msiexec /i gtk-sharp-2.12.26.msi /qn /norestart - cmd: set PATH=%programfiles(x86)%\GtkSharp\2.12\bin\;%PATH% - -cache: - - gtk-sharp-2.12.26.msi - -configuration: - - Release - -after_test: +before_build: +- git submodule update --init +build_script: +- ps: .\build.ps1 -Target "AppVeyor" -Platform "$env:platform" -Configuration "$env:configuration" +after_build: - .\packages\JetBrains.dotMemoryUnit.2.1.20150828.125449\tools\dotMemoryUnit.exe -targetExecutable="%xunit20%\xunit.console.x86.exe" -returnTargetExitCode --"tests\Avalonia.LeakTests\bin\Release\Avalonia.LeakTests.dll" -- ps: nuget\build-appveyor.ps1 - +test: off artifacts: - - path: nuget\*.nupkg - -build: - project: Avalonia.sln - verbosity: minimal + - path: artifacts\nuget\*.nupkg +cache: + - gtk-sharp-2.12.26.msi diff --git a/build.cake b/build.cake new file mode 100644 index 0000000000..e3507d05fa --- /dev/null +++ b/build.cake @@ -0,0 +1,776 @@ +/////////////////////////////////////////////////////////////////////////////// +// ADDINS +/////////////////////////////////////////////////////////////////////////////// + +#addin "nuget:?package=Polly&version=4.2.0" +#addin "nuget:?package=NuGet.Core&version=2.12.0" + +/////////////////////////////////////////////////////////////////////////////// +// TOOLS +/////////////////////////////////////////////////////////////////////////////// + +#tool "nuget:?package=xunit.runner.console&version=2.1.0" + +/////////////////////////////////////////////////////////////////////////////// +// USINGS +/////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Polly; +using NuGet; + +/////////////////////////////////////////////////////////////////////////////// +// ARGUMENTS +/////////////////////////////////////////////////////////////////////////////// + +var target = Argument("target", "Default"); +var platform = Argument("platform", "Any CPU"); +var configuration = Argument("configuration", "Release"); +var skipTests = HasArgument("skip-tests"); +/////////////////////////////////////////////////////////////////////////////// +// CONFIGURATION +/////////////////////////////////////////////////////////////////////////////// + +var MainRepo = "AvaloniaUI/Avalonia"; +var MasterBranch = "master"; +var AssemblyInfoPath = File("./src/Shared/SharedAssemblyInfo.cs"); +var ReleasePlatform = "Any CPU"; +var ReleaseConfiguration = "Release"; +var MSBuildSolution = "./Avalonia.sln"; +var XBuildSolution = "./Avalonia.sln"; + +/////////////////////////////////////////////////////////////////////////////// +// PARAMETERS +/////////////////////////////////////////////////////////////////////////////// + +var isPlatformAnyCPU = StringComparer.OrdinalIgnoreCase.Equals(platform, "Any CPU"); +var isPlatformX86 = StringComparer.OrdinalIgnoreCase.Equals(platform, "x86"); +var isPlatformX64 = StringComparer.OrdinalIgnoreCase.Equals(platform, "x64"); +var isLocalBuild = BuildSystem.IsLocalBuild; +var isRunningOnUnix = IsRunningOnUnix(); +var isRunningOnWindows = IsRunningOnWindows(); +var isRunningOnAppVeyor = BuildSystem.AppVeyor.IsRunningOnAppVeyor; +var isPullRequest = BuildSystem.AppVeyor.Environment.PullRequest.IsPullRequest; +var isMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, BuildSystem.AppVeyor.Environment.Repository.Name); +var isMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, BuildSystem.AppVeyor.Environment.Repository.Branch); +var isTagged = BuildSystem.AppVeyor.Environment.Repository.Tag.IsTag + && !string.IsNullOrWhiteSpace(BuildSystem.AppVeyor.Environment.Repository.Tag.Name); +var isReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleasePlatform, platform) + && StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, configuration); +var isMyGetRelease = !isTagged && isReleasable; +var isNuGetRelease = isTagged && isReleasable; + +/////////////////////////////////////////////////////////////////////////////// +// VERSION +/////////////////////////////////////////////////////////////////////////////// + +var version = ParseAssemblyInfo(AssemblyInfoPath).AssemblyVersion; + +if (isRunningOnAppVeyor) +{ + if (isTagged) + { + // Use Tag Name as version + version = BuildSystem.AppVeyor.Environment.Repository.Tag.Name; + } + else + { + // Use AssemblyVersion with Build as version + version += "-build" + EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-alpha"; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// DIRECTORIES +/////////////////////////////////////////////////////////////////////////////// + +var artifactsDir = (DirectoryPath)Directory("./artifacts"); +var nugetRoot = artifactsDir.Combine("nuget"); + +var dirSuffix = configuration; +var dirSuffixSkia = (isPlatformAnyCPU ? "x86" : platform) + "/" + configuration; +var dirSuffixIOS = "iPhone" + "/" + configuration; + +var buildDirs = + GetDirectories("./src/**/bin/" + dirSuffix) + + GetDirectories("./src/**/obj/" + dirSuffix) + + GetDirectories("./src/Markup/**/bin/" + dirSuffix) + + GetDirectories("./src/Markup/**/obj/" + dirSuffix) + + GetDirectories("./src/Android/**/bin/" + dirSuffix) + + GetDirectories("./src/Android/**/obj/" + dirSuffix) + + GetDirectories("./src/Gtk/**/bin/" + dirSuffix) + + GetDirectories("./src/Gtk/**/obj/" + dirSuffix) + + GetDirectories("./src/iOS/**/bin/" + dirSuffixIOS) + + GetDirectories("./src/iOS/**/obj/" + dirSuffixIOS) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android/bin/" + dirSuffix) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android/obj/" + dirSuffix) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android.TestApp/bin/" + dirSuffix) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Android.TestApp/obj/" + dirSuffix) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Desktop/bin/" + dirSuffixSkia) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.Desktop/obj/" + dirSuffixSkia) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + dirSuffixIOS) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS/obj/" + dirSuffixIOS) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/bin/" + dirSuffixIOS) + + (DirectoryPath)Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/obj/" + dirSuffixIOS) + + GetDirectories("./src/Windows/**/bin/" + dirSuffix) + + GetDirectories("./src/Windows/**/obj/" + dirSuffix) + + GetDirectories("./tests/**/bin/" + dirSuffix) + + GetDirectories("./tests/**/obj/" + dirSuffix) + + GetDirectories("./Samples/**/bin/" + dirSuffix) + + GetDirectories("./Samples/**/obj/" + dirSuffix); + +/////////////////////////////////////////////////////////////////////////////// +// NUGET NUSPECS +/////////////////////////////////////////////////////////////////////////////// + +Information("Getting git modules:"); + +var ignoredSubModulesPaths = System.IO.File.ReadAllLines(".git/config").Where(m=>m.StartsWith("[submodule ")).Select(m => +{ + var path = m.Split(' ')[1].Trim("\"[] \t".ToArray()); + Information(path); + return ((DirectoryPath)Directory(path)).FullPath; +}).ToList(); + +var normalizePath = new Func( + path => path.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar).ToUpperInvariant()); + +// Key: Package Id +// Value is Tuple where Item1: Package Version, Item2: The packages.config file path. +var packageVersions = new Dictionary>>(); + +System.IO.Directory.EnumerateFiles(((DirectoryPath)Directory("./src")).FullPath, "packages.config", SearchOption.AllDirectories).ToList().ForEach(fileName => +{ + if (!ignoredSubModulesPaths.Any(i => normalizePath(fileName).Contains(normalizePath(i)))) + { + var file = new PackageReferenceFile(fileName); + foreach (PackageReference packageReference in file.GetPackageReferences()) + { + IList> versions; + packageVersions.TryGetValue(packageReference.Id, out versions); + if (versions == null) + { + versions = new List>(); + packageVersions[packageReference.Id] = versions; + } + versions.Add(Tuple.Create(packageReference.Version.ToString(), fileName)); + } + } +}); + +Information("Checking installed NuGet package dependencies versions:"); + +packageVersions.ToList().ForEach(package => +{ + var packageVersion = package.Value.First().Item1; + bool isValidVersion = package.Value.All(x => x.Item1 == packageVersion); + if (!isValidVersion) + { + Information("Error: package {0} has multiple versions installed:", package.Key); + foreach (var v in package.Value) + { + Information("{0}, file: {1}", v.Item1, v.Item2); + } + throw new Exception("Detected multiple NuGet package version installed for different projects."); + } +}); + +Information("Setting NuGet package dependencies versions:"); + +var SerilogVersion = packageVersions["Serilog"].FirstOrDefault().Item1; +var SplatVersion = packageVersions["Splat"].FirstOrDefault().Item1; +var SpracheVersion = packageVersions["Sprache"].FirstOrDefault().Item1; +var SystemReactiveVersion = packageVersions["System.Reactive"].FirstOrDefault().Item1; +var SkiaSharpVersion = packageVersions["SkiaSharp"].FirstOrDefault().Item1; +var SharpDXVersion = packageVersions["SharpDX"].FirstOrDefault().Item1; +var SharpDXDirect2D1Version = packageVersions["SharpDX.Direct2D1"].FirstOrDefault().Item1; +var SharpDXDXGIVersion = packageVersions["SharpDX.DXGI"].FirstOrDefault().Item1; + +Information("Package: Serilog, version: {0}", SerilogVersion); +Information("Package: Splat, version: {0}", SplatVersion); +Information("Package: Sprache, version: {0}", SpracheVersion); +Information("Package: System.Reactive, version: {0}", SystemReactiveVersion); +Information("Package: SkiaSharp, version: {0}", SkiaSharpVersion); +Information("Package: SharpDX, version: {0}", SharpDXVersion); +Information("Package: SharpDX.Direct2D1, version: {0}", SharpDXDirect2D1Version); +Information("Package: SharpDX.DXGI, version: {0}", SharpDXDXGIVersion); + +var SetNuGetNuspecCommonProperties = new Action ((nuspec) => { + nuspec.Version = version; + nuspec.Authors = new [] { "Avalonia Team" }; + nuspec.Owners = new [] { "stevenk" }; + nuspec.LicenseUrl = new Uri("http://opensource.org/licenses/MIT"); + nuspec.ProjectUrl = new Uri("https://github.com/AvaloniaUI/Avalonia/"); + nuspec.RequireLicenseAcceptance = false; + nuspec.Symbols = false; + nuspec.NoPackageAnalysis = true; + nuspec.Description = "The Avalonia UI framework"; + nuspec.Copyright = "Copyright 2015"; + nuspec.Tags = new [] { "Avalonia" }; +}); + +var coreLibraries = new string[][] +{ + new [] { "./src/", "Avalonia.Animation", ".dll" }, + new [] { "./src/", "Avalonia.Animation", ".xml" }, + new [] { "./src/", "Avalonia.Base", ".dll" }, + new [] { "./src/", "Avalonia.Base", ".xml" }, + new [] { "./src/", "Avalonia.Controls", ".dll" }, + new [] { "./src/", "Avalonia.Controls", ".xml" }, + new [] { "./src/", "Avalonia.DesignerSupport", ".dll" }, + new [] { "./src/", "Avalonia.DesignerSupport", ".xml" }, + new [] { "./src/", "Avalonia.Diagnostics", ".dll" }, + new [] { "./src/", "Avalonia.Diagnostics", ".xml" }, + new [] { "./src/", "Avalonia.Input", ".dll" }, + new [] { "./src/", "Avalonia.Input", ".xml" }, + new [] { "./src/", "Avalonia.Interactivity", ".dll" }, + new [] { "./src/", "Avalonia.Interactivity", ".xml" }, + new [] { "./src/", "Avalonia.Layout", ".dll" }, + new [] { "./src/", "Avalonia.Layout", ".xml" }, + new [] { "./src/", "Avalonia.Logging.Serilog", ".dll" }, + new [] { "./src/", "Avalonia.Logging.Serilog", ".xml" }, + new [] { "./src/", "Avalonia.SceneGraph", ".dll" }, + new [] { "./src/", "Avalonia.SceneGraph", ".xml" }, + new [] { "./src/", "Avalonia.Styling", ".dll" }, + new [] { "./src/", "Avalonia.Styling", ".xml" }, + new [] { "./src/", "Avalonia.ReactiveUI", ".dll" }, + new [] { "./src/", "Avalonia.Themes.Default", ".dll" }, + new [] { "./src/", "Avalonia.Themes.Default", ".xml" }, + new [] { "./src/Markup/", "Avalonia.Markup", ".dll" }, + new [] { "./src/Markup/", "Avalonia.Markup", ".xml" }, + new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".dll" }, + new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".xml" } +}; + +var coreLibrariesFiles = coreLibraries.Select((lib) => { + return (FilePath)File(lib[0] + lib[1] + "/bin/" + dirSuffix + "/" + lib[1] + lib[2]); +}).ToList(); + +var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => { + return new NuSpecContent { + Source = file.FullPath, Target = "lib/portable-windows8+net45" + }; +}); + +var win32CoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => { + return new NuSpecContent { + Source = file.FullPath, Target = "lib/net45" + }; +}); + +var net45RuntimePlatformExtensions = new [] {".xml", ".dll"}; +var net45RuntimePlatform = net45RuntimePlatformExtensions.Select(libSuffix => { + return new NuSpecContent { + Source = ((FilePath)File("./src/Avalonia.DotNetFrameworkRuntime/bin/" + dirSuffix + "/Avalonia.DotNetFrameworkRuntime" + libSuffix)).FullPath, + Target = "lib/net45" + }; +}); + +var nuspecNuGetSettingsCore = new [] +{ + /////////////////////////////////////////////////////////////////////////////// + // Avalonia + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Serilog", Version = SerilogVersion }, + new NuSpecDependency() { Id = "Splat", Version = SplatVersion }, + new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion }, + new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion } + }, + Files = coreLibrariesNuSpecContent.Concat(win32CoreLibrariesNuSpecContent).Concat(net45RuntimePlatform).ToList(), + BasePath = Directory("./"), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.HtmlRenderer + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.HtmlRenderer", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/portable-windows8+net45" } + }, + BasePath = Directory("./src/Avalonia.HtmlRenderer/bin/" + dirSuffix), + OutputDirectory = nugetRoot + } +}; + +var nuspecNuGetSettingsMobile = new [] +{ + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Android + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Android", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version }, + new NuSpecDependency() { Id = "Avalonia.Skia.Android", Version = version } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.Android.dll", Target = "lib/MonoAndroid10" } + }, + BasePath = Directory("./src/Android/Avalonia.Android/bin/" + dirSuffix), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Skia.Android + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Skia.Android", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version }, + new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.Skia.Android.dll", Target = "lib/MonoAndroid10" } + }, + BasePath = Directory("./src/Skia/Avalonia.Skia.Android/bin/" + dirSuffix), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.iOS + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.iOS", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version }, + new NuSpecDependency() { Id = "Avalonia.Skia.iOS", Version = version } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.iOS.dll", Target = "lib/Xamarin.iOS10" } + }, + BasePath = Directory("./src/iOS/Avalonia.iOS/bin/" + dirSuffixIOS), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Skia.iOS + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Skia.iOS", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version }, + new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.Skia.iOS.dll", Target = "lib/Xamarin.iOS10" } + }, + BasePath = Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + dirSuffixIOS), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Mobile + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Mobile", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia.Android", Version = version }, + new NuSpecDependency() { Id = "Avalonia.iOS", Version = version } + }, + Files = new NuSpecContent[] + { + new NuSpecContent { Source = "licence.md", Target = "" } + }, + BasePath = Directory("./"), + OutputDirectory = nugetRoot + } +}; + +var nuspecNuGetSettingsDesktop = new [] +{ + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Win32 + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Win32", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.Win32.dll", Target = "lib/net45" } + }, + BasePath = Directory("./src/Windows/Avalonia.Win32/bin/" + dirSuffix), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Direct2D1 + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Direct2D1", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version }, + new NuSpecDependency() { Id = "SharpDX", Version = SharpDXVersion }, + new NuSpecDependency() { Id = "SharpDX.Direct2D1", Version = SharpDXDirect2D1Version }, + new NuSpecDependency() { Id = "SharpDX.DXGI", Version = SharpDXDXGIVersion } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.Direct2D1.dll", Target = "lib/net45" } + }, + BasePath = Directory("./src/Windows/Avalonia.Direct2D1/bin/" + dirSuffix), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Gtk + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Gtk", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.Gtk.dll", Target = "lib/net45" } + }, + BasePath = Directory("./src/Gtk/Avalonia.Gtk/bin/" + dirSuffix), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Cairo + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Cairo", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.Cairo.dll", Target = "lib/net45" } + }, + BasePath = Directory("./src/Gtk/Avalonia.Cairo/bin/" + dirSuffix), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Skia.Desktop + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Skia.Desktop", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia", Version = version }, + new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion } + }, + Files = new [] + { + new NuSpecContent { Source = "Avalonia.Skia.Desktop.dll", Target = "lib/net45" } + }, + BasePath = Directory("./src/Skia/Avalonia.Skia.Desktop/bin/" + dirSuffixSkia), + OutputDirectory = nugetRoot + }, + /////////////////////////////////////////////////////////////////////////////// + // Avalonia.Desktop + /////////////////////////////////////////////////////////////////////////////// + new NuGetPackSettings() + { + Id = "Avalonia.Desktop", + Dependencies = new [] + { + new NuSpecDependency() { Id = "Avalonia.Win32", Version = version }, + new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = version }, + new NuSpecDependency() { Id = "Avalonia.Gtk", Version = version }, + new NuSpecDependency() { Id = "Avalonia.Cairo", Version = version }, + new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", Version = version } + }, + Files = new NuSpecContent[] + { + new NuSpecContent { Source = "licence.md", Target = "" } + }, + BasePath = Directory("./"), + OutputDirectory = nugetRoot + } +}; + +var nuspecNuGetSettings = new List(); + +nuspecNuGetSettings.AddRange(nuspecNuGetSettingsCore); +nuspecNuGetSettings.AddRange(nuspecNuGetSettingsDesktop); +nuspecNuGetSettings.AddRange(nuspecNuGetSettingsMobile); + +nuspecNuGetSettings.ForEach((nuspec) => SetNuGetNuspecCommonProperties(nuspec)); + +var nugetPackages = nuspecNuGetSettings.Select(nuspec => { + return nuspec.OutputDirectory.CombineWithFilePath(string.Concat(nuspec.Id, ".", nuspec.Version, ".nupkg")); +}).ToArray(); + +/////////////////////////////////////////////////////////////////////////////// +// INFORMATION +/////////////////////////////////////////////////////////////////////////////// + +Information("Building version {0} of Avalonia ({1}, {2}, {3}) using version {4} of Cake.", + version, + platform, + configuration, + target, + typeof(ICakeContext).Assembly.GetName().Version.ToString()); + +if (isRunningOnAppVeyor) +{ + Information("Repository Name: " + BuildSystem.AppVeyor.Environment.Repository.Name); + Information("Repository Branch: " + BuildSystem.AppVeyor.Environment.Repository.Branch); +} + +Information("Target: " + target); +Information("Platform: " + platform); +Information("Configuration: " + configuration); +Information("IsLocalBuild: " + isLocalBuild); +Information("IsRunningOnUnix: " + isRunningOnUnix); +Information("IsRunningOnWindows: " + isRunningOnWindows); +Information("IsRunningOnAppVeyor: " + isRunningOnAppVeyor); +Information("IsPullRequest: " + isPullRequest); +Information("IsMainRepo: " + isMainRepo); +Information("IsMasterBranch: " + isMasterBranch); +Information("IsTagged: " + isTagged); +Information("IsReleasable: " + isReleasable); +Information("IsMyGetRelease: " + isMyGetRelease); +Information("IsNuGetRelease: " + isNuGetRelease); + +/////////////////////////////////////////////////////////////////////////////// +// TASKS +/////////////////////////////////////////////////////////////////////////////// + +Task("Clean") + .Does(() => +{ + CleanDirectories(buildDirs); + CleanDirectory(artifactsDir); + CleanDirectory(nugetRoot); +}); + +Task("Restore-NuGet-Packages") + .IsDependentOn("Clean") + .Does(() => +{ + var maxRetryCount = 5; + var toolTimeout = 1d; + Policy + .Handle() + .Retry(maxRetryCount, (exception, retryCount, context) => { + if (retryCount == maxRetryCount) + { + throw exception; + } + else + { + Verbose("{0}", exception); + toolTimeout+=0.5; + }}) + .Execute(()=> { + if(isRunningOnWindows) + { + NuGetRestore(MSBuildSolution, new NuGetRestoreSettings { + ToolTimeout = TimeSpan.FromMinutes(toolTimeout) + }); + } + else + { + NuGetRestore(XBuildSolution, new NuGetRestoreSettings { + ToolTimeout = TimeSpan.FromMinutes(toolTimeout) + }); + } + }); +}); + +Task("Build") + .IsDependentOn("Restore-NuGet-Packages") + .Does(() => +{ + if(isRunningOnWindows) + { + MSBuild(MSBuildSolution, settings => { + settings.SetConfiguration(configuration); + settings.WithProperty("Platform", "\"" + platform + "\""); + settings.SetVerbosity(Verbosity.Minimal); + settings.WithProperty("Windows", "True"); + settings.UseToolVersion(MSBuildToolVersion.VS2015); + settings.SetNodeReuse(false); + }); + } + else + { + XBuild(XBuildSolution, settings => { + settings.SetConfiguration(configuration); + settings.WithProperty("Platform", "\"" + platform + "\""); + settings.SetVerbosity(Verbosity.Minimal); + }); + } +}); + +Task("Run-Unit-Tests") + .IsDependentOn("Build") + .WithCriteria(() => !skipTests) + .Does(() => +{ + var pattern = "./tests/Avalonia.*.UnitTests/bin/" + dirSuffix + "/Avalonia.*.UnitTests.dll"; + + Func ExcludeWindowsTests = i => { + return !(i.Path.FullPath.IndexOf("Direct2D", StringComparison.OrdinalIgnoreCase) >= 0); + }; + + var unitTests = isRunningOnWindows ? GetFiles(pattern) : GetFiles(pattern, ExcludeWindowsTests); + + if (isRunningOnWindows) + { + var windowsTests = GetFiles("./tests/Avalonia.DesignerSupport.Tests/bin/" + dirSuffix + "/*Tests.dll") + + GetFiles("./tests/Avalonia.LeakTests/bin/" + dirSuffix + "/*Tests.dll") + + GetFiles("./tests/Avalonia.RenderTests/bin/" + dirSuffix + "/*Tests.dll"); + + unitTests += windowsTests; + } + + var toolPath = (isPlatformAnyCPU || isPlatformX86) ? + "./tools/xunit.runner.console/tools/xunit.console.x86.exe" : + "./tools/xunit.runner.console/tools/xunit.console.exe"; + + var settings = new XUnit2Settings + { + ToolPath = toolPath, + Parallelism = ParallelismOption.None + }; + + if (isRunningOnWindows) + { + settings.NoAppDomain = false; + } + + foreach (var file in unitTests) + { + Information("Running test " + file.GetFilenameWithoutExtension()); + XUnit2(file.FullPath, settings); + } +}); + +Task("Create-NuGet-Packages") + .IsDependentOn("Run-Unit-Tests") + .Does(() => +{ + foreach(var nuspec in nuspecNuGetSettings) + { + NuGetPack(nuspec); + } +}); + +Task("Publish-MyGet") + .IsDependentOn("Create-NuGet-Packages") + .WithCriteria(() => !isLocalBuild) + .WithCriteria(() => !isPullRequest) + .WithCriteria(() => isMainRepo) + .WithCriteria(() => isMasterBranch) + .WithCriteria(() => isMyGetRelease) + .Does(() => +{ + var apiKey = EnvironmentVariable("MYGET_API_KEY"); + if(string.IsNullOrEmpty(apiKey)) + { + throw new InvalidOperationException("Could not resolve MyGet API key."); + } + + var apiUrl = EnvironmentVariable("MYGET_API_URL"); + if(string.IsNullOrEmpty(apiUrl)) + { + throw new InvalidOperationException("Could not resolve MyGet API url."); + } + + foreach(var nupkg in nugetPackages) + { + NuGetPush(nupkg, new NuGetPushSettings { + Source = apiUrl, + ApiKey = apiKey + }); + } +}) +.OnError(exception => +{ + Information("Publish-MyGet Task failed, but continuing with next Task..."); +}); + +Task("Publish-NuGet") + .IsDependentOn("Create-NuGet-Packages") + .WithCriteria(() => !isLocalBuild) + .WithCriteria(() => !isPullRequest) + .WithCriteria(() => isMainRepo) + .WithCriteria(() => isMasterBranch) + .WithCriteria(() => isNuGetRelease) + .Does(() => +{ + var apiKey = EnvironmentVariable("NUGET_API_KEY"); + if(string.IsNullOrEmpty(apiKey)) + { + throw new InvalidOperationException("Could not resolve NuGet API key."); + } + + var apiUrl = EnvironmentVariable("NUGET_API_URL"); + if(string.IsNullOrEmpty(apiUrl)) + { + throw new InvalidOperationException("Could not resolve NuGet API url."); + } + + foreach(var nupkg in nugetPackages) + { + NuGetPush(nupkg, new NuGetPushSettings { + ApiKey = apiKey, + Source = apiUrl + }); + } +}) +.OnError(exception => +{ + Information("Publish-NuGet Task failed, but continuing with next Task..."); +}); + +/////////////////////////////////////////////////////////////////////////////// +// TARGETS +/////////////////////////////////////////////////////////////////////////////// + +Task("Package") + .IsDependentOn("Create-NuGet-Packages"); + +Task("Default") + .IsDependentOn("Package"); + +Task("AppVeyor") + .IsDependentOn("Publish-MyGet") + .IsDependentOn("Publish-NuGet"); + +Task("Travis") + .IsDependentOn("Run-Unit-Tests"); + +/////////////////////////////////////////////////////////////////////////////// +// EXECUTE +/////////////////////////////////////////////////////////////////////////////// + +RunTarget(target); diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000000..0c5ab81334 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,201 @@ +########################################################################## +# This is the Cake bootstrapper script for PowerShell. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +<# + +.SYNOPSIS +This is a Powershell script to bootstrap a Cake build. + +.DESCRIPTION +This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) +and execute your Cake build script with the parameters you provide. + +.PARAMETER Script +The build script to execute. +.PARAMETER Target +The build script target to run. +.PARAMETER Platform +The build platform to use. +.PARAMETER Configuration +The build configuration to use. +.PARAMETER Verbosity +Specifies the amount of information to be displayed. +.PARAMETER Experimental +Tells Cake to use the latest Roslyn release. +.PARAMETER WhatIf +Performs a dry run of the build script. +No tasks will be executed. +.PARAMETER Mono +Tells Cake to use the Mono scripting engine. +.PARAMETER SkipToolPackageRestore +Skips restoring of packages. +.PARAMETER SkipTests +Skips unit tests +.PARAMETER ScriptArgs +Remaining arguments are added here. + +.LINK +http://cakebuild.net + +#> + +[CmdletBinding()] +Param( + [string]$Script = "build.cake", + [string]$Target = "Default", + [ValidateSet("Any CPU", "x86", "x64", "Mono", "iPhone")] + [string]$Platform = "Any CPU", + [ValidateSet("Release", "Debug")] + [string]$Configuration = "Release", + [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] + [string]$Verbosity = "Verbose", + [switch]$Experimental, + [Alias("DryRun","Noop")] + [switch]$WhatIf, + [switch]$Mono, + [switch]$SkipToolPackageRestore, + [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] + [string[]]$ScriptArgs +) + +[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null +function MD5HashFile([string] $filePath) +{ + if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) + { + return $null + } + + [System.IO.Stream] $file = $null; + [System.Security.Cryptography.MD5] $md5 = $null; + try + { + $md5 = [System.Security.Cryptography.MD5]::Create() + $file = [System.IO.File]::OpenRead($filePath) + return [System.BitConverter]::ToString($md5.ComputeHash($file)) + } + finally + { + if ($file -ne $null) + { + $file.Dispose() + } + } +} + +Write-Host "Preparing to run build script..." + +if(!$PSScriptRoot){ + $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent +} + +$TOOLS_DIR = Join-Path $PSScriptRoot "tools" +$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" +$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" +$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" +$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" +$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" + +# Should we use mono? +$UseMono = ""; +if($Mono.IsPresent) { + Write-Verbose -Message "Using the Mono based scripting engine." + $UseMono = "-mono" +} + +# Should we use the new Roslyn? +$UseExperimental = ""; +if($Experimental.IsPresent -and !($Mono.IsPresent)) { + Write-Verbose -Message "Using experimental version of Roslyn." + $UseExperimental = "-experimental" +} + +# Is this a dry run? +$UseDryRun = ""; +if($WhatIf.IsPresent) { + $UseDryRun = "-dryrun" +} + +# Is this a dry run? +$UseSkipTests = ""; +if($SkipTests.IsPresent) { + $UseSkipTests = "-skip-tests" +} + +# Make sure tools folder exists +if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { + Write-Verbose -Message "Creating tools directory..." + New-Item -Path $TOOLS_DIR -Type directory | out-null +} + +# Make sure that packages.config exist. +if (!(Test-Path $PACKAGES_CONFIG)) { + Write-Verbose -Message "Downloading packages.config..." + try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { + Throw "Could not download packages.config." + } +} + +# Try find NuGet.exe in path if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Trying to find nuget.exe in PATH..." + $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) } + $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 + if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { + Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." + $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName + } +} + +# Try download NuGet.exe if not exists +if (!(Test-Path $NUGET_EXE)) { + Write-Verbose -Message "Downloading NuGet.exe..." + try { + (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) + } catch { + Throw "Could not download NuGet.exe." + } +} + +# Save nuget.exe path to environment to be available to child processed +$ENV:NUGET_EXE = $NUGET_EXE + +# Restore tools from NuGet? +if(-Not $SkipToolPackageRestore.IsPresent) { + Push-Location + Set-Location $TOOLS_DIR + + # Check for changes in packages.config and remove installed tools if true. + [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) + if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or + ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { + Write-Verbose -Message "Missing or changed package.config hash..." + Remove-Item * -Recurse -Exclude packages.config,nuget.exe + } + + Write-Verbose -Message "Restoring tools from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occured while restoring NuGet tools." + } + else + { + $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" + } + Write-Verbose -Message ($NuGetOutput | out-string) + Pop-Location +} + +# Make sure that Cake has been installed. +if (!(Test-Path $CAKE_EXE)) { + Throw "Could not find Cake.exe at $CAKE_EXE" +} + +# Start Cake +Write-Host "Running build script..." +Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -platform=`"$Platform`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseSkipTests $UseMono $UseDryRun $UseExperimental $ScriptArgs" +exit $LASTEXITCODE \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000000..206a55d171 --- /dev/null +++ b/build.sh @@ -0,0 +1,105 @@ +#!/usr/bin/env bash + +########################################################################## +# This is the Cake bootstrapper script for Linux and OS X. +# This file was downloaded from https://github.com/cake-build/resources +# Feel free to change this file to fit your needs. +########################################################################## + +# Define directories. +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +TOOLS_DIR=$SCRIPT_DIR/tools +NUGET_EXE=$TOOLS_DIR/nuget.exe +CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe +PACKAGES_CONFIG=$TOOLS_DIR/packages.config +PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum + +# Define md5sum or md5 depending on Linux/OSX +MD5_EXE= +if [[ "$(uname -s)" == "Darwin" ]]; then + MD5_EXE="md5 -r" +else + MD5_EXE="md5sum" +fi + +# Define default arguments. +SCRIPT="build.cake" +TARGET="Default" +CONFIGURATION="Release" +PLATFORM="Any CPU" +VERBOSITY="verbose" +DRYRUN= +SKIP_TESTS= +SHOW_VERSION=false +SCRIPT_ARGUMENTS=() + +# Parse arguments. +for i in "$@"; do + case $1 in + -s|--script) SCRIPT="$2"; shift ;; + -t|--target) TARGET="$2"; shift ;; + -p|--platform) PLATFORM="$2"; shift ;; + -c|--configuration) CONFIGURATION="$2"; shift ;; + --skip-tests) SKIP_TESTS="-skip-tests"; shift ;; + -v|--verbosity) VERBOSITY="$2"; shift ;; + -d|--dryrun) DRYRUN="-dryrun" ;; + --version) SHOW_VERSION=true ;; + --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;; + *) SCRIPT_ARGUMENTS+=("$1") ;; + esac + shift +done + +# Make sure the tools folder exist. +if [ ! -d "$TOOLS_DIR" ]; then + mkdir "$TOOLS_DIR" +fi + +# Make sure that packages.config exist. +if [ ! -f "$TOOLS_DIR/packages.config" ]; then + echo "Downloading packages.config..." + curl -Lsfo "$TOOLS_DIR/packages.config" http://cakebuild.net/download/bootstrapper/packages + if [ $? -ne 0 ]; then + echo "An error occured while downloading packages.config." + exit 1 + fi +fi + +# Download NuGet if it does not exist. +if [ ! -f "$NUGET_EXE" ]; then + echo "Downloading NuGet..." + curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + if [ $? -ne 0 ]; then + echo "An error occured while downloading nuget.exe." + exit 1 + fi +fi + +# Restore tools from NuGet. +pushd "$TOOLS_DIR" >/dev/null +if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then + find . -type d ! -name . | xargs rm -rf +fi + +mono "$NUGET_EXE" install -ExcludeVersion +if [ $? -ne 0 ]; then + echo "Could not restore NuGet packages." + exit 1 +fi + +$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5 + +popd >/dev/null + +# Make sure that Cake has been installed. +if [ ! -f "$CAKE_EXE" ]; then + echo "Could not find Cake.exe at '$CAKE_EXE'." + exit 1 +fi + +# Start Cake +if $SHOW_VERSION; then + exec mono "$CAKE_EXE" -version +else + exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -platform="$PLATFORM" -configuration="$CONFIGURATION" -target=$TARGET $DRYRUN $SKIP_TESTS "${SCRIPT_ARGUMENTS[@]}" +fi diff --git a/docs/tutorial/nuget.md b/docs/tutorial/nuget.md new file mode 100644 index 0000000000..314575258c --- /dev/null +++ b/docs/tutorial/nuget.md @@ -0,0 +1,86 @@ +# Avalonia NuGet Packages + +Avalonia is divided into several `NuGet` packages. + +* The `Avalonia` package contains core portable class libraries. +* The `Dekstop` and `Mobile` packages contain platform specific windowing and rendering back-ends. +* The `Avalonia.Desktop` package is intended to be used by the end users targeting multiple desktop platforms (`Windows`, `Linux` and `OSX`). +* The `Avalonia.iOS` and `Avalonia.Android` packages are intended to be used by the end users targeting specific mobile platforms. +* The `Avalonia.Mobile` package is intended to be used by the end users targeting multiple mobile platforms (`Android` and `iOS`). + +## Core + +* Avalonia (.nupkg) + - Avalonia.Animation (.dll) + - Avalonia.Base (.dll) + - Avalonia.Controls (.dll) + - Avalonia.DesignerSupport (.dll) + - Avalonia.Diagnostics (.dll) + - Avalonia.Input (.dll) + - Avalonia.Interactivity (.dll) + - Avalonia.Layout (.dll) + - Avalonia.Logging.Serilog (.dll) + - Avalonia.SceneGraph (.dll) + - Avalonia.Styling (.dll) + - Avalonia.ReactiveUI (.dll) + - Avalonia.Themes.Default (.dll) + - Avalonia.Markup (.dll) + - Avalonia.Markup.Xaml (.dll) + - Serilog (.nupkg) + - Splat (.nupkg) + - Sprache (.nupkg) + - System.Reactive (.nupkg) + +* Avalonia.HtmlRenderer (.nupkg) + - Avalonia (.nupkg) + +## Desktop + +* Avalonia.Win32 (.nupkg) + - Avalonia.Win32 (.dll) + - Avalonia (.nupkg) + +* Avalonia.Direct2D1 (.nupkg) + - Avalonia.Direct2D1 (.dll) + - Avalonia (.nupkg) + - SharpDX (.nupkg) + - SharpDX.Direct2D1 (.nupkg) + - SharpDX.DXGI (.nupkg) + +* Avalonia.Gtk (.nupkg) + - Avalonia.Gtk (.dll) + - Avalonia (.nupkg) + +* Avalonia.Cairo (.nupkg) + - Avalonia.Cairo (.dll) + - Avalonia (.nupkg) + +* Avalonia.Skia.Desktop (.nupkg) + - Avalonia.Skia.Desktop (.dll) + - Avalonia (.nupkg) + - SkiaSharp (.nupkg) + +* Avalonia.Desktop (.nupkg) + - Avalonia.Win32 (.nupkg) + - Avalonia.Direct2D1 (.nupkg) + - Avalonia.Gtk (.nupkg) + - Avalonia.Cairo (.nupkg) + - Avalonia.Skia.Desktop (.nupkg) + +## Mobile + +* Avalonia.Android (.nupkg) + - Avalonia.Android (.dll) + - Avalonia.Skia.Android (.dll) + - Avalonia (.nupkg) + - SkiaSharp (.nupkg) + +* Avalonia.iOS (.nupkg) + - Avalonia.iOS (.dll) + - Avalonia.Skia.iOS (.dll) + - Avalonia (.nupkg) + - SkiaSharp (.nupkg) + +* Avalonia.Mobile (.nupkg) + - Avalonia.Android (.nupkg) + - Avalonia.iOS (.nupkg) diff --git a/docs/tutorial/toc.yml b/docs/tutorial/toc.yml index 9f4a411cf4..4f46813cd8 100644 --- a/docs/tutorial/toc.yml +++ b/docs/tutorial/toc.yml @@ -1,2 +1,6 @@ - name: Getting Started href: gettingstarted.md +- name: Avalonia NuGet Packages + href: nuget.md +- name: Avalonia for WPF Developers + href: from-wpf.md diff --git a/nuget/.gitignore b/nuget/.gitignore deleted file mode 100644 index 32f9557fad..0000000000 --- a/nuget/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Avalonia -*.nupkg \ No newline at end of file diff --git a/nuget/build-appveyor.ps1 b/nuget/build-appveyor.ps1 deleted file mode 100644 index 1441a6a79a..0000000000 --- a/nuget/build-appveyor.ps1 +++ /dev/null @@ -1,35 +0,0 @@ -$ErrorActionPreference = "Stop" -$scriptpath = $MyInvocation.MyCommand.Path -$dir = Split-Path $scriptpath -Push-Location $dir - - -sv version $env:APPVEYOR_BUILD_NUMBER -#sv version "1-debug" - -sv version 0.4.1-build$version-alpha -sv key $env:myget_key - -. ".\include.ps1" -.\build-version.ps1 $version - -sv reponame $env:APPVEYOR_REPO_NAME -sv repobranch $env:APPVEYOR_REPO_BRANCH -sv pullreq $env:APPVEYOR_PULL_REQUEST_NUMBER - -echo "Checking for publishing" -echo "$reponame $repobranch $pullreq" -if ([string]::IsNullOrWhiteSpace($pullreq)) -{ - echo "Build is not a PR" - if($repobranch -eq "master") - { - echo "Repo branch matched" - foreach($pkg in $Packages) - { - nuget.exe push "$($pkg).$($version).nupkg" $key -Source https://www.myget.org/F/avalonia-ci/api/v2/package - } - } -} - - diff --git a/nuget/build-version.ps1 b/nuget/build-version.ps1 deleted file mode 100644 index c59789ddb8..0000000000 --- a/nuget/build-version.ps1 +++ /dev/null @@ -1,84 +0,0 @@ -$ErrorActionPreference = "Stop" - -. ".\include.ps1" - -foreach($pkg in $Packages) -{ - rm -Force -Recurse .\$pkg -ErrorAction SilentlyContinue -} - -rm -Force -Recurse *.nupkg -ErrorAction SilentlyContinue -Copy-Item template Avalonia -Recurse -sv lib "Avalonia\lib\portable-windows8+net45" -sv build "Avalonia.Desktop\lib\net45" - -sv skia_root "Avalonia.Skia.Desktop" -sv skia_lib "Avalonia.Skia.Desktop\lib\net45" -sv android "Avalonia.Android\lib\MonoAndroid10" -sv ios "Avalonia.iOS\lib\Xamarin.iOS10" - -mkdir $lib -ErrorAction SilentlyContinue -mkdir $build -ErrorAction SilentlyContinue -mkdir $skia_lib -mkdir $android -mkdir $ios - - -Copy-Item ..\src\Avalonia.Animation\bin\Release\Avalonia.Animation.dll $lib -Copy-Item ..\src\Avalonia.Animation\bin\Release\Avalonia.Animation.xml $lib -Copy-Item ..\src\Avalonia.Base\bin\Release\Avalonia.Base.dll $lib -Copy-Item ..\src\Avalonia.Base\bin\Release\Avalonia.Base.xml $lib -Copy-Item ..\src\Avalonia.Controls\bin\Release\Avalonia.Controls.dll $lib -Copy-Item ..\src\Avalonia.Controls\bin\Release\Avalonia.Controls.xml $lib -Copy-Item ..\src\Avalonia.DesignerSupport\bin\Release\Avalonia.DesignerSupport.dll $lib -Copy-Item ..\src\Avalonia.DesignerSupport\bin\Release\Avalonia.DesignerSupport.xml $lib -Copy-Item ..\src\Avalonia.Diagnostics\bin\Release\\Avalonia.Diagnostics.dll $lib -Copy-Item ..\src\Avalonia.Diagnostics\bin\Release\\Avalonia.Diagnostics.xml $lib -Copy-Item ..\src\Avalonia.Input\bin\Release\Avalonia.Input.dll $lib -Copy-Item ..\src\Avalonia.Input\bin\Release\Avalonia.Input.xml $lib -Copy-Item ..\src\Avalonia.Interactivity\bin\Release\Avalonia.Interactivity.dll $lib -Copy-Item ..\src\Avalonia.Interactivity\bin\Release\Avalonia.Interactivity.xml $lib -Copy-Item ..\src\Avalonia.Layout\bin\Release\Avalonia.Layout.dll $lib -Copy-Item ..\src\Avalonia.Layout\bin\Release\Avalonia.Layout.xml $lib -Copy-Item ..\src\Avalonia.Logging.Serilog\bin\Release\Avalonia.Logging.Serilog.dll $lib -Copy-Item ..\src\Avalonia.Logging.Serilog\bin\Release\Avalonia.Logging.Serilog.xml $lib -Copy-Item ..\src\Avalonia.SceneGraph\bin\Release\Avalonia.SceneGraph.dll $lib -Copy-Item ..\src\Avalonia.SceneGraph\bin\Release\Avalonia.SceneGraph.xml $lib -Copy-Item ..\src\Avalonia.Styling\bin\Release\Avalonia.Styling.dll $lib -Copy-Item ..\src\Avalonia.Styling\bin\Release\Avalonia.Styling.xml $lib -Copy-Item ..\src\Avalonia.Themes.Default\bin\Release\Avalonia.Themes.Default.dll $lib -Copy-Item ..\src\Avalonia.Themes.Default\bin\Release\Avalonia.Themes.Default.xml $lib -Copy-Item ..\src\Markup\Avalonia.Markup\bin\Release\Avalonia.Markup.dll $lib -Copy-Item ..\src\Markup\Avalonia.Markup\bin\Release\Avalonia.Markup.xml $lib -Copy-Item ..\src\Markup\Avalonia.Markup.Xaml\bin\Release\Avalonia.Markup.Xaml.dll $lib -Copy-Item ..\src\Markup\Avalonia.Markup.Xaml\bin\Release\Avalonia.Markup.Xaml.xml $lib -Copy-Item ..\src\Avalonia.HtmlRenderer\bin\Release\Avalonia.HtmlRenderer.dll $lib -Copy-Item ..\src\Avalonia.ReactiveUI\bin\Release\Avalonia.ReactiveUI.dll $lib - -Copy-Item ..\src\Windows\Avalonia.Direct2D1\bin\Release\Avalonia.Direct2D1.dll $build -Copy-Item ..\src\Windows\Avalonia.Win32\bin\Release\Avalonia.Win32.dll $build -Copy-Item ..\src\Gtk\Avalonia.Gtk\bin\Release\Avalonia.Gtk.dll $build -Copy-Item ..\src\Gtk\Avalonia.Cairo\bin\Release\Avalonia.Cairo.dll $build - -Copy-Item ..\src\Skia\Avalonia.Skia.Desktop\bin\x86\Release\Avalonia.Skia.Desktop.dll $skia_lib - -Copy-Item ..\src\Android\Avalonia.Android\bin\Release\Avalonia.Android.dll $android -Copy-Item ..\src\Skia\Avalonia.Skia.Android\bin\Release\Avalonia.Skia.Android.dll $android - -Copy-Item ..\src\iOS\Avalonia.iOS\bin\iPhone\Release\Avalonia.iOS.dll $ios -Copy-Item ..\src\Skia\Avalonia.Skia.iOS\bin\iPhone\Release\Avalonia.Skia.iOS.dll $ios - -foreach($pkg in $Packages) -{ - (gc Avalonia\$pkg.nuspec).replace('#VERSION#', $args[0]) | sc $pkg\$pkg.nuspec -} - -foreach($pkg in $Packages) -{ - nuget.exe pack $pkg\$pkg.nuspec -} - -foreach($pkg in $Packages) -{ - rm -Force -Recurse .\$pkg -} \ No newline at end of file diff --git a/nuget/build.ps1 b/nuget/build.ps1 deleted file mode 100644 index 43c3748bdf..0000000000 --- a/nuget/build.ps1 +++ /dev/null @@ -1 +0,0 @@ -.\build-version.ps1 0.4.1 \ No newline at end of file diff --git a/nuget/include.ps1 b/nuget/include.ps1 deleted file mode 100644 index bde8ebb731..0000000000 --- a/nuget/include.ps1 +++ /dev/null @@ -1 +0,0 @@ -$Packages = @("Avalonia", "Avalonia.Desktop", "Avalonia.Skia.Desktop", "Avalonia.Android", "Avalonia.iOS") \ No newline at end of file diff --git a/nuget/template/Avalonia.Android.nuspec b/nuget/template/Avalonia.Android.nuspec deleted file mode 100644 index cdba3b5b0e..0000000000 --- a/nuget/template/Avalonia.Android.nuspec +++ /dev/null @@ -1,28 +0,0 @@ - - - - Avalonia.Android - #VERSION# - Avalonia Team - stevenk - http://opensource.org/licenses/MIT - https://github.com/AvaloniaUI/Avalonia/ - false - The Avalonia UI framework - - Copyright 2015 - Avalonia - - - - - - - - - - - - - - \ No newline at end of file diff --git a/nuget/template/Avalonia.Desktop.nuspec b/nuget/template/Avalonia.Desktop.nuspec deleted file mode 100644 index 70bebd3349..0000000000 --- a/nuget/template/Avalonia.Desktop.nuspec +++ /dev/null @@ -1,30 +0,0 @@ - - - - Avalonia.Desktop - #VERSION# - Avalonia Team - stevenk - http://opensource.org/licenses/MIT - https://github.com/AvaloniaUI/Avalonia/ - false - The Avalonia UI framework - - Copyright 2015 - Avalonia - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/nuget/template/Avalonia.Skia.Desktop.nuspec b/nuget/template/Avalonia.Skia.Desktop.nuspec deleted file mode 100644 index 928b6d3e24..0000000000 --- a/nuget/template/Avalonia.Skia.Desktop.nuspec +++ /dev/null @@ -1,20 +0,0 @@ - - - - Avalonia.Skia.Desktop - #VERSION# - Avalonia Team - stevenk - http://opensource.org/licenses/MIT - https://github.com/AvaloniaUI/Avalonia/ - false - The Avalonia UI framework - - Copyright 2015 - Avalonia - - - - - - \ No newline at end of file diff --git a/nuget/template/Avalonia.iOS.nuspec b/nuget/template/Avalonia.iOS.nuspec deleted file mode 100644 index d6b8e3fbe6..0000000000 --- a/nuget/template/Avalonia.iOS.nuspec +++ /dev/null @@ -1,27 +0,0 @@ - - - - Avalonia.iOS - #VERSION# - Avalonia Team - stevenk - http://opensource.org/licenses/MIT - https://github.com/AvaloniaUI/Avalonia/ - false - The Avalonia UI framework - - Copyright 2015 - Avalonia - - - - - - - - - - - - - \ No newline at end of file diff --git a/nuget/template/Avalonia.nuspec b/nuget/template/Avalonia.nuspec deleted file mode 100644 index 55918715a1..0000000000 --- a/nuget/template/Avalonia.nuspec +++ /dev/null @@ -1,26 +0,0 @@ - - - - Avalonia - #VERSION# - Avalonia Team - stevenk - http://opensource.org/licenses/MIT - https://github.com/AvaloniaUI/Avalonia/ - false - The Avalonia UI framework - Initial alpha release. - Copyright 2015 - Avalonia - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/BindingTest/BindingTest.csproj b/samples/BindingTest/BindingTest.csproj index 3ed2671d0a..0cdb826e11 100644 --- a/samples/BindingTest/BindingTest.csproj +++ b/samples/BindingTest/BindingTest.csproj @@ -93,6 +93,10 @@ + + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0} + Avalonia.DotNetFrameworkRuntime + {3e53a01a-b331-47f3-b828-4a5717e77a24} Avalonia.Markup.Xaml diff --git a/samples/ControlCatalog.Desktop/App.config b/samples/ControlCatalog.Desktop/App.config index 7ef9d715f8..2231c71e63 100644 --- a/samples/ControlCatalog.Desktop/App.config +++ b/samples/ControlCatalog.Desktop/App.config @@ -1,13 +1,13 @@ - + - + - - + + diff --git a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj index f42902b534..82f4ee1c28 100644 --- a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj +++ b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj @@ -64,6 +64,10 @@ {799a7bb5-3c2c-48b6-85a7-406a12c420da} Avalonia.DesignerSupport + + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0} + Avalonia.DotNetFrameworkRuntime + {FB05AC90-89BA-4F2F-A924-F37875FB547C} Avalonia.Cairo diff --git a/samples/TestApplication/TestApplication.csproj b/samples/TestApplication/TestApplication.csproj index bb18d97766..171e9991b6 100644 --- a/samples/TestApplication/TestApplication.csproj +++ b/samples/TestApplication/TestApplication.csproj @@ -83,6 +83,10 @@ + + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0} + Avalonia.DotNetFrameworkRuntime + {FB05AC90-89BA-4F2F-A924-F37875FB547C} Avalonia.Cairo diff --git a/samples/VirtualizationTest/App.config b/samples/VirtualizationTest/App.config index 7ef9d715f8..2231c71e63 100644 --- a/samples/VirtualizationTest/App.config +++ b/samples/VirtualizationTest/App.config @@ -1,13 +1,13 @@ - + - + - - + + diff --git a/samples/VirtualizationTest/VirtualizationTest.csproj b/samples/VirtualizationTest/VirtualizationTest.csproj index 98ca3ab970..512d4c361f 100644 --- a/samples/VirtualizationTest/VirtualizationTest.csproj +++ b/samples/VirtualizationTest/VirtualizationTest.csproj @@ -103,6 +103,10 @@ {7062ae20-5dcc-4442-9645-8195bdece63e} Avalonia.Diagnostics + + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0} + Avalonia.DotNetFrameworkRuntime + {62024b2d-53eb-4638-b26b-85eeaa54866e} Avalonia.Input diff --git a/samples/XamlTestApplication/XamlTestApplication.csproj b/samples/XamlTestApplication/XamlTestApplication.csproj index c902b6dcf4..d3c9ba8d7d 100644 --- a/samples/XamlTestApplication/XamlTestApplication.csproj +++ b/samples/XamlTestApplication/XamlTestApplication.csproj @@ -48,8 +48,8 @@ ..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll True - - ..\..\packages\Sprache.2.0.0.50\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll + + ..\..\packages\Sprache.2.0.0.51\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll True @@ -91,6 +91,10 @@ + + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0} + Avalonia.DotNetFrameworkRuntime + {6417e941-21bc-467b-a771-0de389353ce6} Avalonia.Markup diff --git a/samples/XamlTestApplication/packages.config b/samples/XamlTestApplication/packages.config index dc9c5078a2..7e3e5237a5 100644 --- a/samples/XamlTestApplication/packages.config +++ b/samples/XamlTestApplication/packages.config @@ -2,7 +2,7 @@ - + diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 44de3425ba..1a6624e8f6 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -49,7 +49,7 @@ namespace Avalonia.Android public void Init(Type applicationType) { - SharedPlatform.Register(applicationType.Assembly); + StandardRuntimePlatformServices.Register(applicationType.Assembly); } public IWindowImpl CreateWindow() diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj index 88e66c441a..9af96f0f93 100644 --- a/src/Android/Avalonia.Android/Avalonia.Android.csproj +++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj @@ -77,6 +77,7 @@ + diff --git a/src/Android/Avalonia.Android/RuntimeInfo.cs b/src/Android/Avalonia.Android/RuntimeInfo.cs new file mode 100644 index 0000000000..bb2466c357 --- /dev/null +++ b/src/Android/Avalonia.Android/RuntimeInfo.cs @@ -0,0 +1,18 @@ +using Avalonia.Platform; + +namespace Avalonia.Shared.PlatformSupport +{ + internal partial class StandardRuntimePlatform + { + public RuntimePlatformInfo GetRuntimeInfo() => new RuntimePlatformInfo + { + IsCoreClr = false, + IsDesktop = false, + IsMobile = true, + IsDotNetFramework = false, + IsMono = true, + IsUnix = true, + OperatingSystem = OperatingSystemType.Android + }; + } +} \ No newline at end of file diff --git a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj index a90acabed0..cfc8cd2318 100644 --- a/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj +++ b/src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj @@ -65,15 +65,15 @@ - ..\..\..\packages\Serilog.1.5.9\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll + ..\..\..\packages\Serilog.1.5.14\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll True ..\..\..\packages\Splat.1.6.2\lib\monoandroid\Splat.dll True - - ..\..\..\packages\Sprache.2.0.0.47\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid1+MonoTouch1\Sprache.dll + + ..\..\..\packages\Sprache.2.0.0.51\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll True diff --git a/src/Android/Avalonia.AndroidTestApplication/packages.config b/src/Android/Avalonia.AndroidTestApplication/packages.config index 1b636d41d6..470074798d 100644 --- a/src/Android/Avalonia.AndroidTestApplication/packages.config +++ b/src/Android/Avalonia.AndroidTestApplication/packages.config @@ -1,8 +1,8 @@  - + - + diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj index 107c0e7071..1dfc5cf65b 100644 --- a/src/Avalonia.Base/Avalonia.Base.csproj +++ b/src/Avalonia.Base/Avalonia.Base.csproj @@ -85,7 +85,7 @@ - + diff --git a/src/Avalonia.Base/AvaloniaDisposable.cs b/src/Avalonia.Base/AvaloniaDisposable.cs index 773c7a6e67..9e43a65f26 100644 --- a/src/Avalonia.Base/AvaloniaDisposable.cs +++ b/src/Avalonia.Base/AvaloniaDisposable.cs @@ -20,7 +20,7 @@ namespace Avalonia { IsDisposed = true; #if DEBUG_DISPOSE - DisposedAt = AvaloniaLocator.Current.GetService().GetStackTrace(); + DisposedAt = AvaloniaLocator.Current.GetService().GetStackTrace(); #endif DoDispose(); } diff --git a/src/Avalonia.Base/Platform/IPclPlatformWrapper.cs b/src/Avalonia.Base/Platform/IPclPlatformWrapper.cs deleted file mode 100644 index 2a21f20f91..0000000000 --- a/src/Avalonia.Base/Platform/IPclPlatformWrapper.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace Avalonia.Platform -{ - public interface IPclPlatformWrapper - { - Assembly[] GetLoadedAssemblies(); - void PostThreadPoolItem(Action cb); - IDisposable StartSystemTimer(TimeSpan interval, Action tick); - string GetStackTrace(); - } -} diff --git a/src/Avalonia.Base/Platform/IRuntimePlatform.cs b/src/Avalonia.Base/Platform/IRuntimePlatform.cs new file mode 100644 index 0000000000..e1a09f094d --- /dev/null +++ b/src/Avalonia.Base/Platform/IRuntimePlatform.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Avalonia.Platform +{ + public interface IRuntimePlatform + { + Assembly[] GetLoadedAssemblies(); + void PostThreadPoolItem(Action cb); + IDisposable StartSystemTimer(TimeSpan interval, Action tick); + string GetStackTrace(); + RuntimePlatformInfo GetRuntimeInfo(); + } + + public struct RuntimePlatformInfo + { + public OperatingSystemType OperatingSystem { get; set; } + public bool IsDesktop { get; set; } + public bool IsMobile { get; set; } + public bool IsCoreClr { get; set; } + public bool IsMono { get; set; } + public bool IsDotNetFramework { get; set; } + public bool IsUnix { get; set; } + } + + public enum OperatingSystemType + { + Unknown, + WinNT, + Linux, + OSX, + Android, + iOS + } +} diff --git a/src/Avalonia.Base/Threading/SingleThreadDispatcher.cs b/src/Avalonia.Base/Threading/SingleThreadDispatcher.cs index 815d95ac6e..76d47b30b0 100644 --- a/src/Avalonia.Base/Threading/SingleThreadDispatcher.cs +++ b/src/Avalonia.Base/Threading/SingleThreadDispatcher.cs @@ -33,7 +33,7 @@ namespace Avalonia.Threading } public IDisposable StartTimer(TimeSpan interval, Action tick) - => AvaloniaLocator.Current.GetService().StartSystemTimer(interval, + => AvaloniaLocator.Current.GetService().StartSystemTimer(interval, () => _timerJobRunner.Post(tick, DispatcherPriority.Normal)); public void Signal() => _evnt.Set(); @@ -50,7 +50,7 @@ namespace Avalonia.Threading public static Dispatcher StartNew(CancellationToken token) { var dispatcher = new SingleThreadDispatcher(); - AvaloniaLocator.Current.GetService().PostThreadPoolItem(() => + AvaloniaLocator.Current.GetService().PostThreadPoolItem(() => { dispatcher.MainLoop(token); }); diff --git a/src/Avalonia.Controls/AppBuilder.cs b/src/Avalonia.Controls/AppBuilder.cs index 8b3e0e731a..82698acde7 100644 --- a/src/Avalonia.Controls/AppBuilder.cs +++ b/src/Avalonia.Controls/AppBuilder.cs @@ -3,14 +3,25 @@ using System; using System.Reflection; +using Avalonia.Platform; namespace Avalonia.Controls { /// /// Initializes up platform-specific services for an . /// - public class AppBuilder + public abstract class AppBuilderBase where AppBuilder : AppBuilderBase, new() { + /// + /// Gets or sets the instance. + /// + public IRuntimePlatform RuntimePlatform { get; set; } + + /// + /// Gets or sets a method to call the initialize the runtime platform services (e. g. AssetLoader) + /// + public Action RuntimePlatformServices { get; set; } + /// /// Gets or sets the instance being initialized. /// @@ -32,6 +43,12 @@ namespace Avalonia.Controls /// public Action BeforeStartCallback { get; set; } + protected AppBuilderBase(IRuntimePlatform platform, Action platformSevices) + { + RuntimePlatform = platform; + RuntimePlatformServices = platformSevices; + } + /// /// Begin configuring an . /// @@ -57,6 +74,8 @@ namespace Avalonia.Controls }; } + protected AppBuilder Self => (AppBuilder) this; + /// /// Registers a callback to call before is called on the /// . @@ -66,7 +85,7 @@ namespace Avalonia.Controls public AppBuilder BeforeStarting(Action callback) { BeforeStartCallback = callback; - return this; + return Self; } /// @@ -77,7 +96,7 @@ namespace Avalonia.Controls where TMainWindow : Window, new() { Setup(); - BeforeStartCallback?.Invoke(this); + BeforeStartCallback?.Invoke(Self); var window = new TMainWindow(); window.Show(); @@ -91,7 +110,7 @@ namespace Avalonia.Controls public AppBuilder SetupWithoutStarting() { Setup(); - return this; + return Self; } /// @@ -102,7 +121,7 @@ namespace Avalonia.Controls public AppBuilder UseWindowingSubsystem(Action initializer) { WindowingSubsystem = initializer; - return this; + return Self; } /// @@ -120,7 +139,7 @@ namespace Avalonia.Controls public AppBuilder UseRenderingSubsystem(Action initializer) { RenderingSubsystem = initializer; - return this; + return Self; } /// @@ -140,23 +159,6 @@ namespace Avalonia.Controls init.Invoke(null, null); }; - public AppBuilder UsePlatformDetect() - { - var platformId = (int) - ((dynamic) Type.GetType("System.Environment").GetRuntimeProperty("OSVersion").GetValue(null)).Platform; - if (platformId == 4 || platformId == 6) - { - UseRenderingSubsystem("Avalonia.Cairo"); - UseWindowingSubsystem("Avalonia.Gtk"); - } - else - { - UseRenderingSubsystem("Avalonia.Direct2D1"); - UseWindowingSubsystem("Avalonia.Win32"); - } - return this; - } - /// /// Sets up the platform-speciic services for the . /// @@ -167,6 +169,11 @@ namespace Avalonia.Controls throw new InvalidOperationException("No App instance configured."); } + if (RuntimePlatformServices == null) + { + throw new InvalidOperationException("No runtime platform services configured."); + } + if (WindowingSubsystem == null) { throw new InvalidOperationException("No windowing system configured."); @@ -178,6 +185,7 @@ namespace Avalonia.Controls } Instance.RegisterServices(); + RuntimePlatformServices(); WindowingSubsystem(); RenderingSubsystem(); Instance.Initialize(); diff --git a/src/Avalonia.DesignerSupport/DesignerAssist.cs b/src/Avalonia.DesignerSupport/DesignerAssist.cs index 8787144665..95e7345227 100644 --- a/src/Avalonia.DesignerSupport/DesignerAssist.cs +++ b/src/Avalonia.DesignerSupport/DesignerAssist.cs @@ -37,8 +37,11 @@ namespace Avalonia.DesignerSupport { Design.IsDesignMode = true; Api = new DesignerApi(shared) {UpdateXaml = UpdateXaml, UpdateXaml2 = UpdateXaml2, SetScalingFactor = SetScalingFactor}; - var plat = (IPclPlatformWrapper) Activator.CreateInstance(Assembly.Load(new AssemblyName("Avalonia.Win32")) - .DefinedTypes.First(typeof (IPclPlatformWrapper).GetTypeInfo().IsAssignableFrom).AsType()); + + var runtimeAssembly = Assembly.Load(new AssemblyName("Avalonia.DotNetFrameworkRuntime")); + + var plat = (IRuntimePlatform) Activator.CreateInstance(runtimeAssembly + .DefinedTypes.First(typeof (IRuntimePlatform).GetTypeInfo().IsAssignableFrom).AsType()); TypeInfo app = null; var asms = plat.GetLoadedAssemblies(); @@ -58,7 +61,12 @@ namespace Avalonia.DesignerSupport //Ignore, Assembly.DefinedTypes threw an exception, we can't do anything about that } } - AppBuilder.Configure(app == null ? new DesignerApp() : (Application) Activator.CreateInstance(app.AsType())) + + var builderType = runtimeAssembly.GetType("Avalonia.AppBuilder"); + + var builder = (dynamic)Activator.CreateInstance(builderType, + app == null ? new DesignerApp() : (Application) Activator.CreateInstance(app.AsType())); + builder .UseWindowingSubsystem("Avalonia.Win32") .UseRenderingSubsystem("Avalonia.Direct2D1") .SetupWithoutStarting(); diff --git a/src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs b/src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs new file mode 100644 index 0000000000..5dc36865ee --- /dev/null +++ b/src/Avalonia.DotNetFrameworkRuntime/AppBuilder.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Avalonia.Controls; +using Avalonia.Platform; +using Avalonia.Shared.PlatformSupport; + +namespace Avalonia +{ + public sealed class AppBuilder : AppBuilderBase + { + public AppBuilder() : base(new StandardRuntimePlatform(), () => StandardRuntimePlatformServices.Register()) + { + } + + public AppBuilder(Application app) : this() + { + Instance = app; + } + + public AppBuilder UsePlatformDetect() + { + var platformId = (int)Environment.OSVersion.Platform; + if (platformId == 4 || platformId == 6) + { + UseRenderingSubsystem("Avalonia.Cairo"); + UseWindowingSubsystem("Avalonia.Gtk"); + } + else + { + UseRenderingSubsystem("Avalonia.Direct2D1"); + UseWindowingSubsystem("Avalonia.Win32"); + } + return this; + } + } +} diff --git a/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj b/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj new file mode 100644 index 0000000000..55a4578f59 --- /dev/null +++ b/src/Avalonia.DotNetFrameworkRuntime/Avalonia.DotNetFrameworkRuntime.csproj @@ -0,0 +1,84 @@ + + + + + Debug + AnyCPU + {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0} + Library + Properties + Avalonia.DotNetFrameworkRuntime + Avalonia.DotNetFrameworkRuntime + v4.5 + 512 + + + + true + full + false + bin\Debug\ + TRACE;DEBUG;FULLDOTNET + prompt + 4 + bin\Debug\Avalonia.DotNetFrameworkRuntime.xml + + + pdbonly + true + bin\Release\ + TRACE;FULLDOTNET + prompt + 4 + bin\Release\Avalonia.DotNetFrameworkRuntime.xml + + + + + + ..\..\packages\System.Reactive.Core.3.0.0\lib\net45\System.Reactive.Core.dll + True + + + ..\..\packages\System.Reactive.Interfaces.3.0.0\lib\net45\System.Reactive.Interfaces.dll + True + + + + + + + + + + + + + + + + {B09B78D8-9B26-48B0-9149-D64A2F120F3F} + Avalonia.Base + + + {D2221C82-4A25-4583-9B43-D791E3F6820C} + Avalonia.Controls + + + {f1baa01a-f176-4c6a-b39d-5b40bb1b148f} + Avalonia.Styling + + + + + + + + + diff --git a/src/Avalonia.DotNetFrameworkRuntime/Properties/AssemblyInfo.cs b/src/Avalonia.DotNetFrameworkRuntime/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..f55d3056f6 --- /dev/null +++ b/src/Avalonia.DotNetFrameworkRuntime/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Avalonia.DotNetFrameworkRuntime")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Avalonia.DotNetFrameworkRuntime")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4a1abb09-9047-4bd5-a4ad-a055e52c5ee0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Avalonia.DotNetFrameworkRuntime/RuntimeInfo.cs b/src/Avalonia.DotNetFrameworkRuntime/RuntimeInfo.cs new file mode 100644 index 0000000000..41545a146f --- /dev/null +++ b/src/Avalonia.DotNetFrameworkRuntime/RuntimeInfo.cs @@ -0,0 +1,44 @@ +using System; +using System.Runtime.InteropServices; +using Avalonia.Platform; + +namespace Avalonia.Shared.PlatformSupport +{ + internal partial class StandardRuntimePlatform + { + private static readonly Lazy Info = new Lazy(() => + { + var isMono = Type.GetType("Mono.Runtime") != null; + var isUnix = Environment.OSVersion.Platform == PlatformID.Unix || + Environment.OSVersion.Platform == PlatformID.MacOSX; + return new RuntimePlatformInfo + { + IsCoreClr = false, + IsDesktop = true, + IsDotNetFramework = !isMono, + IsMono = isMono, + IsMobile = false, + IsUnix = isUnix, + OperatingSystem = isUnix ? DetectUnix() : OperatingSystemType.WinNT, + }; + }); + + [DllImport("libc")] + static extern int uname(IntPtr buf); + + static OperatingSystemType DetectUnix() + { + var buffer = Marshal.AllocHGlobal(0x1000); + uname(buffer); + var unixName = Marshal.PtrToStringAnsi(buffer); + Marshal.FreeHGlobal(buffer); + if(unixName=="Darwin") + return OperatingSystemType.OSX; + if (unixName == "Linux") + return OperatingSystemType.Linux; + return OperatingSystemType.Unknown; + } + + public RuntimePlatformInfo GetRuntimeInfo() => Info.Value; + } +} diff --git a/src/Avalonia.DotNetFrameworkRuntime/packages.config b/src/Avalonia.DotNetFrameworkRuntime/packages.config new file mode 100644 index 0000000000..1e93a8c9e7 --- /dev/null +++ b/src/Avalonia.DotNetFrameworkRuntime/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/Gtk/Avalonia.Cairo/CairoPlatform.cs b/src/Gtk/Avalonia.Cairo/CairoPlatform.cs index 2b0fce8210..6606ed4aef 100644 --- a/src/Gtk/Avalonia.Cairo/CairoPlatform.cs +++ b/src/Gtk/Avalonia.Cairo/CairoPlatform.cs @@ -12,7 +12,7 @@ namespace Avalonia { public static class GtkApplicationExtensions { - public static AppBuilder UseCairo(this AppBuilder builder) + public static T UseCairo(this T builder) where T : AppBuilderBase, new() { builder.RenderingSubsystem = Avalonia.Cairo.CairoPlatform.Initialize; return builder; diff --git a/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj b/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj index 4cf732d56a..7e8c118196 100644 --- a/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj +++ b/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj @@ -103,5 +103,4 @@ - \ No newline at end of file diff --git a/src/Gtk/Avalonia.Gtk/GtkPlatform.cs b/src/Gtk/Avalonia.Gtk/GtkPlatform.cs index 3adf1c9b89..455aa67405 100644 --- a/src/Gtk/Avalonia.Gtk/GtkPlatform.cs +++ b/src/Gtk/Avalonia.Gtk/GtkPlatform.cs @@ -8,14 +8,13 @@ using Avalonia.Controls.Platform; using Avalonia.Input.Platform; using Avalonia.Input; using Avalonia.Platform; -using Avalonia.Shared.PlatformSupport; using Avalonia.Controls; namespace Avalonia { public static class GtkApplicationExtensions { - public static AppBuilder UseGtk(this AppBuilder builder) + public static T UseGtk(this T builder) where T : AppBuilderBase, new() { builder.WindowingSubsystem = Avalonia.Gtk.GtkPlatform.Initialize; return builder; @@ -56,7 +55,6 @@ namespace Avalonia.Gtk .Bind().ToConstant(s_instance) .Bind().ToSingleton() .Bind().ToConstant(s_instance); - SharedPlatform.Register(); _uiThread = Thread.CurrentThread; } diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index 45280020c4..2b0d034a5a 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -60,6 +60,7 @@ + @@ -321,8 +322,8 @@ - - ..\..\..\packages\Sprache.2.0.0.50\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll + + ..\..\..\packages\Sprache.2.0.0.51\lib\portable-net4+netcore45+win8+wp8+sl5+MonoAndroid+Xamarin.iOS10+MonoTouch\Sprache.dll True diff --git a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs index 11205972fe..b591654621 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaNamespaceRegistry.cs @@ -168,7 +168,7 @@ namespace Avalonia.Markup.Xaml.Context private void ScanNewAssemblies() { IEnumerable assemblies = AvaloniaLocator.Current - .GetService() + .GetService() ?.GetLoadedAssemblies(); if (assemblies != null) diff --git a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeFeatureProvider.cs b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeFeatureProvider.cs index 4396062e79..fcb5703f83 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeFeatureProvider.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Context/AvaloniaTypeFeatureProvider.cs @@ -174,6 +174,7 @@ namespace Avalonia.Markup.Xaml.Context RegisterTypeConverter(typeof(Uri), new UriTypeConverter()); RegisterTypeConverter(typeof(Cursor), new CursorTypeConverter()); RegisterTypeConverter(typeof(WindowIcon), new IconTypeConverter()); + RegisterTypeConverter(typeof(FontWeight), new FontWeightConverter()); } } } \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/FontWeightConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/FontWeightConverter.cs new file mode 100644 index 0000000000..00964ef043 --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml/Converters/FontWeightConverter.cs @@ -0,0 +1,39 @@ +namespace Avalonia.Markup.Xaml.Converters +{ + using Avalonia.Media; + using OmniXaml.TypeConversion; + using System; + using System.Globalization; + + public class FontWeightConverter : ITypeConverter + { + public bool CanConvertFrom(IValueContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public bool CanConvertTo(IValueContext context, Type destinationType) + { + return false; + } + + public object ConvertFrom(IValueContext context, CultureInfo culture, object value) + { + FontWeight result; + + if (Enum.TryParse(value as string, out result)) + { + return result; + } + else + { + throw new ArgumentException("unable to convert parameter to FontWeight"); + } + } + + public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Markup/Avalonia.Markup.Xaml/packages.config b/src/Markup/Avalonia.Markup.Xaml/packages.config index 12bd37feef..762fe58c1f 100644 --- a/src/Markup/Avalonia.Markup.Xaml/packages.config +++ b/src/Markup/Avalonia.Markup.Xaml/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/Shared/PlatformSupport/PlatformSupport.projitems b/src/Shared/PlatformSupport/PlatformSupport.projitems index 0bf2184e09..a9b6a8fa2a 100644 --- a/src/Shared/PlatformSupport/PlatformSupport.projitems +++ b/src/Shared/PlatformSupport/PlatformSupport.projitems @@ -1,4 +1,4 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) @@ -10,7 +10,7 @@ - - + + \ No newline at end of file diff --git a/src/Shared/PlatformSupport/PclPlatformWrapper.cs b/src/Shared/PlatformSupport/StandardRuntimePlatform.cs similarity index 92% rename from src/Shared/PlatformSupport/PclPlatformWrapper.cs rename to src/Shared/PlatformSupport/StandardRuntimePlatform.cs index ba705c7634..e5ede1c6b4 100644 --- a/src/Shared/PlatformSupport/PclPlatformWrapper.cs +++ b/src/Shared/PlatformSupport/StandardRuntimePlatform.cs @@ -10,7 +10,7 @@ using Avalonia.Platform; namespace Avalonia.Shared.PlatformSupport { - internal class PclPlatformWrapper : IPclPlatformWrapper + internal partial class StandardRuntimePlatform : IRuntimePlatform { public Assembly[] GetLoadedAssemblies() => AppDomain.CurrentDomain.GetAssemblies(); public void PostThreadPoolItem(Action cb) => ThreadPool.UnsafeQueueUserWorkItem(_ => cb(), null); @@ -23,6 +23,8 @@ namespace Avalonia.Shared.PlatformSupport return Disposable.Create(() => timer.Dispose()); } + + public string GetStackTrace() => Environment.StackTrace; } } \ No newline at end of file diff --git a/src/Shared/PlatformSupport/SharedPlatform.cs b/src/Shared/PlatformSupport/StandardRuntimePlatformServices.cs similarity index 74% rename from src/Shared/PlatformSupport/SharedPlatform.cs rename to src/Shared/PlatformSupport/StandardRuntimePlatformServices.cs index 0db01367bb..70601fdf4a 100644 --- a/src/Shared/PlatformSupport/SharedPlatform.cs +++ b/src/Shared/PlatformSupport/StandardRuntimePlatformServices.cs @@ -6,12 +6,12 @@ using Avalonia.Platform; namespace Avalonia.Shared.PlatformSupport { - static class SharedPlatform + static class StandardRuntimePlatformServices { public static void Register(Assembly assembly = null) { AvaloniaLocator.CurrentMutable - .Bind().ToSingleton() + .Bind().ToSingleton() .Bind().ToConstant(new AssetLoader(assembly)); } } diff --git a/src/Shared/SharedAssemblyInfo.cs b/src/Shared/SharedAssemblyInfo.cs index 4a1bebb868..63111eebf4 100644 --- a/src/Shared/SharedAssemblyInfo.cs +++ b/src/Shared/SharedAssemblyInfo.cs @@ -13,6 +13,6 @@ using System.Resources; [assembly: AssemblyTrademark("")] [assembly: NeutralResourcesLanguage("en")] -[assembly: AssemblyVersion("0.4.0")] -[assembly: AssemblyFileVersion("0.4.0")] -[assembly: AssemblyInformationalVersion("0.4.0")] +[assembly: AssemblyVersion("0.4.1")] +[assembly: AssemblyFileVersion("0.4.1")] +[assembly: AssemblyInformationalVersion("0.4.1")] diff --git a/src/Skia/Avalonia.Skia/SkiaPlatform.cs b/src/Skia/Avalonia.Skia/SkiaPlatform.cs index 1d93089e45..3f9e49d3c3 100644 --- a/src/Skia/Avalonia.Skia/SkiaPlatform.cs +++ b/src/Skia/Avalonia.Skia/SkiaPlatform.cs @@ -8,7 +8,7 @@ namespace Avalonia { public static class SkiaApplicationExtensions { - public static AppBuilder UseSkia(this AppBuilder builder) + public static T UseSkia(this T builder) where T : AppBuilderBase, new() { builder.RenderingSubsystem = Avalonia.Skia.SkiaPlatform.Initialize; return builder; diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 6ad64aced1..10f32861e8 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -12,7 +12,7 @@ namespace Avalonia { public static class Direct2DApplicationExtensions { - public static AppBuilder UseDirect2D1(this AppBuilder builder) + public static T UseDirect2D1(this T builder) where T : AppBuilderBase, new() { builder.RenderingSubsystem = Avalonia.Direct2D1.Direct2D1Platform.Initialize; return builder; diff --git a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj index 91d36f09c9..074fe84914 100644 --- a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj +++ b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj @@ -123,7 +123,6 @@ -