committed by
GitHub
32 changed files with 1066 additions and 822 deletions
@ -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,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()] |
[CmdletBinding()] |
||||
Param( |
Param( |
||||
[string]$Script = "build.cake", |
#[switch]$CustomParam, |
||||
[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, |
|
||||
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] |
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] |
||||
[string[]]$ScriptArgs |
[string[]]$BuildArguments |
||||
) |
) |
||||
|
|
||||
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null |
Write-Output "Windows PowerShell $($Host.Version)" |
||||
function MD5HashFile([string] $filePath) |
|
||||
{ |
|
||||
if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) |
|
||||
{ |
|
||||
return $null |
|
||||
} |
|
||||
|
|
||||
[System.IO.Stream] $file = $null; |
|
||||
[System.Security.Cryptography.MD5] $md5 = $null; |
|
||||
try |
|
||||
{ |
|
||||
$md5 = [System.Security.Cryptography.MD5]::Create() |
|
||||
$file = [System.IO.File]::OpenRead($filePath) |
|
||||
return [System.BitConverter]::ToString($md5.ComputeHash($file)) |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
if ($file -ne $null) |
|
||||
{ |
|
||||
$file.Dispose() |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
Write-Host "Preparing to run build script..." |
|
||||
|
|
||||
if(!$PSScriptRoot){ |
|
||||
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent |
|
||||
} |
|
||||
|
|
||||
$TOOLS_DIR = Join-Path $PSScriptRoot "tools" |
Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { exit 1 } |
||||
$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" |
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent |
||||
$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" |
|
||||
$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" |
|
||||
$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" |
|
||||
$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" |
|
||||
|
|
||||
# Should we use mono? |
########################################################################### |
||||
$UseMono = ""; |
# CONFIGURATION |
||||
if($Mono.IsPresent) { |
########################################################################### |
||||
Write-Verbose -Message "Using the Mono based scripting engine." |
|
||||
$UseMono = "-mono" |
|
||||
} |
|
||||
|
|
||||
# Should we use the new Roslyn? |
$BuildProjectFile = "$PSScriptRoot\nukebuild\_build.csproj" |
||||
$UseExperimental = ""; |
$TempDirectory = "$PSScriptRoot\\.tmp" |
||||
if($Experimental.IsPresent -and !($Mono.IsPresent)) { |
|
||||
Write-Verbose -Message "Using experimental version of Roslyn." |
|
||||
$UseExperimental = "-experimental" |
|
||||
} |
|
||||
|
|
||||
# Is this a dry run? |
$DotNetGlobalFile = "$PSScriptRoot\\global.json" |
||||
$UseDryRun = ""; |
$DotNetInstallUrl = "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1" |
||||
if($WhatIf.IsPresent) { |
$DotNetChannel = "Current" |
||||
$UseDryRun = "-dryrun" |
|
||||
} |
|
||||
|
|
||||
# Is this a dry run? |
$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1 |
||||
$UseSkipTests = ""; |
$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 |
||||
if($SkipTests.IsPresent) { |
$env:NUGET_XMLDOC_MODE = "skip" |
||||
$UseSkipTests = "-skip-tests" |
|
||||
} |
|
||||
|
|
||||
# Make sure tools folder exists |
########################################################################### |
||||
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { |
# EXECUTION |
||||
Write-Verbose -Message "Creating tools directory..." |
########################################################################### |
||||
New-Item -Path $TOOLS_DIR -Type directory | out-null |
|
||||
} |
|
||||
|
|
||||
# Make sure that packages.config exist. |
function ExecSafe([scriptblock] $cmd) { |
||||
if (!(Test-Path $PACKAGES_CONFIG)) { |
& $cmd |
||||
Write-Verbose -Message "Downloading packages.config..." |
if ($LASTEXITCODE) { exit $LASTEXITCODE } |
||||
try { (New-Object System.Net.WebClient).DownloadFile("http://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { |
|
||||
Throw "Could not download packages.config." |
|
||||
} |
|
||||
} |
} |
||||
|
|
||||
# Try find NuGet.exe in path if not exists |
# If global.json exists, load expected version |
||||
if (!(Test-Path $NUGET_EXE)) { |
if (Test-Path $DotNetGlobalFile) { |
||||
Write-Verbose -Message "Trying to find nuget.exe in PATH..." |
$DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json) |
||||
$existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_) } |
if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) { |
||||
$NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 |
$DotNetVersion = $DotNetGlobal.sdk.version |
||||
if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { |
|
||||
Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." |
|
||||
$NUGET_EXE = $NUGET_EXE_IN_PATH.FullName |
|
||||
} |
} |
||||
} |
} |
||||
|
|
||||
# Try download NuGet.exe if not exists |
# If dotnet is installed locally, and expected version is not set or installation matches the expected version |
||||
if (!(Test-Path $NUGET_EXE)) { |
if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -ne $null -and ` |
||||
Write-Verbose -Message "Downloading NuGet.exe..." |
(!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) { |
||||
try { |
$env:DOTNET_EXE = (Get-Command "dotnet").Path |
||||
(New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) |
|
||||
} catch { |
|
||||
Throw "Could not download NuGet.exe." |
|
||||
} |
|
||||
} |
} |
||||
|
else { |
||||
# Save nuget.exe path to environment to be available to child processed |
$DotNetDirectory = "$TempDirectory\dotnet-win" |
||||
$ENV:NUGET_EXE = $NUGET_EXE |
$env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" |
||||
|
|
||||
# Restore tools from NuGet? |
# Download install script |
||||
if(-Not $SkipToolPackageRestore.IsPresent) { |
$DotNetInstallFile = "$TempDirectory\dotnet-install.ps1" |
||||
Push-Location |
md -force $TempDirectory > $null |
||||
Set-Location $TOOLS_DIR |
(New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile) |
||||
|
|
||||
# Check for changes in packages.config and remove installed tools if true. |
# Install by channel or version |
||||
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) |
if (!(Test-Path variable:DotNetVersion)) { |
||||
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or |
ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath } |
||||
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { |
} else { |
||||
Write-Verbose -Message "Missing or changed package.config hash..." |
ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } |
||||
Remove-Item * -Recurse -Exclude packages.config,nuget.exe |
|
||||
} |
} |
||||
|
|
||||
Write-Verbose -Message "Restoring tools from NuGet..." |
|
||||
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" |
|
||||
|
|
||||
if ($LASTEXITCODE -ne 0) { |
|
||||
Throw "An error occured while restoring NuGet tools." |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" |
|
||||
} |
|
||||
Write-Verbose -Message ($NuGetOutput | out-string) |
|
||||
Pop-Location |
|
||||
} |
} |
||||
|
|
||||
# Make sure that Cake has been installed. |
Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" |
||||
if (!(Test-Path $CAKE_EXE)) { |
|
||||
Throw "Could not find Cake.exe at $CAKE_EXE" |
|
||||
} |
|
||||
|
|
||||
# Start Cake |
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments } |
||||
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 |
|
||||
|
|||||
@ -1,105 +1,72 @@ |
|||||
#!/usr/bin/env bash |
#!/usr/bin/env bash |
||||
|
|
||||
########################################################################## |
echo $(bash --version 2>&1 | head -n 1) |
||||
# This is the Cake bootstrapper script for Linux and OS X. |
|
||||
# This file was downloaded from https://github.com/cake-build/resources |
|
||||
# Feel free to change this file to fit your needs. |
|
||||
########################################################################## |
|
||||
|
|
||||
# Define directories. |
#CUSTOMPARAM=0 |
||||
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) |
BUILD_ARGUMENTS=() |
||||
TOOLS_DIR=$SCRIPT_DIR/tools |
|
||||
NUGET_EXE=$TOOLS_DIR/nuget.exe |
|
||||
CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe |
|
||||
PACKAGES_CONFIG=$TOOLS_DIR/packages.config |
|
||||
PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum |
|
||||
|
|
||||
# Define md5sum or md5 depending on Linux/OSX |
|
||||
MD5_EXE= |
|
||||
if [[ "$(uname -s)" == "Darwin" ]]; then |
|
||||
MD5_EXE="md5 -r" |
|
||||
else |
|
||||
MD5_EXE="md5sum" |
|
||||
fi |
|
||||
|
|
||||
# Define default arguments. |
|
||||
SCRIPT="build.cake" |
|
||||
TARGET="Default" |
|
||||
CONFIGURATION="Release" |
|
||||
PLATFORM="Any CPU" |
|
||||
VERBOSITY="verbose" |
|
||||
DRYRUN= |
|
||||
SKIP_TESTS= |
|
||||
SHOW_VERSION=false |
|
||||
SCRIPT_ARGUMENTS=() |
|
||||
|
|
||||
# Parse arguments. |
|
||||
for i in "$@"; do |
for i in "$@"; do |
||||
case $1 in |
case $(echo $1 | awk '{print tolower($0)}') in |
||||
-s|--script) SCRIPT="$2"; shift ;; |
# -custom-param) CUSTOMPARAM=1;; |
||||
-t|--target) TARGET="$2"; shift ;; |
*) BUILD_ARGUMENTS+=("$1") ;; |
||||
-p|--platform) PLATFORM="$2"; shift ;; |
|
||||
-c|--configuration) CONFIGURATION="$2"; shift ;; |
|
||||
--skip-tests) SKIP_TESTS="-skip-tests"; shift ;; |
|
||||
-v|--verbosity) VERBOSITY="$2"; shift ;; |
|
||||
-d|--dryrun) DRYRUN="-dryrun" ;; |
|
||||
--version) SHOW_VERSION=true ;; |
|
||||
--) shift; SCRIPT_ARGUMENTS+=("$@"); break ;; |
|
||||
*) SCRIPT_ARGUMENTS+=("$1") ;; |
|
||||
esac |
esac |
||||
shift |
shift |
||||
done |
done |
||||
|
|
||||
# Make sure the tools folder exist. |
set -eo pipefail |
||||
if [ ! -d "$TOOLS_DIR" ]; then |
SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) |
||||
mkdir "$TOOLS_DIR" |
|
||||
fi |
|
||||
|
|
||||
# Make sure that packages.config exist. |
########################################################################### |
||||
if [ ! -f "$TOOLS_DIR/packages.config" ]; then |
# CONFIGURATION |
||||
echo "Downloading packages.config..." |
########################################################################### |
||||
curl -Lsfo "$TOOLS_DIR/packages.config" http://cakebuild.net/download/bootstrapper/packages |
|
||||
if [ $? -ne 0 ]; then |
|
||||
echo "An error occured while downloading packages.config." |
|
||||
exit 1 |
|
||||
fi |
|
||||
fi |
|
||||
|
|
||||
# Download NuGet if it does not exist. |
BUILD_PROJECT_FILE="$SCRIPT_DIR/nukebuild/_build.csproj" |
||||
if [ ! -f "$NUGET_EXE" ]; then |
TEMP_DIRECTORY="$SCRIPT_DIR//.tmp" |
||||
echo "Downloading NuGet..." |
|
||||
curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe |
|
||||
if [ $? -ne 0 ]; then |
|
||||
echo "An error occured while downloading nuget.exe." |
|
||||
exit 1 |
|
||||
fi |
|
||||
fi |
|
||||
|
|
||||
# Restore tools from NuGet. |
DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json" |
||||
pushd "$TOOLS_DIR" >/dev/null |
DOTNET_INSTALL_URL="https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh" |
||||
if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then |
DOTNET_CHANNEL="Current" |
||||
find . -type d ! -name . | xargs rm -rf |
|
||||
fi |
|
||||
|
|
||||
mono "$NUGET_EXE" install -ExcludeVersion |
export DOTNET_CLI_TELEMETRY_OPTOUT=1 |
||||
if [ $? -ne 0 ]; then |
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 |
||||
echo "Could not restore NuGet packages." |
export NUGET_XMLDOC_MODE="skip" |
||||
exit 1 |
|
||||
fi |
|
||||
|
|
||||
$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 global.json exists, load expected version |
||||
if [ ! -f "$CAKE_EXE" ]; then |
if [ -f "$DOTNET_GLOBAL_FILE" ]; then |
||||
echo "Could not find Cake.exe at '$CAKE_EXE'." |
DOTNET_VERSION=$(FirstJsonValue "version" $(cat "$DOTNET_GLOBAL_FILE")) |
||||
exit 1 |
if [ "$DOTNET_VERSION" == "" ]; then |
||||
|
unset DOTNET_VERSION |
||||
|
fi |
||||
fi |
fi |
||||
|
|
||||
# Start Cake |
# If dotnet is installed locally, and expected version is not set or installation matches the expected version |
||||
if $SHOW_VERSION; then |
if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then |
||||
exec mono "$CAKE_EXE" -version |
export DOTNET_EXE="$(command -v dotnet)" |
||||
else |
else |
||||
exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -platform="$PLATFORM" -configuration="$CONFIGURATION" -target=$TARGET $DRYRUN $SKIP_TESTS "${SCRIPT_ARGUMENTS[@]}" |
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" |
||||
|
|
||||
|
# Install by channel or version |
||||
|
if [ -z ${DOTNET_VERSION+x} ]; then |
||||
|
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path |
||||
|
else |
||||
|
"$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path |
||||
|
fi |
||||
fi |
fi |
||||
|
|
||||
|
echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)" |
||||
|
|
||||
|
"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" -- ${BUILD_ARGUMENTS[@]} |
||||
|
|||||
@ -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 |
|
||||
@ -0,0 +1,231 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Diagnostics; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System.Threading; |
||||
|
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); |
||||
|
} |
||||
|
|
||||
|
Target Clean => _ => _.Executes(() => |
||||
|
{ |
||||
|
DeleteDirectories(Parameters.BuildDirs); |
||||
|
EnsureCleanDirectories(Parameters.BuildDirs); |
||||
|
EnsureCleanDirectory(Parameters.ArtifactsDir); |
||||
|
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, 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); |
||||
|
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.Base.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Controls.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Input.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Layout.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Markup.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Styling.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Visuals.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.Skia.UnitTests", false); |
||||
|
RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests", false); |
||||
|
}); |
||||
|
|
||||
|
Target RunRenderTests => _ => _ |
||||
|
.OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows) |
||||
|
.DependsOn(Compile) |
||||
|
.Executes(() => |
||||
|
{ |
||||
|
RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", true); |
||||
|
RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", true); |
||||
|
}); |
||||
|
|
||||
|
Target RunDesignerTests => _ => _ |
||||
|
.OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows) |
||||
|
.DependsOn(Compile) |
||||
|
.Executes(() => |
||||
|
{ |
||||
|
RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", false); |
||||
|
}); |
||||
|
|
||||
|
[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 CreateNugetPackages => _ => _ |
||||
|
.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 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,140 @@ |
|||||
|
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 NukeArgConfiguration { get; set; } |
||||
|
|
||||
|
[Parameter("skip-tests")] |
||||
|
public bool NukeArgSkipTests { get; set; } |
||||
|
|
||||
|
[Parameter("force-nuget-version")] |
||||
|
public string NukeArgForceNugetVersion { 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 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.NukeArgConfiguration ?? "Release"; |
||||
|
SkipTests = b.NukeArgSkipTests; |
||||
|
|
||||
|
// 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.NukeArgForceNugetVersion ?? 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"; |
||||
|
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); |
||||
|
} |
||||
|
|
||||
|
private static string GetVersion() |
||||
|
{ |
||||
|
var xdoc = XDocument.Load("./build/SharedVersion.props"); |
||||
|
return xdoc.Descendants().First(x => x.Name.LocalName == "Version").Value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.IO.Compression; |
||||
|
using System.Linq; |
||||
|
using Nuke.Common; |
||||
|
using Nuke.Common.IO; |
||||
|
|
||||
|
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
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<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')" /> |
||||
|
</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,28 @@ |
|||||
|
// 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; |
||||
|
|
||||
|
using Avalonia.Media; |
||||
|
|
||||
|
using Portable.Xaml.ComponentModel; |
||||
|
|
||||
|
namespace Avalonia.Markup.Xaml.Converters |
||||
|
{ |
||||
|
public class FontFamilyTypeConverter : TypeConverter |
||||
|
{ |
||||
|
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
||||
|
{ |
||||
|
return sourceType == typeof(string); |
||||
|
} |
||||
|
|
||||
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
||||
|
{ |
||||
|
var s = (string)value; |
||||
|
|
||||
|
return FontFamily.Parse(s, context.GetBaseUri()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue