* [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar @ 2016-05-18 22:35 aidecoe 2016-05-18 23:26 ` Peter Stuge ` (3 more replies) 0 siblings, 4 replies; 14+ messages in thread From: aidecoe @ 2016-05-18 22:35 UTC (permalink / raw To: gentoo-dev; +Cc: Amadeusz Żołnowski From: Amadeusz Żołnowski <aidecoe@gentoo.org> It is an eclass providing functions to build Erlang/OTP projects using dev-util/rebar. All packages in upcoming category dev-erlang are going to use this eclass. --- eclass/rebar.eclass | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 eclass/rebar.eclass diff --git a/eclass/rebar.eclass b/eclass/rebar.eclass new file mode 100644 index 0000000..e1ac52f --- /dev/null +++ b/eclass/rebar.eclass @@ -0,0 +1,220 @@ +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +# @ECLASS: rebar.eclass +# @MAINTAINER: +# Amadeusz Żołnowski <aidecoe@gentoo.org> +# @AUTHOR: +# Amadeusz Żołnowski <aidecoe@gentoo.org> +# @BLURB: Build Erlang/OTP projects using dev-util/rebar. +# @DESCRIPTION: +# An eclass providing functions to build Erlang/OTP projects using +# dev-util/rebar. +# +# rebar is a tool which tries to resolve dependencies itself which is by +# cloning remote git repositories. Dependant projects are usually expected to +# be in sub-directory 'deps' rather than looking at system Erlang lib +# directory. Projects relying on rebar usually don't have 'install' make +# targets. The eclass workarounds some of these problems. It handles +# installation in a generic way for Erlang/OTP structured projects. + +case "${EAPI:-0}" in + 0|1|2|3|4) + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" + ;; + 5|6) + ;; + *) + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" + ;; +esac + +[[ ${EAPI} = 5 ]] && inherit eutils + +EXPORT_FUNCTIONS src_prepare src_compile src_install + +RDEPEND="dev-lang/erlang" +DEPEND="${RDEPEND} + dev-util/rebar" + +# @FUNCTION: get_erl_libs +# @RETURN: the path to Erlang lib directory +# @DESCRIPTION: +# Get the full path without EPREFIX to Erlang lib directory. +get_erl_libs() { + echo "/usr/$(get_libdir)/erlang/lib" +} + +# @VARIABLE: ERL_LIBS +# @DESCRIPTION: +# Full path with EPREFIX to Erlang lib directory. Some rebar scripts expect it. +export ERL_LIBS="${EPREFIX}$(get_erl_libs)" + +# @FUNCTION: _find_dep_version +# @INTERNAL +# @USAGE: <project_name> +# @RETURN: full path with EPREFIX to a Erlang package/project +# @DESCRIPTION: +# Find a Erlang package/project by name in Erlang lib directory. Project +# directory is usually suffixed with version. First match to <project_name> or +# <project_name>-* is returned. +_find_dep_version() { + local pn="$1" + local p + + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null + for p in ${pn} ${pn}-*; do + if [[ -d ${p} ]]; then + echo "${p#${pn}-}" + return 0 + fi + done + popd >/dev/null + + return 1 +} + +# @FUNCTION: eawk +# @USAGE: <file> <args> +# @DESCRIPTION: +# Edit file <file> in place with awk. Pass all arguments following <file> to +# awk. +eawk() { + local f="$1"; shift + local tmpf="$(emktemp)" + + cat "${f}" >"${tmpf}" || return 1 + awk "$@" "${tmpf}" >"${f}" +} + +# @FUNCTION: erebar +# @USAGE: <target> +# @DESCRIPTION: +# Run rebar with verbose flag. Die on failure. +erebar() { + debug-print-function ${FUNCNAME} "${@}" + + rebar -v skip_deps=true "$1" || die "rebar $1 failed" +} + +# @FUNCTION: rebar_fix_include_path +# @USAGE: <project_name> [<rebar_config>] +# @DESCRIPTION: +# Fix path in rebar.config to 'include' directory of dependant project/package, +# so it points to installation in system Erlang lib rather than relative 'deps' +# directory. +# +# <rebar_config> is optional. Default is 'rebar.config'. +# +# The function dies on failure. +rebar_fix_include_path() { + debug-print-function ${FUNCNAME} "${@}" + + local pn="$1" + local rebar_config="${2:-rebar.config}" + local erl_libs="${EPREFIX}$(get_erl_libs)" + local pv="$(_find_dep_version "${pn}")" + + eawk "${rebar_config}" \ + -v erl_libs="${erl_libs}" -v pn="${pn}" -v pv="${pv}" \ + '/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { + pattern = "\"(./)?deps/" pn "/include\""; + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { + sub(pattern, "\"" erl_libs "/" pn "-" pv "/include\""); + } + print $0; + next; +} +1 +' || die "failed to fix include paths in ${rebar_config}" +} + +# @FUNCTION: rebar_remove_deps +# @USAGE: [<rebar_config>] +# @DESCRIPTION: +# Remove dependencies list from rebar.config and deceive build rules that any +# dependencies are already fetched and built. Otherwise rebar tries to fetch +# dependencies and compile them. +# +# <rebar_config> is optional. Default is 'rebar.config'. +# +# The function dies on failure. +rebar_remove_deps() { + debug-print-function ${FUNCNAME} "${@}" + + local rebar_config="${1:-rebar.config}" + + mkdir -p "${S}/deps" && :>"${S}/deps/.got" && :>"${S}/deps/.built" || die + eawk "${rebar_config}" \ + '/^{[[:space:]]*deps[[:space:]]*,/, /}[[:space:]]*\.$/ { + if ($0 ~ /}[[:space:]]*\.$/) { + print "{deps, []}."; + } + next; +} +1 +' || die "failed to remove deps from ${rebar_config}" +} + +# @FUNCTION: rebar_set_vsn +# @USAGE: [<version>] +# @DESCRIPTION: +# Set version in project description file if it's not set. +# +# <version> is optional. Default is PV stripped from version suffix. +# +# The function dies on failure. +rebar_set_vsn() { + debug-print-function ${FUNCNAME} "${@}" + + local version="${1:-${PV%_*}}" + + sed -e "s/vsn, git/vsn, \"${version}\"/" \ + -i "${S}/src/${PN}.app.src" \ + || die "failed to set version in src/${PN}.app.src" +} + +# @FUNCTION: rebar_src_prepare +# @DESCRIPTION: +# Prevent rebar from fetching in compiling dependencies. Set version in project +# description file if it's not set. +# +# Existence of rebar.config is optional, but file description file must exist +# at 'src/${PN}.app.src'. +rebar_src_prepare() { + debug-print-function ${FUNCNAME} "${@}" + + rebar_set_vsn + [[ -f rebar.config ]] && rebar_remove_deps +} + +# @FUNCTION: rebar_src_compile +# @DESCRIPTION: +# Compile project with rebar. +rebar_src_compile() { + debug-print-function ${FUNCNAME} "${@}" + + erebar compile +} + +# @FUNCTION: rebar_src_install +# @DESCRIPTION: +# Install BEAM files, include headers, executables and native libraries. +# Install standard docs like README or defined in DOCS variable. Optionally +# +# Function expects that project conforms to Erlang/OTP structure. +rebar_src_install() { + debug-print-function ${FUNCNAME} "${@}" + + local bin + local dest="$(get_erl_libs)/${P}" + + insinto "${dest}" + doins -r ebin + [[ -d include ]] && doins -r include + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done + [[ -d priv ]] && cp -pR priv "${ED}${dest}/" + + einstalldocs +} -- 2.8.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-18 22:35 [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar aidecoe @ 2016-05-18 23:26 ` Peter Stuge 2016-05-20 23:09 ` Amadeusz Żołnowski 2016-05-19 4:39 ` Michał Górny ` (2 subsequent siblings) 3 siblings, 1 reply; 14+ messages in thread From: Peter Stuge @ 2016-05-18 23:26 UTC (permalink / raw To: gentoo-dev Cool! aidecoe@gentoo.org wrote: > +_find_dep_version() { > + local pn="$1" > + local p > + > + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null > + for p in ${pn} ${pn}-*; do > + if [[ -d ${p} ]]; then > + echo "${p#${pn}-}" > + return 0 No popd on success? > + fi > + done > + popd >/dev/null > + > + return 1 > +} > +# @FUNCTION: eawk > +# @USAGE: <file> <args> > +# @DESCRIPTION: > +# Edit file <file> in place with awk. Pass all arguments following <file> to > +# awk. > +eawk() { > + local f="$1"; shift > + local tmpf="$(emktemp)" > + > + cat "${f}" >"${tmpf}" || return 1 > + awk "$@" "${tmpf}" >"${f}" > +} Wouldn't it be nicer to cut cat, awk > $tmpf && mv $tmpf $f ? //Peter ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-18 23:26 ` Peter Stuge @ 2016-05-20 23:09 ` Amadeusz Żołnowski 0 siblings, 0 replies; 14+ messages in thread From: Amadeusz Żołnowski @ 2016-05-20 23:09 UTC (permalink / raw To: Peter Stuge; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 550 bytes --] Peter Stuge <peter@stuge.se> writes: >> + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null >> + for p in ${pn} ${pn}-*; do >> + if [[ -d ${p} ]]; then >> + echo "${p#${pn}-}" >> + return 0 > > No popd on success? Thanks for catching this up! Fixed. >> + local tmpf="$(emktemp)" >> + >> + cat "${f}" >"${tmpf}" || return 1 >> + awk "$@" "${tmpf}" >"${f}" >> +} > > Wouldn't it be nicer to cut cat, awk > $tmpf && mv $tmpf $f ? No. Please see separate review of eawk where it is explained. Thanks, -- Amadeusz Żołnowski [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 950 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-18 22:35 [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar aidecoe 2016-05-18 23:26 ` Peter Stuge @ 2016-05-19 4:39 ` Michał Górny 2016-05-20 23:06 ` Amadeusz Żołnowski 2016-05-21 13:26 ` aidecoe 2016-05-21 23:19 ` aidecoe 3 siblings, 1 reply; 14+ messages in thread From: Michał Górny @ 2016-05-19 4:39 UTC (permalink / raw To: aidecoe; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 8553 bytes --] On Wed, 18 May 2016 23:35:18 +0100 aidecoe@gentoo.org wrote: > From: Amadeusz Żołnowski <aidecoe@gentoo.org> > > It is an eclass providing functions to build Erlang/OTP projects using > dev-util/rebar. All packages in upcoming category dev-erlang are going > to use this eclass. > --- > eclass/rebar.eclass | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 220 insertions(+) > create mode 100644 eclass/rebar.eclass > > diff --git a/eclass/rebar.eclass b/eclass/rebar.eclass > new file mode 100644 > index 0000000..e1ac52f > --- /dev/null > +++ b/eclass/rebar.eclass > @@ -0,0 +1,220 @@ > +# Copyright 1999-2016 Gentoo Foundation > +# Distributed under the terms of the GNU General Public License v2 > +# $Id$ > + > +# @ECLASS: rebar.eclass > +# @MAINTAINER: > +# Amadeusz Żołnowski <aidecoe@gentoo.org> > +# @AUTHOR: > +# Amadeusz Żołnowski <aidecoe@gentoo.org> > +# @BLURB: Build Erlang/OTP projects using dev-util/rebar. > +# @DESCRIPTION: > +# An eclass providing functions to build Erlang/OTP projects using > +# dev-util/rebar. > +# > +# rebar is a tool which tries to resolve dependencies itself which is by > +# cloning remote git repositories. Dependant projects are usually expected to > +# be in sub-directory 'deps' rather than looking at system Erlang lib > +# directory. Projects relying on rebar usually don't have 'install' make > +# targets. The eclass workarounds some of these problems. It handles > +# installation in a generic way for Erlang/OTP structured projects. > + > +case "${EAPI:-0}" in > + 0|1|2|3|4) > + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" > + ;; > + 5|6) > + ;; > + *) > + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" > + ;; > +esac > + > +[[ ${EAPI} = 5 ]] && inherit eutils > + > +EXPORT_FUNCTIONS src_prepare src_compile src_install > + > +RDEPEND="dev-lang/erlang" > +DEPEND="${RDEPEND} > + dev-util/rebar" > + > +# @FUNCTION: get_erl_libs > +# @RETURN: the path to Erlang lib directory > +# @DESCRIPTION: > +# Get the full path without EPREFIX to Erlang lib directory. > +get_erl_libs() { > + echo "/usr/$(get_libdir)/erlang/lib" Missing multilib inherit for EAPI 5. > +} > + > +# @VARIABLE: ERL_LIBS > +# @DESCRIPTION: > +# Full path with EPREFIX to Erlang lib directory. Some rebar scripts expect it. > +export ERL_LIBS="${EPREFIX}$(get_erl_libs)" I think calling get_libdir in global scope is forbidden. You should really export this somewhere in phase function. > + > +# @FUNCTION: _find_dep_version Namespace it, please. Just in case. > +# @INTERNAL > +# @USAGE: <project_name> > +# @RETURN: full path with EPREFIX to a Erlang package/project > +# @DESCRIPTION: > +# Find a Erlang package/project by name in Erlang lib directory. Project > +# directory is usually suffixed with version. First match to <project_name> or > +# <project_name>-* is returned. > +_find_dep_version() { > + local pn="$1" > + local p > + > + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null || die > + for p in ${pn} ${pn}-*; do > + if [[ -d ${p} ]]; then > + echo "${p#${pn}-}" > + return 0 > + fi > + done > + popd >/dev/null || die > + > + return 1 > +} > + > +# @FUNCTION: eawk > +# @USAGE: <file> <args> > +# @DESCRIPTION: > +# Edit file <file> in place with awk. Pass all arguments following <file> to > +# awk. > +eawk() { > + local f="$1"; shift > + local tmpf="$(emktemp)" Missing eutils inherit for EAPI 6. > + > + cat "${f}" >"${tmpf}" || return 1 > + awk "$@" "${tmpf}" >"${f}" > +} > + > +# @FUNCTION: erebar > +# @USAGE: <target> > +# @DESCRIPTION: > +# Run rebar with verbose flag. Die on failure. > +erebar() { > + debug-print-function ${FUNCNAME} "${@}" > + > + rebar -v skip_deps=true "$1" || die "rebar $1 failed" > +} Any reason it doesn't pass all the parameters? This inconsistency with emake etc. could be mildly confusing, esp. that you don't check for wrong argc. > + > +# @FUNCTION: rebar_fix_include_path > +# @USAGE: <project_name> [<rebar_config>] > +# @DESCRIPTION: > +# Fix path in rebar.config to 'include' directory of dependant project/package, > +# so it points to installation in system Erlang lib rather than relative 'deps' > +# directory. > +# > +# <rebar_config> is optional. Default is 'rebar.config'. Is it likely that you would be passing different values to it? Maybe it would be reasonable to make this an eclass variable. > +# > +# The function dies on failure. > +rebar_fix_include_path() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local pn="$1" > + local rebar_config="${2:-rebar.config}" > + local erl_libs="${EPREFIX}$(get_erl_libs)" > + local pv="$(_find_dep_version "${pn}")" > + > + eawk "${rebar_config}" \ > + -v erl_libs="${erl_libs}" -v pn="${pn}" -v pv="${pv}" \ > + '/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { > + pattern = "\"(./)?deps/" pn "/include\""; > + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { > + sub(pattern, "\"" erl_libs "/" pn "-" pv "/include\""); > + } > + print $0; > + next; > +} > +1 > +' || die "failed to fix include paths in ${rebar_config}" I suggest you indent this a bit more since it feels like you start at two tabs and finish at zero. > +} > + > +# @FUNCTION: rebar_remove_deps > +# @USAGE: [<rebar_config>] > +# @DESCRIPTION: > +# Remove dependencies list from rebar.config and deceive build rules that any > +# dependencies are already fetched and built. Otherwise rebar tries to fetch > +# dependencies and compile them. > +# > +# <rebar_config> is optional. Default is 'rebar.config'. > +# > +# The function dies on failure. > +rebar_remove_deps() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local rebar_config="${1:-rebar.config}" > + > + mkdir -p "${S}/deps" && :>"${S}/deps/.got" && :>"${S}/deps/.built" || die > + eawk "${rebar_config}" \ > + '/^{[[:space:]]*deps[[:space:]]*,/, /}[[:space:]]*\.$/ { > + if ($0 ~ /}[[:space:]]*\.$/) { > + print "{deps, []}."; > + } > + next; > +} > +1 > +' || die "failed to remove deps from ${rebar_config}" > +} > + > +# @FUNCTION: rebar_set_vsn > +# @USAGE: [<version>] > +# @DESCRIPTION: > +# Set version in project description file if it's not set. > +# > +# <version> is optional. Default is PV stripped from version suffix. > +# > +# The function dies on failure. > +rebar_set_vsn() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local version="${1:-${PV%_*}}" > + > + sed -e "s/vsn, git/vsn, \"${version}\"/" \ > + -i "${S}/src/${PN}.app.src" \ > + || die "failed to set version in src/${PN}.app.src" > +} > + > +# @FUNCTION: rebar_src_prepare > +# @DESCRIPTION: > +# Prevent rebar from fetching in compiling dependencies. Set version in project > +# description file if it's not set. > +# > +# Existence of rebar.config is optional, but file description file must exist > +# at 'src/${PN}.app.src'. Wouldn't it be reasonable to make this configurable? Of course, it might be better to leave it for a possible future extension when it becomes necessary. > +rebar_src_prepare() { > + debug-print-function ${FUNCNAME} "${@}" > + > + rebar_set_vsn > + [[ -f rebar.config ]] && rebar_remove_deps > +} You're missing obligatory default call for EAPI 6. You should really test stuff before submitting it. > + > +# @FUNCTION: rebar_src_compile > +# @DESCRIPTION: > +# Compile project with rebar. > +rebar_src_compile() { > + debug-print-function ${FUNCNAME} "${@}" > + > + erebar compile > +} > + > +# @FUNCTION: rebar_src_install > +# @DESCRIPTION: > +# Install BEAM files, include headers, executables and native libraries. > +# Install standard docs like README or defined in DOCS variable. Optionally Optionally what? It looks like an unfinished sentence. > +# > +# Function expects that project conforms to Erlang/OTP structure. > +rebar_src_install() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local bin > + local dest="$(get_erl_libs)/${P}" > + > + insinto "${dest}" > + doins -r ebin > + [[ -d include ]] && doins -r include > + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done Please don't do inlines like this. > + [[ -d priv ]] && cp -pR priv "${ED}${dest}/" This is about preserving executable bits, correct? > + > + einstalldocs > +} -- Best regards, Michał Górny <http://dev.gentoo.org/~mgorny/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 949 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-19 4:39 ` Michał Górny @ 2016-05-20 23:06 ` Amadeusz Żołnowski 2016-05-21 7:00 ` Michał Górny 0 siblings, 1 reply; 14+ messages in thread From: Amadeusz Żołnowski @ 2016-05-20 23:06 UTC (permalink / raw To: Michał Górny; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 4257 bytes --] Michał Górny <mgorny@gentoo.org> writes: >> +export ERL_LIBS="${EPREFIX}$(get_erl_libs)" > > I think calling get_libdir in global scope is forbidden. You should > really export this somewhere in phase function. Fixed. >> +# @FUNCTION: _find_dep_version > > Namespace it, please. Just in case. Fixed. >> +_find_dep_version() { >> [...] >> + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null > > || die > > [...] > >> + popd >/dev/null > > || die Fixed. >> +eawk() { >> + local f="$1"; shift >> + local tmpf="$(emktemp)" > > Missing eutils inherit for EAPI 6. Fixed. >> +# @FUNCTION: erebar >> +# @USAGE: <target> >> +# @DESCRIPTION: >> +# Run rebar with verbose flag. Die on failure. >> +erebar() { >> + debug-print-function ${FUNCNAME} "${@}" >> + >> + rebar -v skip_deps=true "$1" || die "rebar $1 failed" >> +} > > Any reason it doesn't pass all the parameters? This inconsistency with > emake etc. could be mildly confusing, esp. that you don't check for > wrong argc. Fixed. >> +# @FUNCTION: rebar_fix_include_path >> +# @USAGE: <project_name> [<rebar_config>] >> +# @DESCRIPTION: >> +# Fix path in rebar.config to 'include' directory of dependant project/package, >> +# so it points to installation in system Erlang lib rather than relative 'deps' >> +# directory. >> +# >> +# <rebar_config> is optional. Default is 'rebar.config'. > > Is it likely that you would be passing different values to it? Maybe it > would be reasonable to make this an eclass variable. Unlikely. But I'd better just remove these parameters rather than defining as eclass variable. >> + eawk "${rebar_config}" \ >> + -v erl_libs="${erl_libs}" -v pn="${pn}" -v pv="${pv}" \ >> + '/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { >> + pattern = "\"(./)?deps/" pn "/include\""; >> + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { >> + sub(pattern, "\"" erl_libs "/" pn "-" pv "/include\""); >> + } >> + print $0; >> + next; >> +} >> +1 >> +' || die "failed to fix include paths in ${rebar_config}" > > I suggest you indent this a bit more since it feels like you start at > two tabs and finish at zero. How? Add space between "'" and "||" like follows? + eawk "${rebar_config}" \ ... + print $0; + next; +} +1 +' || die "failed to fix include paths in ${rebar_config}" It looks a bit weird as well... >> +# @FUNCTION: rebar_src_prepare >> +# @DESCRIPTION: >> +# Prevent rebar from fetching in compiling dependencies. Set version in project >> +# description file if it's not set. >> +# >> +# Existence of rebar.config is optional, but file description file must exist >> +# at 'src/${PN}.app.src'. > > Wouldn't it be reasonable to make this configurable? Of course, it > might be better to leave it for a possible future extension when > it becomes necessary. Which part you mean? 'src/${PN}.app.src'? Fixed: REBAR_APP_SRC eclass var. >> +rebar_src_prepare() { >> + debug-print-function ${FUNCNAME} "${@}" >> + >> + rebar_set_vsn >> + [[ -f rebar.config ]] && rebar_remove_deps >> +} > > You're missing obligatory default call for EAPI 6. You should really > test stuff before submitting it. Shame I have forgot to test it, sorry. I have completely forgotten about EAPI 6. Fixed - I have made it working with EAPI 6 and dropped EAPI 5. >> +# @FUNCTION: rebar_src_install >> +# @DESCRIPTION: >> +# Install BEAM files, include headers, executables and native libraries. >> +# Install standard docs like README or defined in DOCS variable. Optionally > > Optionally what? It looks like an unfinished sentence. Nothing. (-: Some leftover. >> +rebar_src_install() { >> + debug-print-function ${FUNCNAME} "${@}" >> + >> + local bin >> + local dest="$(get_erl_libs)/${P}" >> + >> + insinto "${dest}" >> + doins -r ebin >> + [[ -d include ]] && doins -r include >> + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done > > Please don't do inlines like this. Is there a particular problem with this? >> + [[ -d priv ]] && cp -pR priv "${ED}${dest}/" > > This is about preserving executable bits, correct? Yes. Thanks for review. -- Amadeusz Żołnowski [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 950 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-20 23:06 ` Amadeusz Żołnowski @ 2016-05-21 7:00 ` Michał Górny 2016-05-21 8:35 ` Amadeusz Żołnowski 0 siblings, 1 reply; 14+ messages in thread From: Michał Górny @ 2016-05-21 7:00 UTC (permalink / raw To: Amadeusz Żołnowski; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 692 bytes --] On Sat, 21 May 2016 00:06:01 +0100 Amadeusz Żołnowski <aidecoe@gentoo.org> wrote: > >> +rebar_src_install() { > >> + debug-print-function ${FUNCNAME} "${@}" > >> + > >> + local bin > >> + local dest="$(get_erl_libs)/${P}" > >> + > >> + insinto "${dest}" > >> + doins -r ebin > >> + [[ -d include ]] && doins -r include > >> + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done > > > > Please don't do inlines like this. > > Is there a particular problem with this? Readability and maintainability. At some point someone may want to extend this, and it will no longer work as one-liner. -- Best regards, Michał Górny <http://dev.gentoo.org/~mgorny/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 949 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-21 7:00 ` Michał Górny @ 2016-05-21 8:35 ` Amadeusz Żołnowski 0 siblings, 0 replies; 14+ messages in thread From: Amadeusz Żołnowski @ 2016-05-21 8:35 UTC (permalink / raw To: Michał Górny; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 655 bytes --] Michał Górny <mgorny@gentoo.org> writes: >> >> + [[ -d include ]] && doins -r include >> >> + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done >> > >> > Please don't do inlines like this. >> >> Is there a particular problem with this? > > Readability and maintainability. At some point someone may want to > extend this, and it will no longer work as one-liner. That's rather subjective. Given the context I find concise. When uninlined it takes 4 lines more, gets out of context and looks more noisy to me. If someone would like to extend the inline version it could be uninlined at that point. -- Amadeusz Żołnowski [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 950 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-18 22:35 [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar aidecoe 2016-05-18 23:26 ` Peter Stuge 2016-05-19 4:39 ` Michał Górny @ 2016-05-21 13:26 ` aidecoe 2016-05-21 20:48 ` Michał Górny 2016-05-21 23:19 ` aidecoe 3 siblings, 1 reply; 14+ messages in thread From: aidecoe @ 2016-05-21 13:26 UTC (permalink / raw To: gentoo-dev; +Cc: Amadeusz Żołnowski From: Amadeusz Żołnowski <aidecoe@gentoo.org> It is an eclass providing functions to build Erlang/OTP projects using dev-util/rebar. All packages in upcoming category dev-erlang are going to use this eclass. --- eclass/rebar.eclass | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 eclass/rebar.eclass diff --git a/eclass/rebar.eclass b/eclass/rebar.eclass new file mode 100644 index 0000000..9da1340 --- /dev/null +++ b/eclass/rebar.eclass @@ -0,0 +1,217 @@ +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +# @ECLASS: rebar.eclass +# @MAINTAINER: +# Amadeusz Żołnowski <aidecoe@gentoo.org> +# @AUTHOR: +# Amadeusz Żołnowski <aidecoe@gentoo.org> +# @BLURB: Build Erlang/OTP projects using dev-util/rebar. +# @DESCRIPTION: +# An eclass providing functions to build Erlang/OTP projects using +# dev-util/rebar. +# +# rebar is a tool which tries to resolve dependencies itself which is by +# cloning remote git repositories. Dependant projects are usually expected to +# be in sub-directory 'deps' rather than looking at system Erlang lib +# directory. Projects relying on rebar usually don't have 'install' make +# targets. The eclass workarounds some of these problems. It handles +# installation in a generic way for Erlang/OTP structured projects. + +case "${EAPI:-0}" in + 0|1|2|3|4|5) + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" + ;; + 6) + ;; + *) + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" + ;; +esac + +inherit eutils + +EXPORT_FUNCTIONS src_prepare src_compile src_install + +RDEPEND="dev-lang/erlang" +DEPEND="${RDEPEND} + dev-util/rebar" + +# @ECLASS-VARIABLE: REBAR_APP_SRC +# @DESCRIPTION: +# Relative path to .app.src description file. +REBAR_APP_SRC="${REBAR_APP_SRC-src/${PN}.app.src}" + +# @FUNCTION: get_erl_libs +# @RETURN: the path to Erlang lib directory +# @DESCRIPTION: +# Get the full path without EPREFIX to Erlang lib directory. +get_erl_libs() { + echo "/usr/$(get_libdir)/erlang/lib" +} + +# @FUNCTION: _rebar_find_dep_version +# @INTERNAL +# @USAGE: <project_name> +# @RETURN: full path with EPREFIX to a Erlang package/project +# @DESCRIPTION: +# Find a Erlang package/project by name in Erlang lib directory. Project +# directory is usually suffixed with version. First match to <project_name> or +# <project_name>-* is returned. +_rebar_find_dep_version() { + local pn="$1" + local p + + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null || die + for p in ${pn} ${pn}-*; do + if [[ -d ${p} ]]; then + echo "${p#${pn}-}" + break + fi + done + popd >/dev/null || die + + [[ -d ${p} ]] +} + +# @FUNCTION: erebar +# @USAGE: <targets> +# @DESCRIPTION: +# Run rebar with verbose flag. Die on failure. +erebar() { + debug-print-function ${FUNCNAME} "${@}" + + (( $# > 0 )) || die 'erebar: at least one target is required' + + evar_push ERL_LIBS + export ERL_LIBS="${EPREFIX}$(get_erl_libs)" + rebar -v skip_deps=true "$@" || die "rebar $@ failed" + evar_pop +} + +# @FUNCTION: rebar_fix_include_path +# @USAGE: <project_name> +# @DESCRIPTION: +# Fix path in rebar.config to 'include' directory of dependant project/package, +# so it points to installation in system Erlang lib rather than relative 'deps' +# directory. +# +# The function dies on failure. +rebar_fix_include_path() { + debug-print-function ${FUNCNAME} "${@}" + + local pn="$1" + local erl_libs="${EPREFIX}$(get_erl_libs)" + local pv="$(_rebar_find_dep_version "${pn}")" + + eawk rebar.config \ + -v erl_libs="${erl_libs}" -v pn="${pn}" -v pv="${pv}" \ + '/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { + pattern = "\"(./)?deps/" pn "/include\""; + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { + sub(pattern, "\"" erl_libs "/" pn "-" pv "/include\""); + } + print $0; + next; +} +1 +' || die "failed to fix include paths in rebar.config" +} + +# @FUNCTION: rebar_remove_deps +# @DESCRIPTION: +# Remove dependencies list from rebar.config and deceive build rules that any +# dependencies are already fetched and built. Otherwise rebar tries to fetch +# dependencies and compile them. +# +# The function dies on failure. +rebar_remove_deps() { + debug-print-function ${FUNCNAME} "${@}" + + mkdir -p "${S}/deps" && :>"${S}/deps/.got" && :>"${S}/deps/.built" || die + eawk rebar.config \ + '/^{[[:space:]]*deps[[:space:]]*,/, /}[[:space:]]*\.$/ { + if ($0 ~ /}[[:space:]]*\.$/) { + print "{deps, []}."; + } + next; +} +1 +' || die "failed to remove deps from rebar.config" +} + +# @FUNCTION: rebar_set_vsn +# @USAGE: [<version>] +# @DESCRIPTION: +# Set version in project description file if it's not set. +# +# <version> is optional. Default is PV stripped from version suffix. +# +# The function dies on failure. +rebar_set_vsn() { + debug-print-function ${FUNCNAME} "${@}" + + local version="${1:-${PV%_*}}" + + sed -e "s/vsn, git/vsn, \"${version}\"/" \ + -i "${S}/${REBAR_APP_SRC}" \ + || die "failed to set version in src/${PN}.app.src" +} + +# @FUNCTION: rebar_src_prepare +# @DESCRIPTION: +# Prevent rebar from fetching in compiling dependencies. Set version in project +# description file if it's not set. +# +# Existence of rebar.config is optional, but file description file must exist +# at 'src/${PN}.app.src'. +rebar_src_prepare() { + debug-print-function ${FUNCNAME} "${@}" + + default + rebar_set_vsn + [[ -f rebar.config ]] && rebar_remove_deps +} + +# @FUNCTION: rebar_src_configure +# @DESCRIPTION: +# Configure with ERL_LIBS set. +rebar_src_configure() { + debug-print-function ${FUNCNAME} "${@}" + + evar_push ERL_LIBS + export ERL_LIBS="${EPREFIX}$(get_erl_libs)" + default + evar_pop +} + +# @FUNCTION: rebar_src_compile +# @DESCRIPTION: +# Compile project with rebar. +rebar_src_compile() { + debug-print-function ${FUNCNAME} "${@}" + + erebar compile +} + +# @FUNCTION: rebar_src_install +# @DESCRIPTION: +# Install BEAM files, include headers, executables and native libraries. +# Install standard docs like README or defined in DOCS variable. +# +# Function expects that project conforms to Erlang/OTP structure. +rebar_src_install() { + debug-print-function ${FUNCNAME} "${@}" + + local bin + local dest="$(get_erl_libs)/${P}" + + insinto "${dest}" + doins -r ebin + [[ -d include ]] && doins -r include + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done + [[ -d priv ]] && cp -pR priv "${ED}${dest}/" + + einstalldocs +} -- 2.8.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-21 13:26 ` aidecoe @ 2016-05-21 20:48 ` Michał Górny 2016-05-21 22:11 ` Amadeusz Żołnowski 0 siblings, 1 reply; 14+ messages in thread From: Michał Górny @ 2016-05-21 20:48 UTC (permalink / raw To: aidecoe; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 8020 bytes --] On Sat, 21 May 2016 14:26:00 +0100 aidecoe@gentoo.org wrote: > From: Amadeusz Żołnowski <aidecoe@gentoo.org> > > It is an eclass providing functions to build Erlang/OTP projects using > dev-util/rebar. All packages in upcoming category dev-erlang are going > to use this eclass. > --- > eclass/rebar.eclass | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 217 insertions(+) > create mode 100644 eclass/rebar.eclass > > diff --git a/eclass/rebar.eclass b/eclass/rebar.eclass > new file mode 100644 > index 0000000..9da1340 > --- /dev/null > +++ b/eclass/rebar.eclass > @@ -0,0 +1,217 @@ > +# Copyright 1999-2016 Gentoo Foundation > +# Distributed under the terms of the GNU General Public License v2 > +# $Id$ > + > +# @ECLASS: rebar.eclass > +# @MAINTAINER: > +# Amadeusz Żołnowski <aidecoe@gentoo.org> > +# @AUTHOR: > +# Amadeusz Żołnowski <aidecoe@gentoo.org> > +# @BLURB: Build Erlang/OTP projects using dev-util/rebar. > +# @DESCRIPTION: > +# An eclass providing functions to build Erlang/OTP projects using > +# dev-util/rebar. > +# > +# rebar is a tool which tries to resolve dependencies itself which is by > +# cloning remote git repositories. Dependant projects are usually expected to > +# be in sub-directory 'deps' rather than looking at system Erlang lib > +# directory. Projects relying on rebar usually don't have 'install' make > +# targets. The eclass workarounds some of these problems. It handles > +# installation in a generic way for Erlang/OTP structured projects. > + > +case "${EAPI:-0}" in > + 0|1|2|3|4|5) > + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" > + ;; > + 6) > + ;; > + *) > + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" > + ;; > +esac > + > +inherit eutils > + > +EXPORT_FUNCTIONS src_prepare src_compile src_install > + > +RDEPEND="dev-lang/erlang" > +DEPEND="${RDEPEND} > + dev-util/rebar" > + > +# @ECLASS-VARIABLE: REBAR_APP_SRC > +# @DESCRIPTION: > +# Relative path to .app.src description file. > +REBAR_APP_SRC="${REBAR_APP_SRC-src/${PN}.app.src}" > + > +# @FUNCTION: get_erl_libs > +# @RETURN: the path to Erlang lib directory > +# @DESCRIPTION: > +# Get the full path without EPREFIX to Erlang lib directory. > +get_erl_libs() { > + echo "/usr/$(get_libdir)/erlang/lib" > +} > + > +# @FUNCTION: _rebar_find_dep_version > +# @INTERNAL > +# @USAGE: <project_name> > +# @RETURN: full path with EPREFIX to a Erlang package/project > +# @DESCRIPTION: > +# Find a Erlang package/project by name in Erlang lib directory. Project > +# directory is usually suffixed with version. First match to <project_name> or > +# <project_name>-* is returned. > +_rebar_find_dep_version() { > + local pn="$1" > + local p > + > + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null || die > + for p in ${pn} ${pn}-*; do > + if [[ -d ${p} ]]; then > + echo "${p#${pn}-}" > + break > + fi > + done > + popd >/dev/null || die > + > + [[ -d ${p} ]] > +} > + > +# @FUNCTION: erebar > +# @USAGE: <targets> > +# @DESCRIPTION: > +# Run rebar with verbose flag. Die on failure. > +erebar() { > + debug-print-function ${FUNCNAME} "${@}" > + > + (( $# > 0 )) || die 'erebar: at least one target is required' Why not [[ $# -gt 0 ]]? It's the first time I see someone using (( )) for conditionals. > + > + evar_push ERL_LIBS > + export ERL_LIBS="${EPREFIX}$(get_erl_libs)" local -x ERL_LIBS=... We don't really have to employ terribly ugly eval hackery to have a local variable. > + rebar -v skip_deps=true "$@" || die "rebar $@ failed" > + evar_pop > +} > + > +# @FUNCTION: rebar_fix_include_path > +# @USAGE: <project_name> > +# @DESCRIPTION: > +# Fix path in rebar.config to 'include' directory of dependant project/package, > +# so it points to installation in system Erlang lib rather than relative 'deps' > +# directory. > +# > +# The function dies on failure. > +rebar_fix_include_path() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local pn="$1" > + local erl_libs="${EPREFIX}$(get_erl_libs)" > + local pv="$(_rebar_find_dep_version "${pn}")" > + > + eawk rebar.config \ > + -v erl_libs="${erl_libs}" -v pn="${pn}" -v pv="${pv}" \ > + '/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { > + pattern = "\"(./)?deps/" pn "/include\""; > + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { > + sub(pattern, "\"" erl_libs "/" pn "-" pv "/include\""); > + } > + print $0; > + next; > +} > +1 > +' || die "failed to fix include paths in rebar.config" I meant indent like this: + eawk rebar.config \ + -v erl_libs="${erl_libs}" -v pn="${pn}" -v pv="${pv}" \ + '/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { + pattern = "\"(./)?deps/" pn "/include\""; + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { + sub(pattern, "\"" erl_libs "/" pn "-" pv "/include\""); + } + print $0; + next; + } + 1 + ' || die "failed to fix include paths in rebar.config" > +} > + > +# @FUNCTION: rebar_remove_deps > +# @DESCRIPTION: > +# Remove dependencies list from rebar.config and deceive build rules that any > +# dependencies are already fetched and built. Otherwise rebar tries to fetch > +# dependencies and compile them. > +# > +# The function dies on failure. > +rebar_remove_deps() { > + debug-print-function ${FUNCNAME} "${@}" > + > + mkdir -p "${S}/deps" && :>"${S}/deps/.got" && :>"${S}/deps/.built" || die > + eawk rebar.config \ > + '/^{[[:space:]]*deps[[:space:]]*,/, /}[[:space:]]*\.$/ { > + if ($0 ~ /}[[:space:]]*\.$/) { > + print "{deps, []}."; > + } > + next; > +} > +1 > +' || die "failed to remove deps from rebar.config" > +} > + > +# @FUNCTION: rebar_set_vsn > +# @USAGE: [<version>] > +# @DESCRIPTION: > +# Set version in project description file if it's not set. > +# > +# <version> is optional. Default is PV stripped from version suffix. > +# > +# The function dies on failure. > +rebar_set_vsn() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local version="${1:-${PV%_*}}" > + > + sed -e "s/vsn, git/vsn, \"${version}\"/" \ > + -i "${S}/${REBAR_APP_SRC}" \ > + || die "failed to set version in src/${PN}.app.src" > +} > + > +# @FUNCTION: rebar_src_prepare > +# @DESCRIPTION: > +# Prevent rebar from fetching in compiling dependencies. Set version in project > +# description file if it's not set. > +# > +# Existence of rebar.config is optional, but file description file must exist > +# at 'src/${PN}.app.src'. > +rebar_src_prepare() { > + debug-print-function ${FUNCNAME} "${@}" > + > + default > + rebar_set_vsn > + [[ -f rebar.config ]] && rebar_remove_deps > +} > + > +# @FUNCTION: rebar_src_configure > +# @DESCRIPTION: > +# Configure with ERL_LIBS set. > +rebar_src_configure() { > + debug-print-function ${FUNCNAME} "${@}" > + > + evar_push ERL_LIBS > + export ERL_LIBS="${EPREFIX}$(get_erl_libs)" > + default > + evar_pop > +} > + > +# @FUNCTION: rebar_src_compile > +# @DESCRIPTION: > +# Compile project with rebar. > +rebar_src_compile() { > + debug-print-function ${FUNCNAME} "${@}" > + > + erebar compile > +} > + > +# @FUNCTION: rebar_src_install > +# @DESCRIPTION: > +# Install BEAM files, include headers, executables and native libraries. > +# Install standard docs like README or defined in DOCS variable. > +# > +# Function expects that project conforms to Erlang/OTP structure. > +rebar_src_install() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local bin > + local dest="$(get_erl_libs)/${P}" > + > + insinto "${dest}" > + doins -r ebin > + [[ -d include ]] && doins -r include > + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done > + [[ -d priv ]] && cp -pR priv "${ED}${dest}/" Missing ||die. Just don't do it as one-liner :-P. > + > + einstalldocs > +} -- Best regards, Michał Górny <http://dev.gentoo.org/~mgorny/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 949 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-21 20:48 ` Michał Górny @ 2016-05-21 22:11 ` Amadeusz Żołnowski 0 siblings, 0 replies; 14+ messages in thread From: Amadeusz Żołnowski @ 2016-05-21 22:11 UTC (permalink / raw To: Michał Górny; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 1422 bytes --] Michał Górny <mgorny@gentoo.org> writes: >> +# Run rebar with verbose flag. Die on failure. >> +erebar() { >> + debug-print-function ${FUNCNAME} "${@}" >> + >> + (( $# > 0 )) || die 'erebar: at least one target is required' > > Why not [[ $# -gt 0 ]]? It's the first time I see someone using (( )) > for conditionals. '>' reads better than some '-gt'. >> + evar_push ERL_LIBS >> + export ERL_LIBS="${EPREFIX}$(get_erl_libs)" > > local -x ERL_LIBS=... > > We don't really have to employ terribly ugly eval hackery to have > a local variable. Fixed. I hoped there's better way! (-: > I meant indent like this: > > + eawk rebar.config \ > + -v erl_libs="${erl_libs}" -v pn="${pn}" -v pv="${pv}" \ > + '/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { > + pattern = "\"(./)?deps/" pn "/include\""; > + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { > + sub(pattern, "\"" erl_libs "/" pn "-" pv "/include\""); > + } > + print $0; > + next; > + } > + 1 > + ' || die "failed to fix include paths in rebar.config" OK. >> + insinto "${dest}" >> + doins -r ebin >> + [[ -d include ]] && doins -r include >> + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done >> + [[ -d priv ]] && cp -pR priv "${ED}${dest}/" > > Missing ||die. Just don't do it as one-liner :-P. You've got me! ;-) Thanks, -- Amadeusz Żołnowski [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 950 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-18 22:35 [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar aidecoe ` (2 preceding siblings ...) 2016-05-21 13:26 ` aidecoe @ 2016-05-21 23:19 ` aidecoe 2016-05-21 23:22 ` [gentoo-dev] [PATCH 2/2] Add tests for rebar.eclass aidecoe 2016-05-22 21:14 ` [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar Michał Górny 3 siblings, 2 replies; 14+ messages in thread From: aidecoe @ 2016-05-21 23:19 UTC (permalink / raw To: gentoo-dev; +Cc: Amadeusz Żołnowski From: Amadeusz Żołnowski <aidecoe@gentoo.org> It is an eclass providing functions to build Erlang/OTP projects using dev-util/rebar. All packages in upcoming category dev-erlang are going to use this eclass. --- eclass/rebar.eclass | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 eclass/rebar.eclass diff --git a/eclass/rebar.eclass b/eclass/rebar.eclass new file mode 100644 index 0000000..1a4eaba --- /dev/null +++ b/eclass/rebar.eclass @@ -0,0 +1,223 @@ +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +# @ECLASS: rebar.eclass +# @MAINTAINER: +# Amadeusz Żołnowski <aidecoe@gentoo.org> +# @AUTHOR: +# Amadeusz Żołnowski <aidecoe@gentoo.org> +# @BLURB: Build Erlang/OTP projects using dev-util/rebar. +# @DESCRIPTION: +# An eclass providing functions to build Erlang/OTP projects using +# dev-util/rebar. +# +# rebar is a tool which tries to resolve dependencies itself which is by +# cloning remote git repositories. Dependant projects are usually expected to +# be in sub-directory 'deps' rather than looking at system Erlang lib +# directory. Projects relying on rebar usually don't have 'install' make +# targets. The eclass workarounds some of these problems. It handles +# installation in a generic way for Erlang/OTP structured projects. + +case "${EAPI:-0}" in + 0|1|2|3|4|5) + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" + ;; + 6) + ;; + *) + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" + ;; +esac + +EXPORT_FUNCTIONS src_prepare src_compile src_install + +RDEPEND="dev-lang/erlang" +DEPEND="${RDEPEND} + dev-util/rebar + >=sys-apps/gawk-4.1" + +# @ECLASS-VARIABLE: REBAR_APP_SRC +# @DESCRIPTION: +# Relative path to .app.src description file. +REBAR_APP_SRC="${REBAR_APP_SRC-src/${PN}.app.src}" + +# @FUNCTION: get_erl_libs +# @RETURN: the path to Erlang lib directory +# @DESCRIPTION: +# Get the full path without EPREFIX to Erlang lib directory. +get_erl_libs() { + echo "/usr/$(get_libdir)/erlang/lib" +} + +# @FUNCTION: _rebar_find_dep +# @INTERNAL +# @USAGE: <project_name> +# @RETURN: full path with EPREFIX to a Erlang package/project on success, +# code 1 when dependency is not found and code 2 if multiple versions of +# dependency are found. +# @DESCRIPTION: +# Find a Erlang package/project by name in Erlang lib directory. Project +# directory is usually suffixed with version. It is matched to '<project_name>' +# or '<project_name>-*'. +_rebar_find_dep() { + local pn="$1" + local p + local result + + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null || return 1 + for p in ${pn} ${pn}-*; do + if [[ -d ${p} ]]; then + # Ensure there's at most one matching. + [[ ${result} ]] && return 2 + result="${p}" + fi + done + popd >/dev/null || die + + [[ ${result} ]] || return 1 + echo "${result}" +} + +# @FUNCTION: erebar +# @USAGE: <targets> +# @DESCRIPTION: +# Run rebar with verbose flag. Die on failure. +erebar() { + debug-print-function ${FUNCNAME} "${@}" + + (( $# > 0 )) || die "erebar: at least one target is required" + + local -x ERL_LIBS="${EPREFIX}$(get_erl_libs)" + rebar -v skip_deps=true "$@" || die "rebar $@ failed" +} + +# @FUNCTION: rebar_fix_include_path +# @USAGE: <project_name> +# @DESCRIPTION: +# Fix path in rebar.config to 'include' directory of dependant project/package, +# so it points to installation in system Erlang lib rather than relative 'deps' +# directory. +# +# The function dies on failure. +rebar_fix_include_path() { + debug-print-function ${FUNCNAME} "${@}" + + local pn="$1" + local erl_libs="${EPREFIX}$(get_erl_libs)" + local p + + p="$(_rebar_find_dep "${pn}")" \ + || die "failed to unambiguously resolve dependency of '${pn}'" + + gawk -i inplace \ + -v erl_libs="${erl_libs}" -v pn="${pn}" -v p="${p}" ' +/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { + pattern = "\"(./)?deps/" pn "/include\""; + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { + sub(pattern, "\"" erl_libs "/" p "/include\""); + } + print $0; + next; +} +1 +' rebar.config || die "failed to fix include paths in rebar.config for '${pn}'" +} + +# @FUNCTION: rebar_remove_deps +# @DESCRIPTION: +# Remove dependencies list from rebar.config and deceive build rules that any +# dependencies are already fetched and built. Otherwise rebar tries to fetch +# dependencies and compile them. +# +# The function dies on failure. +rebar_remove_deps() { + debug-print-function ${FUNCNAME} "${@}" + + mkdir -p "${S}/deps" && :>"${S}/deps/.got" && :>"${S}/deps/.built" || die + gawk -i inplace ' +/^{[[:space:]]*deps[[:space:]]*,/, /}[[:space:]]*\.$/ { + if ($0 ~ /}[[:space:]]*\.$/) { + print "{deps, []}."; + } + next; +} +1 +' rebar.config || die "failed to remove deps from rebar.config" +} + +# @FUNCTION: rebar_set_vsn +# @USAGE: [<version>] +# @DESCRIPTION: +# Set version in project description file if it's not set. +# +# <version> is optional. Default is PV stripped from version suffix. +# +# The function dies on failure. +rebar_set_vsn() { + debug-print-function ${FUNCNAME} "${@}" + + local version="${1:-${PV%_*}}" + + sed -e "s/vsn, git/vsn, \"${version}\"/" \ + -i "${S}/${REBAR_APP_SRC}" \ + || die "failed to set version in src/${PN}.app.src" +} + +# @FUNCTION: rebar_src_prepare +# @DESCRIPTION: +# Prevent rebar from fetching in compiling dependencies. Set version in project +# description file if it's not set. +# +# Existence of rebar.config is optional, but file description file must exist +# at 'src/${PN}.app.src'. +rebar_src_prepare() { + debug-print-function ${FUNCNAME} "${@}" + + default + rebar_set_vsn + [[ -f rebar.config ]] && rebar_remove_deps +} + +# @FUNCTION: rebar_src_configure +# @DESCRIPTION: +# Configure with ERL_LIBS set. +rebar_src_configure() { + debug-print-function ${FUNCNAME} "${@}" + + local -x ERL_LIBS="${EPREFIX}$(get_erl_libs)" + default +} + +# @FUNCTION: rebar_src_compile +# @DESCRIPTION: +# Compile project with rebar. +rebar_src_compile() { + debug-print-function ${FUNCNAME} "${@}" + + erebar compile +} + +# @FUNCTION: rebar_src_install +# @DESCRIPTION: +# Install BEAM files, include headers, executables and native libraries. +# Install standard docs like README or defined in DOCS variable. +# +# Function expects that project conforms to Erlang/OTP structure. +rebar_src_install() { + debug-print-function ${FUNCNAME} "${@}" + + local bin + local dest="$(get_erl_libs)/${P}" + + insinto "${dest}" + doins -r ebin + [[ -d include ]] && doins -r include + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done + + if [[ -d priv ]]; then + cp -pR priv "${ED}${dest}/" || die "failed to install priv/" + fi + + einstalldocs +} -- 2.8.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [gentoo-dev] [PATCH 2/2] Add tests for rebar.eclass 2016-05-21 23:19 ` aidecoe @ 2016-05-21 23:22 ` aidecoe 2016-05-22 21:14 ` [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar Michał Górny 1 sibling, 0 replies; 14+ messages in thread From: aidecoe @ 2016-05-21 23:22 UTC (permalink / raw To: gentoo-dev; +Cc: Amadeusz Żołnowski From: Amadeusz Żołnowski <aidecoe@gentoo.org> --- eclass/tests/rebar_fix_include_path.sh | 159 +++++++++++++++++++++++++++++++++ eclass/tests/rebar_remove_deps.sh | 99 ++++++++++++++++++++ eclass/tests/rebar_set_vsn.sh | 115 ++++++++++++++++++++++++ 3 files changed, 373 insertions(+) create mode 100755 eclass/tests/rebar_fix_include_path.sh create mode 100755 eclass/tests/rebar_remove_deps.sh create mode 100755 eclass/tests/rebar_set_vsn.sh diff --git a/eclass/tests/rebar_fix_include_path.sh b/eclass/tests/rebar_fix_include_path.sh new file mode 100755 index 0000000..9047f8d --- /dev/null +++ b/eclass/tests/rebar_fix_include_path.sh @@ -0,0 +1,159 @@ +#!/bin/bash +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +source tests-common.sh + +EAPI=6 + +inherit rebar + +EPREFIX="${tmpdir}/fakeroot" +S="${WORKDIR}/${P}" + +setup() { + mkdir -p "${S}" || die + + for pkg in foo-0.1.0 bar-0.1.0; do + mkdir -p "${EPREFIX}$(get_erl_libs)/${pkg}/include" || die + done + + cat <<EOF >"${S}/typical.config" || die +%%% Comment + +{erl_opts, [debug_info, {src_dirs, ["src"]}, + {i, "include"}, + {i, "deps/foo/include"}, + {i, "../foo/include"}]}. + +{port_env, [{"CFLAGS", "\$CFLAGS"}, {"LDFLAGS", "\$LDFLAGS"}]}. +EOF + + cat <<EOF >"${S}/typical.config.expected" || die +%%% Comment + +{erl_opts, [debug_info, {src_dirs, ["src"]}, + {i, "include"}, + {i, "${EPREFIX}$(get_erl_libs)/foo-0.1.0/include"}, + {i, "../foo/include"}]}. + +{port_env, [{"CFLAGS", "\$CFLAGS"}, {"LDFLAGS", "\$LDFLAGS"}]}. +EOF + + cat <<EOF >"${S}/inc_one_line.config" || die +%%% Comment + +{erl_opts, [debug_info, {src_dirs, ["src"]}, {i, "include"}, {i, "deps/foo/include"}, {i, "../foo/include"}]}. + +{port_env, [{"CFLAGS", "\$CFLAGS"}, {"LDFLAGS", "\$LDFLAGS"}]}. +EOF + + cat <<EOF >"${S}/inc_one_line.config.expected" || die +%%% Comment + +{erl_opts, [debug_info, {src_dirs, ["src"]}, {i, "include"}, {i, "${EPREFIX}$(get_erl_libs)/foo-0.1.0/include"}, {i, "../foo/include"}]}. + +{port_env, [{"CFLAGS", "\$CFLAGS"}, {"LDFLAGS", "\$LDFLAGS"}]}. +EOF +} + +test_typical_config() { + local diff_rc + local unit_rc + + # Prepare + cd "${S}" || die + cp typical.config rebar.config || die + + # Run unit + (rebar_fix_include_path foo) + unit_rc=$? + + # Test result + diff rebar.config typical.config.expected + diff_rc=$? + + [[ ${unit_rc}${diff_rc} = 00 ]] +} + +test_multiple_versions() { + local diff_rc + local unit_rc + + # Prepare + cd "${S}" || die + cp typical.config rebar.config || die + mkdir -p "${EPREFIX}$(get_erl_libs)/foo-1.0.0/include" || die + + # Run unit + (rebar_fix_include_path foo 2>/dev/null) + unit_rc=$? + + # Test result + diff rebar.config typical.config + diff_rc=$? + + # Clean up + rm -r "${EPREFIX}$(get_erl_libs)/foo-1.0.0" || die + + [[ ${unit_rc}${diff_rc} = 10 ]] +} + +test_not_found() { + local diff_rc + local unit_rc + + # Prepare + cd "${S}" || die + cp typical.config rebar.config || die + + # Run unit + (rebar_fix_include_path fo 2>/dev/null) + unit_rc=$? + + # Test result + diff rebar.config typical.config + diff_rc=$? + + [[ ${unit_rc}${diff_rc} = 10 ]] +} + +test_includes_in_one_line() { + local diff_rc + local unit_rc + + # Prepare + cd "${S}" || die + cp inc_one_line.config rebar.config || die + + # Run unit + (rebar_fix_include_path foo) + unit_rc=$? + + # Test result + diff rebar.config inc_one_line.config.expected + diff_rc=$? + + [[ ${unit_rc}${diff_rc} = 00 ]] +} + +setup + +tbegin "rebar_fix_include_path deals with typical config" +test_typical_config +tend $? + +tbegin "rebar_fix_include_path fails on multiple versions of dependency" +test_multiple_versions +tend $? + +tbegin "rebar_fix_include_path fails if dependency is not found" +test_not_found +tend $? + +tbegin "rebar_fix_include_path deals with all includes in one line" +test_includes_in_one_line +tend $? + +texit diff --git a/eclass/tests/rebar_remove_deps.sh b/eclass/tests/rebar_remove_deps.sh new file mode 100755 index 0000000..05207a7 --- /dev/null +++ b/eclass/tests/rebar_remove_deps.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +source tests-common.sh + +EAPI=6 + +inherit rebar + +EPREFIX="${tmpdir}/fakeroot" +S="${WORKDIR}/${P}" + +setup() { + mkdir -p "${S}" || die + + cat <<EOF >"${S}/rebar.config.expected" || die +%%% Comment + +{port_specs, [{"priv/lib/esip_drv.so", ["c_src/esip_codec.c"]}]}. + +{deps, []}. + +{clean_files, ["c_src/esip_codec.gcda", "c_src/esip_codec.gcno"]}. +EOF + + cat <<EOF >"${S}/typical.config" || die +%%% Comment + +{port_specs, [{"priv/lib/esip_drv.so", ["c_src/esip_codec.c"]}]}. + +{deps, [{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.3"}}}, + {fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.3"}}}, + {p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.3"}}}]}. + +{clean_files, ["c_src/esip_codec.gcda", "c_src/esip_codec.gcno"]}. +EOF + + cat <<EOF >"${S}/deps_one_line.config" || die +%%% Comment + +{port_specs, [{"priv/lib/esip_drv.so", ["c_src/esip_codec.c"]}]}. + +{deps, [{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.3"}}}, {fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.3"}}}, {p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.3"}}}]}. + +{clean_files, ["c_src/esip_codec.gcda", "c_src/esip_codec.gcno"]}. +EOF +} + +test_typical_config() { + local diff_rc + local unit_rc + + # Prepare + cd "${S}" || die + cp typical.config rebar.config || die + + # Run unit + (rebar_remove_deps) + unit_rc=$? + + # Test result + diff rebar.config rebar.config.expected + diff_rc=$? + + [[ ${unit_rc}${diff_rc} = 00 ]] +} + +test_deps_in_one_line() { + local diff_rc + local unit_rc + + # Prepare + cd "${S}" || die + cp deps_one_line.config rebar.config || die + + # Run unit + (rebar_remove_deps) + unit_rc=$? + + # Test result + diff rebar.config rebar.config.expected + diff_rc=$? + + [[ ${unit_rc}${diff_rc} = 00 ]] +} + +setup + +tbegin "rebar_remove_deps deals with typical config" +test_typical_config +tend $? + +tbegin "rebar_remove_deps deals with all deps in one line" +test_deps_in_one_line +tend $? + +texit diff --git a/eclass/tests/rebar_set_vsn.sh b/eclass/tests/rebar_set_vsn.sh new file mode 100755 index 0000000..2a9f5bc --- /dev/null +++ b/eclass/tests/rebar_set_vsn.sh @@ -0,0 +1,115 @@ +#!/bin/bash +# Copyright 1999-2016 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +source tests-common.sh + +EAPI=6 + +inherit rebar + +EPREFIX="${tmpdir}/fakeroot" +S="${WORKDIR}/${P}" + +setup() { + mkdir -p "${S}/src" || die + + cat <<EOF >"${S}/app.src.expected" || die +%%% Comment + +{application, esip, + [{description, "ProcessOne SIP server component in Erlang"}, + {vsn, "0"}, + {modules, []}, + {registered, []}, +EOF + + cat <<EOF >"${S}/app.src" || die +%%% Comment + +{application, esip, + [{description, "ProcessOne SIP server component in Erlang"}, + {vsn, git}, + {modules, []}, + {registered, []}, +EOF +} + +test_typical_app_src() { + local diff_rc + local unit_rc + + # Prepare + cd "${S}" || die + cp app.src "src/${PN}.app.src" || die + + # Run unit + (rebar_set_vsn) + unit_rc=$? + + # Test result + diff "src/${PN}.app.src" app.src.expected + diff_rc=$? + + [[ ${unit_rc}${diff_rc} = 00 ]] +} + +test_app_src_missing() { + local unit_rc + + # Prepare + cd "${S}" || die + rm -f "src/${PN}.app.src" || die + + # Run unit + (rebar_set_vsn 2>/dev/null) + unit_rc=$? + + [[ ${unit_rc} = 1 ]] +} + +test_set_custom_version() { + local diff_rc + local unit_rc + + # Prepare + cd "${S}" || die + cp app.src "src/${PN}.app.src" || die + cat <<EOF >"${S}/custom_app.src.expected" || die +%%% Comment + +{application, esip, + [{description, "ProcessOne SIP server component in Erlang"}, + {vsn, "1.2.3"}, + {modules, []}, + {registered, []}, +EOF + + # Run unit + (rebar_set_vsn 1.2.3) + unit_rc=$? + + # Test result + diff "src/${PN}.app.src" custom_app.src.expected + diff_rc=$? + + [[ ${unit_rc}${diff_rc} = 00 ]] +} + + +setup + +tbegin "rebar_set_vsn deals with typical app.src" +test_typical_app_src +tend $? + +tbegin "rebar_set_vsn fails when app.src is missing" +test_app_src_missing +tend $? + +tbegin "rebar_set_vsn sets custom version in app.src" +test_set_custom_version +tend $? + +texit -- 2.8.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-21 23:19 ` aidecoe 2016-05-21 23:22 ` [gentoo-dev] [PATCH 2/2] Add tests for rebar.eclass aidecoe @ 2016-05-22 21:14 ` Michał Górny 2016-05-22 22:07 ` Amadeusz Żołnowski 1 sibling, 1 reply; 14+ messages in thread From: Michał Górny @ 2016-05-22 21:14 UTC (permalink / raw To: aidecoe; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 7772 bytes --] On Sun, 22 May 2016 00:19:49 +0100 aidecoe@gentoo.org wrote: > From: Amadeusz Żołnowski <aidecoe@gentoo.org> > > It is an eclass providing functions to build Erlang/OTP projects using > dev-util/rebar. All packages in upcoming category dev-erlang are going > to use this eclass. > --- > eclass/rebar.eclass | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 223 insertions(+) > create mode 100644 eclass/rebar.eclass > > diff --git a/eclass/rebar.eclass b/eclass/rebar.eclass > new file mode 100644 > index 0000000..1a4eaba > --- /dev/null > +++ b/eclass/rebar.eclass > @@ -0,0 +1,223 @@ > +# Copyright 1999-2016 Gentoo Foundation > +# Distributed under the terms of the GNU General Public License v2 > +# $Id$ > + > +# @ECLASS: rebar.eclass > +# @MAINTAINER: > +# Amadeusz Żołnowski <aidecoe@gentoo.org> > +# @AUTHOR: > +# Amadeusz Żołnowski <aidecoe@gentoo.org> > +# @BLURB: Build Erlang/OTP projects using dev-util/rebar. > +# @DESCRIPTION: > +# An eclass providing functions to build Erlang/OTP projects using > +# dev-util/rebar. > +# > +# rebar is a tool which tries to resolve dependencies itself which is by > +# cloning remote git repositories. Dependant projects are usually expected to > +# be in sub-directory 'deps' rather than looking at system Erlang lib > +# directory. Projects relying on rebar usually don't have 'install' make > +# targets. The eclass workarounds some of these problems. It handles > +# installation in a generic way for Erlang/OTP structured projects. > + > +case "${EAPI:-0}" in > + 0|1|2|3|4|5) > + die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" > + ;; > + 6) > + ;; > + *) > + die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" > + ;; > +esac > + > +EXPORT_FUNCTIONS src_prepare src_compile src_install > + > +RDEPEND="dev-lang/erlang" > +DEPEND="${RDEPEND} > + dev-util/rebar > + >=sys-apps/gawk-4.1" > + > +# @ECLASS-VARIABLE: REBAR_APP_SRC > +# @DESCRIPTION: > +# Relative path to .app.src description file. > +REBAR_APP_SRC="${REBAR_APP_SRC-src/${PN}.app.src}" > + > +# @FUNCTION: get_erl_libs > +# @RETURN: the path to Erlang lib directory > +# @DESCRIPTION: > +# Get the full path without EPREFIX to Erlang lib directory. > +get_erl_libs() { > + echo "/usr/$(get_libdir)/erlang/lib" > +} > + > +# @FUNCTION: _rebar_find_dep > +# @INTERNAL > +# @USAGE: <project_name> > +# @RETURN: full path with EPREFIX to a Erlang package/project on success, > +# code 1 when dependency is not found and code 2 if multiple versions of > +# dependency are found. > +# @DESCRIPTION: > +# Find a Erlang package/project by name in Erlang lib directory. Project > +# directory is usually suffixed with version. It is matched to '<project_name>' > +# or '<project_name>-*'. > +_rebar_find_dep() { > + local pn="$1" > + local p > + local result > + > + pushd "${EPREFIX}$(get_erl_libs)" >/dev/null || return 1 > + for p in ${pn} ${pn}-*; do > + if [[ -d ${p} ]]; then > + # Ensure there's at most one matching. > + [[ ${result} ]] && return 2 > + result="${p}" > + fi > + done > + popd >/dev/null || die > + > + [[ ${result} ]] || return 1 > + echo "${result}" > +} > + > +# @FUNCTION: erebar > +# @USAGE: <targets> > +# @DESCRIPTION: > +# Run rebar with verbose flag. Die on failure. > +erebar() { > + debug-print-function ${FUNCNAME} "${@}" > + > + (( $# > 0 )) || die "erebar: at least one target is required" > + > + local -x ERL_LIBS="${EPREFIX}$(get_erl_libs)" > + rebar -v skip_deps=true "$@" || die "rebar $@ failed" Maybe 'die -n', for consistency with emake? > +} > + > +# @FUNCTION: rebar_fix_include_path > +# @USAGE: <project_name> > +# @DESCRIPTION: > +# Fix path in rebar.config to 'include' directory of dependant project/package, > +# so it points to installation in system Erlang lib rather than relative 'deps' > +# directory. > +# > +# The function dies on failure. > +rebar_fix_include_path() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local pn="$1" > + local erl_libs="${EPREFIX}$(get_erl_libs)" > + local p > + > + p="$(_rebar_find_dep "${pn}")" \ > + || die "failed to unambiguously resolve dependency of '${pn}'" > + > + gawk -i inplace \ > + -v erl_libs="${erl_libs}" -v pn="${pn}" -v p="${p}" ' > +/^{[[:space:]]*erl_opts[[:space:]]*,/, /}[[:space:]]*\.$/ { > + pattern = "\"(./)?deps/" pn "/include\""; > + if (match($0, "{i,[[:space:]]*" pattern "[[:space:]]*}")) { > + sub(pattern, "\"" erl_libs "/" p "/include\""); > + } > + print $0; > + next; > +} > +1 > +' rebar.config || die "failed to fix include paths in rebar.config for '${pn}'" > +} > + > +# @FUNCTION: rebar_remove_deps > +# @DESCRIPTION: > +# Remove dependencies list from rebar.config and deceive build rules that any > +# dependencies are already fetched and built. Otherwise rebar tries to fetch > +# dependencies and compile them. > +# > +# The function dies on failure. > +rebar_remove_deps() { > + debug-print-function ${FUNCNAME} "${@}" > + > + mkdir -p "${S}/deps" && :>"${S}/deps/.got" && :>"${S}/deps/.built" || die > + gawk -i inplace ' > +/^{[[:space:]]*deps[[:space:]]*,/, /}[[:space:]]*\.$/ { > + if ($0 ~ /}[[:space:]]*\.$/) { > + print "{deps, []}."; > + } > + next; > +} > +1 > +' rebar.config || die "failed to remove deps from rebar.config" > +} > + > +# @FUNCTION: rebar_set_vsn > +# @USAGE: [<version>] > +# @DESCRIPTION: > +# Set version in project description file if it's not set. > +# > +# <version> is optional. Default is PV stripped from version suffix. > +# > +# The function dies on failure. > +rebar_set_vsn() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local version="${1:-${PV%_*}}" > + > + sed -e "s/vsn, git/vsn, \"${version}\"/" \ > + -i "${S}/${REBAR_APP_SRC}" \ > + || die "failed to set version in src/${PN}.app.src" > +} > + > +# @FUNCTION: rebar_src_prepare > +# @DESCRIPTION: > +# Prevent rebar from fetching in compiling dependencies. Set version in project I think this sentence is incorrect. > +# description file if it's not set. > +# > +# Existence of rebar.config is optional, but file description file must exist > +# at 'src/${PN}.app.src'. > +rebar_src_prepare() { > + debug-print-function ${FUNCNAME} "${@}" > + > + default > + rebar_set_vsn > + [[ -f rebar.config ]] && rebar_remove_deps > +} > + > +# @FUNCTION: rebar_src_configure > +# @DESCRIPTION: > +# Configure with ERL_LIBS set. > +rebar_src_configure() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local -x ERL_LIBS="${EPREFIX}$(get_erl_libs)" > + default > +} > + > +# @FUNCTION: rebar_src_compile > +# @DESCRIPTION: > +# Compile project with rebar. > +rebar_src_compile() { > + debug-print-function ${FUNCNAME} "${@}" > + > + erebar compile > +} > + > +# @FUNCTION: rebar_src_install > +# @DESCRIPTION: > +# Install BEAM files, include headers, executables and native libraries. > +# Install standard docs like README or defined in DOCS variable. > +# > +# Function expects that project conforms to Erlang/OTP structure. > +rebar_src_install() { > + debug-print-function ${FUNCNAME} "${@}" > + > + local bin > + local dest="$(get_erl_libs)/${P}" > + > + insinto "${dest}" > + doins -r ebin > + [[ -d include ]] && doins -r include > + [[ -d bin ]] && for bin in bin/*; do dobin "$bin"; done > + > + if [[ -d priv ]]; then > + cp -pR priv "${ED}${dest}/" || die "failed to install priv/" > + fi > + > + einstalldocs > +} I think I have no further comments, so the two things above considered, looks good to go. -- Best regards, Michał Górny <http://dev.gentoo.org/~mgorny/> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 949 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar 2016-05-22 21:14 ` [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar Michał Górny @ 2016-05-22 22:07 ` Amadeusz Żołnowski 0 siblings, 0 replies; 14+ messages in thread From: Amadeusz Żołnowski @ 2016-05-22 22:07 UTC (permalink / raw To: Michał Górny; +Cc: gentoo-dev [-- Attachment #1: Type: text/plain, Size: 967 bytes --] Michał Górny <mgorny@gentoo.org> writes: >> +# @FUNCTION: erebar >> +# @USAGE: <targets> >> +# @DESCRIPTION: >> +# Run rebar with verbose flag. Die on failure. >> +erebar() { >> + debug-print-function ${FUNCNAME} "${@}" >> + >> + (( $# > 0 )) || die "erebar: at least one target is required" >> + >> + local -x ERL_LIBS="${EPREFIX}$(get_erl_libs)" >> + rebar -v skip_deps=true "$@" || die "rebar $@ failed" > > Maybe 'die -n', for consistency with emake? Yes, just for consitency... >> +# @FUNCTION: rebar_src_prepare >> +# @DESCRIPTION: >> +# Prevent rebar from fetching in compiling dependencies. Set version in project > > I think this sentence is incorrect. Yes, "in" -> "and". Thanks for catching this! > I think I have no further comments, so the two things above > considered, looks good to go. Thank you for review! I have pushed eclass along with tests. Feel free to comment on tests later. -- Amadeusz Żołnowski [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 950 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2016-05-22 22:08 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-05-18 22:35 [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar aidecoe 2016-05-18 23:26 ` Peter Stuge 2016-05-20 23:09 ` Amadeusz Żołnowski 2016-05-19 4:39 ` Michał Górny 2016-05-20 23:06 ` Amadeusz Żołnowski 2016-05-21 7:00 ` Michał Górny 2016-05-21 8:35 ` Amadeusz Żołnowski 2016-05-21 13:26 ` aidecoe 2016-05-21 20:48 ` Michał Górny 2016-05-21 22:11 ` Amadeusz Żołnowski 2016-05-21 23:19 ` aidecoe 2016-05-21 23:22 ` [gentoo-dev] [PATCH 2/2] Add tests for rebar.eclass aidecoe 2016-05-22 21:14 ` [gentoo-dev] [PATCH] rebar.eclass: Build Erlang/OTP projects using dev-util/rebar Michał Górny 2016-05-22 22:07 ` Amadeusz Żołnowski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox