diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
index d49e95f5b39..2f44a1df58e 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.Designer.cs
@@ -1374,6 +1374,15 @@ public static string XA4248 {
}
}
+ ///
+ /// Looks up a localized string similar to Maven artifact specification '{0}' is invalid. The correct format is 'group_id:artifact_id:version'..
+ ///
+ public static string XA4249 {
+ get {
+ return ResourceManager.GetString("XA4249", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Native library '{0}' will not be bundled because it has an unsupported ABI. Move this file to a directory with a valid Android ABI name such as 'libs/armeabi-v7a/'..
///
diff --git a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
index 6dee6524d06..9f4a6fa5fbd 100644
--- a/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
+++ b/src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
@@ -1067,4 +1067,9 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS
{2} - shared library file name
+
+ Maven artifact specification '{0}' is invalid. The correct format is 'group_id:artifact_id:version'.
+ The following are literal names and should not be translated: Maven, group_id, artifact_id
+{0} - A Maven artifact specification
+
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/JavaDependencyVerification.cs b/src/Xamarin.Android.Build.Tasks/Tasks/JavaDependencyVerification.cs
index 441e1b3ccd5..5ccd8309b75 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/JavaDependencyVerification.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/JavaDependencyVerification.cs
@@ -149,15 +149,12 @@ public void AddAndroidLibraries (ITaskItem []? tasks)
{
foreach (var task in tasks.OrEmpty ()) {
var id = task.GetMetadataOrDefault ("JavaArtifact", string.Empty);
- var version = task.GetMetadataOrDefault ("JavaVersion", string.Empty);
- // TODO: Should raise an error if JavaArtifact is specified but JavaVersion is not
- if (!id.HasValue () || !version.HasValue ())
- continue;
-
- if (version != null && MavenExtensions.TryParseArtifactWithVersion (id, version, log, out var art)) {
- log.LogMessage ("Found Java dependency '{0}:{1}' version '{2}' from AndroidLibrary '{3}'", art.GroupId, art.Id, art.Version, task.ItemSpec);
- artifacts.Add (art.ArtifactString, art);
+ if (MavenExtensions.TryParseArtifacts (id, log, out var parsed)) {
+ foreach (var art in parsed) {
+ log.LogMessage ("Found Java dependency '{0}:{1}' version '{2}' from AndroidLibrary '{3}'", art.GroupId, art.Id, art.Version, task.ItemSpec);
+ artifacts.Add (art.ArtifactString, art);
+ }
}
}
}
@@ -166,20 +163,22 @@ public void AddPackageReferences (ITaskItem []? tasks)
{
foreach (var task in tasks.OrEmpty ()) {
- // See if JavaArtifact/JavaVersion overrides were used
- if (task.TryParseJavaArtifactAndJavaVersion ("PackageReference", log, out var explicit_artifact, out var attributes_specified)) {
- artifacts.Add (explicit_artifact.ArtifactString, explicit_artifact);
+ // See if JavaArtifact override was used
+ if (task.TryParseJavaArtifacts ("PackageReference", log, out var explicit_artifacts, out var attributes_specified)) {
+ foreach (var explicit_artifact in explicit_artifacts)
+ artifacts.Add (explicit_artifact.ArtifactString, explicit_artifact);
+
continue;
}
- // If user tried to specify JavaArtifact or JavaVersion, but did it incorrectly, we do not perform any fallback
+ // If user tried to specify JavaArtifact, but did it incorrectly, we do not perform any fallback
if (attributes_specified)
continue;
// Try parsing the NuGet metadata for Java version information instead
- var artifact = finder?.GetJavaInformation (task.ItemSpec, task.GetMetadataOrDefault ("Version", string.Empty), log);
+ var metadata_artifacts = finder?.GetArtifactsInNugetPackage (task.ItemSpec, task.GetMetadataOrDefault ("Version", string.Empty), log);
- if (artifact != null) {
+ foreach (var artifact in metadata_artifacts ?? []) {
log.LogMessage ("Found Java dependency '{0}:{1}' version '{2}' from PackageReference '{3}'", artifact.GroupId, artifact.Id, artifact.Version, task.ItemSpec);
artifacts.Add (artifact.ArtifactString, artifact);
@@ -193,13 +192,15 @@ public void AddPackageReferences (ITaskItem []? tasks)
public void AddProjectReferences (ITaskItem []? tasks)
{
foreach (var task in tasks.OrEmpty ()) {
- // See if JavaArtifact/JavaVersion overrides were used
- if (task.TryParseJavaArtifactAndJavaVersion ("ProjectReference", log, out var explicit_artifact, out var attributes_specified)) {
- artifacts.Add (explicit_artifact.ArtifactString, explicit_artifact);
+ // See if JavaArtifact override was used
+ if (task.TryParseJavaArtifacts ("ProjectReference", log, out var explicit_artifacts, out var attributes_specified)) {
+ foreach (var explicit_artifact in explicit_artifacts)
+ artifacts.Add (explicit_artifact.ArtifactString, explicit_artifact);
+
continue;
}
- // If user tried to specify JavaArtifact or JavaVersion, but did it incorrectly, we do not perform any fallback
+ // If user tried to specify JavaArtifact, but did it incorrectly, we do not perform any fallback
if (attributes_specified)
continue;
@@ -212,14 +213,12 @@ public void AddIgnoredDependencies (ITaskItem []? tasks)
{
foreach (var task in tasks.OrEmpty ()) {
var id = task.ItemSpec;
- var version = task.GetRequiredMetadata ("AndroidIgnoredJavaDependency", "Version", log);
- if (version is null)
- continue;
-
- if (version != null && MavenExtensions.TryParseArtifactWithVersion (id, version, log, out var art)) {
- log.LogMessage ("Ignoring Java dependency '{0}:{1}' version '{2}'", art.GroupId, art.Id, art.Version);
- artifacts.Add (art.ArtifactString, art);
+ if (MavenExtensions.TryParseArtifacts (id, log, out var parsed)) {
+ foreach (var art in parsed) {
+ log.LogMessage ("Ignoring Java dependency '{0}'", art.VersionedArtifactString);
+ artifacts.Add (art.ArtifactString, art);
+ }
}
}
}
@@ -263,7 +262,7 @@ public MSBuildLoggingPomResolver (TaskLoggingHelper logger)
Artifact? RegisterFromTaskItem (ITaskItem item, string itemName, string filename)
{
- item.TryParseJavaArtifactAndJavaVersion (itemName, logger, out var artifact, out var _);
+ item.TryParseJavaArtifact (itemName, logger, out var artifact, out var _);
if (!File.Exists (filename)) {
logger.LogCodedError ("XA4245", Properties.Resources.XA4245, filename);
@@ -349,9 +348,7 @@ public class Package
public class NuGetPackageVersionFinder
{
readonly LockFile lock_file;
- readonly Dictionary cache = new Dictionary ();
- readonly Regex tag = new Regex ("artifact_versioned=(?.+)?:(?.+?):(?.+)\\s?", RegexOptions.Compiled);
- readonly Regex tag2 = new Regex ("artifact=(?.+)?:(?.+?):(?.+)\\s?", RegexOptions.Compiled);
+ readonly static Regex tag = new Regex (@"artifact(?:_versioned)?=(?[^:\s;,]+):(?[^:\s;,]+):(?[^:\s;,]+)", RegexOptions.Compiled, TimeSpan.FromSeconds (5));
NuGetPackageVersionFinder (LockFile lockFile)
{
@@ -370,59 +367,62 @@ public class NuGetPackageVersionFinder
}
}
- public Artifact? GetJavaInformation (string library, string version, TaskLoggingHelper log)
+ public List GetArtifactsInNugetPackage (string library, string version, TaskLoggingHelper log)
{
- // Check if we already have this one in the cache
- var dictionary_key = $"{library.ToLowerInvariant ()}:{version}";
-
- if (cache.TryGetValue (dictionary_key, out var artifact))
- return artifact;
+ var artifacts = new List ();
// Find the LockFileLibrary
var nuget = lock_file.GetLibrary (library, new NuGet.Versioning.NuGetVersion (version));
if (nuget is null) {
log.LogCodedError ("XA4248", Properties.Resources.XA4248, library, version);
- return null;
+ return artifacts;
}
foreach (var path in lock_file.PackageFolders)
- if (CheckFilePath (path.Path, nuget) is Artifact art) {
- cache.Add (dictionary_key, art);
- return art;
- }
+ AddArtifactsFromNuspec (artifacts, path.Path, nuget);
- return null;
+ return artifacts;
}
- Artifact? CheckFilePath (string nugetPackagePath, LockFileLibrary package)
+ void AddArtifactsFromNuspec (List artifacts, string nugetPackagePath, LockFileLibrary package)
{
// Check NuGet tags
var nuspec = package.Files.FirstOrDefault (f => f.EndsWith (".nuspec", StringComparison.OrdinalIgnoreCase));
if (nuspec is null)
- return null;
+ return;
nuspec = Path.Combine (nugetPackagePath, package.Path, nuspec);
if (!File.Exists (nuspec))
- return null;
+ return;
var reader = new NuGet.Packaging.NuspecReader (nuspec);
var tags = reader.GetTags ();
- // Try the first tag format
- var match = tag.Match (tags);
+ AddArtifactsFromNuspecTags (artifacts, tags);
- // Try the second tag format
- if (!match.Success)
- match = tag2.Match (tags);
+ // TODO: Define a well-known file that can be included in the package like "java-package.txt"
+ }
- if (!match.Success)
- return null;
+ public static void AddArtifactsFromNuspecTags (List artifacts, string tags)
+ {
+ // Try the first tag format
+ try {
+ var matches = tag.Matches (tags);
- // TODO: Define a well-known file that can be included in the package like "java-package.txt"
+ if (matches is null || matches.Count == 0)
+ return;
+
+ foreach (Match match in matches) {
+ var artifact = new Artifact (match.Groups ["GroupId"].Value, match.Groups ["ArtifactId"].Value, match.Groups ["Version"].Value);
- return new Artifact (match.Groups ["GroupId"].Value, match.Groups ["ArtifactId"].Value, match.Groups ["Version"].Value);
+ if (!artifacts.Any (a => a.VersionedArtifactString == artifact.VersionedArtifactString))
+ artifacts.Add (artifact);
+ }
+ } catch (RegexMatchTimeoutException) {
+ return;
+ }
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/MavenDownload.cs b/src/Xamarin.Android.Build.Tasks/Tasks/MavenDownload.cs
index 3ac8d2383c1..81010e803bc 100644
--- a/src/Xamarin.Android.Build.Tasks/Tasks/MavenDownload.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/MavenDownload.cs
@@ -97,8 +97,7 @@ public async override System.Threading.Tasks.Task RunTaskAsync ()
var result = new TaskItem (artifact_file);
- result.SetMetadata ("JavaArtifact", $"{artifact.GroupId}:{artifact.Id}");
- result.SetMetadata ("JavaVersion", artifact.Version);
+ result.SetMetadata ("JavaArtifact", artifact.VersionedArtifactString);
// Allow user to opt out of dependency verification
if (string.Compare (item.GetMetadataOrDefault ("VerifyDependencies", "true"), "false", true) == 0)
@@ -121,8 +120,7 @@ public async override System.Threading.Tasks.Task RunTaskAsync ()
var pom_item = new TaskItem (kv.Value);
var pom_artifact = Artifact.Parse (kv.Key);
- pom_item.SetMetadata ("JavaArtifact", $"{pom_artifact.GroupId}:{pom_artifact.Id}");
- pom_item.SetMetadata ("JavaVersion", pom_artifact.Version);
+ pom_item.SetMetadata ("JavaArtifact", pom_artifact.VersionedArtifactString);
additionalPoms.Add (pom_item);
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs
index df1fb580f45..14e72a467b4 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs
@@ -888,14 +888,9 @@ public void AndroidMavenLibrary_AllDependenciesAreVerified ()
var collection = new XamarinAndroidBindingProject ();
// Dependencies ignored by
- var concurrent = new BuildItem ("AndroidIgnoredJavaDependency", "androidx.concurrent:concurrent-futures");
- concurrent.Metadata.Add ("Version", "1.1.0");
-
- var lifecycle = new BuildItem ("AndroidIgnoredJavaDependency", "androidx.lifecycle:lifecycle-runtime");
- lifecycle.Metadata.Add ("Version", "2.6.2");
-
- var parcelable = new BuildItem ("AndroidIgnoredJavaDependency", "androidx.versionedparcelable:versionedparcelable");
- parcelable.Metadata.Add ("Version", "1.2.0");
+ var concurrent = new BuildItem ("AndroidIgnoredJavaDependency", "androidx.concurrent:concurrent-futures:1.1.0");
+ var lifecycle = new BuildItem ("AndroidIgnoredJavaDependency", "androidx.lifecycle:lifecycle-runtime:2.6.2");
+ var parcelable = new BuildItem ("AndroidIgnoredJavaDependency", "androidx.versionedparcelable:versionedparcelable:1.2.0");
var proj = new XamarinAndroidBindingProject {
Jars = { item, annotations_experimental_androidlib },
@@ -905,8 +900,7 @@ public void AndroidMavenLibrary_AllDependenciesAreVerified ()
proj.AddReference (collection);
var collection_proj = proj.References.First ();
- collection_proj.Metadata.Add ("JavaArtifact", "androidx.collection:collection");
- collection_proj.Metadata.Add ("JavaVersion", "1.3.0");
+ collection_proj.Metadata.Add ("JavaArtifact", "androidx.collection:collection:1.3.0");
using var a = CreateDllBuilder ();
using var b = CreateDllBuilder ();
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/JavaDependencyVerificationTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/JavaDependencyVerificationTests.cs
index f854c422b7e..4c59593ebf3 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/JavaDependencyVerificationTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/JavaDependencyVerificationTests.cs
@@ -161,7 +161,7 @@ public void MalformedMicrosoftPackagesJson ()
BuildEngine = engine,
AndroidLibraries = [
CreateAndroidLibraryTaskItem ("com.google.android.material.jar", pom.FilePath),
- CreateAndroidLibraryTaskItem ("com.google.android.material-core.jar", null, "com.google.android:material-core", "1.0"),
+ CreateAndroidLibraryTaskItem ("com.google.android.material-core.jar", null, "com.google.android:material-core:1.0"),
],
MicrosoftPackagesFile = package_finder.FilePath,
};
@@ -177,6 +177,7 @@ public void DependencyFulfilledByAndroidLibrary ()
{
using var pom = new PomBuilder ("com.google.android", "material", "1.0")
.WithDependency ("com.google.android", "material-core", "1.0")
+ .WithDependency ("com.google.android", "material-foo", "1.0")
.BuildTemporary ();
var engine = new MockBuildEngine (TestContext.Out, []);
@@ -184,7 +185,8 @@ public void DependencyFulfilledByAndroidLibrary ()
BuildEngine = engine,
AndroidLibraries = [
CreateAndroidLibraryTaskItem ("com.google.android.material.jar", pom.FilePath),
- CreateAndroidLibraryTaskItem ("com.google.android.material-core.jar", null, "com.google.android:material-core", "1.0"),
+ CreateAndroidLibraryTaskItem ("com.google.android.material-core.jar", null, "com.google.android:material-core:1.0"),
+ CreateAndroidLibraryTaskItem ("com.google.android.material-foo.jar", null, "org.jetbrains.kotlin:kotlin-stdlib:2.0.0,com.google.android:material-foo:1.0"),
],
};
@@ -199,6 +201,7 @@ public void DependencyFulfilledByProjectReferenceExplicitMetadata ()
{
using var pom = new PomBuilder ("com.google.android", "material", "1.0")
.WithDependency ("com.google.android", "material-core", "1.0")
+ .WithDependency ("com.google.android", "material-foo", "1.0")
.BuildTemporary ();
var engine = new MockBuildEngine (TestContext.Out, []);
@@ -208,7 +211,8 @@ public void DependencyFulfilledByProjectReferenceExplicitMetadata ()
CreateAndroidLibraryTaskItem ("com.google.android.material.jar", pom.FilePath),
],
ProjectReferences = [
- CreateAndroidLibraryTaskItem ("Google.Material.Core.csproj", null, "com.google.android:material-core", "1.0"),
+ CreateAndroidLibraryTaskItem ("Google.Material.Core.csproj", null, "com.google.android:material-core:1.0"),
+ CreateAndroidLibraryTaskItem ("Google.Material.Foo.csproj", null, "org.jetbrains.kotlin:kotlin-stdlib:2.0.0;com.google.android:material-foo:1.0"),
],
};
@@ -223,6 +227,7 @@ public void DependencyFulfilledByPackageReferenceExplicitMetadata ()
{
using var pom = new PomBuilder ("com.google.android", "material", "1.0")
.WithDependency ("com.google.android", "material-core", "1.0")
+ .WithDependency ("com.google.android", "material-foo", "1.0")
.BuildTemporary ();
var engine = new MockBuildEngine (TestContext.Out, []);
@@ -232,7 +237,8 @@ public void DependencyFulfilledByPackageReferenceExplicitMetadata ()
CreateAndroidLibraryTaskItem ("com.google.android.material.jar", pom.FilePath),
],
PackageReferences = [
- CreateAndroidLibraryTaskItem ("Xamarin.Google.Material.Core", null, "com.google.android:material-core", "1.0"),
+ CreateAndroidLibraryTaskItem ("Xamarin.Google.Material.Core", null, "com.google.android:material-core:1.0"),
+ CreateAndroidLibraryTaskItem ("Xamarin.Google.Material.Foo", null, "org.jetbrains.kotlin:kotlin-stdlib:2.0.0 com.google.android:material-foo:1.0"),
],
};
@@ -247,6 +253,7 @@ public void DependencyIgnored ()
{
using var pom = new PomBuilder ("com.google.android", "material", "1.0")
.WithDependency ("com.google.android", "material-core", "1.0")
+ .WithDependency ("com.google.android", "material-foo", "1.0")
.BuildTemporary ();
var engine = new MockBuildEngine (TestContext.Out, []);
@@ -256,7 +263,8 @@ public void DependencyIgnored ()
CreateAndroidLibraryTaskItem ("com.google.android.material.jar", pom.FilePath),
],
IgnoredDependencies = [
- CreateAndroidLibraryTaskItem ("com.google.android:material-core", rawVersion: "1.0"),
+ CreateAndroidLibraryTaskItem ("com.google.android:material-core:1.0"),
+ CreateAndroidLibraryTaskItem ("org.jetbrains.kotlin:kotlin-stdlib:2.0.0\r\ncom.google.android:material-foo:1.0"),
],
};
@@ -279,7 +287,7 @@ public void DependencyWithoutVersionFulfilled ()
BuildEngine = engine,
AndroidLibraries = [
CreateAndroidLibraryTaskItem ("com.google.android.material.jar", pom.FilePath),
- CreateAndroidLibraryTaskItem ("com.google.android.material-core.jar", null, "com.google.android:material-core", "1.0"),
+ CreateAndroidLibraryTaskItem ("com.google.android.material-core.jar", null, "com.google.android:material-core:1.0"),
],
};
@@ -312,7 +320,27 @@ public void DependencyWithoutVersionNotFulfilled ()
Assert.AreEqual ("Java dependency 'com.google.android:material-core' is not satisfied.", engine.Errors [0].Message);
}
- TaskItem CreateAndroidLibraryTaskItem (string name, string? manifest = null, string? javaArtifact = null, string? javaVersion = null, string? rawVersion = null)
+ [TestCase ("artifact_versioned=androidx.core:core:1.2.0", "androidx.core:core:1.2.0")]
+ [TestCase ("artifact_versioned=androidx.core:core", "")] // Invalid specification
+ [TestCase ("artifact_versioned=androidx.core:core:1.2.0 artifact_versioned=androidx.core:core:1.2.0", "androidx.core:core:1.2.0")] // Duplicates are ignored
+ [TestCase ("artifact_versioned=androidx.core:core:1.2.0 artifact_versioned=androidx.window.extensions.core:core:1.0.0", "androidx.core:core:1.2.0|androidx.window.extensions.core:core:1.0.0")]
+ [TestCase ("artifact_versioned=androidx.core:core:1.2.0 artifact=androidx.window.extensions.core:core:1.13.1", "androidx.core:core:1.2.0|androidx.window.extensions.core:core:1.13.1")]
+ [TestCase ("artifact=androidx.core:core:1.2.0 artifact=androidx.window.extensions.core:core:1.13.1", "androidx.core:core:1.2.0|androidx.window.extensions.core:core:1.13.1")]
+ public void AddArtifactsFromNuspecTagsTests (string tags, string expected)
+ {
+ var results = new List ();
+
+ NuGetPackageVersionFinder.AddArtifactsFromNuspecTags (results, tags);
+
+ if (!expected.HasValue ()) {
+ Assert.IsEmpty (results);
+ return;
+ }
+
+ Assert.AreEqual (expected, string.Join ("|", results.Select (p => p.VersionedArtifactString)));
+ }
+
+ TaskItem CreateAndroidLibraryTaskItem (string name, string? manifest = null, string? javaArtifact = null)
{
var item = new TaskItem (name);
@@ -320,10 +348,6 @@ TaskItem CreateAndroidLibraryTaskItem (string name, string? manifest = null, str
item.SetMetadata ("Manifest", manifest);
if (javaArtifact is not null)
item.SetMetadata ("JavaArtifact", javaArtifact);
- if (javaVersion is not null)
- item.SetMetadata ("JavaVersion", javaVersion);
- if (rawVersion is not null)
- item.SetMetadata ("Version", rawVersion);
return item;
}
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/MavenDownloadTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/MavenDownloadTests.cs
index c2ad0117fe4..749dadd35d9 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/MavenDownloadTests.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/MavenDownloadTests.cs
@@ -136,8 +136,7 @@ public async Task MavenCentralSuccess ()
var output_item = task.ResolvedAndroidMavenLibraries! [0];
- Assert.AreEqual ("com.google.auto.value:auto-value-annotations", output_item.GetMetadata ("JavaArtifact"));
- Assert.AreEqual ("1.10.4", output_item.GetMetadata ("JavaVersion"));
+ Assert.AreEqual ("com.google.auto.value:auto-value-annotations:1.10.4", output_item.GetMetadata ("JavaArtifact"));
Assert.AreEqual (Path.Combine (temp_cache_dir, "central", "com.google.auto.value", "auto-value-annotations", "1.10.4", "auto-value-annotations-1.10.4.pom"), output_item.GetMetadata ("Manifest"));
} finally {
DeleteTempDirectory (temp_cache_dir);
@@ -164,8 +163,7 @@ public async Task MavenGoogleSuccess ()
var output_item = task.ResolvedAndroidMavenLibraries! [0];
- Assert.AreEqual ("androidx.core:core", output_item.GetMetadata ("JavaArtifact"));
- Assert.AreEqual ("1.12.0", output_item.GetMetadata ("JavaVersion"));
+ Assert.AreEqual ("androidx.core:core:1.12.0", output_item.GetMetadata ("JavaArtifact"));
Assert.AreEqual (Path.Combine (temp_cache_dir, "google", "androidx.core", "core", "1.12.0", "core-1.12.0.pom"), output_item.GetMetadata ("Manifest"));
} finally {
DeleteTempDirectory (temp_cache_dir);
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/MavenExtensions.cs b/src/Xamarin.Android.Build.Tasks/Utilities/MavenExtensions.cs
index a9b881adec6..7782f36552b 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/MavenExtensions.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/MavenExtensions.cs
@@ -1,6 +1,7 @@
#nullable enable
using System;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
@@ -17,6 +18,7 @@ namespace Xamarin.Android.Tasks;
static class MavenExtensions
{
static readonly char [] separator = [':'];
+ static readonly char [] artifacts_separators = [';', ',', '\r', '\n', '\t', ' '];
///
/// Shortcut for !string.IsNullOrWhiteSpace (s)
@@ -54,47 +56,72 @@ public static bool TryParseArtifactWithVersion (string id, string version, TaskL
return true;
}
- public static bool TryParseJavaArtifactAndJavaVersion (this ITaskItem task, string type, TaskLoggingHelper log, [NotNullWhen (true)] out Artifact? artifact, out bool attributesSpecified)
+ public static bool TryParseArtifacts (string id, TaskLoggingHelper log, out List artifacts)
{
- artifact = null;
- var item_name = task.ItemSpec;
+ artifacts = new List ();
+ var result = true;
- // Convert "../../src/blah/Blah.csproj" to "Blah.csproj"
- if (type == "ProjectReference")
- item_name = Path.GetFileName (item_name);
+ var arts = id.Split (artifacts_separators, StringSplitOptions.RemoveEmptyEntries);
- var has_artifact = task.HasMetadata ("JavaArtifact");
- var has_version = task.HasMetadata ("JavaVersion");
+ foreach (var art in arts) {
- // Lets callers know if user attempted to specify JavaArtifact or JavaVersion, even if they did it incorrectly
- attributesSpecified = has_artifact || has_version;
+ if (Artifact.TryParse (art, out var a)) {
+ artifacts.Add (a);
+ continue;
+ }
+
+ log.LogCodedError ("XA4249", Properties.Resources.XA4249, art);
+ result = false;
+ }
- if (has_artifact && !has_version) {
- log.LogCodedError ("XA4243", Properties.Resources.XA4243, "JavaVersion", "JavaArtifact", type, item_name);
+ return result;
+ }
+
+ public static bool TryParseJavaArtifact (this ITaskItem task, string type, TaskLoggingHelper log, [NotNullWhen (true)]out Artifact? artifact, out bool attributesSpecified)
+ {
+ var result = TryParseJavaArtifacts (task, type, log, out var artifacts, out attributesSpecified);
+
+ if (!result) {
+ artifact = null;
return false;
}
- if (!has_artifact && has_version) {
- log.LogCodedError ("XA4243", Properties.Resources.XA4243, "JavaArtifact", "JavaVersion", type, item_name);
+ // TODO: Need a new message saying that only one JavaArtifact is allowed
+ if (artifacts.Count > 1) {
+ log.LogCodedError ("XA4243", Properties.Resources.XA4243, "JavaArtifact", type, task.ItemSpec);
+ artifact = null;
return false;
}
- if (has_artifact && has_version) {
+ artifact = artifacts.FirstOrDefault ();
+
+ return artifact is not null;
+ }
+
+ public static bool TryParseJavaArtifacts (this ITaskItem task, string type, TaskLoggingHelper log, out List artifacts, out bool attributesSpecified)
+ {
+ artifacts = new List ();
+ var item_name = task.ItemSpec;
+
+ var has_artifact = task.HasMetadata ("JavaArtifact");
+
+ // Lets callers know if user attempted to specify JavaArtifact, even if they did it incorrectly
+ attributesSpecified = has_artifact;
+
+ if (has_artifact) {
var id = task.GetMetadata ("JavaArtifact");
- var version = task.GetMetadata ("JavaVersion");
if (string.IsNullOrWhiteSpace (id)) {
log.LogCodedError ("XA4244", Properties.Resources.XA4244, "JavaArtifact", type, item_name);
return false;
}
- if (string.IsNullOrWhiteSpace (version)) {
- log.LogCodedError ("XA4244", Properties.Resources.XA4244, "JavaVersion", type, item_name);
- return false;
- }
+ if (TryParseArtifacts (id, log, out var parsed)) {
+ foreach (var art in parsed) {
+ log.LogMessage ("Found Java dependency '{0}:{1}' version '{2}' from {3} '{4}' (JavaArtifact)", art.GroupId, art.Id, art.Version, type, item_name);
+ artifacts.Add (art);
+ }
- if (TryParseArtifactWithVersion (id, version, log, out artifact)) {
- log.LogMessage ("Found Java dependency '{0}:{1}' version '{2}' from {3} '{4}' (JavaArtifact)", artifact.GroupId, artifact.Id, artifact.Version, type, item_name);
return true;
}
}