327 changed files with 13348 additions and 2208 deletions
@ -1,16 +1,31 @@ |
|||
This template is not intended to be prescriptive, but to help us review pull requests it would be useful if you included as much of the following information as possible: |
|||
## What does the pull request do? |
|||
|
|||
- What does the pull request do? |
|||
- What is the current behavior? |
|||
- What is the updated/expected behavior with this PR? |
|||
- How was the solution implemented (if it's not obvious)? |
|||
Give a bit of background on the PR here, together with links to with related issues etc. |
|||
|
|||
Checklist: |
|||
## What is the current behavior? |
|||
|
|||
If the PR is a fix, describe the current incorrect behavior, otherwise delete this section. |
|||
|
|||
## What is the updated/expected behavior with this PR? |
|||
|
|||
Describe how to test the PR. |
|||
|
|||
## How was the solution implemented (if it's not obvious)? |
|||
|
|||
Include any information that might be of use to a reviewer here. |
|||
|
|||
## Checklist |
|||
|
|||
- [ ] Added unit tests (if possible)? |
|||
- [ ] Added XML documentation to any related classes? |
|||
- [ ] Consider submitting a PR to https://github.com/AvaloniaUI/Avaloniaui.net with user documentation |
|||
|
|||
## Breaking changes |
|||
|
|||
List any breaking changes here. When the PR is merged please add an entry to https://github.com/AvaloniaUI/Avalonia/wiki/Breaking-Changes |
|||
|
|||
## Fixed issues |
|||
|
|||
If the pull request fixes issue(s) list them like this: |
|||
|
|||
Fixes #123 |
|||
|
|||
@ -1,3 +1,6 @@ |
|||
[submodule "src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github"] |
|||
path = src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github |
|||
url = https://github.com/AvaloniaUI/Portable.Xaml.git |
|||
[submodule "nukebuild/Numerge"] |
|||
path = nukebuild/Numerge |
|||
url = https://github.com/kekekeks/Numerge.git |
|||
|
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -1,24 +0,0 @@ |
|||
language: csharp |
|||
os: |
|||
- linux |
|||
dist: trusty |
|||
osx_image: xcode8.3 |
|||
env: |
|||
global: |
|||
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 |
|||
- DOTNET_CLI_TELEMETRY_OPTOUT=1 |
|||
mono: |
|||
- 5.2.0 |
|||
dotnet: 2.1.200 |
|||
script: |
|||
- sudo apt-get update |
|||
- sudo apt-get install castxml |
|||
- ./build.sh --target "Travis" --configuration "Release" |
|||
notifications: |
|||
email: false |
|||
webhooks: |
|||
urls: |
|||
- https://webhooks.gitter.im/e/98f653320ef2b7506c05 |
|||
on_success: change |
|||
on_failure: always |
|||
on_start: never |
|||
@ -1,5 +1,5 @@ |
|||
<Project> |
|||
<PropertyGroup> |
|||
<PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)artifacts/nuget</PackageOutputPath> |
|||
<PackageOutputPath Condition="'$(PackageOutputPath)' == ''">$(MSBuildThisFileDirectory)build-intermediate/nuget</PackageOutputPath> |
|||
</PropertyGroup> |
|||
</Project> |
|||
|
|||
@ -1,23 +0,0 @@ |
|||
os: Visual Studio 2017 |
|||
skip_branch_with_pr: true |
|||
configuration: |
|||
- Release |
|||
environment: |
|||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 |
|||
DOTNET_CLI_TELEMETRY_OPTOUT: 1 |
|||
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 |
|||
init: |
|||
- ps: if (Test-Path env:nuget_address) {[System.IO.File]::AppendAllText("C:\Windows\System32\drivers\etc\hosts", "`n$($env:nuget_address)`tapi.nuget.org")} |
|||
before_build: |
|||
- git submodule update --init |
|||
build_script: |
|||
- ps: .\build.ps1 -Target "AppVeyor" -Configuration "$env:configuration" |
|||
|
|||
test: off |
|||
artifacts: |
|||
- path: artifacts\nuget\*.nupkg |
|||
- path: artifacts\zip\*.zip |
|||
- path: artifacts\inspectcode.xml |
|||
@ -1,312 +0,0 @@ |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// TOOLS |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#tool "nuget:?package=NuGet.CommandLine&version=4.7.1" |
|||
#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.2.3" |
|||
#tool "nuget:?package=xunit.runner.console&version=2.3.1" |
|||
#tool "nuget:?package=JetBrains.dotMemoryUnit&version=3.0.20171219.105559" |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// USINGS |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// SCRIPTS |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#load "./parameters.cake" |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// SETUP |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
Setup<Parameters>(context => |
|||
{ |
|||
var parameters = new Parameters(context); |
|||
|
|||
Information("Building version {0} of Avalonia ({1}) using version {2} of Cake.", |
|||
parameters.Version, |
|||
parameters.Configuration, |
|||
typeof(ICakeContext).Assembly.GetName().Version.ToString()); |
|||
|
|||
if (parameters.IsRunningOnAppVeyor) |
|||
{ |
|||
Information("Repository Name: " + BuildSystem.AppVeyor.Environment.Repository.Name); |
|||
Information("Repository Branch: " + BuildSystem.AppVeyor.Environment.Repository.Branch); |
|||
} |
|||
Information("Target:" + context.TargetTask.Name); |
|||
Information("Configuration: " + parameters.Configuration); |
|||
Information("IsLocalBuild: " + parameters.IsLocalBuild); |
|||
Information("IsRunningOnUnix: " + parameters.IsRunningOnUnix); |
|||
Information("IsRunningOnWindows: " + parameters.IsRunningOnWindows); |
|||
Information("IsRunningOnAppVeyor: " + parameters.IsRunningOnAppVeyor); |
|||
Information("IsRunnongOnAzure:" + parameters.IsRunningOnAzure); |
|||
Information("IsPullRequest: " + parameters.IsPullRequest); |
|||
Information("IsMainRepo: " + parameters.IsMainRepo); |
|||
Information("IsMasterBranch: " + parameters.IsMasterBranch); |
|||
Information("IsReleaseBranch: " + parameters.IsReleaseBranch); |
|||
Information("IsTagged: " + parameters.IsTagged); |
|||
Information("IsReleasable: " + parameters.IsReleasable); |
|||
Information("IsMyGetRelease: " + parameters.IsMyGetRelease); |
|||
Information("IsNuGetRelease: " + parameters.IsNuGetRelease); |
|||
|
|||
return parameters; |
|||
}); |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// TEARDOWN |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
Teardown<Parameters>((context, buildContext) => |
|||
{ |
|||
Information("Finished running tasks."); |
|||
}); |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// TASKS |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
Task("Clean-Impl") |
|||
.Does<Parameters>(data => |
|||
{ |
|||
CleanDirectories(data.BuildDirs); |
|||
CleanDirectory(data.ArtifactsDir); |
|||
CleanDirectory(data.NugetRoot); |
|||
CleanDirectory(data.ZipRoot); |
|||
CleanDirectory(data.TestResultsRoot); |
|||
}); |
|||
|
|||
void DotNetCoreBuild(Parameters parameters) |
|||
{ |
|||
var settings = new DotNetCoreBuildSettings |
|||
{ |
|||
Configuration = parameters.Configuration, |
|||
MSBuildSettings = new DotNetCoreMSBuildSettings |
|||
{ |
|||
Properties = |
|||
{ |
|||
{ "PackageVersion", new [] { parameters.Version } } |
|||
} |
|||
} |
|||
}; |
|||
|
|||
DotNetCoreBuild(parameters.MSBuildSolution, settings); |
|||
} |
|||
|
|||
Task("Build-Impl") |
|||
.Does<Parameters>(data => |
|||
{ |
|||
if(data.IsRunningOnWindows) |
|||
{ |
|||
MSBuild(data.MSBuildSolution, settings => { |
|||
settings.SetConfiguration(data.Configuration); |
|||
settings.SetVerbosity(Verbosity.Minimal); |
|||
settings.WithProperty("iOSRoslynPathHackRequired", "true"); |
|||
settings.WithProperty("PackageVersion", data.Version); |
|||
settings.UseToolVersion(MSBuildToolVersion.VS2017); |
|||
settings.WithRestore(); |
|||
}); |
|||
} |
|||
else |
|||
{ |
|||
DotNetCoreBuild(data); |
|||
} |
|||
}); |
|||
|
|||
void RunCoreTest(string project, Parameters parameters, bool coreOnly = false) |
|||
{ |
|||
if(!project.EndsWith(".csproj")) |
|||
project = System.IO.Path.Combine(project, System.IO.Path.GetFileName(project)+".csproj"); |
|||
Information("Running tests from " + project); |
|||
var frameworks = new List<string>(){"netcoreapp2.0"}; |
|||
foreach(var fw in frameworks) |
|||
{ |
|||
if(!fw.StartsWith("netcoreapp") && coreOnly) |
|||
continue; |
|||
Information("Running for " + fw); |
|||
|
|||
var settings = new DotNetCoreTestSettings { |
|||
Configuration = parameters.Configuration, |
|||
Framework = fw, |
|||
NoBuild = true, |
|||
NoRestore = true |
|||
}; |
|||
|
|||
if (parameters.PublishTestResults) |
|||
{ |
|||
settings.Logger = "trx"; |
|||
settings.ResultsDirectory = parameters.TestResultsRoot; |
|||
} |
|||
|
|||
DotNetCoreTest(project, settings); |
|||
} |
|||
} |
|||
|
|||
Task("Run-Unit-Tests-Impl") |
|||
.WithCriteria<Parameters>((context, data) => !data.SkipTests) |
|||
.Does<Parameters>(data => |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.Base.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Controls.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Input.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Layout.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Markup.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Styling.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Visuals.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.Skia.UnitTests", data, false); |
|||
RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests", data, false); |
|||
if (data.IsRunningOnWindows) |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.Direct2D1.UnitTests", data, false); |
|||
} |
|||
}); |
|||
|
|||
Task("Run-Designer-Tests-Impl") |
|||
.WithCriteria<Parameters>((context, data) => !data.SkipTests) |
|||
.Does<Parameters>(data => |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", data, false); |
|||
}); |
|||
|
|||
Task("Run-Render-Tests-Impl") |
|||
.WithCriteria<Parameters>((context, data) => !data.SkipTests) |
|||
.WithCriteria<Parameters>((context, data) => data.IsRunningOnWindows) |
|||
.Does<Parameters>(data => |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", data, true); |
|||
RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", data, true); |
|||
}); |
|||
|
|||
Task("Run-Leak-Tests-Impl") |
|||
.WithCriteria<Parameters>((context, data) => !data.SkipTests) |
|||
.WithCriteria<Parameters>((context, data) => data.IsRunningOnWindows) |
|||
.Does(() => |
|||
{ |
|||
var dotMemoryUnit = Context.Tools.Resolve("dotMemoryUnit.exe"); |
|||
var leakTestsExitCode = StartProcess(dotMemoryUnit, new ProcessSettings |
|||
{ |
|||
Arguments = new ProcessArgumentBuilder() |
|||
.Append(Context.Tools.Resolve("xunit.console.x86.exe").FullPath) |
|||
.Append("--propagate-exit-code") |
|||
.Append("--") |
|||
.Append("tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll"), |
|||
Timeout = 120000 |
|||
}); |
|||
|
|||
if (leakTestsExitCode != 0) |
|||
{ |
|||
throw new Exception("Leak Tests failed"); |
|||
} |
|||
}); |
|||
|
|||
Task("Zip-Files-Impl") |
|||
.Does<Parameters>(data => |
|||
{ |
|||
Zip(data.BinRoot, data.ZipCoreArtifacts); |
|||
|
|||
Zip(data.NugetRoot, data.ZipNuGetArtifacts); |
|||
|
|||
Zip(data.ZipSourceControlCatalogDesktopDirs, |
|||
data.ZipTargetControlCatalogDesktopDirs, |
|||
GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dll") + |
|||
GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.config") + |
|||
GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.so") + |
|||
GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dylib") + |
|||
GetFiles(data.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.exe")); |
|||
}); |
|||
|
|||
void DotNetCorePack(Parameters parameters) |
|||
{ |
|||
var settings = new DotNetCorePackSettings |
|||
{ |
|||
Configuration = parameters.Configuration, |
|||
MSBuildSettings = new DotNetCoreMSBuildSettings |
|||
{ |
|||
Properties = |
|||
{ |
|||
{ "PackageVersion", new [] { parameters.Version } } |
|||
} |
|||
} |
|||
}; |
|||
|
|||
DotNetCorePack(parameters.MSBuildSolution, settings); |
|||
} |
|||
|
|||
Task("Create-NuGet-Packages-Impl") |
|||
.Does<Parameters>(data => |
|||
{ |
|||
if(data.IsRunningOnWindows) |
|||
{ |
|||
MSBuild(data.MSBuildSolution, settings => { |
|||
settings.SetConfiguration(data.Configuration); |
|||
settings.SetVerbosity(Verbosity.Minimal); |
|||
settings.WithProperty("iOSRoslynPathHackRequired", "true"); |
|||
settings.WithProperty("PackageVersion", data.Version); |
|||
settings.UseToolVersion(MSBuildToolVersion.VS2017); |
|||
settings.WithRestore(); |
|||
settings.WithTarget("Pack"); |
|||
}); |
|||
} |
|||
else |
|||
{ |
|||
DotNetCorePack(data); |
|||
} |
|||
}); |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// TARGETS |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
Task("Build") |
|||
.IsDependentOn("Clean-Impl") |
|||
.IsDependentOn("Build-Impl"); |
|||
|
|||
Task("Run-Tests") |
|||
.IsDependentOn("Build") |
|||
.IsDependentOn("Run-Unit-Tests-Impl") |
|||
.IsDependentOn("Run-Render-Tests-Impl") |
|||
.IsDependentOn("Run-Designer-Tests-Impl") |
|||
.IsDependentOn("Run-Leak-Tests-Impl"); |
|||
|
|||
Task("Package") |
|||
.IsDependentOn("Run-Tests") |
|||
.IsDependentOn("Create-NuGet-Packages-Impl"); |
|||
|
|||
Task("AppVeyor") |
|||
.IsDependentOn("Package") |
|||
.IsDependentOn("Zip-Files-Impl"); |
|||
|
|||
Task("Travis") |
|||
.IsDependentOn("Run-Tests"); |
|||
|
|||
Task("Azure-Linux") |
|||
.IsDependentOn("Run-Tests"); |
|||
|
|||
Task("Azure-OSX") |
|||
.IsDependentOn("Package") |
|||
.IsDependentOn("Zip-Files-Impl"); |
|||
|
|||
Task("Azure-Windows") |
|||
.IsDependentOn("Package") |
|||
.IsDependentOn("Zip-Files-Impl"); |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
// EXECUTE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
var target = Context.Argument("target", "Default"); |
|||
|
|||
if (target == "Default") |
|||
{ |
|||
target = Context.IsRunningOnWindows() ? "Package" : "Run-Tests"; |
|||
} |
|||
|
|||
RunTarget(target); |
|||
@ -1,201 +1,69 @@ |
|||
########################################################################## |
|||
# 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", "NetCoreOnly", "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, |
|||
#[switch]$CustomParam, |
|||
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] |
|||
[string[]]$ScriptArgs |
|||
[string[]]$BuildArguments |
|||
) |
|||
|
|||
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null |
|||
function MD5HashFile([string] $filePath) |
|||
{ |
|||
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) |
|||
{ |
|||
return $null |
|||
} |
|||
Write-Output "Windows PowerShell $($Host.Version)" |
|||
|
|||
[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){ |
|||
Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { exit 1 } |
|||
$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" |
|||
########################################################################### |
|||
# CONFIGURATION |
|||
########################################################################### |
|||
|
|||
# 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" |
|||
} |
|||
$BuildProjectFile = "$PSScriptRoot\nukebuild\_build.csproj" |
|||
$TempDirectory = "$PSScriptRoot\\.tmp" |
|||
|
|||
# Is this a dry run? |
|||
$UseDryRun = ""; |
|||
if($WhatIf.IsPresent) { |
|||
$UseDryRun = "-dryrun" |
|||
} |
|||
$DotNetGlobalFile = "$PSScriptRoot\\global.json" |
|||
$DotNetInstallUrl = "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1" |
|||
$DotNetChannel = "Current" |
|||
|
|||
# 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 |
|||
} |
|||
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1 |
|||
$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 |
|||
$env:NUGET_XMLDOC_MODE = "skip" |
|||
|
|||
# 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." |
|||
} |
|||
} |
|||
########################################################################### |
|||
# EXECUTION |
|||
########################################################################### |
|||
|
|||
# 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 |
|||
} |
|||
function ExecSafe([scriptblock] $cmd) { |
|||
& $cmd |
|||
if ($LASTEXITCODE) { exit $LASTEXITCODE } |
|||
} |
|||
|
|||
# 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." |
|||
# If global.json exists, load expected version |
|||
if (Test-Path $DotNetGlobalFile) { |
|||
$DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json) |
|||
if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) { |
|||
$DotNetVersion = $DotNetGlobal.sdk.version |
|||
} |
|||
} |
|||
|
|||
# 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 |
|||
# If dotnet is installed locally, and expected version is not set or installation matches the expected version |
|||
if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -ne $null -and ` |
|||
(!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) { |
|||
$env:DOTNET_EXE = (Get-Command "dotnet").Path |
|||
} |
|||
else { |
|||
$DotNetDirectory = "$TempDirectory\dotnet-win" |
|||
$env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" |
|||
|
|||
Write-Verbose -Message "Restoring tools from NuGet..." |
|||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" |
|||
# Download install script |
|||
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1" |
|||
md -force $TempDirectory > $null |
|||
(New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile) |
|||
|
|||
if ($LASTEXITCODE -ne 0) { |
|||
Throw "An error occured while restoring NuGet tools." |
|||
} |
|||
else |
|||
{ |
|||
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" |
|||
# Install by channel or version |
|||
if (!(Test-Path variable:DotNetVersion)) { |
|||
ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath } |
|||
} else { |
|||
ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } |
|||
} |
|||
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" |
|||
} |
|||
Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" |
|||
|
|||
# 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 |
|||
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments } |
|||
|
|||
@ -1,105 +1,72 @@ |
|||
#!/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. |
|||
########################################################################## |
|||
echo $(bash --version 2>&1 | head -n 1) |
|||
|
|||
# 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. |
|||
#CUSTOMPARAM=0 |
|||
BUILD_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") ;; |
|||
case $(echo $1 | awk '{print tolower($0)}') in |
|||
# -custom-param) CUSTOMPARAM=1;; |
|||
*) BUILD_ARGUMENTS+=("$1") ;; |
|||
esac |
|||
shift |
|||
done |
|||
|
|||
# Make sure the tools folder exist. |
|||
if [ ! -d "$TOOLS_DIR" ]; then |
|||
mkdir "$TOOLS_DIR" |
|||
fi |
|||
set -eo pipefail |
|||
SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) |
|||
|
|||
# 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 |
|||
########################################################################### |
|||
# CONFIGURATION |
|||
########################################################################### |
|||
|
|||
# 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 |
|||
BUILD_PROJECT_FILE="$SCRIPT_DIR/nukebuild/_build.csproj" |
|||
TEMP_DIRECTORY="$SCRIPT_DIR//.tmp" |
|||
|
|||
# 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 |
|||
DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json" |
|||
DOTNET_INSTALL_URL="https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh" |
|||
DOTNET_CHANNEL="Current" |
|||
|
|||
mono "$NUGET_EXE" install -ExcludeVersion |
|||
if [ $? -ne 0 ]; then |
|||
echo "Could not restore NuGet packages." |
|||
exit 1 |
|||
fi |
|||
export DOTNET_CLI_TELEMETRY_OPTOUT=1 |
|||
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 |
|||
export NUGET_XMLDOC_MODE="skip" |
|||
|
|||
$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5 |
|||
########################################################################### |
|||
# EXECUTION |
|||
########################################################################### |
|||
|
|||
popd >/dev/null |
|||
function FirstJsonValue { |
|||
perl -nle 'print $1 if m{"'$1'": "([^"\-]+)",?}' <<< ${@:2} |
|||
} |
|||
|
|||
# Make sure that Cake has been installed. |
|||
if [ ! -f "$CAKE_EXE" ]; then |
|||
echo "Could not find Cake.exe at '$CAKE_EXE'." |
|||
exit 1 |
|||
# If global.json exists, load expected version |
|||
if [ -f "$DOTNET_GLOBAL_FILE" ]; then |
|||
DOTNET_VERSION=$(FirstJsonValue "version" $(cat "$DOTNET_GLOBAL_FILE")) |
|||
if [ "$DOTNET_VERSION" == "" ]; then |
|||
unset DOTNET_VERSION |
|||
fi |
|||
fi |
|||
|
|||
# If dotnet is installed locally, and expected version is not set or installation matches the expected version |
|||
if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then |
|||
export DOTNET_EXE="$(command -v dotnet)" |
|||
else |
|||
DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix" |
|||
export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet" |
|||
|
|||
# Download install script |
|||
DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh" |
|||
mkdir -p "$TEMP_DIRECTORY" |
|||
curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL" |
|||
chmod +x "$DOTNET_INSTALL_FILE" |
|||
|
|||
# Start Cake |
|||
if $SHOW_VERSION; then |
|||
exec mono "$CAKE_EXE" -version |
|||
# Install by channel or version |
|||
if [ -z ${DOTNET_VERSION+x} ]; then |
|||
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path |
|||
else |
|||
exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -platform="$PLATFORM" -configuration="$CONFIGURATION" -target=$TARGET $DRYRUN $SKIP_TESTS "${SCRIPT_ARGUMENTS[@]}" |
|||
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path |
|||
fi |
|||
fi |
|||
|
|||
echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)" |
|||
|
|||
"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" -- ${BUILD_ARGUMENTS[@]} |
|||
|
|||
@ -1,5 +1,5 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.0.6.102" /> |
|||
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.9.0.2" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -1,6 +1,6 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="SkiaSharp" Version="1.60.0" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="Avalonia.Skia.Linux.Natives" Version="1.60.0.1" /> |
|||
<PackageReference Include="SkiaSharp" Version="1.68.0" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="SkiaSharp.NativeAssets.Linux" Version="1.68.0" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -0,0 +1,8 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Import Project="$(MSBuildThisFileDirectory)/NetFX.props" /> |
|||
<ItemGroup Condition="$(TargetFramework.StartsWith('net4'))"> |
|||
<Content Include="$(MSBuildThisFileDirectory)/xunit.runner.mono.json" Link="xunit.runner.json" > |
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -0,0 +1 @@ |
|||
{ "appDomain": "denied" } |
|||
@ -1,15 +0,0 @@ |
|||
; This is the default configuration file for Cake. |
|||
; This file was downloaded from https://github.com/cake-build/resources |
|||
|
|||
[Nuget] |
|||
Source=https://api.nuget.org/v3/index.json |
|||
UseInProcessClient=true |
|||
LoadDependencies=false |
|||
|
|||
[Paths] |
|||
Tools=./tools |
|||
Addins=./tools/Addins |
|||
Modules=./tools/Modules |
|||
|
|||
[Settings] |
|||
SkipVerification=false |
|||
@ -1,7 +1,7 @@ |
|||
{ |
|||
"msbuild-sdks": { |
|||
"Microsoft.Build.Traversal": "1.0.43", |
|||
"MSBuild.Sdk.Extras": "1.6.46", |
|||
"MSBuild.Sdk.Extras": "1.6.65", |
|||
"AggregatePackage.NuGet.Sdk" : "0.1.12" |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,8 @@ |
|||
# editorconfig.org |
|||
|
|||
# top-most EditorConfig file |
|||
root = false |
|||
|
|||
# C# files |
|||
[*.cs] |
|||
dotnet_style_require_accessibility_modifiers = never |
|||
@ -0,0 +1,265 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Diagnostics; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Runtime.InteropServices; |
|||
using System.Threading; |
|||
using System.Xml.Linq; |
|||
using Nuke.Common; |
|||
using Nuke.Common.Git; |
|||
using Nuke.Common.ProjectModel; |
|||
using Nuke.Common.Tooling; |
|||
using Nuke.Common.Tools.DotNet; |
|||
using Nuke.Common.Tools.MSBuild; |
|||
using Nuke.Common.Utilities; |
|||
using static Nuke.Common.EnvironmentInfo; |
|||
using static Nuke.Common.IO.FileSystemTasks; |
|||
using static Nuke.Common.IO.PathConstruction; |
|||
using static Nuke.Common.Tools.MSBuild.MSBuildTasks; |
|||
using static Nuke.Common.Tools.DotNet.DotNetTasks; |
|||
using static Nuke.Common.Tools.Xunit.XunitTasks; |
|||
|
|||
|
|||
/* |
|||
Before editing this file, install support plugin for your IDE, |
|||
running and debugging a particular target (optionally without deps) would be way easier |
|||
ReSharper/Rider - https://plugins.jetbrains.com/plugin/10803-nuke-support
|
|||
VSCode - https://marketplace.visualstudio.com/items?itemName=nuke.support
|
|||
|
|||
*/ |
|||
|
|||
partial class Build : NukeBuild |
|||
{ |
|||
BuildParameters Parameters { get; set; } |
|||
protected override void OnBuildInitialized() |
|||
{ |
|||
Parameters = new BuildParameters(this); |
|||
Information("Building version {0} of Avalonia ({1}) using version {2} of Nuke.", |
|||
Parameters.Version, |
|||
Parameters.Configuration, |
|||
typeof(NukeBuild).Assembly.GetName().Version.ToString()); |
|||
|
|||
if (Parameters.IsLocalBuild) |
|||
{ |
|||
Information("Repository Name: " + Parameters.RepositoryName); |
|||
Information("Repository Branch: " + Parameters.RepositoryBranch); |
|||
} |
|||
Information("Configuration: " + Parameters.Configuration); |
|||
Information("IsLocalBuild: " + Parameters.IsLocalBuild); |
|||
Information("IsRunningOnUnix: " + Parameters.IsRunningOnUnix); |
|||
Information("IsRunningOnWindows: " + Parameters.IsRunningOnWindows); |
|||
Information("IsRunningOnAzure:" + Parameters.IsRunningOnAzure); |
|||
Information("IsPullRequest: " + Parameters.IsPullRequest); |
|||
Information("IsMainRepo: " + Parameters.IsMainRepo); |
|||
Information("IsMasterBranch: " + Parameters.IsMasterBranch); |
|||
Information("IsReleaseBranch: " + Parameters.IsReleaseBranch); |
|||
Information("IsReleasable: " + Parameters.IsReleasable); |
|||
Information("IsMyGetRelease: " + Parameters.IsMyGetRelease); |
|||
Information("IsNuGetRelease: " + Parameters.IsNuGetRelease); |
|||
|
|||
void ExecWait(string preamble, string command, string args) |
|||
{ |
|||
Console.WriteLine(preamble); |
|||
Process.Start(new ProcessStartInfo(command, args) {UseShellExecute = false}).WaitForExit(); |
|||
} |
|||
ExecWait("dotnet version:", "dotnet", "--version"); |
|||
if (Parameters.IsRunningOnUnix) |
|||
ExecWait("Mono version:", "mono", "--version"); |
|||
|
|||
|
|||
} |
|||
|
|||
Target Clean => _ => _.Executes(() => |
|||
{ |
|||
DeleteDirectories(Parameters.BuildDirs); |
|||
EnsureCleanDirectories(Parameters.BuildDirs); |
|||
EnsureCleanDirectory(Parameters.ArtifactsDir); |
|||
EnsureCleanDirectory(Parameters.NugetIntermediateRoot); |
|||
EnsureCleanDirectory(Parameters.NugetRoot); |
|||
EnsureCleanDirectory(Parameters.ZipRoot); |
|||
EnsureCleanDirectory(Parameters.TestResultsRoot); |
|||
}); |
|||
|
|||
Target Compile => _ => _ |
|||
.DependsOn(Clean) |
|||
.Executes(() => |
|||
{ |
|||
|
|||
if (Parameters.IsRunningOnWindows) |
|||
MSBuild(Parameters.MSBuildSolution, c => c |
|||
.SetArgumentConfigurator(a => a.Add("/r")) |
|||
.SetConfiguration(Parameters.Configuration) |
|||
.SetVerbosity(MSBuildVerbosity.Minimal) |
|||
.AddProperty("PackageVersion", Parameters.Version) |
|||
.AddProperty("iOSRoslynPathHackRequired", "true") |
|||
.SetToolsVersion(MSBuildToolsVersion._15_0) |
|||
.AddTargets("Build") |
|||
); |
|||
|
|||
else |
|||
DotNetBuild(Parameters.MSBuildSolution, c => c |
|||
.AddProperty("PackageVersion", Parameters.Version) |
|||
.SetConfiguration(Parameters.Configuration) |
|||
); |
|||
}); |
|||
|
|||
void RunCoreTest(string project) |
|||
{ |
|||
if(!project.EndsWith(".csproj")) |
|||
project = System.IO.Path.Combine(project, System.IO.Path.GetFileName(project)+".csproj"); |
|||
Information("Running tests from " + project); |
|||
XDocument xdoc; |
|||
using (var s = File.OpenRead(project)) |
|||
xdoc = XDocument.Load(s); |
|||
|
|||
List<string> frameworks = null; |
|||
var targets = xdoc.Root.Descendants("TargetFrameworks").FirstOrDefault(); |
|||
if (targets != null) |
|||
frameworks = targets.Value.Split(';').Where(f => !string.IsNullOrWhiteSpace(f)).ToList(); |
|||
else |
|||
frameworks = new List<string> {xdoc.Root.Descendants("TargetFramework").First().Value}; |
|||
|
|||
foreach(var fw in frameworks) |
|||
{ |
|||
Information("Running for " + fw); |
|||
DotNetTest(c => |
|||
{ |
|||
c = c |
|||
.SetProjectFile(project) |
|||
.SetConfiguration(Parameters.Configuration) |
|||
.SetFramework(fw) |
|||
.EnableNoBuild() |
|||
.EnableNoRestore(); |
|||
// NOTE: I can see that we could maybe add another extension method "Switch" or "If" to make this more convenient
|
|||
if (Parameters.PublishTestResults) |
|||
c = c.SetLogger("trx").SetResultsDirectory(Parameters.TestResultsRoot); |
|||
return c; |
|||
}); |
|||
} |
|||
} |
|||
|
|||
Target RunCoreLibsTests => _ => _ |
|||
.OnlyWhen(() => !Parameters.SkipTests) |
|||
.DependsOn(Compile) |
|||
.Executes(() => |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.Animation.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Base.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Controls.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Input.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Interactivity.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Layout.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Markup.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Styling.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Visuals.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.Skia.UnitTests"); |
|||
RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests"); |
|||
}); |
|||
|
|||
Target RunRenderTests => _ => _ |
|||
.OnlyWhen(() => !Parameters.SkipTests) |
|||
.DependsOn(Compile) |
|||
.Executes(() => |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj"); |
|||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) |
|||
RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj"); |
|||
}); |
|||
|
|||
Target RunDesignerTests => _ => _ |
|||
.OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows) |
|||
.DependsOn(Compile) |
|||
.Executes(() => |
|||
{ |
|||
RunCoreTest("./tests/Avalonia.DesignerSupport.Tests"); |
|||
}); |
|||
|
|||
[PackageExecutable("JetBrains.dotMemoryUnit", "dotMemoryUnit.exe")] readonly Tool DotMemoryUnit; |
|||
|
|||
Target RunLeakTests => _ => _ |
|||
.OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows) |
|||
.DependsOn(Compile) |
|||
.Executes(() => |
|||
{ |
|||
var testAssembly = "tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll"; |
|||
DotMemoryUnit( |
|||
$"{XunitPath.DoubleQuoteIfNeeded()} --propagate-exit-code -- {testAssembly}", |
|||
timeout: 120_000); |
|||
}); |
|||
|
|||
Target ZipFiles => _ => _ |
|||
.After(CreateNugetPackages, Compile, RunCoreLibsTests, Package) |
|||
.Executes(() => |
|||
{ |
|||
var data = Parameters; |
|||
Zip(data.ZipCoreArtifacts, data.BinRoot); |
|||
Zip(data.ZipNuGetArtifacts, data.NugetRoot); |
|||
Zip(data.ZipTargetControlCatalogDesktopDir, |
|||
GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.dll").Concat( |
|||
GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.config")).Concat( |
|||
GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.so")).Concat( |
|||
GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.dylib")).Concat( |
|||
GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.exe"))); |
|||
}); |
|||
|
|||
Target CreateIntermediateNugetPackages => _ => _ |
|||
.DependsOn(Compile) |
|||
.After(RunTests) |
|||
.Executes(() => |
|||
{ |
|||
if (Parameters.IsRunningOnWindows) |
|||
|
|||
MSBuild(Parameters.MSBuildSolution, c => c |
|||
.SetConfiguration(Parameters.Configuration) |
|||
.SetVerbosity(MSBuildVerbosity.Minimal) |
|||
.AddProperty("PackageVersion", Parameters.Version) |
|||
.AddProperty("iOSRoslynPathHackRequired", "true") |
|||
.SetToolsVersion(MSBuildToolsVersion._15_0) |
|||
.AddTargets("Pack")); |
|||
else |
|||
DotNetPack(Parameters.MSBuildSolution, c => |
|||
c.SetConfiguration(Parameters.Configuration) |
|||
.AddProperty("PackageVersion", Parameters.Version)); |
|||
}); |
|||
|
|||
Target CreateNugetPackages => _ => _ |
|||
.DependsOn(CreateIntermediateNugetPackages) |
|||
.Executes(() => |
|||
{ |
|||
var config = Numerge.MergeConfiguration.LoadFile(RootDirectory / "nukebuild" / "numerge.config"); |
|||
EnsureCleanDirectory(Parameters.NugetRoot); |
|||
if(!Numerge.NugetPackageMerger.Merge(Parameters.NugetIntermediateRoot, Parameters.NugetRoot, config, |
|||
new NumergeNukeLogger())) |
|||
throw new Exception("Package merge failed"); |
|||
}); |
|||
|
|||
Target RunTests => _ => _ |
|||
.DependsOn(RunCoreLibsTests) |
|||
.DependsOn(RunRenderTests) |
|||
.DependsOn(RunDesignerTests) |
|||
.DependsOn(RunLeakTests); |
|||
|
|||
Target Package => _ => _ |
|||
.DependsOn(RunTests) |
|||
.DependsOn(CreateNugetPackages); |
|||
|
|||
Target CiAzureLinux => _ => _ |
|||
.DependsOn(RunTests); |
|||
|
|||
Target CiAzureOSX => _ => _ |
|||
.DependsOn(Package) |
|||
.DependsOn(ZipFiles); |
|||
|
|||
Target CiAzureWindows => _ => _ |
|||
.DependsOn(Package) |
|||
.DependsOn(ZipFiles); |
|||
|
|||
|
|||
public static int Main() => |
|||
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) |
|||
? Execute<Build>(x => x.Package) |
|||
: Execute<Build>(x => x.RunTests); |
|||
|
|||
} |
|||
@ -0,0 +1,142 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Runtime.InteropServices; |
|||
using System.Xml.Linq; |
|||
using Nuke.Common; |
|||
using Nuke.Common.BuildServers; |
|||
using Nuke.Common.Execution; |
|||
using Nuke.Common.IO; |
|||
using static Nuke.Common.IO.FileSystemTasks; |
|||
using static Nuke.Common.IO.PathConstruction; |
|||
using static Nuke.Common.Tools.MSBuild.MSBuildTasks; |
|||
|
|||
public partial class Build |
|||
{ |
|||
[Parameter("configuration")] |
|||
public string Configuration { get; set; } |
|||
|
|||
[Parameter("skip-tests")] |
|||
public bool SkipTests { get; set; } |
|||
|
|||
[Parameter("force-nuget-version")] |
|||
public string ForceNugetVersion { get; set; } |
|||
|
|||
public class BuildParameters |
|||
{ |
|||
public string Configuration { get; } |
|||
public bool SkipTests { get; } |
|||
public string MainRepo { get; } |
|||
public string MasterBranch { get; } |
|||
public string RepositoryName { get; } |
|||
public string RepositoryBranch { get; } |
|||
public string ReleaseConfiguration { get; } |
|||
public string ReleaseBranchPrefix { get; } |
|||
public string MSBuildSolution { get; } |
|||
public bool IsLocalBuild { get; } |
|||
public bool IsRunningOnUnix { get; } |
|||
public bool IsRunningOnWindows { get; } |
|||
public bool IsRunningOnAzure { get; } |
|||
public bool IsPullRequest { get; } |
|||
public bool IsMainRepo { get; } |
|||
public bool IsMasterBranch { get; } |
|||
public bool IsReleaseBranch { get; } |
|||
public bool IsReleasable { get; } |
|||
public bool IsMyGetRelease { get; } |
|||
public bool IsNuGetRelease { get; } |
|||
public bool PublishTestResults { get; } |
|||
public string Version { get; } |
|||
public AbsolutePath ArtifactsDir { get; } |
|||
public AbsolutePath NugetIntermediateRoot { get; } |
|||
public AbsolutePath NugetRoot { get; } |
|||
public AbsolutePath ZipRoot { get; } |
|||
public AbsolutePath BinRoot { get; } |
|||
public AbsolutePath TestResultsRoot { get; } |
|||
public string DirSuffix { get; } |
|||
public List<string> BuildDirs { get; } |
|||
public string FileZipSuffix { get; } |
|||
public AbsolutePath ZipCoreArtifacts { get; } |
|||
public AbsolutePath ZipNuGetArtifacts { get; } |
|||
public AbsolutePath ZipSourceControlCatalogDesktopDir { get; } |
|||
public AbsolutePath ZipTargetControlCatalogDesktopDir { get; } |
|||
|
|||
|
|||
public BuildParameters(Build b) |
|||
{ |
|||
// ARGUMENTS
|
|||
Configuration = b.Configuration ?? "Release"; |
|||
SkipTests = b.SkipTests; |
|||
|
|||
// CONFIGURATION
|
|||
MainRepo = "https://github.com/AvaloniaUI/Avalonia"; |
|||
MasterBranch = "refs/heads/master"; |
|||
ReleaseBranchPrefix = "refs/heads/release/"; |
|||
ReleaseConfiguration = "Release"; |
|||
MSBuildSolution = RootDirectory / "dirs.proj"; |
|||
|
|||
// PARAMETERS
|
|||
IsLocalBuild = Host == HostType.Console; |
|||
IsRunningOnUnix = Environment.OSVersion.Platform == PlatformID.Unix || |
|||
Environment.OSVersion.Platform == PlatformID.MacOSX; |
|||
IsRunningOnWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); |
|||
IsRunningOnAzure = Host == HostType.TeamServices || |
|||
Environment.GetEnvironmentVariable("LOGNAME") == "vsts"; |
|||
|
|||
if (IsRunningOnAzure) |
|||
{ |
|||
RepositoryName = TeamServices.Instance.RepositoryUri; |
|||
RepositoryBranch = TeamServices.Instance.SourceBranch; |
|||
IsPullRequest = TeamServices.Instance.PullRequestId.HasValue; |
|||
IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, TeamServices.Instance.RepositoryUri); |
|||
} |
|||
IsMainRepo = |
|||
StringComparer.OrdinalIgnoreCase.Equals(MainRepo, |
|||
RepositoryName); |
|||
IsMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, |
|||
RepositoryBranch); |
|||
IsReleaseBranch = RepositoryBranch?.StartsWith(ReleaseBranchPrefix, StringComparison.OrdinalIgnoreCase) == |
|||
true; |
|||
|
|||
IsReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, Configuration); |
|||
IsMyGetRelease = IsReleasable; |
|||
IsNuGetRelease = IsMainRepo && IsReleasable && IsReleaseBranch; |
|||
|
|||
// VERSION
|
|||
Version = b.ForceNugetVersion ?? GetVersion(); |
|||
|
|||
if (IsRunningOnAzure) |
|||
{ |
|||
if (!IsNuGetRelease) |
|||
{ |
|||
// Use AssemblyVersion with Build as version
|
|||
Version += "-build" + Environment.GetEnvironmentVariable("BUILD_BUILDID") + "-beta"; |
|||
} |
|||
|
|||
PublishTestResults = true; |
|||
} |
|||
|
|||
// DIRECTORIES
|
|||
ArtifactsDir = RootDirectory / "artifacts"; |
|||
NugetRoot = ArtifactsDir / "nuget"; |
|||
NugetIntermediateRoot = RootDirectory / "build-intermediate" / "nuget"; |
|||
ZipRoot = ArtifactsDir / "zip"; |
|||
BinRoot = ArtifactsDir / "bin"; |
|||
TestResultsRoot = ArtifactsDir / "test-results"; |
|||
BuildDirs = GlobDirectories(RootDirectory, "**bin").Concat(GlobDirectories(RootDirectory, "**obj")).ToList(); |
|||
DirSuffix = Configuration; |
|||
FileZipSuffix = Version + ".zip"; |
|||
ZipCoreArtifacts = ZipRoot / ("Avalonia-" + FileZipSuffix); |
|||
ZipNuGetArtifacts = ZipRoot / ("Avalonia-NuGet-" + FileZipSuffix); |
|||
ZipSourceControlCatalogDesktopDir = |
|||
RootDirectory / ("samples/ControlCatalog.Desktop/bin/" + DirSuffix + "/net461"); |
|||
ZipTargetControlCatalogDesktopDir = ZipRoot / ("ControlCatalog.Desktop-" + FileZipSuffix); |
|||
} |
|||
|
|||
string GetVersion() |
|||
{ |
|||
var xdoc = XDocument.Load(RootDirectory / "build/SharedVersion.props"); |
|||
return xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value; |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,93 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.IO.Compression; |
|||
using System.Linq; |
|||
using Nuke.Common; |
|||
using Nuke.Common.IO; |
|||
using Numerge; |
|||
|
|||
public partial class Build |
|||
{ |
|||
static void Information(string info) |
|||
{ |
|||
Logger.Info(info); |
|||
} |
|||
|
|||
static void Information(string info, params object[] args) |
|||
{ |
|||
Logger.Info(info, args); |
|||
} |
|||
|
|||
private void Zip(PathConstruction.AbsolutePath target, params string[] paths) => Zip(target, paths.AsEnumerable()); |
|||
|
|||
private void Zip(PathConstruction.AbsolutePath target, IEnumerable<string> paths) |
|||
{ |
|||
var targetPath = target.ToString(); |
|||
bool finished = false, atLeastOneFileAdded = false; |
|||
try |
|||
{ |
|||
using (var targetStream = File.Create(targetPath)) |
|||
using(var archive = new System.IO.Compression.ZipArchive(targetStream, ZipArchiveMode.Create)) |
|||
{ |
|||
void AddFile(string path, string relativePath) |
|||
{ |
|||
var e = archive.CreateEntry(relativePath.Replace("\\", "/"), CompressionLevel.Optimal); |
|||
using (var entryStream = e.Open()) |
|||
using (var fileStream = File.OpenRead(path)) |
|||
fileStream.CopyTo(entryStream); |
|||
atLeastOneFileAdded = true; |
|||
} |
|||
|
|||
foreach (var path in paths) |
|||
{ |
|||
if (Directory.Exists(path)) |
|||
{ |
|||
var dirInfo = new DirectoryInfo(path); |
|||
var rootPath = Path.GetDirectoryName(dirInfo.FullName); |
|||
foreach(var fsEntry in dirInfo.EnumerateFileSystemInfos("*", SearchOption.AllDirectories)) |
|||
{ |
|||
if (fsEntry is FileInfo) |
|||
{ |
|||
var relPath = Path.GetRelativePath(rootPath, fsEntry.FullName); |
|||
AddFile(fsEntry.FullName, relPath); |
|||
} |
|||
} |
|||
} |
|||
else if(File.Exists(path)) |
|||
{ |
|||
var name = Path.GetFileName(path); |
|||
AddFile(path, name); |
|||
} |
|||
} |
|||
} |
|||
|
|||
finished = true; |
|||
} |
|||
finally |
|||
{ |
|||
try |
|||
{ |
|||
if (!finished || !atLeastOneFileAdded) |
|||
File.Delete(targetPath); |
|||
} |
|||
catch |
|||
{ |
|||
//Ignore
|
|||
} |
|||
} |
|||
} |
|||
|
|||
class NumergeNukeLogger : INumergeLogger |
|||
{ |
|||
public void Log(NumergeLogLevel level, string message) |
|||
{ |
|||
if(level == NumergeLogLevel.Error) |
|||
Logger.Error(message); |
|||
else if (level == NumergeLogLevel.Warning) |
|||
Logger.Warn(message); |
|||
else |
|||
Logger.Info(message); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>netcoreapp2.0</TargetFramework> |
|||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> |
|||
<RootNamespace></RootNamespace> |
|||
<IsPackable>False</IsPackable> |
|||
<NoWarn>CS0649;CS0169</NoWarn> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Nuke.Common" Version="0.12.3" /> |
|||
<PackageReference Include="xunit.runner.console" Version="2.3.1" /> |
|||
<PackageReference Include="JetBrains.dotMemoryUnit" Version="3.0.20171219.105559" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<NukeMetadata Include="**\*.json" Exclude="bin\**;obj\**" /> |
|||
<NukeExternalFiles Include="**\*.*.ext" Exclude="bin\**;obj\**" /> |
|||
<None Remove="*.csproj.DotSettings;*.ref.*.txt" /> |
|||
|
|||
<!-- Common build related files --> |
|||
<None Include="..\build.ps1" /> |
|||
<None Include="..\build.sh" /> |
|||
<None Include="..\.nuke" /> |
|||
<None Include="..\global.json" Condition="Exists('..\global.json')" /> |
|||
<None Include="..\nuget.config" Condition="Exists('..\nuget.config')" /> |
|||
<None Include="..\Jenkinsfile" Condition="Exists('..\Jenkinsfile')" /> |
|||
<None Include="..\appveyor.yml" Condition="Exists('..\appveyor.yml')" /> |
|||
<None Include="..\.travis.yml" Condition="Exists('..\.travis.yml')" /> |
|||
<None Include="..\GitVersion.yml" Condition="Exists('..\GitVersion.yml')" /> |
|||
<Compile Remove="Numerge/**/*.*" /> |
|||
<Compile Include="Numerge/Numerge/**/*.cs" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,24 @@ |
|||
<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:Boolean x:Key="/Default/CodeInspection/ImplicitNullability/EnableFields/@EntryValue">False</s:Boolean> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_INTERNAL_MODIFIER/@EntryValue">Implicit</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_PRIVATE_MODIFIER/@EntryValue">Implicit</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/METHOD_OR_OPERATOR_BODY/@EntryValue">ExpressionBody</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_MEMBERS/@EntryValue">0</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue">NEXT_LINE</s:String> |
|||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_INVOCATION_LPAR/@EntryValue">False</s:Boolean> |
|||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ATTRIBUTE_LENGTH_FOR_SAME_LINE/@EntryValue">120</s:Int64> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">IF_OWNER_IS_SINGLE_LINE</s:String> |
|||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue">WRAP_IF_LONG</s:String> |
|||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> |
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> |
|||
@ -0,0 +1,23 @@ |
|||
{ |
|||
"Packages": |
|||
[ |
|||
{ |
|||
"Id": "Avalonia", |
|||
"MergeAll": true, |
|||
"Exclude": ["Avalonia.Remote.Protocol"], |
|||
"IncomingIncludeAssetsOverride": "", |
|||
"Merge": [ |
|||
{ |
|||
"Id": "Avalonia.Build.Tasks", |
|||
"IgnoreMissingFrameworkBinaries": true, |
|||
"DoNotMergeDependencies": true |
|||
}, |
|||
{ |
|||
"Id": "Avalonia.DesktopRuntime", |
|||
"IgnoreMissingFrameworkBinaries": true, |
|||
"IgnoreMissingFrameworkDependencies": true |
|||
} |
|||
] |
|||
} |
|||
] |
|||
} |
|||
@ -1,129 +0,0 @@ |
|||
using System.Xml.Linq; |
|||
using System.Linq; |
|||
|
|||
public class Parameters |
|||
{ |
|||
public string Configuration { get; private set; } |
|||
public bool SkipTests { get; private set; } |
|||
public string MainRepo { get; private set; } |
|||
public string MasterBranch { get; private set; } |
|||
public string ReleasePlatform { get; private set; } |
|||
public string ReleaseConfiguration { get; private set; } |
|||
public string ReleaseBranchPrefix { get; private set; } |
|||
public string MSBuildSolution { get; private set; } |
|||
public bool IsLocalBuild { get; private set; } |
|||
public bool IsRunningOnUnix { get; private set; } |
|||
public bool IsRunningOnWindows { get; private set; } |
|||
public bool IsRunningOnAppVeyor { get; private set; } |
|||
public bool IsRunningOnAzure { get; private set; } |
|||
public bool IsPullRequest { get; private set; } |
|||
public bool IsMainRepo { get; private set; } |
|||
public bool IsMasterBranch { get; private set; } |
|||
public bool IsReleaseBranch { get; private set; } |
|||
public bool IsTagged { get; private set; } |
|||
public bool IsReleasable { get; private set; } |
|||
public bool IsMyGetRelease { get; private set; } |
|||
public bool IsNuGetRelease { get; private set; } |
|||
public bool PublishTestResults { get; private set; } |
|||
public string Version { get; private set; } |
|||
public DirectoryPath ArtifactsDir { get; private set; } |
|||
public DirectoryPath NugetRoot { get; private set; } |
|||
public DirectoryPath ZipRoot { get; private set; } |
|||
public DirectoryPath BinRoot { get; private set; } |
|||
public DirectoryPath TestResultsRoot { get; private set; } |
|||
public string DirSuffix { get; private set; } |
|||
public DirectoryPathCollection BuildDirs { get; private set; } |
|||
public string FileZipSuffix { get; private set; } |
|||
public FilePath ZipCoreArtifacts { get; private set; } |
|||
public FilePath ZipNuGetArtifacts { get; private set; } |
|||
public DirectoryPath ZipSourceControlCatalogDesktopDirs { get; private set; } |
|||
public FilePath ZipTargetControlCatalogDesktopDirs { get; private set; } |
|||
|
|||
public Parameters(ICakeContext context) |
|||
{ |
|||
var buildSystem = context.BuildSystem(); |
|||
|
|||
// ARGUMENTS |
|||
Configuration = context.Argument("configuration", "Release"); |
|||
SkipTests = context.HasArgument("skip-tests"); |
|||
|
|||
// CONFIGURATION |
|||
MainRepo = "https://github.com/AvaloniaUI/Avalonia"; |
|||
MasterBranch = "master"; |
|||
ReleaseBranchPrefix = "refs/heads/release/"; |
|||
ReleaseConfiguration = "Release"; |
|||
MSBuildSolution = "./dirs.proj"; |
|||
|
|||
// PARAMETERS |
|||
IsLocalBuild = buildSystem.IsLocalBuild; |
|||
IsRunningOnUnix = context.IsRunningOnUnix(); |
|||
IsRunningOnWindows = context.IsRunningOnWindows(); |
|||
IsRunningOnAppVeyor = buildSystem.AppVeyor.IsRunningOnAppVeyor; |
|||
IsRunningOnAzure = buildSystem.IsRunningOnVSTS || buildSystem.IsRunningOnTFS || context.EnvironmentVariable("LOGNAME") == "vsts"; |
|||
|
|||
IsPullRequest = buildSystem.AppVeyor.Environment.PullRequest.IsPullRequest; |
|||
IsMainRepo = StringComparer.OrdinalIgnoreCase.Equals(MainRepo, context.EnvironmentVariable("BUILD_REPOSITORY_URI")); |
|||
IsMasterBranch = StringComparer.OrdinalIgnoreCase.Equals(MasterBranch, context.EnvironmentVariable("BUILD_SOURCEBRANCHNAME")); |
|||
IsReleaseBranch = (context.EnvironmentVariable("BUILD_SOURCEBRANCH")??"").StartsWith(ReleaseBranchPrefix, StringComparison.OrdinalIgnoreCase); |
|||
IsTagged = buildSystem.AppVeyor.Environment.Repository.Tag.IsTag |
|||
&& !string.IsNullOrWhiteSpace(buildSystem.AppVeyor.Environment.Repository.Tag.Name); |
|||
IsReleasable = StringComparer.OrdinalIgnoreCase.Equals(ReleaseConfiguration, Configuration); |
|||
IsMyGetRelease = !IsTagged && IsReleasable; |
|||
IsNuGetRelease = IsMainRepo && IsReleasable && IsReleaseBranch; |
|||
|
|||
// VERSION |
|||
Version = context.Argument("force-nuget-version", GetVersion()); |
|||
|
|||
if (IsRunningOnAppVeyor) |
|||
{ |
|||
string tagVersion = null; |
|||
if (IsTagged) |
|||
{ |
|||
var tag = buildSystem.AppVeyor.Environment.Repository.Tag.Name; |
|||
var nugetReleasePrefix = "nuget-release-"; |
|||
IsNuGetRelease = IsTagged && IsReleasable && tag.StartsWith(nugetReleasePrefix); |
|||
if(IsNuGetRelease) |
|||
tagVersion = tag.Substring(nugetReleasePrefix.Length); |
|||
} |
|||
if(tagVersion != null) |
|||
{ |
|||
Version = tagVersion; |
|||
} |
|||
else |
|||
{ |
|||
// Use AssemblyVersion with Build as version |
|||
Version += "-build" + context.EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-beta"; |
|||
} |
|||
} |
|||
else if (IsRunningOnAzure) |
|||
{ |
|||
if(!IsNuGetRelease) |
|||
{ |
|||
// Use AssemblyVersion with Build as version |
|||
Version += "-build" + context.EnvironmentVariable("BUILD_BUILDID") + "-beta"; |
|||
} |
|||
|
|||
PublishTestResults = true; |
|||
} |
|||
|
|||
// DIRECTORIES |
|||
ArtifactsDir = (DirectoryPath)context.Directory("./artifacts"); |
|||
NugetRoot = ArtifactsDir.Combine("nuget"); |
|||
ZipRoot = ArtifactsDir.Combine("zip"); |
|||
BinRoot = ArtifactsDir.Combine("bin"); |
|||
TestResultsRoot = ArtifactsDir.Combine("test-results"); |
|||
BuildDirs = context.GetDirectories("**/bin") + context.GetDirectories("**/obj"); |
|||
DirSuffix = Configuration; |
|||
FileZipSuffix = Version + ".zip"; |
|||
ZipCoreArtifacts = ZipRoot.CombineWithFilePath("Avalonia-" + FileZipSuffix); |
|||
ZipNuGetArtifacts = ZipRoot.CombineWithFilePath("Avalonia-NuGet-" + FileZipSuffix); |
|||
ZipSourceControlCatalogDesktopDirs = (DirectoryPath)context.Directory("./samples/ControlCatalog.Desktop/bin/" + DirSuffix + "/net461"); |
|||
ZipTargetControlCatalogDesktopDirs = ZipRoot.CombineWithFilePath("ControlCatalog.Desktop-" + FileZipSuffix); |
|||
} |
|||
|
|||
private static string GetVersion() |
|||
{ |
|||
var xdoc = XDocument.Load("./build/SharedVersion.props"); |
|||
return xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value; |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
<Application xmlns="https://github.com/avaloniaui"> |
|||
<Application.Styles> |
|||
<StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/> |
|||
<StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/> |
|||
</Application.Styles> |
|||
</Application> |
|||
@ -0,0 +1,13 @@ |
|||
using Avalonia; |
|||
using Avalonia.Markup.Xaml; |
|||
|
|||
namespace PlatformSanityChecks |
|||
{ |
|||
public class App : Application |
|||
{ |
|||
public override void Initialize() |
|||
{ |
|||
AvaloniaXamlLoader.Load(this); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>netcoreapp2.0</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Avalonia.Desktop\Avalonia.Desktop.csproj" /> |
|||
<ProjectReference Include="..\..\src\Avalonia.X11\Avalonia.X11.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,132 @@ |
|||
using System; |
|||
using System.Diagnostics; |
|||
using System.Reactive.Disposables; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Threading; |
|||
using Avalonia; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Threading; |
|||
using Avalonia.X11; |
|||
|
|||
namespace PlatformSanityChecks |
|||
{ |
|||
public class Program |
|||
{ |
|||
static Thread UiThread; |
|||
|
|||
static void Main(string[] args) |
|||
{ |
|||
UiThread = Thread.CurrentThread; |
|||
AppBuilder.Configure<App>().RuntimePlatformServicesInitializer(); |
|||
var app = new App(); |
|||
|
|||
AvaloniaX11PlatformExtensions.InitializeX11Platform(); |
|||
|
|||
CheckPlatformThreading(); |
|||
} |
|||
|
|||
static bool CheckAccess() => UiThread == Thread.CurrentThread; |
|||
|
|||
static void VerifyAccess() |
|||
{ |
|||
if (!CheckAccess()) |
|||
Die("Call from invalid thread"); |
|||
} |
|||
|
|||
static Exception Die(string error) |
|||
{ |
|||
Console.Error.WriteLine(error); |
|||
Console.Error.WriteLine(Environment.StackTrace); |
|||
Process.GetCurrentProcess().Kill(); |
|||
throw new Exception(error); |
|||
} |
|||
|
|||
static IDisposable Enter([CallerMemberName] string caller = null) |
|||
{ |
|||
Console.WriteLine("Entering " + caller); |
|||
return Disposable.Create(() => { Console.WriteLine("Leaving " + caller); }); |
|||
} |
|||
|
|||
static void EnterLoop(Action<CancellationTokenSource> cb, [CallerMemberName] string caller = null) |
|||
{ |
|||
using (Enter(caller)) |
|||
{ |
|||
var cts = new CancellationTokenSource(); |
|||
cb(cts); |
|||
Dispatcher.UIThread.MainLoop(cts.Token); |
|||
if (!cts.IsCancellationRequested) |
|||
Die("Unexpected loop exit"); |
|||
} |
|||
} |
|||
|
|||
static void CheckTimerOrdering() => EnterLoop(cts => |
|||
{ |
|||
bool firstFired = false, secondFired = false; |
|||
DispatcherTimer.Run(() => |
|||
{ |
|||
Console.WriteLine("Second tick"); |
|||
VerifyAccess(); |
|||
if (!firstFired) |
|||
throw Die("Invalid timer ordering"); |
|||
if (secondFired) |
|||
throw Die("Invocation of finished timer"); |
|||
secondFired = true; |
|||
cts.Cancel(); |
|||
return false; |
|||
}, TimeSpan.FromSeconds(2)); |
|||
DispatcherTimer.Run(() => |
|||
{ |
|||
Console.WriteLine("First tick"); |
|||
VerifyAccess(); |
|||
if (secondFired) |
|||
throw Die("Invalid timer ordering"); |
|||
if (firstFired) |
|||
throw Die("Invocation of finished timer"); |
|||
firstFired = true; |
|||
return false; |
|||
}, TimeSpan.FromSeconds(1)); |
|||
}); |
|||
|
|||
static void CheckTimerTicking() => EnterLoop(cts => |
|||
{ |
|||
int ticks = 0; |
|||
var st = Stopwatch.StartNew(); |
|||
DispatcherTimer.Run(() => |
|||
{ |
|||
ticks++; |
|||
Console.WriteLine($"Tick {ticks} at {st.Elapsed}"); |
|||
if (ticks == 5) |
|||
{ |
|||
if (st.Elapsed.TotalSeconds < 4.5) |
|||
Die("Timer is too fast"); |
|||
if (st.Elapsed.TotalSeconds > 6) |
|||
Die("Timer is too slow"); |
|||
cts.Cancel(); |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
}, TimeSpan.FromSeconds(1)); |
|||
}); |
|||
|
|||
static void CheckSignaling() => EnterLoop(cts => |
|||
{ |
|||
ThreadPool.QueueUserWorkItem(_ => |
|||
{ |
|||
Thread.Sleep(100); |
|||
Dispatcher.UIThread.Post(() => |
|||
{ |
|||
VerifyAccess(); |
|||
cts.Cancel(); |
|||
}); |
|||
}); |
|||
}); |
|||
|
|||
static void CheckPlatformThreading() |
|||
{ |
|||
CheckSignaling(); |
|||
CheckTimerOrdering(); |
|||
CheckTimerTicking(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="bool"/> properties.
|
|||
/// </summary>
|
|||
public class BoolAnimator : Animator<bool> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override bool Interpolate(double progress, bool oldValue, bool newValue) |
|||
{ |
|||
if(progress >= 1d) |
|||
return newValue; |
|||
if(progress >= 0) |
|||
return oldValue; |
|||
return oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="byte"/> properties.
|
|||
/// </summary>
|
|||
public class ByteAnimator : Animator<byte> |
|||
{ |
|||
const double maxVal = (double)byte.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override byte Interpolate(double progress, byte oldValue, byte newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (byte)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="decimal"/> properties.
|
|||
/// </summary>
|
|||
public class DecimalAnimator : Animator<decimal> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override decimal Interpolate(double progress, decimal oldValue, decimal newValue) |
|||
{ |
|||
return ((newValue - oldValue) * (decimal)progress) + oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="double"/> properties.
|
|||
/// </summary>
|
|||
public class DoubleAnimator : Animator<double> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override double Interpolate(double progress, double oldValue, double newValue) |
|||
{ |
|||
return ((newValue - oldValue) * progress) + oldValue; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="float"/> properties.
|
|||
/// </summary>
|
|||
public class FloatAnimator : Animator<float> |
|||
{ |
|||
/// <inheritdocs/>
|
|||
public override float Interpolate(double progress, float oldValue, float newValue) |
|||
{ |
|||
return (float)(((newValue - oldValue) * progress) + oldValue); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Int16"/> properties.
|
|||
/// </summary>
|
|||
public class Int16Animator : Animator<Int16> |
|||
{ |
|||
const double maxVal = (double)Int16.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override Int16 Interpolate(double progress, Int16 oldValue, Int16 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (Int16)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Int32"/> properties.
|
|||
/// </summary>
|
|||
public class Int32Animator : Animator<Int32> |
|||
{ |
|||
const double maxVal = (double)Int32.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override Int32 Interpolate(double progress, Int32 oldValue, Int32 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (Int32)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="Int64"/> properties.
|
|||
/// </summary>
|
|||
public class Int64Animator : Animator<Int64> |
|||
{ |
|||
const double maxVal = (double)Int64.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override Int64 Interpolate(double progress, Int64 oldValue, Int64 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (Int64)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="UInt16"/> properties.
|
|||
/// </summary>
|
|||
public class UInt16Animator : Animator<UInt16> |
|||
{ |
|||
const double maxVal = (double)UInt16.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override UInt16 Interpolate(double progress, UInt16 oldValue, UInt16 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (UInt16)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="UInt32"/> properties.
|
|||
/// </summary>
|
|||
public class UInt32Animator : Animator<UInt32> |
|||
{ |
|||
const double maxVal = (double)UInt32.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override UInt32 Interpolate(double progress, UInt32 oldValue, UInt32 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (UInt32)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
|
|||
namespace Avalonia.Animation.Animators |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="UInt64"/> properties.
|
|||
/// </summary>
|
|||
public class UInt64Animator : Animator<UInt64> |
|||
{ |
|||
const double maxVal = (double)UInt64.MaxValue; |
|||
|
|||
/// <inheritdocs/>
|
|||
public override UInt64 Interpolate(double progress, UInt64 oldValue, UInt64 newValue) |
|||
{ |
|||
var normOV = oldValue / maxVal; |
|||
var normNV = newValue / maxVal; |
|||
var deltaV = normNV - normOV; |
|||
return (UInt64)Math.Round(maxVal * ((deltaV * progress) + normOV)); |
|||
} |
|||
} |
|||
} |
|||
@ -1,35 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Animator that handles <see cref="double"/> properties.
|
|||
/// </summary>
|
|||
public class DoubleAnimator : Animator<double> |
|||
{ |
|||
|
|||
/// <inheritdocs/>
|
|||
protected override double DoInterpolation(double t, double neutralValue) |
|||
{ |
|||
var pair = GetKFPairAndIntraKFTime(t); |
|||
double y0, y1; |
|||
|
|||
var firstKF = pair.KFPair.FirstKeyFrame; |
|||
var secondKF = pair.KFPair.SecondKeyFrame; |
|||
|
|||
if (firstKF.isNeutral) |
|||
y0 = neutralValue; |
|||
else |
|||
y0 = firstKF.TargetValue; |
|||
|
|||
if (secondKF.isNeutral) |
|||
y1 = neutralValue; |
|||
else |
|||
y1 = secondKF.TargetValue; |
|||
|
|||
// Do linear parametric interpolation
|
|||
return y0 + (pair.IntraKFTime) * (y1 - y0); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,176 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the valid modes for a <see cref="IterationCount"/>.
|
|||
/// </summary>
|
|||
public enum IterationType |
|||
{ |
|||
Many, |
|||
Infinite |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines the number of iterations of an animation.
|
|||
/// Also defines its repeat behavior.
|
|||
/// </summary>
|
|||
[TypeConverter(typeof(IterationCountTypeConverter))] |
|||
public struct IterationCount : IEquatable<IterationCount> |
|||
{ |
|||
private readonly IterationType _type; |
|||
private readonly ulong _value; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IterationCount"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The number of iterations of an animation.</param>
|
|||
public IterationCount(ulong value) |
|||
: this(value, IterationType.Many) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="IterationCount"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The size of the IterationCount.</param>
|
|||
/// <param name="type">The unit of the IterationCount.</param>
|
|||
public IterationCount(ulong value, IterationType type) |
|||
{ |
|||
if (type > IterationType.Infinite) |
|||
{ |
|||
throw new ArgumentException("Invalid value", nameof(type)); |
|||
} |
|||
|
|||
_type = type; |
|||
_value = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets an instance of <see cref="IterationCount"/> that indicates that an animation
|
|||
/// should repeat forever.
|
|||
/// </summary>
|
|||
public static IterationCount Infinite => new IterationCount(0, IterationType.Infinite); |
|||
|
|||
/// <summary>
|
|||
/// Gets the unit of the <see cref="IterationCount"/>.
|
|||
/// </summary>
|
|||
public IterationType RepeatType => _type; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value that indicates whether the <see cref="IterationCount"/> is set to loop.
|
|||
/// </summary>
|
|||
public bool IsInfinite => _type == IterationType.Infinite; |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of repeat iterations.
|
|||
/// </summary>
|
|||
public ulong Value => _value; |
|||
|
|||
/// <summary>
|
|||
/// Compares two IterationCount structures for equality.
|
|||
/// </summary>
|
|||
/// <param name="a">The first IterationCount.</param>
|
|||
/// <param name="b">The second IterationCount.</param>
|
|||
/// <returns>True if the structures are equal, otherwise false.</returns>
|
|||
public static bool operator ==(IterationCount a, IterationCount b) |
|||
{ |
|||
return (a.IsInfinite && b.IsInfinite) |
|||
|| (a._value == b._value && a._type == b._type); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two IterationCount structures for inequality.
|
|||
/// </summary>
|
|||
/// <param name="rc1">The first IterationCount.</param>
|
|||
/// <param name="rc2">The first IterationCount.</param>
|
|||
/// <returns>True if the structures are unequal, otherwise false.</returns>
|
|||
public static bool operator !=(IterationCount rc1, IterationCount rc2) |
|||
{ |
|||
return !(rc1 == rc2); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines whether the <see cref="IterationCount"/> is equal to the specified object.
|
|||
/// </summary>
|
|||
/// <param name="o">The object with which to test equality.</param>
|
|||
/// <returns>True if the objects are equal, otherwise false.</returns>
|
|||
public override bool Equals(object o) |
|||
{ |
|||
if (o == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!(o is IterationCount)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return this == (IterationCount)o; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two IterationCount structures for equality.
|
|||
/// </summary>
|
|||
/// <param name="IterationCount">The structure with which to test equality.</param>
|
|||
/// <returns>True if the structures are equal, otherwise false.</returns>
|
|||
public bool Equals(IterationCount IterationCount) |
|||
{ |
|||
return this == IterationCount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a hash code for the IterationCount.
|
|||
/// </summary>
|
|||
/// <returns>The hash code.</returns>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return _value.GetHashCode() ^ _type.GetHashCode(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a string representation of the <see cref="IterationCount"/>.
|
|||
/// </summary>
|
|||
/// <returns>The string representation.</returns>
|
|||
public override string ToString() |
|||
{ |
|||
if (IsInfinite) |
|||
{ |
|||
return "Infinite"; |
|||
} |
|||
|
|||
string s = _value.ToString(); |
|||
return s; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Parses a string to return a <see cref="IterationCount"/>.
|
|||
/// </summary>
|
|||
/// <param name="s">The string.</param>
|
|||
/// <returns>The <see cref="IterationCount"/>.</returns>
|
|||
public static IterationCount Parse(string s) |
|||
{ |
|||
s = s.ToUpperInvariant().Trim(); |
|||
|
|||
if (s.EndsWith("INFINITE")) |
|||
{ |
|||
return Infinite; |
|||
} |
|||
else |
|||
{ |
|||
if (s.StartsWith("-")) |
|||
throw new InvalidCastException("IterationCount can't be a negative number."); |
|||
|
|||
var value = ulong.Parse(s, CultureInfo.InvariantCulture); |
|||
|
|||
return new IterationCount(value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a pair of keyframe, usually the
|
|||
/// Start and End keyframes of a <see cref="Animator{T}"/> object.
|
|||
/// </summary>
|
|||
public struct KeyFramePair<T> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes this <see cref="KeyFramePair{T}"/>
|
|||
/// </summary>
|
|||
/// <param name="FirstKeyFrame"></param>
|
|||
/// <param name="LastKeyFrame"></param>
|
|||
public KeyFramePair((T TargetValue, bool isNeutral) FirstKeyFrame, (T TargetValue, bool isNeutral) LastKeyFrame) : this() |
|||
{ |
|||
this.FirstKeyFrame = FirstKeyFrame; |
|||
this.SecondKeyFrame = LastKeyFrame; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// First <see cref="KeyFrame"/> object.
|
|||
/// </summary>
|
|||
public (T TargetValue, bool isNeutral) FirstKeyFrame { get; } |
|||
|
|||
/// <summary>
|
|||
/// Second <see cref="KeyFrame"/> object.
|
|||
/// </summary>
|
|||
public (T TargetValue, bool isNeutral) SecondKeyFrame { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Avalonia.Collections; |
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// A collection of <see cref="KeyFrame"/>s.
|
|||
/// </summary>
|
|||
public class KeyFrames : AvaloniaList<KeyFrame> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="KeyFrames"/> class.
|
|||
/// </summary>
|
|||
public KeyFrames() |
|||
{ |
|||
ResetBehavior = ResetBehavior.Remove; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="KeyFrames"/> class.
|
|||
/// </summary>
|
|||
/// <param name="items">The initial items in the collection.</param>
|
|||
public KeyFrames(IEnumerable<KeyFrame> items) |
|||
: base(items) |
|||
{ |
|||
ResetBehavior = ResetBehavior.Remove; |
|||
} |
|||
} |
|||
} |
|||
@ -1,199 +0,0 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System; |
|||
using System.ComponentModel; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Animation |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the valid modes for a <see cref="RepeatCount"/>.
|
|||
/// </summary>
|
|||
public enum RepeatType |
|||
{ |
|||
None, |
|||
Repeat, |
|||
Loop |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines the number of iterations of an animation.
|
|||
/// Also defines its repeat behavior.
|
|||
/// </summary>
|
|||
[TypeConverter(typeof(RepeatCountTypeConverter))] |
|||
public struct RepeatCount : IEquatable<RepeatCount> |
|||
{ |
|||
private readonly RepeatType _type; |
|||
private readonly ulong _value; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RepeatCount"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The number of iterations of an animation.</param>
|
|||
public RepeatCount(ulong value) |
|||
: this(value, RepeatType.Repeat) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RepeatCount"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="value">The size of the RepeatCount.</param>
|
|||
/// <param name="type">The unit of the RepeatCount.</param>
|
|||
public RepeatCount(ulong value, RepeatType type) |
|||
{ |
|||
if (type < RepeatType.None || type > RepeatType.Loop) |
|||
{ |
|||
throw new ArgumentException("Invalid value", "type"); |
|||
} |
|||
|
|||
_type = type; |
|||
_value = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets an instance of <see cref="RepeatCount"/> that indicates that an animation
|
|||
/// should repeat forever.
|
|||
/// </summary>
|
|||
public static RepeatCount Loop => new RepeatCount(0, RepeatType.Loop); |
|||
|
|||
/// <summary>
|
|||
/// Gets an instance of <see cref="RepeatCount"/> that indicates that an animation
|
|||
/// should not repeat.
|
|||
/// </summary>
|
|||
public static RepeatCount None => new RepeatCount(0, RepeatType.None); |
|||
|
|||
/// <summary>
|
|||
/// Gets the unit of the <see cref="RepeatCount"/>.
|
|||
/// </summary>
|
|||
public RepeatType RepeatType => _type; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value that indicates whether the <see cref="RepeatCount"/> is set to loop.
|
|||
/// </summary>
|
|||
public bool IsLoop => _type == RepeatType.Loop; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value that indicates whether the <see cref="RepeatCount"/> is set to not repeat.
|
|||
/// </summary>
|
|||
public bool IsNone => _type == RepeatType.None; |
|||
|
|||
/// <summary>
|
|||
/// Gets the number of repeat iterations.
|
|||
/// </summary>
|
|||
public ulong Value => _value; |
|||
|
|||
/// <summary>
|
|||
/// Compares two RepeatCount structures for equality.
|
|||
/// </summary>
|
|||
/// <param name="a">The first RepeatCount.</param>
|
|||
/// <param name="b">The second RepeatCount.</param>
|
|||
/// <returns>True if the structures are equal, otherwise false.</returns>
|
|||
public static bool operator ==(RepeatCount a, RepeatCount b) |
|||
{ |
|||
return (a.IsNone && b.IsNone) && (a.IsLoop && b.IsLoop) |
|||
|| (a._value == b._value && a._type == b._type); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two RepeatCount structures for inequality.
|
|||
/// </summary>
|
|||
/// <param name="rc1">The first RepeatCount.</param>
|
|||
/// <param name="rc2">The first RepeatCount.</param>
|
|||
/// <returns>True if the structures are unequal, otherwise false.</returns>
|
|||
public static bool operator !=(RepeatCount rc1, RepeatCount rc2) |
|||
{ |
|||
return !(rc1 == rc2); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Determines whether the <see cref="RepeatCount"/> is equal to the specified object.
|
|||
/// </summary>
|
|||
/// <param name="o">The object with which to test equality.</param>
|
|||
/// <returns>True if the objects are equal, otherwise false.</returns>
|
|||
public override bool Equals(object o) |
|||
{ |
|||
if (o == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!(o is RepeatCount)) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return this == (RepeatCount)o; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Compares two RepeatCount structures for equality.
|
|||
/// </summary>
|
|||
/// <param name="RepeatCount">The structure with which to test equality.</param>
|
|||
/// <returns>True if the structures are equal, otherwise false.</returns>
|
|||
public bool Equals(RepeatCount RepeatCount) |
|||
{ |
|||
return this == RepeatCount; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a hash code for the RepeatCount.
|
|||
/// </summary>
|
|||
/// <returns>The hash code.</returns>
|
|||
public override int GetHashCode() |
|||
{ |
|||
return _value.GetHashCode() ^ _type.GetHashCode(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets a string representation of the <see cref="RepeatCount"/>.
|
|||
/// </summary>
|
|||
/// <returns>The string representation.</returns>
|
|||
public override string ToString() |
|||
{ |
|||
if (IsLoop) |
|||
{ |
|||
return "Auto"; |
|||
} |
|||
else if (IsNone) |
|||
{ |
|||
return "None"; |
|||
} |
|||
|
|||
string s = _value.ToString(); |
|||
return s; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Parses a string to return a <see cref="RepeatCount"/>.
|
|||
/// </summary>
|
|||
/// <param name="s">The string.</param>
|
|||
/// <returns>The <see cref="RepeatCount"/>.</returns>
|
|||
public static RepeatCount Parse(string s) |
|||
{ |
|||
s = s.ToUpperInvariant().Trim(); |
|||
|
|||
if (s == "NONE") |
|||
{ |
|||
return None; |
|||
} |
|||
else if (s.EndsWith("LOOP")) |
|||
{ |
|||
return Loop; |
|||
} |
|||
else |
|||
{ |
|||
if(s.StartsWith("-")) |
|||
throw new InvalidCastException("RepeatCount can't be a negative number."); |
|||
|
|||
var value = ulong.Parse(s, CultureInfo.InvariantCulture); |
|||
|
|||
if (value == 1) |
|||
return None; |
|||
|
|||
return new RepeatCount(value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
|
|||
namespace Avalonia.Data.Converters |
|||
{ |
|||
/// <summary>
|
|||
/// Provides a set of useful <see cref="IValueConverter"/>s for working with objects.
|
|||
/// </summary>
|
|||
public static class ObjectConverters |
|||
{ |
|||
/// <summary>
|
|||
/// A value converter that returns true if the input object is a null reference.
|
|||
/// </summary>
|
|||
public static readonly IValueConverter IsNull = |
|||
new FuncValueConverter<object, bool>(x => x is null); |
|||
|
|||
/// <summary>
|
|||
/// A value converter that returns true if the input object is not null.
|
|||
/// </summary>
|
|||
public static readonly IValueConverter IsNotNull = |
|||
new FuncValueConverter<object, bool>(x => !(x is null)); |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Avalonia.Threading |
|||
{ |
|||
public class ThreadSafeObjectPool<T> where T : class, new() |
|||
{ |
|||
private Stack<T> _stack = new Stack<T>(); |
|||
private object _lock = new object(); |
|||
public static ThreadSafeObjectPool<T> Default { get; } = new ThreadSafeObjectPool<T>(); |
|||
|
|||
public T Get() |
|||
{ |
|||
lock (_lock) |
|||
{ |
|||
if(_stack.Count == 0) |
|||
return new T(); |
|||
return _stack.Pop(); |
|||
} |
|||
} |
|||
|
|||
public void Return(T obj) |
|||
{ |
|||
lock (_stack) |
|||
{ |
|||
_stack.Push(obj); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue