dev-cpp/pangomm: stable 2.42.1 for hppa, bug #717144
[gentoo.git] / eclass / cargo.eclass
index a86bb9e037a5327d54871ffc31cc4b0c3ca0dbdb..6f7ffdb626b4143730f56d4f0ea9005f4b6887d8 100644 (file)
@@ -1,40 +1,53 @@
-# Copyright 1999-2016 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
 # Distributed under the terms of the GNU General Public License v2
-# $Id$
 
 # @ECLASS: cargo.eclass
 # @MAINTAINER:
 # rust@gentoo.org
 # @AUTHOR:
 # Doug Goldstein <cardoe@gentoo.org>
+# @SUPPORTED_EAPIS: 6 7
 # @BLURB: common functions and variables for cargo builds
 
 if [[ -z ${_CARGO_ECLASS} ]]; then
 _CARGO_ECLASS=1
 
+# we need this for 'cargo vendor' subcommand and net.offline config knob
+RUST_DEPEND=">=virtual/rust-1.37.0"
+
 case ${EAPI} in
-       6) : ;;
+       6) DEPEND="${RUST_DEPEND}";;
+       7) BDEPEND="${RUST_DEPEND}";;
        *) die "EAPI=${EAPI:-0} is not supported" ;;
 esac
 
-EXPORT_FUNCTIONS src_unpack
+inherit multiprocessing
+
+EXPORT_FUNCTIONS src_unpack src_compile src_install src_test
+
+IUSE="${IUSE} debug"
 
 ECARGO_HOME="${WORKDIR}/cargo_home"
-ECARGO_REPO="github.com-88ac128001ac3a9a"
-ECARGO_INDEX="${ECARGO_HOME}/registry/index/${ECARGO_REPO}"
-ECARGO_SRC="${ECARGO_HOME}/registry/src/${ECARGO_REPO}"
-ECARGO_CACHE="${ECARGO_HOME}/registry/cache/${ECARGO_REPO}"
+ECARGO_VENDOR="${ECARGO_HOME}/gentoo"
+
+# @ECLASS-VARIABLE: CARGO_INSTALL_PATH
+# @DESCRIPTION:
+# Allows overriding the default cwd to run cargo install from
+: ${CARGO_INSTALL_PATH:=.}
 
 # @FUNCTION: cargo_crate_uris
 # @DESCRIPTION:
 # Generates the URIs to put in SRC_URI to help fetch dependencies.
 cargo_crate_uris() {
-       for crate in $*; do
+       local -r regex='^([a-zA-Z0-9_\-]+)-([0-9]+\.[0-9]+\.[0-9]+.*)$'
+       local crate
+       for crate in "$@"; do
                local name version url
-               name="${crate%-*}"
-               version="${crate##*-}"
+               [[ $crate =~ $regex ]] || die "Could not parse name and version from crate: $crate"
+               name="${BASH_REMATCH[1]}"
+               version="${BASH_REMATCH[2]}"
                url="https://crates.io/api/v1/crates/${name}/${version}/download -> ${crate}.crate"
-               echo $url
+               echo "${url}"
        done
 }
 
@@ -44,18 +57,29 @@ cargo_crate_uris() {
 cargo_src_unpack() {
        debug-print-function ${FUNCNAME} "$@"
 
-       mkdir -p "${ECARGO_INDEX}" || die
-       mkdir -p "${ECARGO_CACHE}" || die
-       mkdir -p "${ECARGO_SRC}" || die
+       mkdir -p "${ECARGO_VENDOR}" || die
        mkdir -p "${S}" || die
 
-       local archive
+       local archive shasum pkg
        for archive in ${A}; do
                case "${archive}" in
                        *.crate)
-                               ebegin "Unpacking ${archive}"
-                               cp "${DISTDIR}"/${archive} "${ECARGO_CACHE}/" || die
-                               tar -xf "${DISTDIR}"/${archive} -C "${ECARGO_SRC}/" || die
+                               ebegin "Loading ${archive} into Cargo registry"
+                               tar -xf "${DISTDIR}"/${archive} -C "${ECARGO_VENDOR}/" || die
+                               # generate sha256sum of the crate itself as cargo needs this
+                               shasum=$(sha256sum "${DISTDIR}"/${archive} | cut -d ' ' -f 1)
+                               pkg=$(basename ${archive} .crate)
+                               cat <<- EOF > ${ECARGO_VENDOR}/${pkg}/.cargo-checksum.json
+                               {
+                                       "package": "${shasum}",
+                                       "files": {}
+                               }
+                               EOF
+                               # if this is our target package we need it in ${WORKDIR} too
+                               # to make ${S} (and handle any revisions too)
+                               if [[ ${P} == ${pkg}* ]]; then
+                                       tar -xf "${DISTDIR}"/${archive} -C "${WORKDIR}" || die
+                               fi
                                eend $?
                                ;;
                        cargo-snapshot*)
