* [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 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-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-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