# Copyright 1999-2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

EAPI=8

# Upstream ships an in-tree PEP 517 backend (backends/pep517.py) that proxies
# flit_core and additionally generates the auto-complete index (awscli/data/
# ac.index) and injects it -- plus everything under bin/ -- into the wheel.
DISTUTILS_USE_PEP517=standalone
PYTHON_COMPAT=( python3_{12..14} )

inherit distutils-r1 shell-completion

MY_P=aws-cli-${PV}
DESCRIPTION="Universal Command Line Environment for AWS, version 2"
HOMEPAGE="
	https://aws.amazon.com/cli/
	https://github.com/aws/aws-cli/
"
# AWS CLI v2 is not published on PyPI -- the only source release is the
# GitHub tag.  Do not add the pypi eclass here.
SRC_URI="
	https://github.com/aws/aws-cli/archive/${PV}.tar.gz
		-> ${MY_P}.gh.tar.gz
"
S=${WORKDIR}/${MY_P}

LICENSE="Apache-2.0"
SLOT="0"
KEYWORDS="~amd64 ~arm64"

# awscli/{botocore,s3transfer} are vendored *forks* in v2, not copies of the
# upstream releases: the v2-only features (SSO, the auto-prompt, the new
# `aws s3` CRT transfer manager) live in those forks.  Unlike the v1 ebuild
# they must NOT be unbundled, and dev-python/{botocore,s3transfer} must not be
# pulled in -- they would only shadow the forks.
RDEPEND="
	>=dev-python/awscrt-0.36.2[${PYTHON_USEDEP}]
	>=dev-python/colorama-0.2.5[${PYTHON_USEDEP}]
	>=dev-python/distro-1.5.0[${PYTHON_USEDEP}]
	>=dev-python/docutils-0.10[${PYTHON_USEDEP}]
	>=dev-python/jmespath-0.7.1[${PYTHON_USEDEP}]
	>=dev-python/prompt-toolkit-3.0.24[${PYTHON_USEDEP}]
	>=dev-python/python-dateutil-2.1[${PYTHON_USEDEP}]
	>=dev-python/ruamel-yaml-0.15.0[${PYTHON_USEDEP}]
	>=dev-python/ruamel-yaml-clib-0.2.0[${PYTHON_USEDEP}]
	>=dev-python/urllib3-1.25.4[${PYTHON_USEDEP}]
	dev-python/wcwidth[${PYTHON_USEDEP}]
	!app-admin/awscli
	!app-admin/awscli-bin
"
# The backend imports awscli.autocomplete.generator and walks the whole
# clidriver to emit ac.index, so every runtime dependency has to be importable
# at build time as well.
BDEPEND="
	${RDEPEND}
	>=dev-python/flit-core-3.7.1[${PYTHON_USEDEP}]
	test? (
		dev-python/jsonschema[${PYTHON_USEDEP}]
	)
"

# The test suite declares no pytest_plugins and needs none of the plugins
# distutils-r1 would otherwise autoload; jsonschema (a plain import in
# tests/functional) is the only extra it actually uses.
EPYTEST_PLUGINS=()
EPYTEST_XDIST=1
distutils_enable_tests pytest

PATCHES=(
	# Upstream pins prompt-toolkit<3.0.52 to hide a real bug in its own
	# wizard toolbar; that pin is not satisfiable here, so fix the bug.
	"${FILESDIR}"/${PN}-prompt-toolkit-toolbar-init.patch
)

python_prepare_all() {
	distutils-r1_python_prepare_all

	# Strip upstream's overzealous upper bounds.  AWS ships a locked
	# dependency closure with its own bundled interpreter; on a distro the
	# ceilings are already violated by docutils, prompt-toolkit, distro,
	# jmespath, urllib3 and wcwidth.  The first two expressions mirror what
	# ::gentoo's app-admin/awscli does to setup.py; the third one is needed
	# because "wcwidth<0.3.0" has no comma before the ceiling.
	sed -i \
		-e 's:,<[=0-9.]*::' \
		-e 's:==:>=:' \
		-e 's:"wcwidth<[=0-9.]*":"wcwidth":' \
		pyproject.toml || die

	# A surviving ceiling does not fail the build -- it fails much later, when
	# a user's resolver refuses the installed version.  Assert instead.
	local leftover
	leftover=$(grep -n '^[[:space:]]*"[^"]*<' pyproject.toml)
	if [[ -n ${leftover} ]]; then
		eerror "Unrelaxed upper bound(s) left in pyproject.toml:"
		eerror "${leftover}"
		die "dependency ceiling relaxation is incomplete"
	fi
}

python_test() {
	# Cap the xdist workers by available memory, not by core count.  Every
	# worker imports the vendored botocore, whose 1868 service models (110M
	# of JSON on disk, several times that once parsed into Python dicts)
	# plus the 20M autocomplete index cost well over 1G of RSS each -- and
	# unlike a compiler process, a worker holds that for the whole run
	# instead of freeing it between files.  Measured on a 32-thread host:
	# the eclass default of -n32 (from MAKEOPTS) peaked above 50G, more
	# than a chromium build.  Re-measured at -n11: still a 60G peak, i.e.
	# ~5G per worker.  Budget 8G each, never exceed the core count, and let
	# anyone who knows their machine better override EPYTEST_JOBS.
	if [[ -z ${EPYTEST_JOBS} ]]; then
		local mem_gib=$(( $(awk '/MemAvailable/{ print $2 }' /proc/meminfo) / 1048576 ))
		local EPYTEST_JOBS=$(( mem_gib / 8 ))
		local cores=$(get_makeopts_jobs)
		(( EPYTEST_JOBS > cores )) && EPYTEST_JOBS=${cores}
		(( EPYTEST_JOBS < 1 )) && EPYTEST_JOBS=1
		einfo "Limiting pytest to ${EPYTEST_JOBS} job(s) for ${mem_gib}G available"
	fi

	# Only two of the five test trees are runnable here:
	#   tests/integration  - needs real AWS credentials and network access
	#   tests/dependencies - asserts the pinned closure in requirements*.txt
	#                        still matches pyproject.toml, which we relax above
	#   tests/backends     - exercises upstream's standalone installer/venv
	#                        machinery (and needs the deprecated dev-python/py),
	#                        none of which this ebuild uses
	local EPYTEST_DESELECT=(
		# Needs the generated ac.index, which lives in the *installed*
		# package; the source tree in ${S} occludes it during the run
		# (portage warns about this as an occluded package).
		tests/functional/autocomplete/test_main.py::test_smoke_test_completer

		# Asserts a specific locale.getpreferredencoding() result; depends
		# on the builder's locale, not on this package.
		"tests/unit/test_compat.py::TestGetPreferredEncoding::test_getpreferredencoding_with_env_var"
	)

	epytest tests/{functional,unit}
}

python_install_all() {
	newbashcomp bin/aws_bash_completer aws
	newzshcomp bin/aws_zsh_completer.sh _aws

	distutils-r1_python_install_all

	# The in-tree backend injects *everything* under bin/ into the wheel's
	# data/scripts directory, so all five files land in /usr/bin.  Keep `aws`
	# and `aws_completer` (the latter is what `complete -C` invokes); drop the
	# Windows launcher and the two completion snippets installed above.
	rm "${ED}"/usr/bin/{aws.cmd,aws_bash_completer,aws_zsh_completer.sh} || die
}