зеркало из https://github.com/xamarin/AndroidX.git
Update the build script to use the new dotnet tools
This commit is contained in:
Родитель
2d63d41148
Коммит
2b1af69499
|
@ -1,11 +1,14 @@
|
|||
|
||||
variables:
|
||||
VERBOSITY: normal
|
||||
BUILD_NUMBER: $[counter('$(Build.SourceBranchName)_counter', 1)]
|
||||
MONO_VERSION: 5_18_1
|
||||
XCODE_VERSION: 10.2.1
|
||||
VERBOSITY: minimal
|
||||
BUILD_NUMBER: $[counter('$(Build.SourceBranchName)_counter', 1)]
|
||||
API_TOOLS_VERSION: 1.0.2-preview.5
|
||||
BINDERATOR_VERSION: 0.2.0
|
||||
DOTNET_CORE_VERSION: 2.2.x
|
||||
# PACKAGE_VERSION_SUFFIX: <string>
|
||||
# XAMARIN_ANDROID_PATH: <path to Xamarin.Android>
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
|
@ -16,76 +19,69 @@ resources:
|
|||
|
||||
jobs:
|
||||
|
||||
# run the build
|
||||
- job: build
|
||||
displayName: 'Build Libraries & NuGets (macOS)'
|
||||
strategy:
|
||||
matrix:
|
||||
macos:
|
||||
imageName: macos-10.14
|
||||
windows:
|
||||
imageName: vs2017-win2016
|
||||
displayName: 'Build'
|
||||
pool:
|
||||
vmImage: macos-10.14
|
||||
name: $(imageName)
|
||||
steps:
|
||||
# Make sure to select the correct Xamarin and mono
|
||||
# install xamarin
|
||||
- bash: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh $(MONO_VERSION)
|
||||
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
|
||||
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
|
||||
displayName: 'Use the correct version of the .NET Core SDK'
|
||||
condition: eq(variables['System.JobName'], 'macos')
|
||||
inputs:
|
||||
version: $(DOTNET_CORE_VERSION)
|
||||
- powershell: dotnet tool install -g api-tools --version $(API_TOOLS_VERSION)
|
||||
displayName: 'Install api-tools'
|
||||
# Build the libraries and packages
|
||||
- bash: sh build.sh --target=ci --settings_skipverification=true --verbosity=$(VERBOSITY)
|
||||
displayName: 'Build NuGets'
|
||||
# run the diff
|
||||
- powershell: |
|
||||
if (Get-ChildItem output -Filter *.nupkg) {
|
||||
api-tools nuget-diff output --latest --group-ids --output output/api-diff --cache externals/package_cache
|
||||
}
|
||||
displayName: 'API diff'
|
||||
# Publish the artifacts
|
||||
- powershell: dotnet tool install -g xamarin.androidbinderator.tool --version $(BINDERATOR_VERSION)
|
||||
displayName: 'Install xamarin-android-binderator'
|
||||
- powershell: dotnet tool install -g xamarin.androidx.migration.tool --version $(BINDERATOR_VERSION)
|
||||
displayName: 'Install androidx-migrator'
|
||||
# run the main build
|
||||
- powershell: .\build.ps1 --target=ci --verbosity=$(VERBOSITY)
|
||||
displayName: 'Run build'
|
||||
# publish the nugets
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish unsigned artifacts'
|
||||
condition: eq(variables['System.JobName'], 'macos')
|
||||
displayName: 'Publish artifacts'
|
||||
inputs:
|
||||
pathToPublish: '$(Build.SourcesDirectory)/output'
|
||||
artifactName: 'nuget'
|
||||
|
||||
- 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
|
||||
PathToPublish: output
|
||||
ArtifactName: nuget
|
||||
# publish the output with the os name
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: 'Publish Windows artifacts'
|
||||
displayName: 'Publish artifacts'
|
||||
inputs:
|
||||
pathToPublish: '$(Build.SourcesDirectory)/output'
|
||||
artifactName: 'windows_output'
|
||||
# # 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
|
||||
PathToPublish: output
|
||||
ArtifactName: 'output-$(System.JobName)'
|
||||
|
||||
# only sign the packages when running on Windows, and using the private server which has the certificates
|
||||
- ${{ if eq(variables['System.TeamProject'], 'devdiv') }}:
|
||||
- job: signing
|
||||
displayName: Signing NuGets
|
||||
variables:
|
||||
skipComponentGovernanceDetection: true
|
||||
dependsOn: build
|
||||
pool:
|
||||
name: VSEng-XamarinCustom
|
||||
demands:
|
||||
- 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:
|
||||
# don't checkout code and sign the packages
|
||||
- checkout: none
|
||||
|
|
287
build.cake
287
build.cake
|
@ -1,66 +1,90 @@
|
|||
// Tools needed by cake addins
|
||||
#tool nuget:?package=Cake.MonoApiTools&version=3.0.1
|
||||
#tool nuget:?package=vswhere
|
||||
#tool nuget:?package=vswhere&version=2.7.1
|
||||
|
||||
// Cake Addins
|
||||
#addin nuget:?package=Cake.FileHelpers&version=3.1.0
|
||||
#addin nuget:?package=Cake.Compression&version=0.1.6
|
||||
#addin nuget:?package=Cake.MonoApiTools&version=3.0.1
|
||||
#addin nuget:?package=Cake.FileHelpers&version=3.2.0
|
||||
#addin nuget:?package=Cake.Compression&version=0.2.3
|
||||
#addin nuget:?package=Xamarin.Nuget.Validator&version=1.1.1
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Xamarin.Nuget.Validator;
|
||||
|
||||
// From Cake.Xamarin.Build, dumps out versions of things
|
||||
//LogSystemInfo ();
|
||||
|
||||
// The main configuration points
|
||||
var TARGET = Argument ("t", Argument ("target", "Default"));
|
||||
var BUILD_CONFIG = Argument ("config", "Release");
|
||||
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.*
|
||||
// https://dl.google.com/dl/android/maven2/com/android/support/group-index.xml
|
||||
// Master list of all the packages in the repo:
|
||||
// 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";
|
||||
|
||||
// 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
|
||||
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/";
|
||||
if (IsRunningOnWindows ()) {
|
||||
var vsInstallPath = VSWhereLatest (new VSWhereLatestSettings { Requires = "Component.Xamarin" });
|
||||
MONODROID_BASE_PATH = vsInstallPath.Combine ("Common7/IDE/ReferenceAssemblies/Microsoft/Framework/MonoAndroid/");
|
||||
// Resolve Xamarin.Android installation
|
||||
var ANDROID_SDK_BASE_VERSION = "v1.0";
|
||||
var ANDROID_SDK_VERSION = "v9.0";
|
||||
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") ?? "";
|
||||
if (string.IsNullOrEmpty(BUILD_NUMBER)) {
|
||||
BUILD_NUMBER = "0";
|
||||
}
|
||||
var REQUIRED_DOTNET_TOOLS = new [] {
|
||||
"xamarin-android-binderator",
|
||||
"api-tools",
|
||||
"xamarin.androidx.migration.tool"
|
||||
};
|
||||
|
||||
Information ("MONODROID_BASE_PATH: {0}", MONODROID_BASE_PATH);
|
||||
Information ("MONODROID_PATH: {0}", MONODROID_PATH);
|
||||
Information ("ANDROIDX_MAPPER_EXE: {0}", ANDROIDX_MAPPER_EXE);
|
||||
Information ("BUILD_NUMBER: {0}", BUILD_NUMBER);
|
||||
// Log some variables
|
||||
Information ("XAMARIN_ANDROID_PATH: {0}", XAMARIN_ANDROID_PATH);
|
||||
Information ("ANDROID_SDK_VERSION: {0}", ANDROID_SDK_VERSION);
|
||||
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
|
||||
// ######################################################
|
||||
|
||||
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")
|
||||
.Does(() =>
|
||||
{
|
||||
|
@ -78,25 +102,30 @@ Task("javadocs")
|
|||
var outTxtPath = srcJarPath.Replace("-sources.jar", "-paramnames.txt");
|
||||
var outXmlPath = srcJarPath.Replace("-sources.jar", "-paramnames.xml");
|
||||
|
||||
StartProcess("java", "-jar \"" + MakeAbsolute(astJar).FullPath + "\" --text \"" + srcJarPath + "\" \"" + outTxtPath + "\"");
|
||||
StartProcess("java", "-jar \"" + MakeAbsolute(astJar).FullPath + "\" --xml \"" + srcJarPath + "\" \"" + outXmlPath + "\"");
|
||||
RunProcess("java", "-jar \"" + MakeAbsolute(astJar).FullPath + "\" --text \"" + srcJarPath + "\" \"" + outTxtPath + "\"");
|
||||
RunProcess("java", "-jar \"" + MakeAbsolute(astJar).FullPath + "\" --xml \"" + srcJarPath + "\" \"" + outXmlPath + "\"");
|
||||
}
|
||||
});
|
||||
|
||||
Task("binderate")
|
||||
Task("check-tools")
|
||||
.Does(() =>
|
||||
{
|
||||
if (!DirectoryExists("./util/binderator"))
|
||||
{
|
||||
EnsureDirectoryExists("./util/binderator");
|
||||
Unzip ("./util/binderator.zip", "./util/binderator");
|
||||
var installedTools = RunProcessWithOutput("dotnet", "tool list -g");
|
||||
foreach (var toolName in REQUIRED_DOTNET_TOOLS) {
|
||||
if (installedTools.All(l => l.IndexOf(toolName, StringComparison.OrdinalIgnoreCase) == -1))
|
||||
throw new Exception ($"Missing dotnet tool: {toolName}");
|
||||
}
|
||||
});
|
||||
|
||||
var configFile = new FilePath("./config.json");
|
||||
var basePath = new DirectoryPath ("./");
|
||||
Task ("binderate")
|
||||
.Does (() =>
|
||||
{
|
||||
var configFile = MakeAbsolute(new FilePath("./config.json")).FullPath;
|
||||
var basePath = MakeAbsolute(new DirectoryPath ("./")).FullPath;
|
||||
|
||||
StartProcess("dotnet", "./util/binderator/android-binderator.dll --config=\""
|
||||
+ MakeAbsolute(configFile).FullPath + "\" --basepath=\"" + MakeAbsolute(basePath).FullPath + "\"");
|
||||
// Run the dotnet tool for binderator
|
||||
RunProcess("xamarin-android-binderator",
|
||||
$"--config=\"{configFile}\" --basepath=\"{basePath}\"");
|
||||
|
||||
// format the targets file so they are pretty in the package
|
||||
var targetsFiles = GetFiles("generated/**/*.targets");
|
||||
|
@ -110,18 +139,20 @@ Task("binderate")
|
|||
Task("libs")
|
||||
.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
|
||||
MSBuild ("./generated/AndroidX.sln", c => {
|
||||
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" });
|
||||
});
|
||||
MSBuild("./generated/AndroidX.sln", settings);
|
||||
});
|
||||
|
||||
Task("nuget")
|
||||
|
@ -132,7 +163,8 @@ Task("samples")
|
|||
.Does(() =>
|
||||
{
|
||||
// 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 itemGroup = new XElement(xmlns + "ItemGroup");
|
||||
foreach (var nupkg in GetFiles("./output/*.nupkg")) {
|
||||
|
@ -147,7 +179,7 @@ Task("samples")
|
|||
}
|
||||
var xdoc = new XDocument(new XElement(xmlns + "Project", itemGroup));
|
||||
xdoc.Save("./output/AllPackages.targets");
|
||||
|
||||
|
||||
// clear the packages folder so we always use the latest
|
||||
var packagesPath = MakeAbsolute((DirectoryPath)"./samples/packages").FullPath;
|
||||
EnsureDirectoryExists(packagesPath);
|
||||
|
@ -170,9 +202,7 @@ Task("samples")
|
|||
Task("nuget-validation")
|
||||
.Does(() =>
|
||||
{
|
||||
//setup validation options
|
||||
var options = new Xamarin.Nuget.Validator.NugetValidatorOptions()
|
||||
{
|
||||
var options = new NugetValidatorOptions {
|
||||
Copyright = "© Microsoft Corporation. All rights reserved.",
|
||||
Author = "Microsoft",
|
||||
Owner = "Microsoft",
|
||||
|
@ -182,69 +212,31 @@ Task("nuget-validation")
|
|||
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)
|
||||
{
|
||||
Information ("Verifiying Metadata of {0}", nupkgFile.GetFilename ());
|
||||
|
||||
var result = Xamarin.Nuget.Validator.NugetValidator.Validate(MakeAbsolute(nupkgFile).FullPath, options);
|
||||
|
||||
if (!result.Success)
|
||||
{
|
||||
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 ());
|
||||
foreach (var nupkgFile in nupkgFiles) {
|
||||
var fname = nupkgFile.GetFilename();
|
||||
Information($"Verifiying metadata of {fname}...");
|
||||
var result = NugetValidator.Validate(MakeAbsolute(nupkgFile).FullPath, options);
|
||||
if (!result.Success) {
|
||||
Error($"Metadata validation failed for: {fname} ");
|
||||
Error(string.Join("\n ", result.ErrorMessages));
|
||||
throw new Exception($"Invalid Metadata for: {fname}");
|
||||
} else {
|
||||
Information($"Metadata validation passed for: {fname}");
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Task ("androidxmapper")
|
||||
.Does (() =>
|
||||
{
|
||||
MSBuild (
|
||||
"./util/AndroidXMapper/AndroidXMapper.sln", c => {
|
||||
c.Configuration = BUILD_CONFIG;
|
||||
c.MaxCpuCount = 0;
|
||||
c.Verbosity = VERBOSITY;
|
||||
c.Restore = true;
|
||||
});
|
||||
});
|
||||
|
||||
Task ("diff")
|
||||
.IsDependentOn ("merge")
|
||||
.Does (() =>
|
||||
{
|
||||
var SEARCH_DIRS = new DirectoryPath [] {
|
||||
MONODROID_BASE_PATH.Combine("v1.0"),
|
||||
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");
|
||||
RunProcess("api-tools",
|
||||
"nuget-diff output --latest --group-ids --output output/api-diff --cache externals/package_cache");
|
||||
});
|
||||
|
||||
Task ("generate-mapping")
|
||||
.IsDependentOn ("androidxmapper")
|
||||
.IsDependentOn ("merge")
|
||||
.Does (() =>
|
||||
{
|
||||
|
@ -254,60 +246,47 @@ Task ("generate-mapping")
|
|||
DownloadFile (SUPPORT_MERGED_DLL_URL, "./output/AndroidSupport.Merged.dll");
|
||||
}
|
||||
|
||||
var result = StartProcess(ANDROIDX_MAPPER_EXE,
|
||||
// generate the mapping
|
||||
RunProcess("androidx-migrator",
|
||||
$"generate -v " +
|
||||
$" -s " + MakeAbsolute((FilePath)"./output/AndroidSupport.Merged.dll") +
|
||||
$" -x " + MakeAbsolute((FilePath)"./output/AndroidX.Merged.dll") +
|
||||
$" -j " + MakeAbsolute((FilePath)"./util/AndroidXMapper/Resources/androidx-class-mapping.csv") +
|
||||
$" -m " + MakeAbsolute((FilePath)"./util/AndroidXMapper/Resources/override-mapping.csv") +
|
||||
$" -o " + MakeAbsolute((FilePath)"./output/androidx-mapping.csv"));
|
||||
if (result != 0)
|
||||
throw new Exception($"The androidxmapper failed with error code {result}.");
|
||||
$" --support ./output/AndroidSupport.Merged.dll" +
|
||||
$" --androidx ./output/AndroidX.Merged.dll" +
|
||||
$" --java ./util/AndroidXMapper/Resources/androidx-class-mapping.csv" +
|
||||
$" --override ./util/AndroidXMapper/Resources/override-mapping.csv" +
|
||||
$" --output ./output/androidx-mapping.csv");
|
||||
});
|
||||
|
||||
Task ("merge")
|
||||
.IsDependentOn ("androidxmapper")
|
||||
.IsDependentOn ("libs")
|
||||
.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
|
||||
.GroupBy(d => new FileInfo(d.FullPath).Name)
|
||||
.Select(g => g.FirstOrDefault())
|
||||
.ToList();
|
||||
|
||||
// merge them all
|
||||
EnsureDirectoryExists("./output/");
|
||||
var result = StartProcess(ANDROIDX_MAPPER_EXE,
|
||||
RunProcess("androidx-migrator",
|
||||
$"merge" +
|
||||
$" -a {string.Join(" -a ", mergeDlls)} " +
|
||||
$" -o " + MakeAbsolute((FilePath)"./output/AndroidX.Merged.dll") +
|
||||
$" -s \"{MONODROID_PATH}\" " +
|
||||
$" --inject-assemblyname");
|
||||
if (result != 0)
|
||||
throw new Exception($"The androidxmapper failed with error code {result}.");
|
||||
$" --assembly " + string.Join(" --assembly ", mergeDlls) +
|
||||
$" --output ./output/AndroidX.Merged.dll" +
|
||||
$" --search \"{XAMARIN_ANDROID_PATH}/{ANDROID_SDK_VERSION}\" " +
|
||||
$" --search \"{XAMARIN_ANDROID_PATH}/{ANDROID_SDK_BASE_VERSION}\" " +
|
||||
$" --inject-assemblyname");
|
||||
});
|
||||
|
||||
Task ("ci-setup")
|
||||
.WithCriteria (!BuildSystem.IsLocalBuild)
|
||||
.Does (() =>
|
||||
Task("inject-variables")
|
||||
.WithCriteria(!BuildSystem.IsLocalBuild)
|
||||
.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";
|
||||
|
||||
ReplaceTextInFiles(glob, "{BUILD_COMMIT}", buildCommit);
|
||||
ReplaceTextInFiles(glob, "{BUILD_NUMBER}", buildNumber);
|
||||
ReplaceTextInFiles(glob, "{BUILD_TIMESTAMP}", buildTimestamp);
|
||||
ReplaceTextInFiles(glob, "{BUILD_COMMIT}", BUILD_COMMIT);
|
||||
ReplaceTextInFiles(glob, "{BUILD_NUMBER}", BUILD_NUMBER);
|
||||
ReplaceTextInFiles(glob, "{BUILD_TIMESTAMP}", BUILD_TIMESTAMP);
|
||||
});
|
||||
|
||||
Task ("clean")
|
||||
|
@ -319,9 +298,6 @@ Task ("clean")
|
|||
if (DirectoryExists ("./generated"))
|
||||
DeleteDirectory ("./generated", true);
|
||||
|
||||
if (DirectoryExists ("./util/binderator"))
|
||||
DeleteDirectory ("./util/binderator", true);
|
||||
|
||||
CleanDirectories ("./**/packages");
|
||||
});
|
||||
|
||||
|
@ -334,8 +310,17 @@ Task ("full-run")
|
|||
.IsDependentOn ("nuget")
|
||||
.IsDependentOn ("samples");
|
||||
|
||||
Task ("Default")
|
||||
.IsDependentOn ("binderate")
|
||||
.IsDependentOn ("nuget")
|
||||
.IsDependentOn ("nuget-validation")
|
||||
.IsDependentOn ("generate-mapping")
|
||||
.IsDependentOn ("diff")
|
||||
.IsDependentOn ("samples");
|
||||
|
||||
Task ("ci")
|
||||
.IsDependentOn ("ci-setup")
|
||||
.IsDependentOn ("check-tools")
|
||||
.IsDependentOn ("inject-variables")
|
||||
.IsDependentOn ("binderate")
|
||||
.IsDependentOn ("nuget")
|
||||
.IsDependentOn ("nuget-validation")
|
||||
|
|
70
build.ps1
70
build.ps1
|
@ -25,10 +25,6 @@ Specifies the amount of information to be displayed.
|
|||
Shows description about tasks.
|
||||
.PARAMETER DryRun
|
||||
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
|
||||
Skips restoring of packages.
|
||||
.PARAMETER ScriptArgs
|
||||
|
@ -49,13 +45,28 @@ Param(
|
|||
[switch]$ShowDescription,
|
||||
[Alias("WhatIf", "Noop")]
|
||||
[switch]$DryRun,
|
||||
[switch]$Experimental,
|
||||
[switch]$Mono,
|
||||
[switch]$SkipToolPackageRestore,
|
||||
[Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
|
||||
[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
|
||||
function MD5HashFile([string] $filePath)
|
||||
{
|
||||
|
@ -85,7 +96,7 @@ function GetProxyEnabledWebClient
|
|||
{
|
||||
$wc = New-Object System.Net.WebClient
|
||||
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
|
||||
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
|
||||
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
|
||||
$wc.Proxy = $proxy
|
||||
return $wc
|
||||
}
|
||||
|
@ -111,16 +122,17 @@ $CAKE_PACKAGES_CONFIG = Join-Path $PSScriptRoot "cake.packages.config"
|
|||
# Make sure tools folder exists
|
||||
if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
|
||||
Write-Verbose -Message "Creating tools directory..."
|
||||
New-Item -Path $TOOLS_DIR -Type directory | out-null
|
||||
New-Item -Path $TOOLS_DIR -Type Directory | Out-Null
|
||||
}
|
||||
|
||||
# Make sure that packages.config exist.
|
||||
if (!(Test-Path $PACKAGES_CONFIG)) {
|
||||
if (!(Test-Path $CAKE_PACKAGES_CONFIG)) {
|
||||
Write-Verbose -Message "Downloading packages.config..."
|
||||
try {
|
||||
Write-Verbose -Message "Downloading packages.config..."
|
||||
try {
|
||||
$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."
|
||||
}
|
||||
} else {
|
||||
|
@ -152,7 +164,12 @@ if (!(Test-Path $NUGET_EXE)) {
|
|||
}
|
||||
|
||||
# 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?
|
||||
if(-Not $SkipToolPackageRestore.IsPresent) {
|
||||
|
@ -160,16 +177,16 @@ if(-Not $SkipToolPackageRestore.IsPresent) {
|
|||
Set-Location $TOOLS_DIR
|
||||
|
||||
# Check for changes in packages.config and remove installed tools if true.
|
||||
[string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
|
||||
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
|
||||
($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
|
||||
[string] $md5Hash = MD5HashFile $PACKAGES_CONFIG
|
||||
if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
|
||||
Write-Verbose -Message "Missing or changed package.config hash..."
|
||||
Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery |
|
||||
Remove-Item -Recurse
|
||||
}
|
||||
|
||||
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) {
|
||||
Throw "An error occurred while restoring NuGet tools."
|
||||
|
@ -178,7 +195,7 @@ if(-Not $SkipToolPackageRestore.IsPresent) {
|
|||
{
|
||||
$md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
|
||||
}
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
Write-Verbose -Message ($NuGetOutput | Out-String)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
@ -189,13 +206,13 @@ if (Test-Path $ADDINS_PACKAGES_CONFIG) {
|
|||
Set-Location $ADDINS_DIR
|
||||
|
||||
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) {
|
||||
Throw "An error occurred while restoring NuGet addins."
|
||||
}
|
||||
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
Write-Verbose -Message ($NuGetOutput | Out-String)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
@ -206,13 +223,13 @@ if (Test-Path $MODULES_PACKAGES_CONFIG) {
|
|||
Set-Location $MODULES_DIR
|
||||
|
||||
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) {
|
||||
Throw "An error occurred while restoring NuGet modules."
|
||||
}
|
||||
|
||||
Write-Verbose -Message ($NuGetOutput | out-string)
|
||||
Write-Verbose -Message ($NuGetOutput | Out-String)
|
||||
|
||||
Pop-Location
|
||||
}
|
||||
|
@ -222,6 +239,11 @@ if (!(Test-Path $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
|
||||
|
@ -231,11 +253,9 @@ if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
|
|||
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
|
||||
if ($ShowDescription) { $cakeArguments += "-showdescription" }
|
||||
if ($DryRun) { $cakeArguments += "-dryrun" }
|
||||
if ($Experimental) { $cakeArguments += "-experimental" }
|
||||
if ($Mono) { $cakeArguments += "-mono" }
|
||||
$cakeArguments += $ScriptArgs
|
||||
|
||||
# Start Cake
|
||||
Write-Host "Running build script..."
|
||||
&$CAKE_EXE $cakeArguments
|
||||
exit $LASTEXITCODE
|
||||
Invoke-Expression "& $CAKE_EXE_INVOCATION $($cakeArguments -join " ")"
|
||||
exit $LASTEXITCODE
|
||||
|
|
17
cake.config
17
cake.config
|
@ -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]
|
||||
UseInProcessClient=false
|
||||
LoadDependencies=true
|
||||
[Nuget]
|
||||
Source=https://api.nuget.org/v3/index.json
|
||||
UseInProcessClient=true
|
||||
LoadDependencies=false
|
||||
|
||||
[Paths]
|
||||
Tools=./tools
|
||||
Addins=./tools/Addins
|
||||
Modules=./tools/Modules
|
||||
|
||||
[Settings]
|
||||
SkipVerification=true
|
||||
SkipVerification=false
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Cake" version="0.30.0" />
|
||||
<package id="Cake" version="0.34.1" />
|
||||
</packages>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "2.2.401"
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
@using System.Linq
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="MSBuild.Sdk.Extras/2.0.31">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>MonoAndroid90</TargetFramework>
|
||||
<IsBindingProject>true</IsBindingProject>
|
||||
|
@ -171,10 +171,4 @@
|
|||
</ItemGroup>
|
||||
}
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSBuild.Sdk.Extras" Version="1.4.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -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,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
|
|
Двоичные данные
util/binderator.zip
Двоичные данные
util/binderator.zip
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче