1
0
ocaml-rpm-macros/ocaml-findlib.rpm.prov_req.attr.sh
Olaf Hering 6267059f33 - Adjust parser of ocamfind() requires
Take negative predicates in requires() into account, and ignore them.
  This is supposed to avoid dependency cycles due to excessive
  list of dependencies.

OBS-URL: https://build.opensuse.org/package/show/devel:languages:ocaml/ocaml-rpm-macros?expand=0&rev=50
2021-01-27 19:24:48 +00:00

230 lines
6.4 KiB
Bash

#!/bin/bash
set -e
prov_req_name="ocamlfind"
td=`mktemp --directory`
test -n "${td}"
_x() {
rm -rf "${td}"
}
trap _x EXIT
cmd=
test "$1" = "-prov" && cmd=prov
test "$1" = "-req" && cmd=req
do_work() {
local f=$1
local pkg_name
local pkg_prov_req
local pkg_prov
local pkg_req
local elem req
pkg_name="${f##*/}"
if test "${pkg_name}" = "META"
then
pkg_name="${f%/*}"
pkg_name="${pkg_name##*/}"
else
pkg_name="${pkg_name#META.}"
fi
pkg_prov_req="`
env \
pkg_name="${pkg_name}" \
cmd="${cmd}" \
awk '
BEGIN {
dbg=0;
count=1;
depth=0;
pkg_name=ENVIRON["pkg_name"];
cmd=ENVIRON["cmd"];
if(dbg) printf "bEGIN \\"%s\\" cmd: %s\n", pkg_name, cmd > "/dev/stderr" ;
requires[pkg_name]=""
ppx_runtime_deps[pkg_name]=""
pkg_names[depth]=pkg_name
}
{
if(dbg) printf "line: %s\n", $0 > "/dev/stderr"
}
/^[[:blank:]]*directory[[:blank:]]*=/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
if (depth == 0) {
x = split($0, a, "\\"");
if ( a[2] ) {
candidate = a[2];
if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ;
if (candidate ~ /^\^/) {
next
}
if (candidate ~ /^\+/) {
candidate = substr(candidate, 2);
}
if (candidate ~ /^\//) {
x = split(candidate, a, "/");
if ( x )
candidate = a[x];
}
if (candidate ~ /^\.\.\//) {
x = split(candidate, a, "/");
if ( x )
candidate = a[x];
}
if(dbg) printf "dir: %s %s\n", x, candidate > "/dev/stderr" ;
if (candidate != pkg_name) {
requires[candidate] = requires[pkg_name];
delete requires[pkg_name];
pkg_name = candidate;
if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
pkg_names[depth]=pkg_name
} else {
if(dbg) printf "pkg_name remains %s\n", pkg_name > "/dev/stderr" ;
}
}
}
next
}
/^[[:blank:]]*requires(|\([^-][^)]+\))[[:blank:]]*(+=|=)/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
done=0
requires_line = ""
do {
need_next_line = 1
line = $0
requires_line = sprintf("%s%s", requires_line, line)
l = length(requires_line)
qm = index(requires_line, "\\"")
if (l > qm) {
line = substr(requires_line, qm + 1)
qm = index(line, "\\"")
need_next_line = qm == 0
}
if (need_next_line) {
done = getline == 0
} else {
done = 1
}
} while (done == 0)
x = split(requires_line, a, "\\"");
if ( a[2] ) {
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
x = gsub("[[:blank:]]+", ",", a[2]);
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
if (requires[pkg_name] == "") {
requires[pkg_name] = a[2]
} else {
requires[pkg_name] = sprintf("%s,%s", requires[pkg_name],a[2])
}
}
next
}
/^[[:blank:]]*ppx_runtime_deps[[:blank:]]*(+=|=)/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
done=0
ppx_runtime_deps_line = ""
do {
need_next_line = 1
line = $0
ppx_runtime_deps_line = sprintf("%s%s", ppx_runtime_deps_line, line)
l = length(ppx_runtime_deps_line)
qm = index(ppx_runtime_deps_line, "\\"")
if (l > qm) {
line = substr(ppx_runtime_deps_line, qm + 1)
qm = index(line, "\\"")
need_next_line = qm == 0
}
if (need_next_line) {
done = getline == 0
} else {
done = 1
}
} while (done == 0)
x = split(ppx_runtime_deps_line, a, "\\"");
if ( a[2] ) {
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
x = gsub("[[:blank:]]+", ",", a[2]);
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
if (ppx_runtime_deps[pkg_name] == "") {
ppx_runtime_deps[pkg_name] = a[2]
} else {
requires[pkg_name] = sprintf("%s,%s", requires[pkg_name],a[2])
}
}
next
}
/^[[:blank:]]*package[[:blank:]]/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
depth = depth + 1;
if(dbg) printf "depth %s\n", depth > "/dev/stderr" ;
x = split($0, a, "\\"");
if ( a[2] ) {
if(dbg) printf "req2 %s %s\n", x, a[2] > "/dev/stderr" ;
pkg_name = pkg_name"."a[2];
requires[pkg_name]=""
pkg_names[depth]=pkg_name
if(dbg) printf "new pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
}
next
}
/^[[:blank:]]*)/ {
if(dbg) printf "GOT: %s\n", $0 > "/dev/stderr" ;
depth = depth -1;
if(dbg) printf "depth %s\n", depth > "/dev/stderr" ;
pkg_name=pkg_names[depth]
if(dbg) printf "old pkg_name %s %s\n", x, pkg_name > "/dev/stderr" ;
next
}
END {
if(dbg) printf "eND \\"%s\\"\n", pkg_name > "/dev/stderr" ;
for (req in requires) {
if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr";
# format: provides:requires
printf "%s:%s\n", req, requires[req];
}
for (req in ppx_runtime_deps) {
if(dbg)printf "eNd \\"%s\\"\n", req > "/dev/stderr";
# format: provides:requires
printf "%s:%s\n", req, ppx_runtime_deps[req];
}
if(dbg) printf "ENd \\"%s\\"\n", pkg_name > "/dev/stderr" ;
}
' \"${f}\"
`"
for elem in ${pkg_prov_req}
do
pkg_prov="${elem%%:*}"
pkg_req="${elem#*:}"
pkg_req="${pkg_req//,/ }"
if test -n "${pkg_prov}" && test "${cmd}" = "prov"
then
echo "${prov_req_name}($pkg_prov)"
fi
if test "${cmd}" = "req"
then
for i in ${pkg_req}
do
echo "${prov_req_name}(${i})"
done
fi
done
}
while read filename
do
case "${filename}" in
*/META*) do_work "${filename}" ;;
*) ;;
esac
done
# vim: tw=666 ts=2 shiftwidth=2 et