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

androidenv: support nonstandard SDK versions (#473517)

parents c3e68d6b 03d6e4bc
Loading
Loading
Loading
Loading
+28 −41
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@ let
  # Parses a list of versions, substituting "latest" with the latest version.
  parseVersions =
    repo: key: versions:
    lib.unique (map (parseVersion repo key) versions);
    lib.sort (a: b: lib.strings.compareVersions (toString a) (toString b) > 0) (
      lib.unique (map (parseVersion repo key) versions)
    );
in
{
  repoJson ? ./repo.json,
@@ -98,14 +100,27 @@ in
  numLatestPlatformVersions ? 1,
  platformVersions ?
    if minPlatformVersion != null && maxPlatformVersion != null then
      # Range between min and max, inclusive.
      let
        minPlatformVersionInt = coerceIntVersion (parseVersion repo "platforms" minPlatformVersion);
        maxPlatformVersionInt = coerceIntVersion (parseVersion repo "platforms" maxPlatformVersion);
      in
      lib.range (lib.min minPlatformVersionInt maxPlatformVersionInt) (
        minPlatformVersion' = parseVersion repo "platforms" minPlatformVersion;
        maxPlatformVersion' = parseVersion repo "platforms" maxPlatformVersion;
        minPlatformVersionInt = coerceIntVersion minPlatformVersion';
        maxPlatformVersionInt = coerceIntVersion maxPlatformVersion';
        range = lib.range (lib.min minPlatformVersionInt maxPlatformVersionInt) (
          lib.max minPlatformVersionInt maxPlatformVersionInt
      )
        );
      in
      # Don't use the actual latest version in lieu of the rounded version here,
      # since when Google upgrades it would have the nasty side effect of being
      # unstable and picking 35 -> 36 -> 37 instead of 35 -> 36.1 -> 37.
      # Best to stay consistent.
      #
      # However, if only one platform is requested and it's the latest (which is the default),
      # we should use it.
      if lib.length range == 1 then lib.singleton maxPlatformVersion' else range
    else
      # Use numLatestPlatformVersions with a lower cutoff of minPlatformVersion (defaulting to 1)
      # to determine how many of the latest *major* versions we should pick.
      let
        minPlatformVersionInt =
          if minPlatformVersion == null then
@@ -116,8 +131,10 @@ in
        firstPlatformVersionInt = lib.max minPlatformVersionInt (
          latestPlatformVersionInt - (lib.max 1 numLatestPlatformVersions) + 1
        );
        range = lib.range firstPlatformVersionInt latestPlatformVersionInt;
      in
      lib.range firstPlatformVersionInt latestPlatformVersionInt,
      # Ditto, see above.
      if lib.length range == 1 then lib.singleton repo.latest.platforms else range,
  includeSources ? false,
  includeSystemImages ? false,
  systemImageTypes ? [
@@ -144,7 +161,7 @@ in

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

  # Determine the Android os identifier from Nix's system identifier
  os =
@@ -220,28 +237,6 @@ 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 =
@@ -547,17 +542,14 @@ lib.recurseIntoAttrs rec {
  platforms = map (
    version:
    deployAndroidPackage {
      package = checkVersion [ archivesByApiLevel allArchives.packages ] "platforms" version;
      package = checkVersion 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 [ archivesByApiLevel allArchives.packages ] "sources" version;
      package = checkVersion allArchives.packages "sources" version;
    }
  ) platformVersions';

@@ -576,12 +568,7 @@ lib.recurseIntoAttrs rec {
        # ```
        let
          availablePackages =
            map
              (
                abiVersion:
                archivesByApiLevel.system-images.${toString apiVersion}.${type}.${abiVersion}
                or allArchives.system-images.${toString apiVersion}.${type}.${abiVersion}
              )
            map (abiVersion: allArchives.system-images.${toString apiVersion}.${type}.${abiVersion})
              (
                builtins.filter (
                  abiVersion: lib.hasAttrByPath [ (toString apiVersion) type abiVersion ] allArchives.system-images
+8 −7
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ let
    };
  */

  inherit (pkgs) lib;

  # Otherwise, just use the in-tree androidenv:
  androidEnv = pkgs.callPackage ./.. {
    inherit pkgs licenseAccepted;
@@ -77,10 +79,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;
  latestSdkVersion = lib.foldl' (
    s: x: if lib.strings.compareVersions (toString x) s > 0 then toString x else s
  ) "0" androidComposition.platformVersions;
  jdk = pkgs.jdk;
in
pkgs.mkShell rec {
@@ -129,7 +130,7 @@ pkgs.mkShell rec {
            "platform-tools" "platforms;android-${toString latestSdkVersion}" \
            "system-images;android-${toString latestSdkVersion};google_apis;x86_64"
          )
          ${pkgs.lib.optionalString emulatorSupported ''packages+=("emulator")''}
          ${lib.optionalString emulatorSupported ''packages+=("emulator")''}

          for package in "''${packages[@]}"; do
            if [[ ! $installed_packages_section =~ "$package" ]]; then
@@ -154,7 +155,7 @@ pkgs.mkShell rec {
          installed_packages_section=$(echo "''${output%%Available Packages*}" | awk 'NR>4 {print $1}')

          excluded_packages=(ndk)
          for x in $(seq 1 ${toString latestSdk}); do
          for x in $(seq 1 ${lib.versions.major (toString latestSdkVersion)}); do
            excluded_packages+=(
              "platforms;android-$x"
              "sources;android-$x"
@@ -182,7 +183,7 @@ pkgs.mkShell rec {
          ];
        }
        (
          pkgs.lib.optionalString emulatorSupported ''
          lib.optionalString emulatorSupported ''
            export ANDROID_USER_HOME=$PWD/.android
            mkdir -p $ANDROID_USER_HOME

+13 −4
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ let
    };
  */

  inherit (pkgs) lib;

  # Otherwise, just use the in-tree androidenv:
  androidEnv = pkgs.callPackage ./.. {
    inherit pkgs licenseAccepted;
@@ -48,7 +50,13 @@ let
    includeSystemImages = false;
    includeEmulator = false;

    platformVersions = [ "latest" ];
    platformVersions = [
      "UpsideDownCake"
      "36"
      "36x"
      "latest"
      "CANARY"
    ];

    # Accepting more licenses declaratively:
    extraLicenses = [
@@ -70,7 +78,9 @@ let
  androidComposition = androidEnv.composeAndroidPackages sdkArgs;
  androidSdk = androidComposition.androidsdk;
  platformTools = androidComposition.platform-tools;
  latestSdk = pkgs.lib.foldl' pkgs.lib.max 0 androidComposition.platformVersions;
  latestSdkVersion = lib.foldl' (
    s: x: if lib.strings.compareVersions (toString x) s > 0 then toString x else s
  ) "0" androidComposition.platformVersions;
  jdk = pkgs.jdk;
in
pkgs.mkShell {
@@ -97,7 +107,6 @@ pkgs.mkShell {
  '';

  passthru.tests = {

    shell-without-emulator-sdkmanager-packages-test =
      pkgs.runCommand "shell-without-emulator-sdkmanager-packages-test"
        {
@@ -113,7 +122,7 @@ pkgs.mkShell {

          packages=(
            "build-tools" "cmdline-tools" \
            "platform-tools" "platforms;android-${toString latestSdk}"
            "platform-tools" "platforms;android-${toString latestSdkVersion}"
          )

          for package in "''${packages[@]}"; do
+10 −8
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ let
    };
  */

  inherit (pkgs) lib;

  # Otherwise, just use the in-tree androidenv:
  androidEnv = pkgs.callPackage ./.. {
    inherit pkgs licenseAccepted;
@@ -109,8 +111,12 @@ let

  androidSdk = androidComposition.androidsdk;
  platformTools = androidComposition.platform-tools;
  firstSdk = pkgs.lib.foldl' pkgs.lib.min 100 androidComposition.platformVersions;
  latestSdk = pkgs.lib.foldl' pkgs.lib.max 0 androidComposition.platformVersions;
  firstSdkVersion = lib.foldl' (
    s: x: if lib.strings.compareVersions (toString x) s < 0 then toString x else s
  ) "100" androidComposition.platformVersions;
  latestSdkVersion = lib.foldl' (
    s: x: if lib.strings.compareVersions (toString x) s > 0 then toString x else s
  ) "0" androidComposition.platformVersions;
  jdk = pkgs.jdk;
in
pkgs.mkShell rec {
@@ -181,15 +187,11 @@ pkgs.mkShell rec {
            "extras;google;gcm"
          )

          for x in $(seq ${toString firstSdk} ${toString latestSdk}); do
            if [ $x -ne 34 ]; then
              # FIXME couldn't find platforms;android-34, even though it's in the correct directory!! sdkmanager's bug?!
              packages+=("platforms;android-$x")
            fi
          for x in $(seq ${toString firstSdkVersion} ${toString latestSdkVersion}); do
            packages+=("sources;android-$x")
          done

          ${pkgs.lib.optionalString includeAuto ''packages+=("extras;google;auto")''}
          ${lib.optionalString includeAuto ''packages+=("extras;google;auto")''}

          for package in "''${packages[@]}"; do
            if [[ ! $installed_packages_section =~ "$package" ]]; then