Open
Conversation
10b4527 to
1a94a8d
Compare
tests/Xamarin.Android.Tools.AndroidSdk-Tests/SdkManagerTests.cs
Outdated
Show resolved
Hide resolved
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
930f96d to
8bc3209
Compare
5565656 to
bdeeb7f
Compare
Contributor
- Add TryDeleteFiles batch helper to FileUtil - Use FileUtil.TryDeleteFiles/TryDeleteDirectory in SdkManager cleanup - Replace direct Process.Start in SetExecutablePermissions with ProcessUtils - Add XML doc remarks explaining why elevated flow uses Process.Start directly - Simplify RunSdkManagerElevatedAsync temp file management - Use single GUID for all temp files in elevated flow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Check exitCode from sdkmanager --licenses - Only treat non-zero as non-fatal when output matches known 'already accepted' cases - Throw InvalidOperationException for genuine failures (missing Java, permissions, etc.) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… ManifestSource property Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace duplicated path-writability check with existing FileUtil helper. Direct Process.Start in elevated path is intentional (UAC requires UseShellExecute). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add environment variables and UseShellExecute support to ProcessUtils.StartProcess - Replace SdkManager.VerifyChecksum with DownloadUtils.VerifyChecksum - Replace SdkManager.DownloadFileAsync with DownloadUtils.DownloadFileAsync - Refactor RunSdkManagerElevatedAsync to use ProcessUtils - Remove ~60 lines of duplicated process/download code Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e AndroidEnvironmentHelper, reorder methods - Replace raw ProcessStartInfo with ProcessUtils.CreateProcessStartInfo in SdkManager.Process and Licenses - Merge two VerifyChecksum overloads into single method with default parameter - Restore AndroidEnvironmentHelper (consumed by maui DevTools CLI) - Move public AreLicensesAccepted before internal/private methods in Licenses Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ckupPath, fix XML docs - Change RunSdkManagerAsync to accept string[] instead of single string - Pass packages as individual args to avoid ArgumentList quoting issues - Escape arguments in elevated cmd.exe script to prevent injection - Fix httpClient field indentation in SdkManager.cs - Null-guard backupPath in Bootstrap.cs cleanup - Split duplicate XML doc blocks in ProcessUtils.cs - Split cmd.exe args properly: /c and script path as separate args Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…unner - Validate package arguments reject shell-special characters (&|><^) - Apply sanitization to env vars and arguments in elevated script Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Replace async ProcessUtils.StartProcess().Result with synchronous Process.Start/WaitForExit to avoid thread-pool starvation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace single 'echo y|' with a for-loop that generates 100 'y' responses, matching the non-elevated path's continuous feeding behavior. This ensures multi-license operations complete successfully. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dkManagerFailure helpers - Extract RequireSdkManagerPath() combining ThrowIfDisposed + FindSdkManagerPath - Extract ThrowOnSdkManagerFailure() to consolidate error logging + throw pattern - Simplify GetEnvironmentVariables() with collection initializer - Remove verbose XML doc comments on private methods - Net reduction: 39 lines across 4 files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nownVersions, use ProcessUtils in FileUtil - Fix double-enumeration in InstallAsync/UninstallAsync by materializing once - Derive ApiLevelToVersionMap from AndroidVersions.KnownVersions instead of hardcoding - Use ProcessUtils.StartProcess in SetExecutablePermissions instead of raw Process - Reword copilot-instructions to clarify ProcessUtils wraps ArgumentList Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rename to SetExecutablePermissionsAsync with CancellationToken support - Remove .GetAwaiter().GetResult() blocking call - Properly await ProcessUtils.StartProcess in bootstrap flow Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The sdkmanager shell script uses save()/eval which concatenates individually-quoted arguments into a single string. On macOS/Linux, pass arguments as a single Arguments string instead of ArgumentList to work around this shell script bug. Also fix double-enumeration in UninstallAsync by materializing the packages collection upfront. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nd SetExecutablePermissionsAsync - Chmod: Use managed File.SetUnixFileMode on net7.0+ instead of P/Invoke (see https://learn.microsoft.com/dotnet/api/system.io.file.setunixfilemode) - CopyDirectoryRecursive: Use DirectoryInfo, validate source exists (based on patterns from https://github.com/dotnet/sdk) - SetExecutablePermissionsAsync: Add cancellation check per file - Guard libc chmod P/Invoke with #if !NET7_0_OR_GREATER Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ariables Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Convert SdkBootstrapProgress, SdkLicense, SdkManifestComponent to records - Remove unused methods from AndroidEnvironmentHelper (GetRuntimeIdentifiers, MapApiLevelToVersion, MapTagIdToDisplayName) per review guidance - Fix copilot-instructions: use mslearn MCP instead of listing API limitations, remove dotnet-format suggestion to avoid mass reformatting - Fix chmod comment to clarify C# lacks octal literals - Simplify license check loop: remove initial 500ms delay, put delay first - Add .nupkg to .gitignore - Simplify BootstrapAsync and Packages code Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…cords Use one-liner positional record syntax and update all call sites to constructor syntax. Remove EnvironmentVariableNames usage from this PR (handled by #290). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
6afcbfa to
05eefc5
Compare
Remove StartShellExecuteProcessAsync, RequiresElevation, RunSdkManagerElevatedAsync, and SanitizeCmdArgument. Elevation support will be added in a separate PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The AbiToArchMap and MapAbiToArchitecture were not used by any code. Keep only GetEnvironment which is used by SdkManager. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Avoids typos and string comparisons. The XML attribute value is parsed into the enum during manifest parsing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove unused AndroidEnvironmentHelper class - Remove unused SdkManagerTimeout property - Remove unused sdkManagerPath in AcceptLicensesAsync - Make SdkManifestComponent and GetManifestComponentsAsync internal - Remove unused TryDeleteFiles and CopyDirectoryRecursive from FileUtil Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reuse the existing DownloadUtils.ReadAsStringAsync helper which handles the netstandard2.0 vs NET5+ API difference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use a list reference instead of string section tracking, eliminating duplicate add logic and string comparisons. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds SDK bootstrap and
sdkmanagerwrapper toXamarin.Android.Tools.AndroidSdk, enabling programmatic Android SDK setup from scratch.Closes #271
Architecture
Two-phase approach:
cmdline-tools/<version>/sdkmanagerCLI for all package operationsFile Structure
SdkManageris split into focused partial classes for maintainability:SdkManager.cs- Core class, properties, constructor, dispose (~84 lines)SdkManager.Manifest.cs- Manifest download and XML parsing (~141 lines)SdkManager.Bootstrap.cs- SDK bootstrap/download/extract flow (~175 lines)SdkManager.Packages.cs- Package list/install/uninstall/update + output parsing (~228 lines)SdkManager.Licenses.cs- License accept/parse/check operations (~246 lines)SdkManager.Process.cs- Process execution, elevation, download, checksum, env config (~307 lines)Supporting files:
EnvironmentVariableNames.cs- Centralized constants forANDROID_HOME,JAVA_HOME, etc.FileUtil.cs- Extended with chmod, recursive copy, executable permissions, elevation checkModels/Sdk/*.cs- Data models:SdkPackage,SdkLicense,SdkManifestComponent,SdkBootstrapProgress.github/copilot-instructions.md- Updated coding conventionsSdkManagerTests.cs- 534 lines of testsKey Features
~/.androidso sdkmanager writes install properties in user-writable locationDirectory.Movefalls back to recursive copyFileUtil.cs- no duplication across domain classesTests
89 tests pass (4 skipped). Covers manifest parsing, list output parsing, license parsing, error cases.
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com