Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[XABT] Allow deployment artifacts to specify multiple JavaDependencyVerification JavaArtifact libraries. #9112

Merged
merged 3 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1067,4 +1067,9 @@ To use a custom JDK path for a command line build, set the 'JavaSdkDirectory' MS
{2} - shared library file name
</comment>
</data>
<data name="XA4249" xml:space="preserve">
<value>Maven artifact specification '{0}' is invalid. The correct format is 'group_id:artifact_id:version'.</value>
<comment>The following are literal names and should not be translated: Maven, group_id, artifact_id
{0} - A Maven artifact specification</comment>
</data>
</root>
106 changes: 53 additions & 53 deletions src/Xamarin.Android.Build.Tasks/Tasks/JavaDependencyVerification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
}
Expand All @@ -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);

Expand All @@ -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;

Expand All @@ -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}:{1}' version '{2}'", art.GroupId, art.Id, art.Version);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we're now standardizing on "group:id:version" within %(JavaArtifacts), should we use that here as well?

artifacts.Add (art.ArtifactString, art);
}
}
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -349,9 +348,7 @@ public class Package
public class NuGetPackageVersionFinder
{
readonly LockFile lock_file;
readonly Dictionary<string, Artifact> cache = new Dictionary<string, Artifact> ();
readonly Regex tag = new Regex ("artifact_versioned=(?<GroupId>.+)?:(?<ArtifactId>.+?):(?<Version>.+)\\s?", RegexOptions.Compiled);
readonly Regex tag2 = new Regex ("artifact=(?<GroupId>.+)?:(?<ArtifactId>.+?):(?<Version>.+)\\s?", RegexOptions.Compiled);
readonly static Regex tag = new Regex (@"artifact(?:_versioned)?=(?<GroupId>[^:\s;,]+):(?<ArtifactId>[^:\s;,]+):(?<Version>[^:\s;,]+)", RegexOptions.Compiled, TimeSpan.FromSeconds (5));

NuGetPackageVersionFinder (LockFile lockFile)
{
Expand All @@ -370,59 +367,62 @@ public class NuGetPackageVersionFinder
}
}

public Artifact? GetJavaInformation (string library, string version, TaskLoggingHelper log)
public List<Artifact> 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<Artifact> ();

// 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<Artifact> 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<Artifact> 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;
}
}
}
6 changes: 2 additions & 4 deletions src/Xamarin.Android.Build.Tasks/Tasks/MavenDownload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -888,14 +888,9 @@ public void AndroidMavenLibrary_AllDependenciesAreVerified ()
var collection = new XamarinAndroidBindingProject ();

// Dependencies ignored by <AndroidIgnoredJavaDependency>
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 },
Expand All @@ -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 ();
Expand Down
Loading
Loading