From c2597065fbda27db4f1df4fbf42b97b20aa590b5 Mon Sep 17 00:00:00 2001 From: gryf Date: Mon, 24 Aug 2020 14:32:25 +0200 Subject: [PATCH] Added xonsh shell from rindeal repo. --- app-shells/xonsh/Manifest | 4 + app-shells/xonsh/xonsh-0.9.19.ebuild | 54 +++ app-shells/xonsh/xonsh-0.9.9.ebuild | 54 +++ eclass/arrays.eclass | 55 +++ eclass/git-hosting.eclass | 511 ++++++++++++++++++++++++ eclass/portage-functions-patched.eclass | 19 + eclass/rindeal.eclass | 355 ++++++++++++++++ 7 files changed, 1052 insertions(+) create mode 100644 app-shells/xonsh/Manifest create mode 100644 app-shells/xonsh/xonsh-0.9.19.ebuild create mode 100644 app-shells/xonsh/xonsh-0.9.9.ebuild create mode 100644 eclass/arrays.eclass create mode 100644 eclass/git-hosting.eclass create mode 100644 eclass/portage-functions-patched.eclass create mode 100644 eclass/rindeal.eclass diff --git a/app-shells/xonsh/Manifest b/app-shells/xonsh/Manifest new file mode 100644 index 0000000..cd84c35 --- /dev/null +++ b/app-shells/xonsh/Manifest @@ -0,0 +1,4 @@ +DIST github--xonsh--xonsh--0.9.19.tar.gz 2535369 BLAKE2B b3ecf5be62540cc62494a8f845abf055a8c3085d90c60e18c2c6fe2b02c72ebd028538991fa6c837c83b3020a0c0a1f21785ca40e6d309f93b882334e92566f5 SHA512 d49e8a327a48e7b8ba047cd3e0930d6da1334b0057e8ab374c310c5cff14230c1efd1a9597c5df17f56f4b3d02a4fc78cceb2b766da1dbeaf4cb46266cc4e568 +DIST github--xonsh--xonsh--0.9.9.tar.gz 2030995 BLAKE2B 07c6f3f7cc5fe04168b87dfe96707961573e33f58cd157f44512351af23590e52e8591af990040e39744742b41d3f9546104117eaf26bf56c56da0bbcefcdce8 SHA512 16fb0e8df19427a89589016cb31980ea1ca5646286ab004cc1c06ec5778ed53c420c6e5e36ae972c85fe76f33f0d0e6dad69287901e9a8d40ed57e719f8306dd +EBUILD xonsh-0.9.19.ebuild 1218 BLAKE2B dc8257a360d35aee80df9096c2f3751ad1b55fa23375d87448c641bd416a681beec6037b15871007a26ebd161d9497bacd371536e098c8090d800f581b671e53 SHA512 99556e8c59edf24195e143403dee617dd1520394af162bee34890976fa168cfea9a067f9c396d85cd0e56d7ba279266df91c652850a6b5e5c96e3fa8fca646e7 +EBUILD xonsh-0.9.9.ebuild 1218 BLAKE2B dc8257a360d35aee80df9096c2f3751ad1b55fa23375d87448c641bd416a681beec6037b15871007a26ebd161d9497bacd371536e098c8090d800f581b671e53 SHA512 99556e8c59edf24195e143403dee617dd1520394af162bee34890976fa168cfea9a067f9c396d85cd0e56d7ba279266df91c652850a6b5e5c96e3fa8fca646e7 diff --git a/app-shells/xonsh/xonsh-0.9.19.ebuild b/app-shells/xonsh/xonsh-0.9.19.ebuild new file mode 100644 index 0000000..cc42beb --- /dev/null +++ b/app-shells/xonsh/xonsh-0.9.19.ebuild @@ -0,0 +1,54 @@ +# Copyright 1999-2017 Gentoo Foundation +# Copyright 2017-2019 Jan Chren (rindeal) +# Distributed under the terms of the GNU General Public License v2 + +# NOTICE: ebuild is not finished, but basic features should work + +EAPI=7 +inherit rindeal + +## git-hosting.eclass: +GH_RN="github" + +## python-*.eclass: +PYTHON_COMPAT=( python3_{5,6,7} ) + +## EXPORT_FUNCTIONS: src_unpack +inherit git-hosting + +## EXPORT_FUNCTIONS: src_prepare src_configure src_compile src_test src_install +## variables: PYTHON_USEDEP +inherit distutils-r1 + +## functions: optfeature +inherit eutils + +DESCRIPTION="Python-powered, cross-platform, Unix-gazing shell" +HOMEPAGE_A=( + "https://xonsh.readthedocs.org/" + "${GH_HOMEPAGE}" +) +LICENSE="BSD" + +SLOT="0" + +KEYWORDS="~amd64 ~arm ~arm64" +IUSE_A=( ) + +CDEPEND_A=( + "dev-python/ply[${PYTHON_USEDEP}]" + "dev-python/pygments[${PYTHON_USEDEP}]" +) +DEPEND_A=( "${CDEPEND_A[@]}" + # setup.py is not using 'console_scripts' so no runtime dep on setuptools + "dev-python/setuptools[${PYTHON_USEDEP}]" +) +RDEPEND_A=( "${CDEPEND_A[@]}" ) + +inherit arrays + +pkg_postinst() { + elog "Optional features" + optfeature "Jupyter kernel support" dev-python/jupyter + optfeature "Alternative to readline backend" dev-python/prompt_toolkit +} diff --git a/app-shells/xonsh/xonsh-0.9.9.ebuild b/app-shells/xonsh/xonsh-0.9.9.ebuild new file mode 100644 index 0000000..cc42beb --- /dev/null +++ b/app-shells/xonsh/xonsh-0.9.9.ebuild @@ -0,0 +1,54 @@ +# Copyright 1999-2017 Gentoo Foundation +# Copyright 2017-2019 Jan Chren (rindeal) +# Distributed under the terms of the GNU General Public License v2 + +# NOTICE: ebuild is not finished, but basic features should work + +EAPI=7 +inherit rindeal + +## git-hosting.eclass: +GH_RN="github" + +## python-*.eclass: +PYTHON_COMPAT=( python3_{5,6,7} ) + +## EXPORT_FUNCTIONS: src_unpack +inherit git-hosting + +## EXPORT_FUNCTIONS: src_prepare src_configure src_compile src_test src_install +## variables: PYTHON_USEDEP +inherit distutils-r1 + +## functions: optfeature +inherit eutils + +DESCRIPTION="Python-powered, cross-platform, Unix-gazing shell" +HOMEPAGE_A=( + "https://xonsh.readthedocs.org/" + "${GH_HOMEPAGE}" +) +LICENSE="BSD" + +SLOT="0" + +KEYWORDS="~amd64 ~arm ~arm64" +IUSE_A=( ) + +CDEPEND_A=( + "dev-python/ply[${PYTHON_USEDEP}]" + "dev-python/pygments[${PYTHON_USEDEP}]" +) +DEPEND_A=( "${CDEPEND_A[@]}" + # setup.py is not using 'console_scripts' so no runtime dep on setuptools + "dev-python/setuptools[${PYTHON_USEDEP}]" +) +RDEPEND_A=( "${CDEPEND_A[@]}" ) + +inherit arrays + +pkg_postinst() { + elog "Optional features" + optfeature "Jupyter kernel support" dev-python/jupyter + optfeature "Alternative to readline backend" dev-python/prompt_toolkit +} diff --git a/eclass/arrays.eclass b/eclass/arrays.eclass new file mode 100644 index 0000000..1779059 --- /dev/null +++ b/eclass/arrays.eclass @@ -0,0 +1,55 @@ +# Copyright 2016-2019 Jan Chren (rindeal) +# Distributed under the terms of the GNU General Public License v2 + +### +# Usage: +# +# CDEPEND_A=() +# DEPEND_A=( "${CDEPEND_A[@]}" ) +# RDEPEND_A=( "${CDEPEND_A[@]}" ) +# +# inherit arrays +# +### + + +case "${EAPI:-0}" in +'6' | '7' ) ;; +* ) die "Unsupported EAPI='${EAPI}' for '${ECLASS}'" ;; +esac + + +_v_a=( + HOMEPAGE LICENSE + + SRC_URI + + KEYWORDS + IUSE + + {C,,R,P,B}DEPEND + + REQUIRED_USE + + ## java-*.eclass: + CP_DEPEND + JAVA_SRC_DIR +) +for _v in "${_v_a[@]}" +do + if [[ "$(declare -p ${_v}_A 2>/dev/null)" == "declare -a"* ]] + then + debug-print "${ECLASS}: Converting '${_v}_A' to '${_v}'" + + debug-print "${ECLASS}: Current value='${!_v}'" + eval "${_v}=\" \${${_v}_A[*]}\"" + debug-print "${ECLASS}: New value='${!_v}'" + + debug-print "${ECLASS}: Unsetting '${_v}_A'" + unset "${_v}_A" + elif [[ -v ${_v} ]] + then + debug-print "${ECLASS}: Variable '${_v}' exists, but is not an array." + fi +done +unset _v _v_a diff --git a/eclass/git-hosting.eclass b/eclass/git-hosting.eclass new file mode 100644 index 0000000..24003aa --- /dev/null +++ b/eclass/git-hosting.eclass @@ -0,0 +1,511 @@ +# Copyright 2016-2017,2019 Jan Chren (rindeal) +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: git-hosting.eclass +# @MAINTAINER: +# Jan Chren (rindeal) +# @BLURB: Support eclass for packages hosted on online git hosting services like GitHub + +if [[ -z "${_RINDEAL_GH_ECLASS}" ]] +then + +case "${EAPI:-0}" in +6 | 7 ) ;; +* ) die "Unsupported EAPI='${EAPI}' for '${ECLASS}'" ;; +esac + + +### BEGIN Constants + +declare -g -r -a -- _GH_AVAILABLE_PROVIDERS=( + bitbucket + github + gitlab + kernel + freedesktop +) + +### END Constants + + +### BEGIN Base classes + +_gh_provider:bitbucket:base_url() { printf '%s' 'bitbucket.org' ; } +_gh_provider:bitbucket:snap_ext() { printf '%s' '.tar.bz2' ; } +_gh_provider:bitbucket:snap_url_tail() { + (( $# != 1 )) && die + + local -r -- ref="${1}" + local -r -- snap_ext="$(_gh_provider:bitbucket:snap_ext)" + + printf '%s' "get/${ref}${snap_ext}" +} + + +_gh_provider:github:base_url() { printf '%s' 'github.com' ; } +_gh_provider:github:snap_ext() { printf '%s' '.tar.gz' ; } +_gh_provider:github:snap_url_tail() { + (( $# != 1 )) && die + + local -r -- ref="${1}" + local -r -- snap_ext="$(_gh_provider:github:snap_ext)" + + printf '%s' "archive/${ref}${snap_ext}" +} + + +_gh_provider:gitlab:base_url() { printf '%s' 'gitlab.com' ; } +_gh_provider:gitlab:snap_ext() { printf '%s' '.tar.bz2' ; } +_gh_provider:gitlab:snap_url_tail() { + (( $# != 1 )) && die + + local -r -- ref="${1}" + local -r -- snap_ext="$(_gh_provider:gitlab:snap_ext)" + + printf '%s' "repository/archive${snap_ext}?ref=${ref}" +} + + +_gh_provider:kernel:base_url() { printf '%s' 'git.kernel.org/pub/scm' ; } +_gh_provider:kernel:snap_ext() { printf '%s' '.tar.gz' ; } +_gh_provider:kernel:snap_url_tail() { + (( $# != 1 )) && die + + local -r -- ref="${1}" + local -r -- snap_ext="$(_gh_provider:kernel:snap_ext)" + + printf '%s' "snapshot/${ref}${snap_ext}" +} + + +_gh_provider:freedesktop:base_url() { printf '%s' 'cgit.freedesktop.org' ; } +_gh_provider:freedesktop:snap_ext() { printf '%s' '.tar.bz2' ; } +_gh_provider:freedesktop:snap_url_tail() { + (( $# != 1 )) && die + + local -r -- ref="${1}" + local -r -- snap_ext="$(_gh_provider:freedesktop:snap_ext)" + + printf '%s' "snapshot/${ref}${snap_ext}" +} + + +_gh_provider:gentoo:base_url() { printf '%s' 'gitweb.gentoo.org' ; } +_gh_provider:gentoo:snap_ext() { printf '%s' '.tar.bz2' ; } +_gh_provider:gentoo:snap_url_tail() { + (( $# != 1 )) && die + + local -r -- ref="${1}" + local -r -- snap_ext="$(_gh_provider:gentoo:snap_ext)" + + printf '%s' "snapshot/${ref}${snap_ext}" +} + +### END Base classes + + +### BEGIN Functions + +_gh_provider:exists() { + (( $# != 1 )) && die + + local -r -- provider="${1}" + + local e + for e in "${_GH_AVAILABLE_PROVIDERS[@]}"; do + [[ "${e}" == "${provider}" ]] && return 0 + done + + return 1 +} + +## +# @FUNCTION: _gh_parse_rn +# @PRIVATE +# @USAGE: $0 "${rn}" provider path repo +# @DESCRIPTION: parses RN into its components +## +_gh_parse_rn() { + (( $# != 4 )) && die "${FUNCNAME}: Not enough arguments provided" + + local -r -- rn="${1}" ; shift + local -n -- provider_nref="${1}" ; shift + local -n -- path_nref="${1}" ; shift + local -n -- repo_nref="${1}" ; shift + + # TODO: change it to allow for spaces in components + local -r -a rn_a=( ${rn//':'/ } ) + + case "${#rn_a[*]}" in + '3' ) + repo_nref="${rn_a[2]}" + ;& + '2' ) + path_nref="${rn_a[1]}" + ;& + '1' ) + provider_nref="${rn_a[0]}" + ;; + * ) + die + ;; + esac + + return 0 +} + +## +# @FUNCTION: _gh_gen_repo_url +# @PRIVATE +# @USAGE: $0 "${provider}" "${path}" "${repo}" repo_url +# @DESCRIPTION: Generate base URL of the repository. Can be used as a homepage. +## +_gh_gen_repo_url() { + (( $# != 4 )) && die "${FUNCNAME}: Not enough arguments provided" + + local -r -- provider="${1}" ; shift + local -r -- path="${1}" ; shift + local -r -- repo="${1}" ; shift + local -n -- repo_url_nref="${1}" ; shift + + local -r -- base_url="$(_gh_provider:${provider}:base_url)" + + repo_url_nref="https://${base_url}${path:+"/${path}"}${repo:+"/${repo}"}" + + return 0 +} + + +## +# @FUNCTION: git-hosting_gen_live_url +# @USAGE: $0 "${gh_rn}" live_url +# @DESCRIPTION: Generate URL for git +## +git-hosting_gen_live_url() { + (( $# != 2 )) && die "${FUNCNAME}: Not enough arguments provided" + + local -r -- rn="${1}" ; shift + local -n -- live_url_nref="${1}" ; shift + + local -- provider user repo + _gh_parse_rn "${rn}" provider user repo + readonly provider user repo + + local -- repo_url + _gh_gen_repo_url "${provider}" "${user}" "${repo}" repo_url + readonly repo_url + + live_url_nref="${repo_url%'.git'}.git" +} + +## +# @FUNCTION: git-hosting_gen_snapshot_url +# @USAGE: $0 "${rn}" "${ref}" snapshot_url distfile +# @DESCRIPTION: Generate snapshot URL +## +git-hosting_gen_snapshot_url() { + (( $# != 4 )) && die + + local -r -- rn="${1}" ; shift + local -r -- ref="${1}" ; shift + local -n -- snapshot_url_nref="${1}" ; shift + local -n -- distfile_nref="${1}" ; shift + + local -- provider path repo + _gh_parse_rn "${rn}" provider path repo + readonly provider path repo + + local -- repo_url + _gh_gen_repo_url "${provider}" "${path}" "${repo}" repo_url + readonly repo_url + + local -r -- snap_url_tail="$( _gh_provider:${provider}:snap_url_tail "${ref}" )" + + local -- _distfile_base="${provider}--${path}--${repo}--${ref}" + _distfile_base="${_distfile_base//'/'/_}" + + snapshot_url_nref="${repo_url}/${snap_url_tail}" + distfile_nref="${_distfile_base}$( _gh_provider:${provider}:snap_ext )" +} + +## +# @FUNCTION: git-hosting_unpack +## +git-hosting_unpack() { + (( $# != 2 )) && die + local -r -- unpack_from="${1}" + # do not use '${S}' for 'unpack_to' as user might overwrite 'S' leading to a wrong behaviour + local -r -- unpack_to="${2}" + + printf ">>> Unpacking '%s' to '%s'\n" "${unpack_from##*/}" "${unpack_to}" + mkdir -p "${unpack_to}" || die "Failed to create '${unpack_to}' directory" + local tar=( tar --extract + --strip-components=1 + --file="${unpack_from}" --directory="${unpack_to}" ) + "${tar[@]}" || die "Failed to extract '${unpack_from}' archive" + + ## filter 'unpack_from' from 'A' + local f new_a_a=() + for f in ${A} ; do + if [[ "${f}" != "${unpack_from##*/}" ]] ; then + new_a_a+=( "${f}" ) + fi + done + A="${new_a_a[@]}" + + return 0 +} + +### END Functions + + +### BEGIN Variables + +## +# @ECLASS-VARIABLE: GH_RN +# @DEFAULT_UNSET +# @DESCRIPTION: +# Resource name. A string in the format: +# +# [[:][:]] +# +# Default and is ${PN}. +## +[[ -z "${GH_RN}" ]] && die "GH_RN must be set to a non-empty value" + +## +# @ECLASS-VARIABLE: GH_PROVIDER +# @READONLY +# @DEFAULT_UNSET +# @DESCRIPTION: +# Contains the first part of GH_RN - the git hosting provider. +# Currently one of 'github', 'gitlab', 'bitbucket', 'kernel'. +## +GH_PROVIDER= + +## +# @ECLASS-VARIABLE: _GH_PATH +# @READONLY +# @PRIVATE +# @DEFAULT: ${PN} +# @DESCRIPTION: +# Contains the second part of GH_RN - the path. +## +_GH_PATH="${PN}" + +## +# @ECLASS-VARIABLE: GH_REPO +# @READONLY +# @DEFAULT: ${PN} +# @DESCRIPTION: +# Contains the third part of GH_RN - the repository name. +## +GH_REPO="${PN}" + +_gh_parse_rn "${GH_RN}" GH_PROVIDER _GH_PATH GH_REPO + +case "${GH_PROVIDER}" in +'kernel' ) + # make sure `.git` is appended + GH_REPO="${GH_REPO%'.git'}.git" + # append `PN` if requested + [[ -z "${_GH_PATH##*/}" ]] && _GH_PATH+="${PN}" + ;; +esac + +declare -g -r -- GH_PROVIDER _GH_PATH GH_REPO + +## +# @ECLASS-VARIABLE: _GH_RN +# @READONLY +# @PRIVATE +# @DESCRIPTION: +# Expanded form of GH_RN, always has all three components. +## +declare -g -r -- _GH_RN="${GH_PROVIDER}:${_GH_PATH}:${GH_REPO}" + +## +# @ECLASS-VARIABLE: GH_FETCH_TYPE +# @DEFAULT: 'snapshot', for versions containing '9999' defaults to 'live' +# @DESCRIPTION: +# Defines if fetched from git ("live") or archive ("snapshot") or eclass +# shouldn't handle fetching at all ("manual"). +## +if [[ -z "${GH_FETCH_TYPE}" ]] ; then + if [[ "${PV}" == *9999* ]] ; then + GH_FETCH_TYPE='live' + else + GH_FETCH_TYPE='snapshot' + fi +fi +declare -g -r -- GH_FETCH_TYPE + +## +# @ECLASS-VARIABLE: GH_REF +# @DEFAULT: for 'snapshot', "${PV}" +# @DESCRIPTION: +# Tag/commit/git_ref (except branches) that is fetched from git hosting provider. +## +if [[ -z "${GH_REF}" ]] ; then + case "${GH_FETCH_TYPE}" in + 'snapshot' ) + # a research conducted on April 2016 among the first 700 repos with >10000 stars on GitHub shows: + # - no tags: 158 + # - `v` prefix: 350 + # - no prefix: 192 + GH_REF="${PV}" + ;; + 'live' | 'manual' ) + : + ;; + * ) + die "Unsupported fetch type: '${GH_FETCH_TYPE}'" + ;; + esac +fi +declare -g -r -- GH_REF + +## +# @ECLASS-VARIABLE: _GH_DOMAIN +# @PRIVATE +# @READONLY +# @DESCRIPTION: +# Base +## +declare -g -r -- _GH_DOMAIN="$(_gh_provider:${GH_PROVIDER}:base_url)" + +## +# @ECLASS-VARIABLE: GH_REPO_URL +# @READONLY +# @DEFAULT: "https://${_GH_BASE_URL}/${_GH_PATH}/${GH_REPO}" +# @DESCRIPTION: +# Base uri of the repo +## +_gh_gen_repo_url "${GH_PROVIDER}" "${_GH_PATH}" "${GH_REPO}" GH_REPO_URL +declare -g -r -- GH_REPO_URL + +## +# @ECLASS-VARIABLE: GH_HOMEPAGE +# @READONLY +# @DEFAULT: "${GH_REPO_URL}" +# @DESCRIPTION: +# Homepage of the repository hosted by the git hosting provider/ +## +declare -g -r -- GH_HOMEPAGE="${GH_REPO_URL}" + + +case "${GH_FETCH_TYPE}" in +'snapshot' ) + git-hosting_gen_snapshot_url "${_GH_RN}" "${GH_REF}" _GH_SNAPSHOT_SRC_URI _GH_DISTFILE + declare -g -r -- _GH_SNAPSHOT_SRC_URI _GH_DISTFILE + ;; +'live' | 'manual' ) + : + ;; +* ) + die "Unsupported fetch type: '${GH_FETCH_TYPE}'" + ;; +esac + +RESTRICT+=" mirror" + +### END Variables + + +### BEGIN Inherits + +case "${GH_FETCH_TYPE}" in +'live' ) + [[ -z "${EGIT_REPO_URI}" ]] && \ + git-hosting_gen_live_url "${_GH_RN}" EGIT_REPO_URI + [[ -n "${GH_REF}" && -z "${EGIT_COMMIT}" ]] && \ + EGIT_COMMIT="${GH_REF}" + [[ -z "${EGIT_CLONE_TYPE}" ]] && \ + EGIT_CLONE_TYPE="shallow" + + inherit git-r3 + ;; +'snapshot' | 'manual' ) + : + ;; +*) + die "Unsupported fetch type: '${GH_FETCH_TYPE}'" + ;; +esac + +### END Inherits + + +### BEGIN Portage variables + +# set SRC_URI only for 'snapshot' GH_FETCH_TYPE +case "${GH_FETCH_TYPE}" in +'snapshot' ) + SRC_URI="${_GH_SNAPSHOT_SRC_URI} -> ${_GH_DISTFILE}" + ;; +'live' | 'manual' ) + : + ;; +* ) + die "Unsupported fetch type: '${GH_FETCH_TYPE}'" + ;; +esac + +: "${HOMEPAGE:="${GH_HOMEPAGE}"}" + +# prefer their CDN over Gentoo mirrors +RESTRICT="${RESTRICT} primaryuri" + +### END Portage variables + + +# debug-print summary +if [[ -n "${EBUILD_PHASE_FUNC}" && "${EBUILD_PHASE_FUNC}" == 'pkg_setup' ]] ; then + debug-print "${ECLASS}: -- vardump --" + for _v in $(compgen -A variable) ; do + if [[ "${_v}" == "GH_"* || "${_v}" == "EGIT_"* ]] ; then + debug-print "${ECLASS}: ${_v}='${!_v}'" + fi + done + debug-print "${ECLASS}: ----" + unset _v +fi + + +### BEGIN Exported functions + +EXPORT_FUNCTIONS src_unpack + +## +# @FUNCTION: git-hosting_src_unpack +# @DESCRIPTION: +# Handles unpacking of special source files, like git snapshots, live git repos, ... +# +# Please note that if GH_FETCH_TYPE=~(live|snapshot) this function won't unpack files from SRC_URI +# other than those it added itself, additionally, upon execution it filters them out of '${A}' variable, so +# that you can than loop through '${A}' safely and unpack the rest yourself or just call default(). +## +git-hosting_src_unpack() { + debug-print-function "${FUNCNAME}" + + case "${GH_FETCH_TYPE}" in + 'live' ) + git-r3_src_unpack + ;; + 'snapshot' ) + git-hosting_unpack "${DISTDIR}/${_GH_DISTFILE}" "${WORKDIR}/${P}" + ;; + 'manual' ) + default + ;; + * ) + die + ;; + esac +} + +### END Exported functions + + +_RINDEAL_GH_ECLASS=1 +fi diff --git a/eclass/portage-functions-patched.eclass b/eclass/portage-functions-patched.eclass new file mode 100644 index 0000000..2ba4831 --- /dev/null +++ b/eclass/portage-functions-patched.eclass @@ -0,0 +1,19 @@ +# Copyright 2016, 2019 Jan Chren (rindeal) +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: portage-functions-patched.eclass +# @BLURB: Set of portage functions overrides + +case "${EAPI:-"0"}" in +"6" | "7" ) ;; +* ) die "EAPI='${EAPI}' is not supported by ECLASS='${ECLASS}'" ;; +esac + + +## Origin: portage - bin/isolated-functions.sh +rindeal:has() { + local -r -- IFS=$'\a' + + [[ "${IFS}${*:2}${IFS}" == *"${IFS}${1}${IFS}"* ]] +} +has() { rindeal:has "${@}" ; } diff --git a/eclass/rindeal.eclass b/eclass/rindeal.eclass new file mode 100644 index 0000000..591a5d6 --- /dev/null +++ b/eclass/rindeal.eclass @@ -0,0 +1,355 @@ +# Copyright 2016-2019 Jan Chren (rindeal) +# Distributed under the terms of the GNU General Public License v2 + +# @ECLASS: rindeal.eclass +# @BLURB: Base eclass for all ebuilds +# @DESCRIPTION: +# This eclass should be inheritted by all ebuilds right after the EAPI specification before any inherits. + + +# fight with portage and override it again and again +inherit portage-functions-patched + + +if ! (( _RINDEAL_ECLASS )) +then + +case "${EAPI:-0}" in +'6' | '7' ) ;; +* ) die "EAPI='${EAPI}' is not supported by '${ECLASS}' eclass" ;; +esac + + +rindeal:func_exists() { + declare -F "${1}" >/dev/null +} + + +### BEGIN: "Command not found" handler + +if rindeal:func_exists command_not_found_handle +then + # portage registers a cnf handler for the `depend` phase + # https://github.com/gentoo/portage/commit/40da7ee19c4c195da35083bf2d2fcbd852ad3846 + if [[ "${EBUILD_PHASE}" != 'depend' ]] + then + eqawarn "${ECLASS}.eclass: command_not_found_handle() already registered" + fi +else + +command_not_found_handle() { + debug-print-function "${FUNCNAME[0]}" "${@}" + local -r -- cmd="${1}" + + ## do not die in a pipe + [[ -t 1 ]] || return 127 + + ## do not die in a subshell + local _pid _cmd _state _ppid _pgrp _session _tty_nr _tpgid _rest + read _pid _cmd _state _ppid _pgrp _session _tty_nr _tpgid _rest < /proc/self/stat + (( $$ == _tpgid )) && return 127 + + die "'${cmd}': command not found" +} + +fi + +### END: "Command not found" handler + + +### BEGIN: Death hooks + +rindeal:__death_hook() { + eerror "" + eerror "Ask for help at https://github.com/rindeal/rindeal-ebuild-repo/issues" + eerror "instead of posting to https://forums.gentoo.org/ or worse https://bugs.gentoo.org/." + eerror "" +} + +if ! rindeal:has rindeal:__death_hook ${EBUILD_DEATH_HOOKS} +then + EBUILD_DEATH_HOOKS+=" rindeal:__death_hook" +fi + +### END: Death hooks + + +### BEGIN: hooking infrastructure + +_rindeal:hooks:get_orig_prefix() { + echo "__original_" +} + +_rindeal:hooks:call_orig() { + debug-print-function "${FUNCNAME[0]}" "${@}" + + local -r -- func="$(_rindeal:hooks:get_orig_prefix)${1}" + + if ! rindeal:func_exists "${func}" + then + die "${ECLASS}.eclass: ${FUNCNAME}: function '${func}' doesn't exist" + fi + + "${func}" "${@:2}" +} + +_rindeal:hooks:save() { + debug-print-function "${FUNCNAME[0]}" "${@}" + + (( $# != 1 )) && die + + local -r -- name="${1}" + local -r -- orig_prefix="$(_rindeal:hooks:get_orig_prefix)" + + # make sure we don't create an infinite loop + if ! rindeal:func_exists "${orig_prefix}${name}" + then + + # save original implementation under a different name + eval "${orig_prefix}$(declare -f "${name}")" + fi +} + +### END: hooking infrastructure + + +### BEGIN: inherit hook + +_rindeal:hooks:save inherit + +## "static" assoc array +if [[ -z "$(declare -p _RINDEAL_ECLASS_SWAPS 2>/dev/null)" ]] +then +declare -g -A _RINDEAL_ECLASS_SWAPS=( + ['flag-o-matic']='flag-o-matic-patched' + ['ninja-utils']='ninja-utils-patched' + ['versionator']='versionator-patched' + ['vala']='vala-patched' +) +fi + +inherit() { + local -a new_args=( ) + + local -- old_eclass + for old_eclass in "${@}" + do + if [[ -v _RINDEAL_ECLASS_SWAPS["${old_eclass}"] ]] + then + local new_eclass="${_RINDEAL_ECLASS_SWAPS["${old_eclass}"]}" + + debug-print "${ECLASS}.eclass, ${FUNCNAME[0]}(): swapping '${old_eclass}' for '${new_eclass}" + + if [[ -n "${new_eclass}" ]] + then + new_args+=( "${new_eclass}" ) + fi + + # prevent infinite loops + unset "_RINDEAL_ECLASS_SWAPS[${old_eclass}]" + else + new_args+=( "${old_eclass}" ) + fi + done + + if (( ${#new_args[@]} )) + then + _rindeal:hooks:call_orig inherit "${new_args[@]}" + else + debug-print "${ECLASS}.eclass, ${FUNCNAME[0]}(): skipping orig call since all its arguments were erased" + fi +} + +### END: inherit hook + + +### BEGIN: standard tool wrappers + +# `NO_V` env var implementation for use in standard tool wrappers +_NO_V() { + (( NO_V )) || printf -- "--verbose" +} + +rpushd() { + pushd "${@}" >/dev/null || die -n +} + +rpopd() { + popd "${@}" >/dev/null || die -n +} + +rmkdir() { + mkdir $(_NO_V) --parents "${@}" || die -n +} + +rcp() { + cp $(_NO_V) "${@}" || die -n +} + +rmv() { + mv $(_NO_V) "${@}" || die -n +} + +rln() { + ln $(_NO_V) "${@}" || die -n +} + +rchown() { + chown $(_NO_V) "${@}" || die -n +} + +rchmod() { + chmod $(_NO_V) "${@}" || die -n +} + +rrm() { + rm $(_NO_V) --interactive=never --preserve-root --one-file-system "${@}" || die -n +} + +rrmdir() { + rmdir $(_NO_V) "${@}" || die -n +} + +rsed() { + if (( RINDEAL_DEBUG )) + then + local -a diff_prog=( diff -u ) + if command -v colordiff >/dev/null + then + diff_prog=( colordiff -u ) + fi + + local -A file_list + local -a pretty_sed + local -i i record_files=0 + for (( i = 1 ; i <= $# ; i ++ )) + do + local arg="${!i}" + if (( record_files )) + then + file_list+=( ["${arg}"]="${RANDOM}${RANDOM}${RANDOM}" ) + else + if [[ "${arg}" == "--" ]] + then + record_files=1 + else + pretty_sed+=( "'${arg}'" ) + fi + fi + done + + (( ${#file_list[*]} )) || die -n + + local temp_dir="$(mktemp -d || die -n)" + + ## backup original versions + local -- f + for f in "${!file_list[@]}" + do + cp -- "${f}" "${temp_dir}/${file_list["${f}"]}" || die -n + done + fi + + sed "${@}" || die -n + + if (( RINDEAL_DEBUG )) + then + local f + for f in "${!file_list[@]}" + do + echo "*** diff of '${f}'" + echo "*** for sed ${pretty_sed[*]}:" + "${diff_prog[@]}" "${temp_dir}/${file_list["${f}"]}" "${f}" + local code=$? + (( code == 2 )) && die -n + (( code == 0 )) && eqawarn "sed didn't change anything" + done + rm -r -- "${temp_dir}" || die -n + fi +} + +# Usage: rdosym [...] +rdosym() { + local -i _rel_arg=0 + + while (( ${#} )) + do + case "${1}" in + --rel ) _rel_arg=1 ;; + -- ) + (( ${#} < 2 )) && die "Not enough arguments given" + + shift # consume double dash + + local -r -- _target_arg="${1}" + shift + + local -r -a _linkpath_args=( "${@}" ) + break + ;; + * ) die "Unknown argument '${1}'" ;; + esac + shift + done + + local -- _target="${_target_arg}" + + local -- _linkpath + for _linkpath in "${_linkpath_args[@]}" + do + local -- _target="${_target_arg}" + + if (( _rel_arg )) + then + local -- _linkpath_dir="$(dirname "${_linkpath}" || die)" + local -a realpath_cmd=( realpath + --canonicalize-missing + --no-symlinks + --relative-to="${_linkpath_dir}" + "${_target}" + ) + _target="$("${realpath_cmd[@]}" || die)" + fi + + echo "dosym: '${_linkpath}' -> '${_target}' ('${_target_arg}')" + dosym "${_target}" "${_linkpath}" + done +} + +### END: standard tool wrappers + +yesno() +{ + (( ${#} != 1 )) && die + local -r -- input_arg="${1}" + + local -- input="${input_arg}" + + ## strip whitespace around input string + while [[ "${input}" == [[:space:]]* ]] + do + input="${input#[[:space:]]}" + done + while [[ "${input}" == *[[:space:]] ]] + do + input="${input%[[:space:]]}" + done + + case "${input}" in + [Yy][Ee][Ss] | [Tt][Rr][Uu][Ee] | [Oo][Nn] | 1 ) return 0 ;; + [Nn][Oo] | [Ff][Aa][Ll][Ss][Ee] | [Oo][Ff][Ff] | 0 ) return -1 ;; + * ) + debug-print "${FUNCNAME[0]}: no match for '${1}'" + return -1 + ;; + esac +} + +# this function can be used for a first line in files generated by the ebuild logic +print_generated_file_header() { + printf "Automatically generated by %s/%s on %s\n" "${CATEGORY}" "${PF}" "$(date --utc --iso-8601=minutes)" +} + + +_RINDEAL_ECLASS=1 +fi