Unverified Commit e23332c1 authored by @mjones's avatar @mjones Committed by GitHub
Browse files

androidenv: fix 'latest' where SDK level is not an int (#470569)

parents 9792f74f dcac273d
Loading
Loading
Loading
Loading
+54 −12
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ let
  # Coerces a string to an int.
  coerceInt = val: if lib.isInt val then val else lib.toIntBase10 val;

  coerceIntVersion = v: coerceInt (lib.versions.major v);
  coerceIntVersion = v: coerceInt (lib.versions.major (toString v));

  # Parses a single version, substituting "latest" with the latest version.
  parseVersion =
@@ -144,7 +144,7 @@ in

let
  # Resolve all the platform versions.
  platformVersions' = map coerceInt (parseVersions repo "platforms" platformVersions);
  platformVersions' = map coerceIntVersion (parseVersions repo "platforms" platformVersions);

  # Determine the Android os identifier from Nix's system identifier
  os =
@@ -220,6 +220,28 @@ let
    extras = fetchArchives repo.extras;
  };

  # Latest packages that are typically keyed by the API level.
  archivesByApiLevel =
    let
      # Transforms the given attrset mapping API levels (with possible suffixes and minor versions)
      # into the latest API level for each major version.
      mkLatestByApiLevel =
        packages:
        lib.filterAttrs (_: value: value != null) (
          lib.mapAttrs (
            _: value:
            (lib.findFirst (x: x.name == lib.versions.majorMinor x.name) { value = null; } (
              lib.lists.sort (x: y: lib.strings.versionOlder y.name x.name) value
            )).value
          ) (lib.groupBy (x: lib.versions.major x.name) (lib.attrsToList packages))
        );
    in
    {
      platforms = mkLatestByApiLevel allArchives.packages.platforms;
      sources = mkLatestByApiLevel allArchives.packages.sources;
      system-images = mkLatestByApiLevel allArchives.system-images;
    };

  # Lift the archives to the package level for easy search,
  # and add recurseIntoAttrs to all of them.
  allPackages =
@@ -284,17 +306,28 @@ let
    lib.hasAttrByPath [ package (toString version) ] packages;

  # Displays a nice error message that includes the available options if a version doesn't exist.
  # Note that allPackages can be a list of package sets, or a single package set. Pass a list if
  # you want to prioritize elements to the left (e.g. for passing a platform major version).
  checkVersion =
    packages: package: version:
    if hasVersion packages package version then
      packages.${package}.${toString version}
    else
    allPackages: package: version:
    let
      # Convert the package sets to a list.
      allPackages' = if lib.isList allPackages then allPackages else lib.singleton allPackages;

      # Pick the first package set where we have the version.
      packageSet = lib.findFirst (packages: hasVersion packages package version) null allPackages';
    in
    if packageSet == null then
      throw ''
        The version ${toString version} is missing in package ${package}.
        The only available versions are ${
          builtins.concatStringsSep ", " (builtins.attrNames packages.${package})
          lib.concatStringsSep ", " (
            lib.attrNames (lib.foldl (s: x: s // (x.${package} or { })) { } allPackages')
          )
        }.
      '';
      ''
    else
      packageSet.${package}.${toString version};

  # Returns true if we should link the specified plugins.
  shouldLink =
@@ -508,19 +541,23 @@ lib.recurseIntoAttrs rec {
    '';
  };

  # This is a list of the chosen API levels, as integers.
  platformVersions = platformVersions';

  platforms = map (
    version:
    deployAndroidPackage {
      package = checkVersion allArchives.packages "platforms" version;
      package = checkVersion [ archivesByApiLevel allArchives.packages ] "platforms" version;
    }
  ) platformVersions';

  # This exposes the version strings (e.g. "36.1" for API 36).
  platformVersionStrings = map (platform: platform.version) platforms;

  sources = map (
    version:
    deployAndroidPackage {
      package = checkVersion allArchives.packages "sources" version;
      package = checkVersion [ archivesByApiLevel allArchives.packages ] "sources" version;
    }
  ) platformVersions';

@@ -539,14 +576,19 @@ lib.recurseIntoAttrs rec {
        # ```
        let
          availablePackages =
            map (abiVersion: allArchives.system-images.${toString apiVersion}.${type}.${abiVersion})
            map
              (
                abiVersion:
                archivesByApiLevel.system-images.${toString apiVersion}.${type}.${abiVersion}
                or allArchives.system-images.${toString apiVersion}.${type}.${abiVersion}
              )
              (
                builtins.filter (
                  abiVersion: lib.hasAttrByPath [ (toString apiVersion) type abiVersion ] allArchives.system-images
                ) abiVersions
              );

          instructions = builtins.listToAttrs (
          instructions = lib.listToAttrs (
            map (package: {
              name = package.name;
              value = lib.optionalString (lib.hasPrefix "google_apis" type) ''
+6 −3
Original line number Diff line number Diff line
@@ -78,6 +78,9 @@ let
  androidSdk = androidComposition.androidsdk;
  platformTools = androidComposition.platform-tools;
  latestSdk = pkgs.lib.foldl' pkgs.lib.max 0 androidComposition.platformVersions;
  latestSdkVersion = pkgs.lib.foldl' (
    s: x: if pkgs.lib.strings.compareVersions x s > 0 then x else s
  ) "0" androidComposition.platformVersionStrings;
  jdk = pkgs.jdk;
in
pkgs.mkShell rec {
@@ -123,8 +126,8 @@ pkgs.mkShell rec {

          packages=(
            "build-tools" "cmdline-tools" \
            "platform-tools" "platforms;android-${toString latestSdk}" \
            "system-images;android-${toString latestSdk};google_apis;x86_64"
            "platform-tools" "platforms;android-${toString latestSdkVersion}" \
            "system-images;android-${toString latestSdkVersion};google_apis;x86_64"
          )
          ${pkgs.lib.optionalString emulatorSupported ''packages+=("emulator")''}

@@ -184,7 +187,7 @@ pkgs.mkShell rec {
            mkdir -p $ANDROID_USER_HOME

            avdmanager delete avd -n testAVD || true
            echo "" | avdmanager create avd --force --name testAVD --package 'system-images;android-${toString latestSdk};google_apis;x86_64'
            echo "" | avdmanager create avd --force --name testAVD --package 'system-images;android-${toString latestSdkVersion};google_apis;x86_64'
            result=$(avdmanager list avd)

            if [[ ! $result =~ "Name: testAVD" ]]; then
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ let
    includeSystemImages = false;
    includeEmulator = false;

    platformVersions = [ "latest" ];

    # Accepting more licenses declaratively:
    extraLicenses = [
      # Already accepted for you with the global accept_license = true or