Update the build script to use the new dotnet tools

This commit is contained in:
Matthew Leibowitz 2019-08-08 03:46:36 +02:00
Родитель 2d63d41148
Коммит 2b1af69499
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 00A672181E6BF432
22 изменённых файлов: 241 добавлений и 3526 удалений

Просмотреть файл

@ -1,11 +1,14 @@
variables: variables:
VERBOSITY: normal
BUILD_NUMBER: $[counter('$(Build.SourceBranchName)_counter', 1)]
MONO_VERSION: 5_18_1 MONO_VERSION: 5_18_1
XCODE_VERSION: 10.2.1 XCODE_VERSION: 10.2.1
VERBOSITY: minimal
BUILD_NUMBER: $[counter('$(Build.SourceBranchName)_counter', 1)]
API_TOOLS_VERSION: 1.0.2-preview.5 API_TOOLS_VERSION: 1.0.2-preview.5
BINDERATOR_VERSION: 0.2.0
DOTNET_CORE_VERSION: 2.2.x DOTNET_CORE_VERSION: 2.2.x
# PACKAGE_VERSION_SUFFIX: <string>
# XAMARIN_ANDROID_PATH: <path to Xamarin.Android>
resources: resources:
repositories: repositories:
@ -16,76 +19,69 @@ resources:
jobs: jobs:
# run the build
- job: build - job: build
displayName: 'Build Libraries & NuGets (macOS)' strategy:
matrix:
macos:
imageName: macos-10.14
windows:
imageName: vs2017-win2016
displayName: 'Build'
pool: pool:
vmImage: macos-10.14 name: $(imageName)
steps: steps:
# Make sure to select the correct Xamarin and mono # install xamarin
- bash: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh $(MONO_VERSION) - bash: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh $(MONO_VERSION)
displayName: 'Switch to the latest Xamarin SDK' displayName: 'Switch to the latest Xamarin SDK'
condition: eq(variables['System.JobName'], 'macos')
- bash: echo '##vso[task.setvariable variable=MD_APPLE_SDK_ROOT;]'/Applications/Xcode_$(XCODE_VERSION).app;sudo xcode-select --switch /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer - bash: echo '##vso[task.setvariable variable=MD_APPLE_SDK_ROOT;]'/Applications/Xcode_$(XCODE_VERSION).app;sudo xcode-select --switch /Applications/Xcode_$(XCODE_VERSION).app/Contents/Developer
displayName: 'Switch to the latest Xcode' displayName: 'Switch to the latest Xcode'
# install the tools condition: eq(variables['System.JobName'], 'macos')
# install dotnet and tools
- bash: echo '##vso[task.setvariable variable=PATH;]'$PATH:$HOME/.dotnet/tools
displayName: 'Add ~/.dotnet/tools to the PATH environment variable'
condition: eq(variables['System.JobName'], 'macos')
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Use the correct version of the .NET Core SDK' displayName: 'Use the correct version of the .NET Core SDK'
condition: eq(variables['System.JobName'], 'macos')
inputs: inputs:
version: $(DOTNET_CORE_VERSION) version: $(DOTNET_CORE_VERSION)
- powershell: dotnet tool install -g api-tools --version $(API_TOOLS_VERSION) - powershell: dotnet tool install -g api-tools --version $(API_TOOLS_VERSION)
displayName: 'Install api-tools' displayName: 'Install api-tools'
# Build the libraries and packages - powershell: dotnet tool install -g xamarin.androidbinderator.tool --version $(BINDERATOR_VERSION)
- bash: sh build.sh --target=ci --settings_skipverification=true --verbosity=$(VERBOSITY) displayName: 'Install xamarin-android-binderator'
displayName: 'Build NuGets' - powershell: dotnet tool install -g xamarin.androidx.migration.tool --version $(BINDERATOR_VERSION)
# run the diff displayName: 'Install androidx-migrator'
- powershell: | # run the main build
if (Get-ChildItem output -Filter *.nupkg) { - powershell: .\build.ps1 --target=ci --verbosity=$(VERBOSITY)
api-tools nuget-diff output --latest --group-ids --output output/api-diff --cache externals/package_cache displayName: 'Run build'
} # publish the nugets
displayName: 'API diff'
# Publish the artifacts
- task: PublishBuildArtifacts@1 - task: PublishBuildArtifacts@1
displayName: 'Publish unsigned artifacts' condition: eq(variables['System.JobName'], 'macos')
displayName: 'Publish artifacts'
inputs: inputs:
pathToPublish: '$(Build.SourcesDirectory)/output' PathToPublish: output
artifactName: 'nuget' ArtifactName: nuget
# publish the output with the os name
- job: build_windows
displayName: 'Build Libraries & NuGets (Windows)'
pool:
vmImage: vs2017-win2016
steps:
# Build the libraries and packages
- powershell: .\build.ps1 --target=ci --settings_skipverification=true --verbosity=$(VERBOSITY)
displayName: 'Build everything'
# Publish the artifacts
- task: PublishBuildArtifacts@1 - task: PublishBuildArtifacts@1
displayName: 'Publish Windows artifacts' displayName: 'Publish artifacts'
inputs: inputs:
pathToPublish: '$(Build.SourcesDirectory)/output' PathToPublish: output
artifactName: 'windows_output' ArtifactName: 'output-$(System.JobName)'
# # Run some internal auditing
# - ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
# - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
# displayName: Component Detection - Log
# inputs:
# scanType: LogOnly
# - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
# displayName: Component Detection - Report
# - task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@1
# displayName: 'PoliCheck'
# inputs:
# targetType: F
# only sign the packages when running on Windows, and using the private server which has the certificates # only sign the packages when running on Windows, and using the private server which has the certificates
- ${{ if eq(variables['System.TeamProject'], 'devdiv') }}: - ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
- job: signing - job: signing
displayName: Signing NuGets displayName: Signing NuGets
variables:
skipComponentGovernanceDetection: true
dependsOn: build dependsOn: build
pool: pool:
name: VSEng-XamarinCustom name: VSEng-XamarinCustom
demands: demands:
- corpnet - corpnet
condition: and(succeeded(), or(startsWith(variables['Build.SourceBranch'], 'refs/tags/'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq(variables['Build.SourceBranch'], 'refs/heads/AndroidX'))) condition: and(succeeded(), or(startsWith(variables['Build.SourceBranch'], 'refs/tags/'), eq(variables['CodeSign'], 'true')))
steps: steps:
# don't checkout code and sign the packages # don't checkout code and sign the packages
- checkout: none - checkout: none

Просмотреть файл

@ -1,66 +1,90 @@
// Tools needed by cake addins // Tools needed by cake addins
#tool nuget:?package=Cake.MonoApiTools&version=3.0.1 #tool nuget:?package=vswhere&version=2.7.1
#tool nuget:?package=vswhere
// Cake Addins // Cake Addins
#addin nuget:?package=Cake.FileHelpers&version=3.1.0 #addin nuget:?package=Cake.FileHelpers&version=3.2.0
#addin nuget:?package=Cake.Compression&version=0.1.6 #addin nuget:?package=Cake.Compression&version=0.2.3
#addin nuget:?package=Cake.MonoApiTools&version=3.0.1
#addin nuget:?package=Xamarin.Nuget.Validator&version=1.1.1 #addin nuget:?package=Xamarin.Nuget.Validator&version=1.1.1
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Xml; using System.Xml;
using System.Xml.Linq; using System.Xml.Linq;
using Xamarin.Nuget.Validator;
// From Cake.Xamarin.Build, dumps out versions of things // The main configuration points
//LogSystemInfo ();
var TARGET = Argument ("t", Argument ("target", "Default")); var TARGET = Argument ("t", Argument ("target", "Default"));
var BUILD_CONFIG = Argument ("config", "Release"); var BUILD_CONFIG = Argument ("config", "Release");
var VERBOSITY = (Verbosity) Enum.Parse (typeof(Verbosity), Argument ("v", Argument ("verbosity", "Normal")), true); var VERBOSITY = (Verbosity) Enum.Parse (typeof(Verbosity), Argument ("v", Argument ("verbosity", "Normal")), true);
var PACKAGE_VERSION_SUFFIX = EnvironmentVariable ("PACKAGE_VERSION_SUFFIX");
var XAMARIN_ANDROID_PATH = EnvironmentVariable ("XAMARIN_ANDROID_PATH");
// Lists all the artifacts and their versions for com.android.support.* // Lists all the artifacts and their versions for com.android.support.*
// https://dl.google.com/dl/android/maven2/com/android/support/group-index.xml // https://dl.google.com/dl/android/maven2/com/android/support/group-index.xml
// Master list of all the packages in the repo: // Master list of all the packages in the repo:
// https://dl.google.com/dl/android/maven2/master-index.xml // https://dl.google.com/dl/android/maven2/master-index.xml
var NUGET_PRE = "";
// FROM: https://dl.google.com/android/repository/addon2-1.xml
var BUILD_TOOLS_URL = "https://dl-ssl.google.com/android/repository/build-tools_r28-macosx.zip";
var ANDROID_SDK_VERSION = "v9.0";
var TF_MONIKER = "monoandroid90";
var REF_DOCS_URL = "https://bosstoragemirror.blob.core.windows.net/android-docs-scraper/a7/a712886a8b4ee709f32d51823223039883d38734/androidx.zip"; var REF_DOCS_URL = "https://bosstoragemirror.blob.core.windows.net/android-docs-scraper/a7/a712886a8b4ee709f32d51823223039883d38734/androidx.zip";
// We grab the previous release's api-info.xml to use as a comparison for this build's generated info to make an api-diff
var BASE_API_INFO_URL = EnvironmentVariable("MONO_API_INFO_XML_URL") ?? "https://github.com/xamarin/AndroidSupportComponents/releases/download/28.0.0.2/AndroidSupport.api-info.xml";
// In order to create the type mapping, we need to get the AndroidSupport.Merged.dll // In order to create the type mapping, we need to get the AndroidSupport.Merged.dll
var SUPPORT_MERGED_DLL_URL = EnvironmentVariable("SUPPORT_MERGED_DLL_URL") ?? $"https://github.com/xamarin/AndroidSupportComponents/releases/download/28.0.0.2/AndroidSupport.Merged.dll"; var SUPPORT_MERGED_DLL_URL = EnvironmentVariable("SUPPORT_MERGED_DLL_URL") ?? $"https://github.com/xamarin/AndroidSupportComponents/releases/download/28.0.0.2/AndroidSupport.Merged.dll";
var MONODROID_BASE_PATH = (DirectoryPath)"/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/xbuild-frameworks/MonoAndroid/"; // Resolve Xamarin.Android installation
if (IsRunningOnWindows ()) { var ANDROID_SDK_BASE_VERSION = "v1.0";
var vsInstallPath = VSWhereLatest (new VSWhereLatestSettings { Requires = "Component.Xamarin" }); var ANDROID_SDK_VERSION = "v9.0";
MONODROID_BASE_PATH = vsInstallPath.Combine ("Common7/IDE/ReferenceAssemblies/Microsoft/Framework/MonoAndroid/"); if (string.IsNullOrEmpty(XAMARIN_ANDROID_PATH)) {
if (IsRunningOnWindows()) {
var vsInstallPath = VSWhereLatest(new VSWhereLatestSettings { Requires = "Component.Xamarin" });
XAMARIN_ANDROID_PATH = vsInstallPath.Combine("Common7/IDE/ReferenceAssemblies/Microsoft/Framework/MonoAndroid").FullPath;
} else {
if (DirectoryExists("/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/xamarin.android/xbuild-frameworks/MonoAndroid"))
XAMARIN_ANDROID_PATH = "/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/xamarin.android/xbuild-frameworks/MonoAndroid";
else
XAMARIN_ANDROID_PATH = "/Library/Frameworks/Xamarin.Android.framework/Versions/Current/lib/xbuild-frameworks/MonoAndroid";
}
} }
var MONODROID_PATH = MONODROID_BASE_PATH.Combine(ANDROID_SDK_VERSION); if (!DirectoryExists($"{XAMARIN_ANDROID_PATH}/{ANDROID_SDK_VERSION}"))
throw new Exception($"Unable to find Xamarin.Android {ANDROID_SDK_VERSION} at {XAMARIN_ANDROID_PATH}.");
var ANDROIDX_MAPPER_EXE = MakeAbsolute ((FilePath)$"util/AndroidXMapper/AndroidXMapper/bin/{BUILD_CONFIG}/net47/AndroidXMapper.exe"); // Load all the git variables
var BUILD_COMMIT = EnvironmentVariable("BUILD_SOURCEVERSION") ?? "DEV";
var BUILD_NUMBER = EnvironmentVariable("BUILD_NUMBER") ?? "DEBUG";
var BUILD_TIMESTAMP = DateTime.UtcNow.ToString();
var BUILD_NUMBER = EnvironmentVariable("BUILD_NUMBER") ?? ""; var REQUIRED_DOTNET_TOOLS = new [] {
if (string.IsNullOrEmpty(BUILD_NUMBER)) { "xamarin-android-binderator",
BUILD_NUMBER = "0"; "api-tools",
} "xamarin.androidx.migration.tool"
};
Information ("MONODROID_BASE_PATH: {0}", MONODROID_BASE_PATH); // Log some variables
Information ("MONODROID_PATH: {0}", MONODROID_PATH); Information ("XAMARIN_ANDROID_PATH: {0}", XAMARIN_ANDROID_PATH);
Information ("ANDROIDX_MAPPER_EXE: {0}", ANDROIDX_MAPPER_EXE); Information ("ANDROID_SDK_VERSION: {0}", ANDROID_SDK_VERSION);
Information ("BUILD_NUMBER: {0}", BUILD_NUMBER); Information ("BUILD_COMMIT: {0}", BUILD_COMMIT);
Information ("BUILD_NUMBER: {0}", BUILD_NUMBER);
Information ("BUILD_TIMESTAMP: {0}", BUILD_TIMESTAMP);
// You shouldn't have to configure anything below here // You shouldn't have to configure anything below here
// ###################################################### // ######################################################
void RunProcess(FilePath fileName, string processArguments)
{
var exitCode = StartProcess(fileName, processArguments);
if (exitCode != 0)
throw new Exception ($"Process {fileName} exited with code {exitCode}.");
}
string[] RunProcessWithOutput(FilePath fileName, string processArguments)
{
var exitCode = StartProcess(fileName, new ProcessSettings {
Arguments = processArguments,
RedirectStandardOutput = true,
RedirectStandardError = true
}, out var procOut);
if (exitCode != 0)
throw new Exception ($"Process {fileName} exited with code {exitCode}.");
return procOut.ToArray();;
}
Task("javadocs") Task("javadocs")
.Does(() => .Does(() =>
{ {
@ -78,25 +102,30 @@ Task("javadocs")
var outTxtPath = srcJarPath.Replace("-sources.jar", "-paramnames.txt"); var outTxtPath = srcJarPath.Replace("-sources.jar", "-paramnames.txt");
var outXmlPath = srcJarPath.Replace("-sources.jar", "-paramnames.xml"); var outXmlPath = srcJarPath.Replace("-sources.jar", "-paramnames.xml");
StartProcess("java", "-jar \"" + MakeAbsolute(astJar).FullPath + "\" --text \"" + srcJarPath + "\" \"" + outTxtPath + "\""); RunProcess("java", "-jar \"" + MakeAbsolute(astJar).FullPath + "\" --text \"" + srcJarPath + "\" \"" + outTxtPath + "\"");
StartProcess("java", "-jar \"" + MakeAbsolute(astJar).FullPath + "\" --xml \"" + srcJarPath + "\" \"" + outXmlPath + "\""); RunProcess("java", "-jar \"" + MakeAbsolute(astJar).FullPath + "\" --xml \"" + srcJarPath + "\" \"" + outXmlPath + "\"");
} }
}); });
Task("binderate") Task("check-tools")
.Does(() => .Does(() =>
{ {
if (!DirectoryExists("./util/binderator")) var installedTools = RunProcessWithOutput("dotnet", "tool list -g");
{ foreach (var toolName in REQUIRED_DOTNET_TOOLS) {
EnsureDirectoryExists("./util/binderator"); if (installedTools.All(l => l.IndexOf(toolName, StringComparison.OrdinalIgnoreCase) == -1))
Unzip ("./util/binderator.zip", "./util/binderator"); throw new Exception ($"Missing dotnet tool: {toolName}");
} }
});
var configFile = new FilePath("./config.json"); Task ("binderate")
var basePath = new DirectoryPath ("./"); .Does (() =>
{
var configFile = MakeAbsolute(new FilePath("./config.json")).FullPath;
var basePath = MakeAbsolute(new DirectoryPath ("./")).FullPath;
StartProcess("dotnet", "./util/binderator/android-binderator.dll --config=\"" // Run the dotnet tool for binderator
+ MakeAbsolute(configFile).FullPath + "\" --basepath=\"" + MakeAbsolute(basePath).FullPath + "\""); RunProcess("xamarin-android-binderator",
$"--config=\"{configFile}\" --basepath=\"{basePath}\"");
// format the targets file so they are pretty in the package // format the targets file so they are pretty in the package
var targetsFiles = GetFiles("generated/**/*.targets"); var targetsFiles = GetFiles("generated/**/*.targets");
@ -110,18 +139,20 @@ Task("binderate")
Task("libs") Task("libs")
.Does(() => .Does(() =>
{ {
var settings = new MSBuildSettings()
.SetConfiguration(BUILD_CONFIG)
.SetVerbosity(VERBOSITY)
.SetMaxCpuCount(0)
.WithRestore()
.WithProperty("PackageVersionSuffix", PACKAGE_VERSION_SUFFIX)
.WithProperty("PackageRequireLicenseAcceptance", "true")
.WithProperty("PackageOutputPath", MakeAbsolute ((DirectoryPath)"./output/").FullPath)
.WithProperty("DesignTimeBuild", "false")
.WithProperty("AndroidSdkBuildToolsVersion", "28.0.3")
.WithTarget("Pack");
// build and pack in one go // build and pack in one go
MSBuild ("./generated/AndroidX.sln", c => { MSBuild("./generated/AndroidX.sln", settings);
c.Configuration = BUILD_CONFIG;
c.MaxCpuCount = 0;
c.Verbosity = VERBOSITY;
c.Targets.Clear();
c.Targets.Add("Pack");
c.Properties.Add("PackageOutputPath", new [] { MakeAbsolute(new FilePath("./output")).FullPath });
c.Properties.Add("PackageRequireLicenseAcceptance", new [] { "true" });
c.Properties.Add("DesignTimeBuild", new [] { "false" });
c.Properties.Add("AndroidSdkBuildToolsVersion", new [] { "28.0.3" });
});
}); });
Task("nuget") Task("nuget")
@ -132,7 +163,8 @@ Task("samples")
.Does(() => .Does(() =>
{ {
// TODO: make this actually work with more than just this sample // TODO: make this actually work with more than just this sample
// make a big .targets file that pulls in everything
var xmlns = (XNamespace)"http://schemas.microsoft.com/developer/msbuild/2003"; var xmlns = (XNamespace)"http://schemas.microsoft.com/developer/msbuild/2003";
var itemGroup = new XElement(xmlns + "ItemGroup"); var itemGroup = new XElement(xmlns + "ItemGroup");
foreach (var nupkg in GetFiles("./output/*.nupkg")) { foreach (var nupkg in GetFiles("./output/*.nupkg")) {
@ -147,7 +179,7 @@ Task("samples")
} }
var xdoc = new XDocument(new XElement(xmlns + "Project", itemGroup)); var xdoc = new XDocument(new XElement(xmlns + "Project", itemGroup));
xdoc.Save("./output/AllPackages.targets"); xdoc.Save("./output/AllPackages.targets");
// clear the packages folder so we always use the latest // clear the packages folder so we always use the latest
var packagesPath = MakeAbsolute((DirectoryPath)"./samples/packages").FullPath; var packagesPath = MakeAbsolute((DirectoryPath)"./samples/packages").FullPath;
EnsureDirectoryExists(packagesPath); EnsureDirectoryExists(packagesPath);
@ -170,9 +202,7 @@ Task("samples")
Task("nuget-validation") Task("nuget-validation")
.Does(() => .Does(() =>
{ {
//setup validation options var options = new NugetValidatorOptions {
var options = new Xamarin.Nuget.Validator.NugetValidatorOptions()
{
Copyright = "© Microsoft Corporation. All rights reserved.", Copyright = "© Microsoft Corporation. All rights reserved.",
Author = "Microsoft", Author = "Microsoft",
Owner = "Microsoft", Owner = "Microsoft",
@ -182,69 +212,31 @@ Task("nuget-validation")
ValidPackageNamespace = new [] { "Xamarin" }, ValidPackageNamespace = new [] { "Xamarin" },
}; };
var nupkgFiles = GetFiles ("./output/*.nupkg"); var nupkgFiles = GetFiles("./output/*.nupkg");
Information("Found {0} NuGet packages to validate.", nupkgFiles.Count());
Information ("Found ({0}) Nuget's to validate", nupkgFiles.Count ()); foreach (var nupkgFile in nupkgFiles) {
var fname = nupkgFile.GetFilename();
foreach (var nupkgFile in nupkgFiles) Information($"Verifiying metadata of {fname}...");
{ var result = NugetValidator.Validate(MakeAbsolute(nupkgFile).FullPath, options);
Information ("Verifiying Metadata of {0}", nupkgFile.GetFilename ()); if (!result.Success) {
Error($"Metadata validation failed for: {fname} ");
var result = Xamarin.Nuget.Validator.NugetValidator.Validate(MakeAbsolute(nupkgFile).FullPath, options); Error(string.Join("\n ", result.ErrorMessages));
throw new Exception($"Invalid Metadata for: {fname}");
if (!result.Success) } else {
{ Information($"Metadata validation passed for: {fname}");
Information ("Metadata validation failed for: {0} \n\n", nupkgFile.GetFilename ());
Information (string.Join("\n ", result.ErrorMessages));
throw new Exception ($"Invalid Metadata for: {nupkgFile.GetFilename ()}");
}
else
{
Information ("Metadata validation passed for: {0}", nupkgFile.GetFilename ());
} }
} }
});
Task ("androidxmapper")
.Does (() =>
{
MSBuild (
"./util/AndroidXMapper/AndroidXMapper.sln", c => {
c.Configuration = BUILD_CONFIG;
c.MaxCpuCount = 0;
c.Verbosity = VERBOSITY;
c.Restore = true;
});
}); });
Task ("diff") Task ("diff")
.IsDependentOn ("merge")
.Does (() => .Does (() =>
{ {
var SEARCH_DIRS = new DirectoryPath [] { RunProcess("api-tools",
MONODROID_BASE_PATH.Combine("v1.0"), "nuget-diff output --latest --group-ids --output output/api-diff --cache externals/package_cache");
MONODROID_PATH,
};
EnsureDirectoryExists("./output/");
MonoApiInfo ("./output/AndroidX.Merged.dll", "./output/api-info.xml", new MonoApiInfoToolSettings {
SearchPaths = SEARCH_DIRS
});
DownloadFile (BASE_API_INFO_URL, "./output/api-info.previous.xml");
// Now diff against current released api info
MonoApiDiff ("./output/api-info.previous.xml", "./output/api-info.xml", "./output/api-diff.xml");
// Now let's make pretty files
MonoApiHtml ("./output/api-info.previous.xml", "./output/api-info.xml", "./output/api-diff.html");
MonoApiMarkdown ("./output/api-info.previous.xml", "./output/api-info.xml", "./output/api-diff.md");
}); });
Task ("generate-mapping") Task ("generate-mapping")
.IsDependentOn ("androidxmapper")
.IsDependentOn ("merge") .IsDependentOn ("merge")
.Does (() => .Does (() =>
{ {
@ -254,60 +246,47 @@ Task ("generate-mapping")
DownloadFile (SUPPORT_MERGED_DLL_URL, "./output/AndroidSupport.Merged.dll"); DownloadFile (SUPPORT_MERGED_DLL_URL, "./output/AndroidSupport.Merged.dll");
} }
var result = StartProcess(ANDROIDX_MAPPER_EXE, // generate the mapping
RunProcess("androidx-migrator",
$"generate -v " + $"generate -v " +
$" -s " + MakeAbsolute((FilePath)"./output/AndroidSupport.Merged.dll") + $" --support ./output/AndroidSupport.Merged.dll" +
$" -x " + MakeAbsolute((FilePath)"./output/AndroidX.Merged.dll") + $" --androidx ./output/AndroidX.Merged.dll" +
$" -j " + MakeAbsolute((FilePath)"./util/AndroidXMapper/Resources/androidx-class-mapping.csv") + $" --java ./util/AndroidXMapper/Resources/androidx-class-mapping.csv" +
$" -m " + MakeAbsolute((FilePath)"./util/AndroidXMapper/Resources/override-mapping.csv") + $" --override ./util/AndroidXMapper/Resources/override-mapping.csv" +
$" -o " + MakeAbsolute((FilePath)"./output/androidx-mapping.csv")); $" --output ./output/androidx-mapping.csv");
if (result != 0)
throw new Exception($"The androidxmapper failed with error code {result}.");
}); });
Task ("merge") Task ("merge")
.IsDependentOn ("androidxmapper")
.IsDependentOn ("libs") .IsDependentOn ("libs")
.Does (() => .Does (() =>
{ {
var allDlls = GetFiles ($"./generated/*/bin/{BUILD_CONFIG}/{TF_MONIKER}/Xamarin.*.dll"); // find all the dlls
var allDlls = GetFiles($"./generated/*/bin/{BUILD_CONFIG}/monoandroid*/Xamarin.*.dll");
var mergeDlls = allDlls var mergeDlls = allDlls
.GroupBy(d => new FileInfo(d.FullPath).Name) .GroupBy(d => new FileInfo(d.FullPath).Name)
.Select(g => g.FirstOrDefault()) .Select(g => g.FirstOrDefault())
.ToList(); .ToList();
// merge them all
EnsureDirectoryExists("./output/"); EnsureDirectoryExists("./output/");
var result = StartProcess(ANDROIDX_MAPPER_EXE, RunProcess("androidx-migrator",
$"merge" + $"merge" +
$" -a {string.Join(" -a ", mergeDlls)} " + $" --assembly " + string.Join(" --assembly ", mergeDlls) +
$" -o " + MakeAbsolute((FilePath)"./output/AndroidX.Merged.dll") + $" --output ./output/AndroidX.Merged.dll" +
$" -s \"{MONODROID_PATH}\" " + $" --search \"{XAMARIN_ANDROID_PATH}/{ANDROID_SDK_VERSION}\" " +
$" --inject-assemblyname"); $" --search \"{XAMARIN_ANDROID_PATH}/{ANDROID_SDK_BASE_VERSION}\" " +
if (result != 0) $" --inject-assemblyname");
throw new Exception($"The androidxmapper failed with error code {result}.");
}); });
Task ("ci-setup") Task("inject-variables")
.WithCriteria (!BuildSystem.IsLocalBuild) .WithCriteria(!BuildSystem.IsLocalBuild)
.Does (() => .Does(() =>
{ {
var buildCommit = "DEV";
var buildNumber = "DEBUG";
var buildTimestamp = DateTime.UtcNow.ToString ();
if (BuildSystem.IsRunningOnJenkins) {
buildNumber = BuildSystem.Jenkins.Environment.Build.BuildTag;
buildCommit = EnvironmentVariable("GIT_COMMIT") ?? buildCommit;
} else if (BuildSystem.IsRunningOnVSTS) {
buildNumber = BuildSystem.TFBuild.Environment.Build.Number;
buildCommit = BuildSystem.TFBuild.Environment.Repository.SourceVersion;
}
var glob = "./source/AssemblyInfo.cs"; var glob = "./source/AssemblyInfo.cs";
ReplaceTextInFiles(glob, "{BUILD_COMMIT}", buildCommit); ReplaceTextInFiles(glob, "{BUILD_COMMIT}", BUILD_COMMIT);
ReplaceTextInFiles(glob, "{BUILD_NUMBER}", buildNumber); ReplaceTextInFiles(glob, "{BUILD_NUMBER}", BUILD_NUMBER);
ReplaceTextInFiles(glob, "{BUILD_TIMESTAMP}", buildTimestamp); ReplaceTextInFiles(glob, "{BUILD_TIMESTAMP}", BUILD_TIMESTAMP);
}); });
Task ("clean") Task ("clean")
@ -319,9 +298,6 @@ Task ("clean")
if (DirectoryExists ("./generated")) if (DirectoryExists ("./generated"))
DeleteDirectory ("./generated", true); DeleteDirectory ("./generated", true);
if (DirectoryExists ("./util/binderator"))
DeleteDirectory ("./util/binderator", true);
CleanDirectories ("./**/packages"); CleanDirectories ("./**/packages");
}); });
@ -334,8 +310,17 @@ Task ("full-run")
.IsDependentOn ("nuget") .IsDependentOn ("nuget")
.IsDependentOn ("samples"); .IsDependentOn ("samples");
Task ("Default")
.IsDependentOn ("binderate")
.IsDependentOn ("nuget")
.IsDependentOn ("nuget-validation")
.IsDependentOn ("generate-mapping")
.IsDependentOn ("diff")
.IsDependentOn ("samples");
Task ("ci") Task ("ci")
.IsDependentOn ("ci-setup") .IsDependentOn ("check-tools")
.IsDependentOn ("inject-variables")
.IsDependentOn ("binderate") .IsDependentOn ("binderate")
.IsDependentOn ("nuget") .IsDependentOn ("nuget")
.IsDependentOn ("nuget-validation") .IsDependentOn ("nuget-validation")

Просмотреть файл

@ -25,10 +25,6 @@ Specifies the amount of information to be displayed.
Shows description about tasks. Shows description about tasks.
.PARAMETER DryRun .PARAMETER DryRun
Performs a dry run. Performs a dry run.
.PARAMETER Experimental
Uses the nightly builds of the Roslyn script engine.
.PARAMETER Mono
Uses the Mono Compiler rather than the Roslyn script engine.
.PARAMETER SkipToolPackageRestore .PARAMETER SkipToolPackageRestore
Skips restoring of packages. Skips restoring of packages.
.PARAMETER ScriptArgs .PARAMETER ScriptArgs
@ -49,13 +45,28 @@ Param(
[switch]$ShowDescription, [switch]$ShowDescription,
[Alias("WhatIf", "Noop")] [Alias("WhatIf", "Noop")]
[switch]$DryRun, [switch]$DryRun,
[switch]$Experimental,
[switch]$Mono,
[switch]$SkipToolPackageRestore, [switch]$SkipToolPackageRestore,
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
[string[]]$ScriptArgs [string[]]$ScriptArgs
) )
# Attempt to set highest encryption available for SecurityProtocol.
# PowerShell will not set this by default (until maybe .NET 4.6.x). This
# will typically produce a message for PowerShell v2 (just an info
# message though)
try {
# Set TLS 1.2 (3072), then TLS 1.1 (768), then TLS 1.0 (192), finally SSL 3.0 (48)
# Use integers because the enumeration values for TLS 1.2 and TLS 1.1 won't
# exist in .NET 4.0, even though they are addressable if .NET 4.5+ is
# installed (.NET 4.5 is an in-place upgrade).
# PowerShell Core already has support for TLS 1.2 so we can skip this if running in that.
if (-not $IsCoreCLR) {
[System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192 -bor 48
}
} catch {
Write-Output 'Unable to set PowerShell to use TLS 1.2 and TLS 1.1 due to old .NET Framework installed. If you see underlying connection closed or trust errors, you may need to upgrade to .NET Framework 4.5+ and PowerShell v3'
}
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null [Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
function MD5HashFile([string] $filePath) function MD5HashFile([string] $filePath)
{ {
@ -85,7 +96,7 @@ function GetProxyEnabledWebClient
{ {
$wc = New-Object System.Net.WebClient $wc = New-Object System.Net.WebClient
$proxy = [System.Net.WebRequest]::GetSystemWebProxy() $proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
$wc.Proxy = $proxy $wc.Proxy = $proxy
return $wc return $wc
} }
@ -111,16 +122,17 @@ $CAKE_PACKAGES_CONFIG = Join-Path $PSScriptRoot "cake.packages.config"
# Make sure tools folder exists # Make sure tools folder exists
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
Write-Verbose -Message "Creating tools directory..." Write-Verbose -Message "Creating tools directory..."
New-Item -Path $TOOLS_DIR -Type directory | out-null New-Item -Path $TOOLS_DIR -Type Directory | Out-Null
} }
# Make sure that packages.config exist. # Make sure that packages.config exist.
if (!(Test-Path $PACKAGES_CONFIG)) { if (!(Test-Path $PACKAGES_CONFIG)) {
if (!(Test-Path $CAKE_PACKAGES_CONFIG)) { if (!(Test-Path $CAKE_PACKAGES_CONFIG)) {
Write-Verbose -Message "Downloading packages.config..." Write-Verbose -Message "Downloading packages.config..."
try { try {
$wc = GetProxyEnabledWebClient $wc = GetProxyEnabledWebClient
$wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG)
} catch {
Throw "Could not download packages.config." Throw "Could not download packages.config."
} }
} else { } else {
@ -152,7 +164,12 @@ if (!(Test-Path $NUGET_EXE)) {
} }
# Save nuget.exe path to environment to be available to child processed # Save nuget.exe path to environment to be available to child processed
$ENV:NUGET_EXE = $NUGET_EXE $env:NUGET_EXE = $NUGET_EXE
$env:NUGET_EXE_INVOCATION = if ($IsLinux -or $IsMacOS) {
"mono `"$NUGET_EXE`""
} else {
"`"$NUGET_EXE`""
}
# Restore tools from NuGet? # Restore tools from NuGet?
if(-Not $SkipToolPackageRestore.IsPresent) { if(-Not $SkipToolPackageRestore.IsPresent) {
@ -160,16 +177,16 @@ if(-Not $SkipToolPackageRestore.IsPresent) {
Set-Location $TOOLS_DIR Set-Location $TOOLS_DIR
# Check for changes in packages.config and remove installed tools if true. # Check for changes in packages.config and remove installed tools if true.
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG) [string] $md5Hash = MD5HashFile $PACKAGES_CONFIG
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
Write-Verbose -Message "Missing or changed package.config hash..." Write-Verbose -Message "Missing or changed package.config hash..."
Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery | Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery |
Remove-Item -Recurse Remove-Item -Recurse
} }
Write-Verbose -Message "Restoring tools from NuGet..." Write-Verbose -Message "Restoring tools from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
$NuGetOutput = Invoke-Expression "& $env:NUGET_EXE_INVOCATION install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
Throw "An error occurred while restoring NuGet tools." Throw "An error occurred while restoring NuGet tools."
@ -178,7 +195,7 @@ if(-Not $SkipToolPackageRestore.IsPresent) {
{ {
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
} }
Write-Verbose -Message ($NuGetOutput | out-string) Write-Verbose -Message ($NuGetOutput | Out-String)
Pop-Location Pop-Location
} }
@ -189,13 +206,13 @@ if (Test-Path $ADDINS_PACKAGES_CONFIG) {
Set-Location $ADDINS_DIR Set-Location $ADDINS_DIR
Write-Verbose -Message "Restoring addins from NuGet..." Write-Verbose -Message "Restoring addins from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" $NuGetOutput = Invoke-Expression "& $env:NUGET_EXE_INVOCATION install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`""
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
Throw "An error occurred while restoring NuGet addins." Throw "An error occurred while restoring NuGet addins."
} }
Write-Verbose -Message ($NuGetOutput | out-string) Write-Verbose -Message ($NuGetOutput | Out-String)
Pop-Location Pop-Location
} }
@ -206,13 +223,13 @@ if (Test-Path $MODULES_PACKAGES_CONFIG) {
Set-Location $MODULES_DIR Set-Location $MODULES_DIR
Write-Verbose -Message "Restoring modules from NuGet..." Write-Verbose -Message "Restoring modules from NuGet..."
$NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" $NuGetOutput = Invoke-Expression "& $env:NUGET_EXE_INVOCATION install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`""
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
Throw "An error occurred while restoring NuGet modules." Throw "An error occurred while restoring NuGet modules."
} }
Write-Verbose -Message ($NuGetOutput | out-string) Write-Verbose -Message ($NuGetOutput | Out-String)
Pop-Location Pop-Location
} }
@ -222,6 +239,11 @@ if (!(Test-Path $CAKE_EXE)) {
Throw "Could not find Cake.exe at $CAKE_EXE" Throw "Could not find Cake.exe at $CAKE_EXE"
} }
$CAKE_EXE_INVOCATION = if ($IsLinux -or $IsMacOS) {
"mono `"$CAKE_EXE`""
} else {
"`"$CAKE_EXE`""
}
# Build Cake arguments # Build Cake arguments
@ -231,11 +253,9 @@ if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
if ($ShowDescription) { $cakeArguments += "-showdescription" } if ($ShowDescription) { $cakeArguments += "-showdescription" }
if ($DryRun) { $cakeArguments += "-dryrun" } if ($DryRun) { $cakeArguments += "-dryrun" }
if ($Experimental) { $cakeArguments += "-experimental" }
if ($Mono) { $cakeArguments += "-mono" }
$cakeArguments += $ScriptArgs $cakeArguments += $ScriptArgs
# Start Cake # Start Cake
Write-Host "Running build script..." Write-Host "Running build script..."
&$CAKE_EXE $cakeArguments Invoke-Expression "& $CAKE_EXE_INVOCATION $($cakeArguments -join " ")"
exit $LASTEXITCODE exit $LASTEXITCODE

Просмотреть файл

@ -1,8 +1,15 @@
; The configuration file for Cake. ; This is the default configuration file for Cake.
; This file was downloaded from https://github.com/cake-build/resources
[NuGet] [Nuget]
UseInProcessClient=false Source=https://api.nuget.org/v3/index.json
LoadDependencies=true UseInProcessClient=true
LoadDependencies=false
[Paths]
Tools=./tools
Addins=./tools/Addins
Modules=./tools/Modules
[Settings] [Settings]
SkipVerification=true SkipVerification=false

Просмотреть файл

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Cake" version="0.30.0" /> <package id="Cake" version="0.34.1" />
</packages> </packages>

5
global.json Normal file
Просмотреть файл

@ -0,0 +1,5 @@
{
"sdk": {
"version": "2.2.401"
}
}

Просмотреть файл

@ -1,5 +1,5 @@
@using System.Linq @using System.Linq
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="MSBuild.Sdk.Extras/2.0.31">
<PropertyGroup> <PropertyGroup>
<TargetFramework>MonoAndroid90</TargetFramework> <TargetFramework>MonoAndroid90</TargetFramework>
<IsBindingProject>true</IsBindingProject> <IsBindingProject>true</IsBindingProject>
@ -171,10 +171,4 @@
</ItemGroup> </ItemGroup>
} }
<ItemGroup>
<PackageReference Include="MSBuild.Sdk.Extras" Version="1.4.0" PrivateAssets="All" />
</ItemGroup>
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
</Project> </Project>

288
util/AndroidXMapper/.gitignore поставляемый
Просмотреть файл

@ -1,288 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Microsoft Azure ApplicationInsights config file
ApplicationInsights.config
# Windows Store app package directory
AppPackages/
BundleArtifacts/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
# FAKE - F# Make
.fake/
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate
*.xcscmblueprint
## Obj-C/Swift specific
*.hmap
*.ipa
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
# Pods/
# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts
Carthage/Build
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
fastlane/report.xml
fastlane/screenshots
.vscode/

Просмотреть файл

@ -1,25 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28606.126
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidXMapper", "AndroidXMapper\AndroidXMapper.csproj", "{FC5A597E-B645-4F7A-994B-639787F92FA0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FC5A597E-B645-4F7A-994B-639787F92FA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC5A597E-B645-4F7A-994B-639787F92FA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC5A597E-B645-4F7A-994B-639787F92FA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC5A597E-B645-4F7A-994B-639787F92FA0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6B1166B4-0102-495F-B720-E755FA917EC8}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net47</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ILRepack.Lib" Version="2.0.16" />
<PackageReference Include="Mono.Cecil" Version="0.10.3" />
<PackageReference Include="Mono.Options" Version="5.3.0.1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,185 +0,0 @@
using ILRepacking;
using Mono.Cecil;
using Mono.Cecil.Cil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace AndroidXMapper
{
public class AssemblyMerger
{
private const string InjectedAttributeNamespace = "Xamarin.AndroidX.Internal";
private const string InjectedAttributeTypeName = "InjectedAssemblyNameAttribute";
public AssemblyMerger(List<string> assemblies, List<string> searchDirectories, bool injectAssemblyNames)
{
Assemblies = assemblies ?? throw new ArgumentNullException(nameof(assemblies));
SearchDirectories = searchDirectories ?? new List<string>();
InjectAssemblyNames = injectAssemblyNames;
}
public List<string> Assemblies { get; }
public List<string> SearchDirectories { get; }
public bool InjectAssemblyNames { get; }
public void Merge(string outputPath)
{
var assemblies = Assemblies;
if (Program.Verbose)
{
Console.WriteLine("Merging:");
foreach (var include in assemblies)
Console.WriteLine($" - {include}");
}
var tempRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
if (InjectAssemblyNames)
{
assemblies = assemblies.ToList();
if (!Directory.Exists(tempRoot))
Directory.CreateDirectory(tempRoot);
for (int i = 0; i < assemblies.Count; i++)
{
var ass = assemblies[i];
var temp = Path.Combine(tempRoot, Guid.NewGuid().ToString() + ".dll");
InjectAssemblyName(ass, temp);
assemblies[i] = temp;
}
if (Program.Verbose)
{
Console.WriteLine("Temporary assemblies:");
foreach (var include in assemblies)
Console.WriteLine($" - {include}");
}
}
var options = new RepackOptions
{
InputAssemblies = assemblies.ToArray(),
OutputFile = outputPath,
SearchDirectories = SearchDirectories.ToArray(),
CopyAttributes = true,
AllowMultipleAssemblyLevelAttributes = true,
LogVerbose = Program.Verbose
};
var repacker = new ILRepack(options);
repacker.Repack();
if (InjectAssemblyNames)
{
MergeAssemblyNameAttributes(outputPath);
if (Directory.Exists(tempRoot))
Directory.Delete(tempRoot, true);
}
}
private void InjectAssemblyName(string assemblyPath, string outputPath)
{
var assemblyName = Path.GetFileNameWithoutExtension(assemblyPath);
using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath))
{
var module = assembly.MainModule;
var mscorlibName = module.AssemblyReferences.FirstOrDefault(a => a.Name == "mscorlib");
var mscorlib = module.AssemblyResolver.Resolve(mscorlibName);
var attributeType = mscorlib.MainModule.GetType("System.Attribute");
var baseCtor = attributeType.Methods.FirstOrDefault(m => m.Name == ".ctor");
var iana = new TypeDefinition(InjectedAttributeNamespace, InjectedAttributeTypeName, TypeAttributes.Class);
iana.BaseType = module.ImportReference(attributeType);
var field = new FieldDefinition("assemblyName", FieldAttributes.Private | FieldAttributes.InitOnly, module.TypeSystem.String);
var getterAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName;
var getter = new MethodDefinition("get_AssemblyName", getterAttributes, module.TypeSystem.String);
getter.DeclaringType = iana;
getter.HasThis = true;
getter.IsGetter = true;
getter.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
getter.Body.Instructions.Add(Instruction.Create(OpCodes.Ldfld, field));
getter.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
var property = new PropertyDefinition("AssemblyName", PropertyAttributes.None, module.TypeSystem.String);
property.HasThis = true;
property.GetMethod = getter;
var methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
var ctor = new MethodDefinition(".ctor", methodAttributes, module.TypeSystem.Void);
var param = new ParameterDefinition("assemblyName", ParameterAttributes.None, module.TypeSystem.String);
ctor.Parameters.Add(param);
ctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
ctor.Body.Instructions.Add(Instruction.Create(OpCodes.Call, module.ImportReference(baseCtor)));
ctor.Body.Instructions.Add(Instruction.Create(OpCodes.Nop));
ctor.Body.Instructions.Add(Instruction.Create(OpCodes.Nop));
ctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
ctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_1));
ctor.Body.Instructions.Add(Instruction.Create(OpCodes.Stfld, field));
ctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
iana.Fields.Add(field);
iana.Properties.Add(property);
iana.Methods.Add(ctor);
iana.Methods.Add(getter);
module.Types.Add(iana);
foreach (var type in module.Types)
{
type.CustomAttributes.Add(new CustomAttribute(ctor)
{
ConstructorArguments = { new CustomAttributeArgument(module.TypeSystem.String, assemblyName) }
});
}
assembly.Write(outputPath);
}
}
private void MergeAssemblyNameAttributes(string assemblyPath)
{
using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { ReadWrite = true }))
{
var correct = assembly.MainModule.GetType(InjectedAttributeNamespace + "." + InjectedAttributeTypeName);
correct.Attributes |= TypeAttributes.Public;
correct.CustomAttributes.Clear();
foreach (var type in assembly.MainModule.Types.ToArray())
{
var attribute = type.CustomAttributes.FirstOrDefault(a => IsRandomType(a.AttributeType));
if (attribute != null && attribute.Constructor.DeclaringType != correct)
{
type.CustomAttributes.Add(new CustomAttribute(correct.Methods[0])
{
ConstructorArguments = { attribute.ConstructorArguments[0] }
});
type.CustomAttributes.Remove(attribute);
}
}
foreach (var type in assembly.MainModule.Types.Where(IsRandomType).ToArray())
{
assembly.MainModule.Types.Remove(type);
}
assembly.Write();
}
bool IsRandomType(TypeReference attr)
{
return
attr.Namespace == InjectedAttributeNamespace &&
attr.Name.EndsWith(InjectedAttributeTypeName) &&
attr.Name != InjectedAttributeTypeName;
}
}
}
}

Просмотреть файл

@ -1,41 +0,0 @@
using System.Collections.Generic;
namespace AndroidXMapper
{
public struct BindingType
{
public static BindingType Empty = new BindingType(FullType.Empty, FullType.Empty);
public FullType NetType;
public FullType JavaType;
public BindingType(FullType netType, FullType javaType)
{
NetType = netType;
JavaType = javaType;
}
public override bool Equals(object obj) =>
obj is BindingType other &&
EqualityComparer<FullType>.Default.Equals(NetType, other.NetType) &&
EqualityComparer<FullType>.Default.Equals(JavaType, other.JavaType);
public override int GetHashCode() =>
(NetType, JavaType).GetHashCode();
public override string ToString() =>
$"{NetType} ({JavaType})";
public void Deconstruct(out FullType netType, out FullType javaType)
{
netType = NetType;
javaType = JavaType;
}
public static implicit operator (FullType NetType, FullType JavaType) (BindingType value) =>
(value.NetType, value.JavaType);
public static implicit operator BindingType((FullType NetType, FullType JavaType) value) =>
new BindingType(value.NetType, value.JavaType);
}
}

Просмотреть файл

@ -1,53 +0,0 @@
namespace AndroidXMapper
{
public struct FullType
{
public static FullType Empty = new FullType(string.Empty, string.Empty, string.Empty);
public string Container;
public string Namespace;
public string Name;
public FullType(string ns, string n)
{
Container = string.Empty;
Namespace = ns;
Name = n;
}
public FullType(string container, string ns, string n)
{
Container = container;
Namespace = ns;
Name = n;
}
public string FullName =>
$"{Namespace}.{Name}";
public bool IsEmpty =>
string.IsNullOrEmpty(Namespace) || string.IsNullOrEmpty(Name);
public override bool Equals(object obj) =>
obj is FullType other && Container == other.Container && Namespace == other.Namespace && Name == other.Name;
public override int GetHashCode() =>
(Container, Namespace, Name).GetHashCode();
public override string ToString() =>
FullName;
public void Deconstruct(out string c, out string ns, out string n)
{
c = Container;
ns = Namespace;
n = Name;
}
public static implicit operator (string Container, string Namespace, string Name) (FullType value) =>
(value.Container, value.Namespace, value.Name);
public static implicit operator FullType((string Container, string Namespace, string Name) value) =>
new FullType(value.Container, value.Namespace, value.Name);
}
}

Просмотреть файл

@ -1,141 +0,0 @@
using Mono.Options;
using System;
using System.Collections.Generic;
using System.IO;
namespace AndroidXMapper
{
public class GenerateCommand : Command
{
public GenerateCommand()
: base("generate", "Generates the mapping file.")
{
Options = new OptionSet
{
$"usage: {Program.Name} {Name} [OPTIONS]",
"",
Help,
"",
{ "s|support=", "The path to the merged Android.Support assembly", v => AndroidSupportAssembly = v },
{ "x|androidx=", "The path to the merged AndroidX assembly", v => AndroidXAssembly = v },
{ "j|java=", "The path to the Java mapping csv", v => JavaTypeMapping = v },
{ "m|override=", "The path to the mapping overides csv", v => OverrideMapping = v },
{ "o|output=", "The output path to use for the generated mapping", v => SetOutputPath(v) },
{ "exclude-warnings", "Include warnings in the output", v => ExcludeWarnings = v != null },
{ "?|h|help", "Show this message and exit", _ => ShowHelp = true },
};
}
private void SetOutputPath(string path)
{
if (string.IsNullOrWhiteSpace(path))
return;
if (path.EndsWith("/") || path.EndsWith("\\"))
path += "androidx-mapping.csv";
var dir = Path.GetDirectoryName(path);
if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(dir))
Directory.CreateDirectory(dir);
OutputPath = path;
}
public bool ShowHelp { get; private set; }
public bool ExcludeWarnings { get; private set; }
public string AndroidSupportAssembly { get; private set; }
public string AndroidXAssembly { get; private set; }
public string JavaTypeMapping { get; private set; }
public string OverrideMapping { get; private set; }
public string OutputPath { get; private set; }
public override int Invoke(IEnumerable<string> args)
{
StreamWriter writer = null;
try
{
var extra = Options.Parse(args);
if (ShowHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
if (!ValidateArguments())
return 1;
var outputWriter = string.IsNullOrWhiteSpace(OutputPath)
? Console.Out
: (writer = new StreamWriter(OutputPath));
var generator = new MappingGenerator(AndroidSupportAssembly, AndroidXAssembly, OverrideMapping, JavaTypeMapping);
generator.Generate(outputWriter, !ExcludeWarnings);
return 0;
}
catch (Exception ex)
{
Console.Error.WriteLine($"{Program.Name}: An error occurred: `{ex.Message}`.");
if (Program.Verbose)
Console.Error.WriteLine(ex);
return 1;
}
finally
{
writer?.Dispose();
}
}
private bool ValidateArguments()
{
var hasError = false;
if (string.IsNullOrEmpty(AndroidSupportAssembly))
{
Console.Error.WriteLine($"{Program.Name}: Missing required argument `--support=PATH`.");
hasError = true;
}
else if (!File.Exists(AndroidSupportAssembly))
{
Console.Error.WriteLine($"{Program.Name}: File does not exist: `{AndroidSupportAssembly}`.");
hasError = true;
}
if (string.IsNullOrEmpty(AndroidXAssembly))
{
Console.Error.WriteLine($"{Program.Name}: Missing required argument `--androidx=PATH`.");
hasError = true;
}
else if (!File.Exists(AndroidXAssembly))
{
Console.Error.WriteLine($"{Program.Name}: File does not exist: `{AndroidXAssembly}`.");
hasError = true;
}
if (!string.IsNullOrEmpty(JavaTypeMapping) && !File.Exists(JavaTypeMapping))
{
Console.Error.WriteLine($"{Program.Name}: File does not exist: `{JavaTypeMapping}`.");
hasError = true;
}
if (!string.IsNullOrEmpty(OverrideMapping) && !File.Exists(OverrideMapping))
{
Console.Error.WriteLine($"{Program.Name}: File does not exist: `{OverrideMapping}`.");
hasError = true;
}
if (hasError)
Console.Error.WriteLine($"{Program.Name}: Use `{Program.Name} help {Name}` for details.");
return !hasError;
}
}
}

Просмотреть файл

@ -1,317 +0,0 @@
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace AndroidXMapper
{
public class MappingGenerator
{
private readonly List<TypeMapping> typeMappings = new List<TypeMapping>();
public string SupportAssemblyPath { get; }
public string AndroidXAssemblyPath { get; }
public string OverridesPath { get; }
public string JavaMappingPath { get; }
public MappingGenerator(string supportAssemblyPath, string androidXAssemblyPath, string overridesPath, string javaMappingPath)
{
SupportAssemblyPath = supportAssemblyPath ?? throw new ArgumentNullException(nameof(supportAssemblyPath));
AndroidXAssemblyPath = androidXAssemblyPath ?? throw new ArgumentNullException(nameof(androidXAssemblyPath));
OverridesPath = overridesPath;
JavaMappingPath = javaMappingPath;
}
public void Generate(TextWriter writer, bool includeWarnings)
{
// load all the types and mappings
var supportTypes = GetAllTypes(SupportAssemblyPath);
var xTypes = GetAllTypes(AndroidXAssemblyPath);
var overrideMappings = LoadMapping(OverridesPath);
var javaMappings = LoadMapping(JavaMappingPath);
WriteRecord(
writer,
new BindingType(
new FullType("Support .NET assembly", "Support .NET namespace", "Support .NET type name"),
new FullType("Support Java package", "Support Java class")),
new BindingType(
new FullType("AndroidX .NET assembly", "AndroidX .NET namespace", "AndroidX .NET type name"),
new FullType("AndroidX Java package", "AndroidX Java class")),
"Messages");
// PART A: Go through all the types in the Support assembly and
// try and find a matching AndroidX type.
foreach (var supportType in supportTypes)
{
var useJavaType = !supportType.JavaType.IsEmpty && javaMappings.Count > 0;
if (TryGetMapping(overrideMappings, supportType.NetType, out var overrideType))
{
// 1. First check the specific/manual overrides provided.
var matched = xTypes.Where(t => t.NetType.FullName == overrideType).ToList();
if (matched.Count == 0)
{
if (includeWarnings)
WriteRecord(writer, $"WARNING: Unable to find override type for type {overrideType}.");
}
else
{
foreach (var m in matched)
{
typeMappings.Add(new TypeMapping(supportType, m));
WriteRecord(writer, supportType, m);
}
}
}
else if (TryGetExactMatch(xTypes, supportType, out var exactMatch))
{
// 2. Then, check to see if there is an exact match for the
// full name of the .NET or Java type.
typeMappings.Add(new TypeMapping(supportType, exactMatch));
WriteRecord(writer, supportType, exactMatch);
}
else if (useJavaType && TryGetMapping(javaMappings, supportType.JavaType, out var androidx))
{
// 3. If not, then do a look up based on the Java types.
var matched = xTypes.Where(t => t.JavaType.FullName == androidx).ToList();
// a special case for the XxxConsts types
const string ConstsSuffix = "Consts";
if (matched.Count == 2 && matched.Any(m => m.NetType.Name.EndsWith(ConstsSuffix)))
{
matched.RemoveAll(m => m.NetType.Name.EndsWith(ConstsSuffix) != supportType.NetType.Name.EndsWith(ConstsSuffix));
}
if (matched.Count == 0)
{
if (includeWarnings)
WriteRecord(writer, $"WARNING: Unable to find AndroidX type for Java type {androidx}.");
}
else
{
// if we have an exact name match, then use that
var exact = matched.Where(m => m.NetType.Name == supportType.NetType.Name).ToList();
if (exact.Count == 1)
matched = exact;
foreach (var m in matched)
{
typeMappings.Add(new TypeMapping(supportType, m));
WriteRecord(writer, supportType, m);
}
}
}
else
{
// 4. As a last resort, use the .NET class name and try
// and find a match using just the name.
var matched = xTypes.Where(xt => xt.NetType.Name == supportType.NetType.Name).ToList();
if (matched.Count == 0)
{
if (includeWarnings)
WriteRecord(writer, $"WARNING: Unable to find AndroidX type for .NET type {supportType.NetType}.");
}
else
{
foreach (var m in matched)
{
var msg = string.Empty;
if (includeWarnings && useJavaType)
{
msg = $"WARNING: Unable to find a Java mapping, so took a guess.";
if (matched.Count > 1)
msg += $" Found more than 1 item: " + string.Join(", ", matched);
}
typeMappings.Add(new TypeMapping(supportType, m));
WriteRecord(writer, supportType, m, msg);
}
}
}
}
// PART B: Make sure all the Java mappings exist in the final CSV.
foreach (var mapping in javaMappings.Skip(1))
{
var mapped = typeMappings.FirstOrDefault(k => k.SupportType.JavaType.FullName == mapping.Key);
if (!mapped.SupportType.JavaType.IsEmpty)
continue;
WriteRecord(
writer,
new BindingType(FullType.Empty, GetJavaFullType(mapping.Key)),
new BindingType(FullType.Empty, GetJavaFullType(mapping.Value)),
$"WARNING: No .NET types found.");
}
}
private static FullType GetJavaFullType(string javaFullName)
{
for (var i = 1; i < javaFullName.Length; i++)
{
if (char.IsUpper(javaFullName, i) && javaFullName[i - 1] == '.')
return new FullType(
javaFullName.Substring(0, i - 1),
javaFullName.Substring(i));
}
return FullType.Empty;
}
private static void WriteRecord(TextWriter writer, string message) =>
WriteRecord(writer, BindingType.Empty, BindingType.Empty, message);
private static void WriteRecord(TextWriter writer, BindingType supportType, BindingType androidXType, string message = "")
{
writer.WriteLine(
$"{supportType.NetType.Namespace}," +
$"{supportType.NetType.Name}," +
$"{androidXType.NetType.Namespace}," +
$"{androidXType.NetType.Name}," +
$"{supportType.NetType.Container}," +
$"{androidXType.NetType.Container}," +
$"{supportType.JavaType.Namespace}," +
$"{supportType.JavaType.Name}," +
$"{androidXType.JavaType.Namespace}," +
$"{androidXType.JavaType.Name}," +
message);
}
private bool TryGetExactMatch(IEnumerable<BindingType> xTypes, BindingType supportType, out BindingType exactMatch)
{
var netMatches = xTypes.Where(t => t.NetType.FullName == supportType.NetType.FullName).ToList();
if (netMatches.Count == 1)
{
exactMatch = netMatches[0];
return true;
}
var javaMatches = xTypes.Where(t => t.JavaType.FullName == supportType.JavaType.FullName).ToList();
if (javaMatches.Count == 1)
{
exactMatch = javaMatches[0];
return true;
}
exactMatch = BindingType.Empty;
return false;
}
private bool TryGetMapping(Dictionary<string, string> mappings, FullType type, out string androidx)
{
if (mappings.TryGetValue(type.FullName, out androidx))
return true;
string nested = "";
while (type.Name.Contains("."))
{
nested = type.Name.Substring(type.Name.LastIndexOf(".")) + nested;
type.Name = type.Name.Substring(0, type.Name.LastIndexOf("."));
if (mappings.TryGetValue(type.FullName, out androidx))
{
androidx += nested;
return true;
}
}
return false;
}
private Dictionary<string, string> LoadMapping(string mapping)
{
var dic = new Dictionary<string, string>();
if (!string.IsNullOrWhiteSpace(mapping) && File.Exists(mapping))
{
var lines = File.ReadAllLines(mapping);
foreach (var line in lines)
{
var parts = line.Split(',');
dic.Add(parts[0], parts[1]);
}
}
return dic;
}
private List<BindingType> GetAllTypes(string assemblyPath)
{
if (string.IsNullOrWhiteSpace(assemblyPath))
throw new ArgumentException($"Invalid assembly path: {assemblyPath}", nameof(assemblyPath));
if (!File.Exists(assemblyPath))
throw new FileNotFoundException($"The assembly does not exist: {assemblyPath}");
using (var assembly = AssemblyDefinition.ReadAssembly(assemblyPath))
{
var types = assembly.MainModule.GetTypes();
return types.Where(IsValidType).Select(GetFullType).ToList();
}
}
private bool IsValidType(TypeDefinition typeDefinition)
{
if (typeDefinition.Namespace == "Java.Interop" && typeDefinition.Name.EndsWith("__TypeRegistrations"))
return false;
if (typeDefinition.Name == "<Module>" || typeDefinition.Name.StartsWith("<>c__DisplayClass"))
return false;
return true;
}
private BindingType GetFullType(TypeDefinition typeDefinition)
{
var assembly = GetAttributeValue(typeDefinition, "Xamarin.AndroidX.Internal.InjectedAssemblyNameAttribute");
var ns = typeDefinition.Namespace;
var name = typeDefinition.Name;
var java = GetJavaType(typeDefinition);
var parent = typeDefinition.DeclaringType;
while (parent != null)
{
assembly = GetAttributeValue(parent, "Xamarin.AndroidX.Internal.InjectedAssemblyNameAttribute");
ns = parent.Namespace;
name = parent.Name + "." + name;
parent = parent.DeclaringType;
}
return new BindingType(new FullType(assembly, ns, name), java);
}
private static string GetAttributeValue(TypeDefinition typeDefinition, string attributeType, int index = 0)
{
var attribute = typeDefinition
?.CustomAttributes
?.FirstOrDefault(a => a.AttributeType.FullName == attributeType);
var value = attribute
?.ConstructorArguments
?.Skip(index)
?.FirstOrDefault()
.Value as string ?? string.Empty;
return value;
}
private FullType GetJavaType(TypeDefinition typeDefinition)
{
var javaType = GetAttributeValue(typeDefinition, "Android.Runtime.RegisterAttribute");
var parts = javaType?.Split('/');
var type = parts?.LastOrDefault()?.Split('$');
if (parts?.Length > 0 && type?.Length > 0)
return new FullType(string.Join(".", parts.Take(parts.Length - 1)), string.Join(".", type));
else
return FullType.Empty;
}
}
}

Просмотреть файл

@ -1,113 +0,0 @@
using Mono.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace AndroidXMapper
{
public class MergeCommand : Command
{
public MergeCommand()
: base("merge", "Merges the various AndroidX libraries.")
{
Options = new OptionSet
{
$"usage: {Program.Name} {Name} [OPTIONS]",
"",
Help,
"",
{ "a|assembly=", "One or more assemblies to merge", v => Assemblies.Add(v) },
{ "o|output=", "The output path to use for the merged assembly", v => SetOutputPath(v) },
{ "s|search=", "One or more search directories", v => SearchDirectories.Add(v) },
{ "inject-assemblyname", "Add the assembly names to the types", _ => InjectAssemblyNames = true },
{ "?|h|help", "Show this message and exit", _ => ShowHelp = true },
};
}
private void SetOutputPath(string path)
{
if (string.IsNullOrWhiteSpace(path))
return;
if (path.EndsWith("/") || path.EndsWith("\\"))
path += "AndroidX.Merged.dll";
var dir = Path.GetDirectoryName(path);
if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(dir))
Directory.CreateDirectory(dir);
OutputPath = path;
}
public bool ShowHelp { get; private set; }
public List<string> Assemblies { get; } = new List<string>();
public string OutputPath { get; private set; }
public List<string> SearchDirectories { get; } = new List<string>();
public bool InjectAssemblyNames { get; private set; }
public override int Invoke(IEnumerable<string> args)
{
try
{
var extra = Options.Parse(args);
if (ShowHelp)
{
Options.WriteOptionDescriptions(CommandSet.Out);
return 0;
}
if (!ValidateArguments())
return 1;
var merger = new AssemblyMerger(Assemblies, SearchDirectories, InjectAssemblyNames);
merger.Merge(OutputPath);
return 0;
}
catch (Exception ex)
{
Console.Error.WriteLine($"{Program.Name}: An error occurred: `{ex.Message}`.");
if (Program.Verbose)
Console.Error.WriteLine(ex);
return 1;
}
}
private bool ValidateArguments()
{
var hasError = false;
if (string.IsNullOrWhiteSpace(OutputPath))
{
Console.Error.WriteLine($"{Program.Name}: An output path is required `--output=PATH`.");
hasError = true;
}
if (Assemblies.Count == 0)
{
Console.Error.WriteLine($"{Program.Name}: At least one assembly is required `--assembly=PATH`.");
hasError = true;
}
var missing = Assemblies.Where(i => !File.Exists(i));
if (missing.Any())
{
foreach (var file in missing)
Console.Error.WriteLine($"{Program.Name}: File does not exist: `{file}`.");
hasError = true;
}
if (hasError)
Console.Error.WriteLine($"{Program.Name}: Use `{Program.Name} help {Name}` for details.");
return !hasError;
}
}
}

Просмотреть файл

@ -1,29 +0,0 @@
using Mono.Options;
namespace AndroidXMapper
{
public class Program
{
public const string Name = "androidxmapper";
public static bool Verbose;
static int Main(string[] args)
{
var commands = new CommandSet(Name)
{
$"usage: {Name} COMMAND [OPTIONS]",
"",
"A utility that helps create the Android.Support to AndroidX mapping file.",
"",
"Global options:",
{ "v|verbose", "Use a more verbose output", _ => Verbose = true },
"",
"Available commands:",
new GenerateCommand(),
new MergeCommand(),
};
return commands.Run(args);
}
}
}

Просмотреть файл

@ -1,39 +0,0 @@
using System.Collections.Generic;
namespace AndroidXMapper
{
public struct TypeMapping
{
public BindingType SupportType;
public BindingType AndroidXType;
public TypeMapping(BindingType supportType, BindingType androidXType)
{
SupportType = supportType;
AndroidXType = androidXType;
}
public override bool Equals(object obj) =>
obj is TypeMapping other &&
EqualityComparer<BindingType>.Default.Equals(SupportType, other.SupportType) &&
EqualityComparer<BindingType>.Default.Equals(AndroidXType, other.AndroidXType);
public override int GetHashCode() =>
(SupportType, AndroidXType).GetHashCode();
public override string ToString() =>
$"{SupportType} => {AndroidXType}";
public void Deconstruct(out BindingType supportType, out BindingType androidXType)
{
supportType = SupportType;
androidXType = AndroidXType;
}
public static implicit operator (BindingType SupportType, BindingType AndroidXType) (TypeMapping value) =>
(value.SupportType, value.AndroidXType);
public static implicit operator TypeMapping((BindingType SupportType, BindingType AndroidXType) value) =>
new TypeMapping(value.SupportType, value.AndroidXType);
}
}

Просмотреть файл

@ -1,104 +0,0 @@
Old build artifact,AndroidX build artifact
android.arch.core:common,androidx.arch.core:core-common:2.0.0-rc01
android.arch.core:core,androidx.arch.core:core:2.0.0-rc01
android.arch.core:core-testing,androidx.arch.core:core-testing:2.0.0-rc01
android.arch.core:runtime,androidx.arch.core:core-runtime:2.0.0-rc01
android.arch.lifecycle:common,androidx.lifecycle:lifecycle-common:2.0.0-rc01
android.arch.lifecycle:common-java8,androidx.lifecycle:lifecycle-common-java8:2.0.0-rc01
android.arch.lifecycle:compiler,androidx.lifecycle:lifecycle-compiler:2.0.0-rc01
android.arch.lifecycle:extensions,androidx.lifecycle:lifecycle-extensions:2.0.0-rc01
android.arch.lifecycle:livedata,androidx.lifecycle:lifecycle-livedata:2.0.0-rc01
android.arch.lifecycle:livedata-core,androidx.lifecycle:lifecycle-livedata-core:2.0.0-rc01
android.arch.lifecycle:reactivestreams,androidx.lifecycle:lifecycle-reactivestreams:2.0.0-rc01
android.arch.lifecycle:runtime,androidx.lifecycle:lifecycle-runtime:2.0.0-rc01
android.arch.lifecycle:viewmodel,androidx.lifecycle:lifecycle-viewmodel:2.0.0-rc01
android.arch.paging:common,androidx.paging:paging-common:2.0.0-rc01
android.arch.paging:runtime,androidx.paging:paging-runtime:2.0.0-rc01
android.arch.paging:rxjava2,androidx.paging:paging-rxjava2:2.0.0-rc01
android.arch.persistence.room:common,androidx.room:room-common:2.0.0-rc01
android.arch.persistence.room:compiler,androidx.room:room-compiler:2.0.0-rc01
android.arch.persistence.room:guava,androidx.room:room-guava:2.0.0-rc01
android.arch.persistence.room:migration,androidx.room:room-migration:2.0.0-rc01
android.arch.persistence.room:runtime,androidx.room:room-runtime:2.0.0-rc01
android.arch.persistence.room:rxjava2,androidx.room:room-rxjava2:2.0.0-rc01
android.arch.persistence.room:testing,androidx.room:room-testing:2.0.0-rc01
android.arch.persistence:db,androidx.sqlite:sqlite:2.0.0-rc01
android.arch.persistence:db-framework,androidx.sqlite:sqlite-framework:2.0.0-rc01
com.android.support.constraint:constraint-layout,androidx.constraintlayout:constraintlayout:1.1.2
com.android.support.constraint:constraint-layout-solver,androidx.constraintlayout:constraintlayout-solver:1.1.2
com.android.support.test.espresso.idling:idling-concurrent,androidx.test.espresso.idling:idling-concurrent:3.1.0
com.android.support.test.espresso.idling:idling-net,androidx.test.espresso.idling:idling-net:3.1.0
com.android.support.test.espresso:espresso-accessibility,androidx.test.espresso:espresso-accessibility:3.1.0
com.android.support.test.espresso:espresso-contrib,androidx.test.espresso:espresso-contrib:3.1.0
com.android.support.test.espresso:espresso-core,androidx.test.espresso:espresso-core:3.1.0
com.android.support.test.espresso:espresso-idling-resource,androidx.test.espresso:espresso-idling-resource:3.1.0
com.android.support.test.espresso:espresso-intents,androidx.test.espresso:espresso-intents:3.1.0
com.android.support.test.espresso:espresso-remote,androidx.test.espresso:espresso-remote:3.1.0
com.android.support.test.espresso:espresso-web,androidx.test.espresso:espresso-web:3.1.0
com.android.support.test.janktesthelper:janktesthelper,androidx.test.jank:janktesthelper:1.0.1
com.android.support.test.services:test-services,androidx.test:test-services:1.1.0
com.android.support.test.uiautomator:uiautomator,androidx.test.uiautomator:uiautomator:2.2.0
com.android.support.test:monitor,androidx.test:monitor:1.1.0
com.android.support.test:orchestrator,androidx.test:orchestrator:1.1.0
com.android.support.test:rules,androidx.test:rules:1.1.0
com.android.support.test:runner,androidx.test:runner:1.1.0
com.android.support:animated-vector-drawable,androidx.vectordrawable:vectordrawable-animated:1.0.0
com.android.support:appcompat-v7,androidx.appcompat:appcompat:1.0.0
com.android.support:asynclayoutinflater,androidx.asynclayoutinflater:asynclayoutinflater:1.0.0
com.android.support:car,androidx.car:car:1.0.0-alpha5
com.android.support:cardview-v7,androidx.cardview:cardview:1.0.0
com.android.support:collections,androidx.collection:collection:1.0.0
com.android.support:coordinatorlayout,androidx.coordinatorlayout:coordinatorlayout:1.0.0
com.android.support:cursoradapter,androidx.cursoradapter:cursoradapter:1.0.0
com.android.support:customtabs,androidx.browser:browser:1.0.0
com.android.support:customview,androidx.customview:customview:1.0.0
com.android.support:design,com.google.android.material:material:1.0.0-rc01
com.android.support:documentfile,androidx.documentfile:documentfile:1.0.0
com.android.support:drawerlayout,androidx.drawerlayout:drawerlayout:1.0.0
com.android.support:exifinterface,androidx.exifinterface:exifinterface:1.0.0
com.android.support:gridlayout-v7,androidx.gridlayout:gridlayout:1.0.0
com.android.support:heifwriter,androidx.heifwriter:heifwriter:1.0.0
com.android.support:interpolator,androidx.interpolator:interpolator:1.0.0
com.android.support:leanback-v17,androidx.leanback:leanback:1.0.0
com.android.support:loader,androidx.loader:loader:1.0.0
com.android.support:localbroadcastmanager,androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
com.android.support:media2,androidx.media2:media2:1.0.0-alpha03
com.android.support:media2-exoplayer,androidx.media2:media2-exoplayer:1.0.0-alpha01
com.android.support:mediarouter-v7,androidx.mediarouter:mediarouter:1.0.0
com.android.support:multidex,androidx.multidex:multidex:2.0.0
com.android.support:multidex-instrumentation,androidx.multidex:multidex-instrumentation:2.0.0
com.android.support:palette-v7,androidx.palette:palette:1.0.0
com.android.support:percent,androidx.percentlayout:percentlayout:1.0.0
com.android.support:preference-leanback-v17,androidx.leanback:leanback-preference:1.0.0
com.android.support:preference-v14,androidx.legacy:legacy-preference-v14:1.0.0
com.android.support:preference-v7,androidx.preference:preference:1.0.0
com.android.support:print,androidx.print:print:1.0.0
com.android.support:recommendation,androidx.recommendation:recommendation:1.0.0
com.android.support:recyclerview-selection,androidx.recyclerview:recyclerview-selection:1.0.0
com.android.support:recyclerview-v7,androidx.recyclerview:recyclerview:1.0.0
com.android.support:slices-builders,androidx.slice:slice-builders:1.0.0
com.android.support:slices-core,androidx.slice:slice-core:1.0.0
com.android.support:slices-view,androidx.slice:slice-view:1.0.0
com.android.support:slidingpanelayout,androidx.slidingpanelayout:slidingpanelayout:1.0.0
com.android.support:support-annotations,androidx.annotation:annotation:1.0.0
com.android.support:support-compat,androidx.core:core:1.0.0
com.android.support:support-content,androidx.contentpager:contentpager:1.0.0
com.android.support:support-core-ui,androidx.legacy:legacy-support-core-ui:1.0.0
com.android.support:support-core-utils,androidx.legacy:legacy-support-core-utils:1.0.0
com.android.support:support-dynamic-animation,androidx.dynamicanimation:dynamicanimation:1.0.0
com.android.support:support-emoji,androidx.emoji:emoji:1.0.0
com.android.support:support-emoji-appcompat,androidx.emoji:emoji-appcompat:1.0.0
com.android.support:support-emoji-bundled,androidx.emoji:emoji-bundled:1.0.0
com.android.support:support-fragment,androidx.fragment:fragment:1.0.0
com.android.support:support-media-compat,androidx.media:media:1.0.0
com.android.support:support-tv-provider,androidx.tvprovider:tvprovider:1.0.0
com.android.support:support-v13,androidx.legacy:legacy-support-v13:1.0.0
com.android.support:support-v4,androidx.legacy:legacy-support-v4:1.0.0
com.android.support:support-vector-drawable,androidx.vectordrawable:vectordrawable:1.0.0
com.android.support:swiperefreshlayout,androidx.swiperefreshlayout:swiperefreshlayout:1.0.0
com.android.support:textclassifier,androidx.textclassifier:textclassifier:1.0.0
com.android.support:transition,androidx.transition:transition:1.0.0
com.android.support:versionedparcelable,androidx.versionedparcelable:versionedparcelable:1.0.0
com.android.support:viewpager,androidx.viewpager:viewpager:1.0.0
com.android.support:wear,androidx.wear:wear:1.0.0
com.android.support:webkit,androidx.webkit:webkit:1.0.0
1 Old build artifact AndroidX build artifact
2 android.arch.core:common androidx.arch.core:core-common:2.0.0-rc01
3 android.arch.core:core androidx.arch.core:core:2.0.0-rc01
4 android.arch.core:core-testing androidx.arch.core:core-testing:2.0.0-rc01
5 android.arch.core:runtime androidx.arch.core:core-runtime:2.0.0-rc01
6 android.arch.lifecycle:common androidx.lifecycle:lifecycle-common:2.0.0-rc01
7 android.arch.lifecycle:common-java8 androidx.lifecycle:lifecycle-common-java8:2.0.0-rc01
8 android.arch.lifecycle:compiler androidx.lifecycle:lifecycle-compiler:2.0.0-rc01
9 android.arch.lifecycle:extensions androidx.lifecycle:lifecycle-extensions:2.0.0-rc01
10 android.arch.lifecycle:livedata androidx.lifecycle:lifecycle-livedata:2.0.0-rc01
11 android.arch.lifecycle:livedata-core androidx.lifecycle:lifecycle-livedata-core:2.0.0-rc01
12 android.arch.lifecycle:reactivestreams androidx.lifecycle:lifecycle-reactivestreams:2.0.0-rc01
13 android.arch.lifecycle:runtime androidx.lifecycle:lifecycle-runtime:2.0.0-rc01
14 android.arch.lifecycle:viewmodel androidx.lifecycle:lifecycle-viewmodel:2.0.0-rc01
15 android.arch.paging:common androidx.paging:paging-common:2.0.0-rc01
16 android.arch.paging:runtime androidx.paging:paging-runtime:2.0.0-rc01
17 android.arch.paging:rxjava2 androidx.paging:paging-rxjava2:2.0.0-rc01
18 android.arch.persistence.room:common androidx.room:room-common:2.0.0-rc01
19 android.arch.persistence.room:compiler androidx.room:room-compiler:2.0.0-rc01
20 android.arch.persistence.room:guava androidx.room:room-guava:2.0.0-rc01
21 android.arch.persistence.room:migration androidx.room:room-migration:2.0.0-rc01
22 android.arch.persistence.room:runtime androidx.room:room-runtime:2.0.0-rc01
23 android.arch.persistence.room:rxjava2 androidx.room:room-rxjava2:2.0.0-rc01
24 android.arch.persistence.room:testing androidx.room:room-testing:2.0.0-rc01
25 android.arch.persistence:db androidx.sqlite:sqlite:2.0.0-rc01
26 android.arch.persistence:db-framework androidx.sqlite:sqlite-framework:2.0.0-rc01
27 com.android.support.constraint:constraint-layout androidx.constraintlayout:constraintlayout:1.1.2
28 com.android.support.constraint:constraint-layout-solver androidx.constraintlayout:constraintlayout-solver:1.1.2
29 com.android.support.test.espresso.idling:idling-concurrent androidx.test.espresso.idling:idling-concurrent:3.1.0
30 com.android.support.test.espresso.idling:idling-net androidx.test.espresso.idling:idling-net:3.1.0
31 com.android.support.test.espresso:espresso-accessibility androidx.test.espresso:espresso-accessibility:3.1.0
32 com.android.support.test.espresso:espresso-contrib androidx.test.espresso:espresso-contrib:3.1.0
33 com.android.support.test.espresso:espresso-core androidx.test.espresso:espresso-core:3.1.0
34 com.android.support.test.espresso:espresso-idling-resource androidx.test.espresso:espresso-idling-resource:3.1.0
35 com.android.support.test.espresso:espresso-intents androidx.test.espresso:espresso-intents:3.1.0
36 com.android.support.test.espresso:espresso-remote androidx.test.espresso:espresso-remote:3.1.0
37 com.android.support.test.espresso:espresso-web androidx.test.espresso:espresso-web:3.1.0
38 com.android.support.test.janktesthelper:janktesthelper androidx.test.jank:janktesthelper:1.0.1
39 com.android.support.test.services:test-services androidx.test:test-services:1.1.0
40 com.android.support.test.uiautomator:uiautomator androidx.test.uiautomator:uiautomator:2.2.0
41 com.android.support.test:monitor androidx.test:monitor:1.1.0
42 com.android.support.test:orchestrator androidx.test:orchestrator:1.1.0
43 com.android.support.test:rules androidx.test:rules:1.1.0
44 com.android.support.test:runner androidx.test:runner:1.1.0
45 com.android.support:animated-vector-drawable androidx.vectordrawable:vectordrawable-animated:1.0.0
46 com.android.support:appcompat-v7 androidx.appcompat:appcompat:1.0.0
47 com.android.support:asynclayoutinflater androidx.asynclayoutinflater:asynclayoutinflater:1.0.0
48 com.android.support:car androidx.car:car:1.0.0-alpha5
49 com.android.support:cardview-v7 androidx.cardview:cardview:1.0.0
50 com.android.support:collections androidx.collection:collection:1.0.0
51 com.android.support:coordinatorlayout androidx.coordinatorlayout:coordinatorlayout:1.0.0
52 com.android.support:cursoradapter androidx.cursoradapter:cursoradapter:1.0.0
53 com.android.support:customtabs androidx.browser:browser:1.0.0
54 com.android.support:customview androidx.customview:customview:1.0.0
55 com.android.support:design com.google.android.material:material:1.0.0-rc01
56 com.android.support:documentfile androidx.documentfile:documentfile:1.0.0
57 com.android.support:drawerlayout androidx.drawerlayout:drawerlayout:1.0.0
58 com.android.support:exifinterface androidx.exifinterface:exifinterface:1.0.0
59 com.android.support:gridlayout-v7 androidx.gridlayout:gridlayout:1.0.0
60 com.android.support:heifwriter androidx.heifwriter:heifwriter:1.0.0
61 com.android.support:interpolator androidx.interpolator:interpolator:1.0.0
62 com.android.support:leanback-v17 androidx.leanback:leanback:1.0.0
63 com.android.support:loader androidx.loader:loader:1.0.0
64 com.android.support:localbroadcastmanager androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
65 com.android.support:media2 androidx.media2:media2:1.0.0-alpha03
66 com.android.support:media2-exoplayer androidx.media2:media2-exoplayer:1.0.0-alpha01
67 com.android.support:mediarouter-v7 androidx.mediarouter:mediarouter:1.0.0
68 com.android.support:multidex androidx.multidex:multidex:2.0.0
69 com.android.support:multidex-instrumentation androidx.multidex:multidex-instrumentation:2.0.0
70 com.android.support:palette-v7 androidx.palette:palette:1.0.0
71 com.android.support:percent androidx.percentlayout:percentlayout:1.0.0
72 com.android.support:preference-leanback-v17 androidx.leanback:leanback-preference:1.0.0
73 com.android.support:preference-v14 androidx.legacy:legacy-preference-v14:1.0.0
74 com.android.support:preference-v7 androidx.preference:preference:1.0.0
75 com.android.support:print androidx.print:print:1.0.0
76 com.android.support:recommendation androidx.recommendation:recommendation:1.0.0
77 com.android.support:recyclerview-selection androidx.recyclerview:recyclerview-selection:1.0.0
78 com.android.support:recyclerview-v7 androidx.recyclerview:recyclerview:1.0.0
79 com.android.support:slices-builders androidx.slice:slice-builders:1.0.0
80 com.android.support:slices-core androidx.slice:slice-core:1.0.0
81 com.android.support:slices-view androidx.slice:slice-view:1.0.0
82 com.android.support:slidingpanelayout androidx.slidingpanelayout:slidingpanelayout:1.0.0
83 com.android.support:support-annotations androidx.annotation:annotation:1.0.0
84 com.android.support:support-compat androidx.core:core:1.0.0
85 com.android.support:support-content androidx.contentpager:contentpager:1.0.0
86 com.android.support:support-core-ui androidx.legacy:legacy-support-core-ui:1.0.0
87 com.android.support:support-core-utils androidx.legacy:legacy-support-core-utils:1.0.0
88 com.android.support:support-dynamic-animation androidx.dynamicanimation:dynamicanimation:1.0.0
89 com.android.support:support-emoji androidx.emoji:emoji:1.0.0
90 com.android.support:support-emoji-appcompat androidx.emoji:emoji-appcompat:1.0.0
91 com.android.support:support-emoji-bundled androidx.emoji:emoji-bundled:1.0.0
92 com.android.support:support-fragment androidx.fragment:fragment:1.0.0
93 com.android.support:support-media-compat androidx.media:media:1.0.0
94 com.android.support:support-tv-provider androidx.tvprovider:tvprovider:1.0.0
95 com.android.support:support-v13 androidx.legacy:legacy-support-v13:1.0.0
96 com.android.support:support-v4 androidx.legacy:legacy-support-v4:1.0.0
97 com.android.support:support-vector-drawable androidx.vectordrawable:vectordrawable:1.0.0
98 com.android.support:swiperefreshlayout androidx.swiperefreshlayout:swiperefreshlayout:1.0.0
99 com.android.support:textclassifier androidx.textclassifier:textclassifier:1.0.0
100 com.android.support:transition androidx.transition:transition:1.0.0
101 com.android.support:versionedparcelable androidx.versionedparcelable:versionedparcelable:1.0.0
102 com.android.support:viewpager androidx.viewpager:viewpager:1.0.0
103 com.android.support:wear androidx.wear:wear:1.0.0
104 com.android.support:webkit androidx.webkit:webkit:1.0.0

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +0,0 @@
Old type,AndroidX type
Android.Support.V4.Media.MediaSessionManager,AndroidX.Media.MediaSessionManager
Android.Support.V4.App.ActionBarDrawerToggle.IDelegate,AndroidX.Legacy.App.ActionBarDrawerToggle.IDelegate
Android.Support.V4.App.ActionBarDrawerToggle.IDelegateProvider,AndroidX.Legacy.App.ActionBarDrawerToggle.IDelegateProvider
Android.Support.V7.App.ActionBarDrawerToggle.IDelegate,AndroidX.AppCompat.App.ActionBarDrawerToggle.IDelegate
Android.Support.V7.App.ActionBarDrawerToggle.IDelegateProvider,AndroidX.AppCompat.App.ActionBarDrawerToggle.IDelegateProvider
1 Old type AndroidX type
2 Android.Support.V4.Media.MediaSessionManager AndroidX.Media.MediaSessionManager
3 Android.Support.V4.App.ActionBarDrawerToggle.IDelegate AndroidX.Legacy.App.ActionBarDrawerToggle.IDelegate
4 Android.Support.V4.App.ActionBarDrawerToggle.IDelegateProvider AndroidX.Legacy.App.ActionBarDrawerToggle.IDelegateProvider
5 Android.Support.V7.App.ActionBarDrawerToggle.IDelegate AndroidX.AppCompat.App.ActionBarDrawerToggle.IDelegate
6 Android.Support.V7.App.ActionBarDrawerToggle.IDelegateProvider AndroidX.AppCompat.App.ActionBarDrawerToggle.IDelegateProvider

Двоичные данные
util/binderator.zip

Двоичный файл не отображается.