Skip to content

Resolve and refresh Android command-line tools by installed Pkg.Revision#12154

Open
rmarinho wants to merge 2 commits into
mainfrom
rmarinho-fix-cmdline-tools-resolution
Open

Resolve and refresh Android command-line tools by installed Pkg.Revision#12154
rmarinho wants to merge 2 commits into
mainfrom
rmarinho-fix-cmdline-tools-resolution

Conversation

@rmarinho

Copy link
Copy Markdown
Member

Summary

  • resolve sdkmanager, avdmanager, and future command-line tools through one shared Pkg.Revision-aware resolver
  • expose the selected manager path and revision, and conditionally install only cmdline-tools;latest when the installed manager is missing or stale
  • preserve legacy tools/bin/sdkmanager compatibility, parse available SDK updates correctly, and add coverage for precedence, fallbacks, prereleases, refresh, cancellation, and progress

Testing

  • dotnet test external/xamarin-android-tools/tests/Xamarin.Android.Tools.AndroidSdk-Tests/Xamarin.Android.Tools.AndroidSdk-Tests.csproj -c Release --no-restore --filter "FullyQualifiedName~CommandLineToolsResolverTests|FullyQualifiedName~SdkManagerTests"
  • dotnet build external/xamarin-android-tools/Xamarin.Android.Tools.sln -c Release --no-restore

Fixes #12137

Unify command-line tool discovery around Pkg.Revision and add a conditional cmdline-tools;latest refresh path.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 189aca0e-61f3-48f5-8a5c-aa9a6fdd7f9b
Copilot AI review requested due to automatic review settings July 17, 2026 11:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Xamarin.Android.Tools.AndroidSdk command-line tool discovery to be Pkg.Revision-aware, so sdkmanager/avdmanager selection is based on the highest installed revision (from source.properties) rather than directory name precedence, and adds an “ensure latest” workflow for conditional refresh.

Changes:

  • Added a shared CommandLineToolsResolver + new public SdkManager.FindSdkManager()/EnsureLatestCommandLineToolsAsync() APIs to select and refresh command-line tools by installed Pkg.Revision.
  • Updated ProcessUtils.FindCmdlineTool() and SdkManager.FindSdkManagerPath() to use the shared resolver (consistent selection across tools).
  • Improved sdkmanager --list parsing to include “Available Updates”, and added test coverage for precedence/fallbacks, prereleases, refresh, cancellation, and progress.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
external/xamarin-android-tools/tests/Xamarin.Android.Tools.AndroidSdk-Tests/SdkManagerTests.cs Updates list-parsing test to validate inclusion of “Available Updates”.
external/xamarin-android-tools/tests/Xamarin.Android.Tools.AndroidSdk-Tests/CommandLineToolsResolverTests.cs Adds coverage for revision-based selection, prerelease ordering, legacy fallback, and refresh behavior.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/SdkManager.Packages.cs Extends sdkmanager --list parsing to include updates in the available set.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/SdkManager.CommandLineTools.cs Introduces revision-aware sdkmanager discovery and conditional install of cmdline-tools;latest.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/ProcessUtils.cs Routes cmdline-tool discovery through the new resolver.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/Models/Sdk/SdkBootstrapProgress.cs Updates progress summary to cover refresh operations.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/Models/Sdk/SdkBootstrapPhase.cs Adds phases for update checking and installation.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/Models/Sdk/CommandLineTool.cs Adds a public model for resolved tool path + revision.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/CommandLineToolsResolver.cs Implements Pkg.Revision-aware resolution with deterministic fallback behavior.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt Declares newly introduced public APIs and enum members for netstandard2.0.
external/xamarin-android-tools/src/Xamarin.Android.Tools.AndroidSdk/PublicAPI/net10.0/PublicAPI.Unshipped.txt Declares newly introduced public APIs and enum members for net10.0.

Validate resolved tool paths and preserve disposal checks in the injectable ensure path.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 189aca0e-61f3-48f5-8a5c-aa9a6fdd7f9b
Comment on lines +38 to +40
var legacyPath = Path.Combine (sdkPath, "tools", "bin", toolName + extension);
if (!File.Exists (legacyPath))
return null;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would just remove this for any new code -- no one should be using tools only cmdline-tools.

Comment on lines +71 to +75
var normalizedVersion = new Version (
parsedVersion.Major,
Math.Max (parsedVersion.Minor, 0),
Math.Max (parsedVersion.Build, 0),
Math.Max (parsedVersion.Revision, 0));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why does this put 0's for all the components? It seems like we could just use what Version.TryParse() returns.

The reason this would be weird, is all the existing command-line tools versions only have two components like X.Y.

Comment on lines +139 to +141
var sourceProperties = Path.Combine (directory, "source.properties");
if (!File.Exists (sourceProperties))
return false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

source.properties is a common thing for all Android SDK components. Is this the first case we are parsing it? Or should we be reusing existing code.

If this is net-new code, should we put it in an internal utility class if we might use it elsewhere in the future?

Comment on lines +1 to +2
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We don't have to put these, do we know why the AI is doing it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Resolve and refresh Android command-line tools by installed Pkg.Revision

3 participants