@@ -67,19 +91,104 @@ cargo_src_unpack() {
                                touch "${S}"/target/snapshot/bin/cargo || die
                                eend $?
                                ;;
-                       cargo-registry*)
-                               ebegin "Unpacking ${archive}"
-                               tar -xzf "${DISTDIR}"/${archive} -C "${ECARGO_INDEX}" --strip-components 1 || die
-                               # prevent cargo from attempting to download this again
-                               touch "${ECARGO_INDEX}"/.cargo-index-lock || die
-                               eend $?
-                               ;;
                        *)
                                unpack ${archive}
                                ;;
                esac
        done
+
+       cargo_gen_config
 }
 
+# @FUNCTION: cargo_live_src_unpack
+# @DESCRIPTION:
+# Runs 'cargo fetch' and vendors downloaded crates for offline use, used in live ebuilds
+
+cargo_live_src_unpack() {
+       debug-print-function ${FUNCNAME} "$@"
+
+       [[ "${PV}" == *9999* ]] || die "${FUNCNAME} only allowed in live/9999 ebuilds"
+       [[ "${EBUILD_PHASE}" == unpack ]] || die "${FUNCNAME} only allowed in src_unpack"
+
+       mkdir -p "${S}" || die
+
+       pushd "${S}" > /dev/null || die
+       CARGO_HOME="${ECARGO_HOME}" cargo fetch || die
+       CARGO_HOME="${ECARGO_HOME}" cargo vendor "${ECARGO_VENDOR}" || die
+       popd > /dev/null || die
+
+       cargo_gen_config
+}
+
+# @FUNCTION: cargo_gen_config
+# @DESCRIPTION:
+# Generate the $CARGO_HOME/config necessary to use our local registry and settings.
+# Cargo can also be configured through environment variables in addition to the TOML syntax below.
+# For each configuration key below of the form foo.bar the environment variable CARGO_FOO_BAR
+# can also be used to define the value.
+# Environment variables will take precedent over TOML configuration,
+# and currently only integer, boolean, and string keys are supported.
+# For example the build.jobs key can also be defined by CARGO_BUILD_JOBS.
+# Or setting CARGO_TERM_VERBOSE=false in make.conf will make build quieter.
+cargo_gen_config() {
+       debug-print-function ${FUNCNAME} "$@"
+
+       cat <<- EOF > "${ECARGO_HOME}/config"
+       [source.gentoo]
+       directory = "${ECARGO_VENDOR}"
+
+       [source.crates-io]
+       replace-with = "gentoo"
+       local-registry = "/nonexistant"
+
+       [net]
+       offline = true
+
+       [build]
+       jobs = $(makeopts_jobs)
+
+       [term]
+       verbose = true
+       EOF
+       # honor NOCOLOR setting
+       [[ "${NOCOLOR}" = true || "${NOCOLOR}" = yes ]] && echo "color = 'never'" >> "${ECARGO_HOME}/config"
+}
+
+# @FUNCTION: cargo_src_compile
+# @DESCRIPTION:
+# Build the package using cargo build
+cargo_src_compile() {
+       debug-print-function ${FUNCNAME} "$@"
+
+       export CARGO_HOME="${ECARGO_HOME}"
+
+       cargo build $(usex debug "" --release) "$@" \
+               || die "cargo build failed"
+}
+
+# @FUNCTION: cargo_src_install
+# @DESCRIPTION:
+# Installs the binaries generated by cargo
+cargo_src_install() {
+       debug-print-function ${FUNCNAME} "$@"
+
+       cargo install --path ${CARGO_INSTALL_PATH} \
+               --root="${ED}/usr" $(usex debug --debug "") "$@" \
+               || die "cargo install failed"
+       rm -f "${ED}/usr/.crates.toml"
+       rm -f "${ED}/usr/.crates2.json"
+
+       [ -d "${S}/man" ] && doman "${S}/man" || return 0
+}
+
+# @FUNCTION: cargo_src_test
+# @DESCRIPTION:
+# Test the package using cargo test
+cargo_src_test() {
+       debug-print-function ${FUNCNAME} "$@"
+
+       cargo test $(usex debug "" --release) "$@" \
+               || die "cargo test failed"
+}
 
 fi