fedora-rpmdevtools/qa-robot .cvsignore, NONE, 1.1 Makefile.am, NONE, 1.1 rpmargs.in, NONE, 1.1 rpmelfsym, NONE, 1.1 rpmfile, NONE, 1.1 rpmpeek.in, NONE, 1.1 rpmsodiff.in, NONE, 1.1 rpmsoname, NONE, 1.1 tmpdir.sh.in, NONE, 1.1 trap.sh.in, NONE, 1.1

Ville Skytta (scop) fedora-extras-commits at redhat.com
Sat Jun 16 19:12:32 UTC 2007


Author: scop

Update of /cvs/fedora/fedora-rpmdevtools/qa-robot
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv22657/qa-robot

Added Files:
	.cvsignore Makefile.am rpmargs.in rpmelfsym rpmfile rpmpeek.in 
	rpmsodiff.in rpmsoname tmpdir.sh.in trap.sh.in 
Log Message:
Add rpmsodiff and dependencies from ALT Linux's qa-robot package.


--- NEW FILE .cvsignore ---
Makefile
Makefile.in
rpmargs
rpmargs.1
rpmelfsym.1
rpmfile.1
rpmpeek
rpmpeek.1
rpmsodiff
rpmsodiff.1
rpmsoname.1
tmpdir.sh
trap.sh


--- NEW FILE Makefile.am ---
pkgdatadir = $(datadir)/rpmdevtools
POD2MAN = pod2man --release "$(PACKAGE) $(VERSION)" --center ""

dist_bin_SCRIPTS = rpmargs rpmelfsym rpmfile rpmpeek rpmsodiff rpmsoname

dist_pkgdata_DATA = tmpdir.sh trap.sh

dist_man1_MANS = rpmargs.1 rpmelfsym.1 rpmfile.1 rpmpeek.1 rpmsodiff.1 \
	rpmsoname.1

MAINTAINERCLEANFILES = $(dist_man1_MANS) rpmargs rpmpeek rpmsodiff \
	tmpdir.sh trap.sh

all: $(dist_man1_MANS)

%: %.in
	sed -e 's|@pkgdatadir@|$(pkgdatadir)|g' $< > $@
	chmod +x $@

%.1: %
	$(POD2MAN) $< $@


--- NEW FILE rpmargs.in ---
#!/bin/sh -ef
export LC_ALL=C

rpmargs_cmd=
while getopts c:h rpmargs_opt; do
	case "$rpmargs_opt" in
		c) rpmargs_cmd="${OPTARG:?}"
			readonly rpmargs_cmd ;;
		h) pod2usage --exit=0 "$0"; exit 0 ;;
		*) pod2usage --exit=2 "$0"; exit 2 ;;
	esac
done
shift "$((OPTIND-1))"; OPTIND=1

if [ -z "$rpmargs_cmd" ]; then
	echo "${0##*/}: command not specified" >&2
	pod2usage --exit=2 "$0"; exit 2
fi

if [ -z "$*" ]; then
	echo "${0##*/}: not enough arguments" >&2
	pod2usage --exit=2 "$0"; exit 2
fi

rpmargs_files()
{
	ls -1 "$1" |grep -x '[^.].*[.]rpm' >rpmargs_files
	sort -o rpmargs_files -u rpmargs_files
	local f
	while read -r f; do
		$rpmargs_cmd "$1/$f" >rpmargs.out
		[ -s rpmargs.out ] || continue
		awk -v f="$f" '{print f"\t"$0}' rpmargs.out
	done <rpmargs_files
}

. @pkgdatadir@/tmpdir.sh
rpmargs_tmpdir=$TMPDIR

for rpmarg; do
	rpmarg="$(readlink -ev "${rpmarg:?}")"
	cd "$rpmargs_tmpdir"
	if [ -d "$rpmarg" ]; then
		rpmargs_files "$rpmarg"
	else 
		$rpmargs_cmd "$rpmarg"
	fi
	cd - >/dev/null
done

: <<'__EOF__'

=head1	NAME

rpmargs - process RPM packages

=head1	SYNOPSIS

B<rpmargs>
[B<-h>]
B<-c> I<command>
[I<FILE>...] [I<DIR>...]

=head1	DESCRIPTION

B<rpmargs> executes a I<command> against each RPM package given on the
command line.  Extra word splitting is performed on the I<command>.
Each I<FILE> is treated as RPM package.  Each I<DIR> is processed with C<*.rpm>
pattern, and RPM file basename is prepended to the I<command> output.

=head1	OPTIONS

=over

=item	B<-h>

Display this help and exit.

=back

=head1	AUTHOR

Written by Alexey Tourbin <at at altlinux.org>.

=head1	COPYING

Copyright (c) 2005 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=cut

__EOF__


--- NEW FILE rpmelfsym ---
#!/bin/sh -ef
export LC_ALL=C

rpmelfsym()
{
	rpmfile "$1" >files
	awk -F'\t' '$NF~/ELF.*(dynamic|shared)/{printf"./%s\0",$1}' files >elfs0
	[ -s elfs0 ] || return 0
	rpmpeek "$1" xargs -r0 nm -Do <elfs0 >nm.out
	awk '{OFS="\t";sub("^./","",$1);sub(":[0-9a-fA-F]*$","",$1);print}' nm.out
}

. rpmargs -c rpmelfsym "$@"

: <<'__EOF__'

=head1	NAME

rpmelfsym - list symbols from object files in RPM packages

=head1	SYNOPSIS

B<rpmelfsym> [B<-h>] [I<FILE>...] [I<DIR>...]

=head1	DESCRIPTION

B<rpmelfsym> produces three-column output: file name, symbol type,
and symbol name, as determined by nm(1).  Only dynamically linked
executable files and shared libraries are processed, and only dynamic
symbols are listed.
When processing a directory, an additional column is prepended to the
output, which is typically RPM file basename.

=head1	OPTIONS

=over

=item	B<-h>

Display this help and exit.

=back

=head1	AUTHOR

Written by Alexey Tourbin <at at altlinux.org>.

=head1	COPYING

Copyright (c) 2005 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=head1	SEE ALSO

rpmfile(1),
rpmpeek(1),
nm(1)

=cut

__EOF__


--- NEW FILE rpmfile ---
#!/bin/sh -ef
export LC_ALL=C

rpmfile()
{
	rpm -qp --qf '[%{FILENAMES}\t%{FILEMODES:octal}\n]' "$1" >files
	[ -s files ] || return 0
	awk -F'\t' '{print"./"$1}' files |rpmpeek "$1" \
		file -b -f - >types || [ -s types ] || return 1
	paste files types
}

. rpmargs -c rpmfile "$@"

: <<'__EOF__'

=head1	NAME

rpmfile - list file modes and types in RPM packages

=head1	SYNOPSIS

B<rpmfile> [B<-h>] [I<FILE>...] [I<DIR>...]

=head1	DESCRIPTION

B<rpmfile> produces three-column output: file name, file mode (octal),
and file type, as determined by file(1).
When processing a directory, an additional column is prepended to the
output, which is typically RPM file basename.

=head1	OPTIONS

=over

=item	B<-h>

Display this help and exit.

=back

=head1	AUTHOR

Written by Alexey Tourbin <at at altlinux.org>.

=head1	COPYING

Copyright (c) 2005 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=head1	SEE ALSO

rpmargs(1),
rpm(8),
rpm2cpio(8),
file(1)

=cut

__EOF__


--- NEW FILE rpmpeek.in ---
#!/bin/sh -ef
export LC_ALL=C

while getopts h opt; do
	case "$opt" in
		h) pod2usage --exit=0 "$0"; exit 0 ;;
		*) pod2usage --exit=2 "$0"; exit 2 ;;
	esac
done
shift "$((OPTIND-1))"

if [ $# -lt 2 ]; then
	echo "${0##*/}: not enough arguments" >&2
	pod2usage --exit=2 "$0"; exit 2
fi

. @pkgdatadir@/tmpdir.sh
rpm2cpio "$1" |(cd "$TMPDIR"; fakeroot -s .fakedata -- \
	cpio -idmu --quiet --no-absolute-filenames) || exit 2
shift
cd "$TMPDIR"
export RPM_BUILD_ROOT="$TMPDIR"
fakeroot -i .fakedata -- "$@"

: <<'__EOF__'

=head1	NAME

rpmpeek - execute command within RPM contents

=head1	SYNOPSIS

B<rpmpeek> [B<-h>] I<RPM> I<command> [I<args>...]

=head1	DESCRIPTION

B<rpmpeek> unpacks I<RPM> contents into a temporary directory and
executes a I<command> under that directory.  The directory is purged
upon exit.

=head1	AUTHOR

Written by Alexey Tourbin <at at altlinux.org>.

=head1	COPYING

Copyright (c) 2005 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=head1	SEE ALSO

rpm(8),
rpm2cpio(8),
fakeroot(1)

=cut

__EOF__


--- NEW FILE rpmsodiff.in ---
#!/bin/sh -ef
export LC_ALL=C

while getopts h opt; do
	case "$opt" in
		h) pod2usage --exit=0 "$0"; exit 0 ;;
		*) pod2usage --exit=2 "$0"; exit 2 ;;
	esac
done
shift "$((OPTIND-1))"; OPTIND=1

if [ $# -lt 2 ]; then
	echo "${0##*/}: not enough arguments" >&2
	pod2usage --exit=2 "$0"; exit 2
fi
if [ $# -gt 2 ]; then
	echo "${0##*/}: too many arguments" >&2
	pod2usage --exit=2 "$0"; exit 2
fi

rpm1="$(readlink -ev "$1")"
rpm2="$(readlink -ev "$2")"
set -- "$rpm1" "$rpm2"
b1="${1##*/}"; bb1="${b1%.*.rpm}"
b2="${2##*/}"; bb2="${b2%.*.rpm}"
[ "$bb1" != "$bb2" ] || bb2="$bb2+"

. @pkgdatadir@/tmpdir.sh
cd "$TMPDIR"

rpmsoname "$1" >so1; sort -t$'\t' -u -k2 -o so1 -u so1
rpmsoname "$2" >so2; sort -t$'\t' -u -k2 -o so2 -u so2
join -t$'\t' -j 2 so1 so2 >so3
join -t$'\t' -j 2 -v1 so1 so2 >so3.1
join -t$'\t' -j 2 -v2 so1 so2 >so3.2

if [ -s so3.1 ]; then	echo "	sonames only in $bb1 [1]:"; cat so3.1; echo; fi
if [ -s so3.2 ]; then	echo "	sonames only in $bb2 [2]:"; cat so3.2; echo; fi
if [ -s so3 ];	then	echo "	common sonames:"; cat so3; echo;
		else	echo "	no common sonames"; exit; fi

rpmelfsym "$1" >sym1; sort -u sym1 -o sym1
rpmelfsym "$2" >sym2; sort -u sym2 -o sym2
cut -f1,2 so3 |sort -t$'\t' -u -k2 |join -t$'\t' -12 -21 -o '1.1 2.2 2.3' - sym1 |awk -F'\t' '$2~/[DTW]/' |sort -u >def1
cut -f1,3 so3 |sort -t$'\t' -u -k2 |join -t$'\t' -12 -21 -o '1.1 2.2 2.3' - sym2 |awk -F'\t' '$2~/[DTW]/' |sort -u >def2
mkdir "$bb1" "$bb2"
cut -f1 so3 |sort -u |while read -r soname; do
	echo "$soname" |join -t$'\t' -o '2.3 2.2' - def1 |sort -u >"$bb1/$soname"; touch -r "$1" "$bb1/$soname"
	echo "$soname" |join -t$'\t' -o '2.3 2.2' - def2 |sort -u >"$bb2/$soname"; touch -r "$2" "$bb2/$soname"
	if diff -U1 "$bb1/$soname" "$bb2/$soname"; then
		echo "$soname definitions unchanged"; echo
		continue
	fi
	echo
	comm -23 "$bb1/$soname" "$bb2/$soname" >minus
	comm -13 "$bb1/$soname" "$bb2/$soname" >plus
	join -t$'\t' -v1 minus plus >removed
	join -t$'\t' -v2 minus plus >added
	join -t$'\t' minus plus >changed
	[ -s removed ] && { echo "	$(wc -l <removed) symbols removed"; awk -F'\t' '{print$2,$1}' removed |sort -u; echo; }
	[ -s added ] && { echo "	$(wc -l <added) symbols added"; awk -F'\t' '{print$2,$1}' added |sort -u; echo; }
	[ -s changed ] && { echo "	$(wc -l <changed) symbols changed"; awk -F'\t' '{print$2,$3,$1}' changed |sort -u; echo; }
	if [ -s added ]; then 
		echo "# template for $soname version script"
		echo "${bb2%-*} {" |sed 's/-.*-/_/;s/-/_/;s/.*/\U&/'
		echo "    global:"
		cut -f1 added |sort -u |sed 's/^/\t/;s/$/;/'
		echo "};"
		echo
	fi
done

echo vim\:ft=diff

: <<'__EOF__'

=head1	NAME

rpmsodiff - compare library symbols in two rpm packages

=head1	SYNOPSIS

B<rpmsodiff>
[B<-h>]
I<libname-v1-alt1.i586.rpm>
I<libname-v2-alt2.i586.rpm>

=head1	COPYING

Copyright (c) 2006, 2007 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=cut

__EOF__


--- NEW FILE rpmsoname ---
#!/bin/sh -ef
export LC_ALL=C

rpmsoname()
{
	rpm -qp --qf '[%{PROVIDES}\n]' "$1" >prov || return
	grep -oE '^lib[^/()]+[.]so\>[^/()]*' prov >sonames || return 0

	# Files map to themselves; symbolic links cause a headache.
	# Sample file entry:	perl5.8.7	/usr/bin/perl5.8.7
	# Sample link entry:	libperl.so.5.8	/usr/lib/libperl.so.5.8	libperl.so.5.8.7
	rpm -qp --qf '[%{BASENAMES}\t%{FILENAMES}\t%{FILELINKTOS}\n]' "$1" >list
	awk -F'\t' '$NF==""{print$1"\t"$2}$NF{print>"/dev/fd/3"}' list >files 3>links

	# Make links absolute.  Sample diff:
	# 	-perl5	/usr/bin/perl5	perl5.8.7
	# 	+perl5	/usr/bin/perl5	/usr/bin/perl5.8.7
	perl -MFile::Spec::Functions=rel2abs -MFile::Basename=dirname -ni -aF'\t' -le \
		'$F[-1]=rel2abs$F[-1],dirname$F[-2];{$F[-1]=~s$/[^/]+/\.\./$/$&&redo}$,="\t",print at F' links

	# Now follow links (i.e. a->b,b->c => a->c,b->c). Sample diff:
	#	-libpri.so       /usr/lib/libpri.so      /usr/lib/libpri.so.1
	#	+libpri.so       /usr/lib/libpri.so      /usr/lib/libpri.so.1.0
	#	 libpri.so.1     /usr/lib/libpri.so.1    /usr/lib/libpri.so.1.0
	while :; do
		sort -t$'\t' -o links1 -k3,3 links
		sort -t$'\t' -o links2 -k2,2 links
		join -t$'\t' -13 -22 -o '1.1 1.2 2.3' links1 links2 >elinks
		[ -s elinks ] || break
		sort -t$'\t' -o links -u -k1,2 elinks links
	done

	# Join links against files.
	sort -t$'\t' -o files -k2 files
	sort -t$'\t' -o links -k3 links
	join -t$'\t' -12 -23 -o '2.1 2.3' files links >filelinks
	join -t$'\t' -12 -23 -o '2.1 2.3' -v2 files links >externlinks

	# Now ready to join sonames on files+filelinks.
	sort -o sonames -u sonames
	sort -o map -u files filelinks
	join -t$'\t' -j 1 -o '2.1 2.2' sonames map >mapped
	join -t$'\t' -j 1 -o 0 -v1 sonames map >unmapped

	# The results.
	awk -F'\t' '{print$2"\t"$1}' mapped |sort -u

	# Now warnings.
	join -t$'\t' -j 1 -o '1.1 1.2 2.2' mapped mapped |awk -F'\t' \
		'$2!=$3{print$1"\t"$2}' >multimapped
	if [ -s multimapped ]; then
		echo "warning: ${1##*/}: multimapped sonames:"
		sort -u multimapped
	fi >&2
	if [ -s unmapped ]; then
		echo "warning: ${1##*/}: unmapped sonames:"
		# TODO: extra analysis based on externlinks
		sort -u unmapped
	fi >&2
}

. rpmargs -c rpmsoname "$@"

: <<'__EOF__'

=head1	NAME

rpmsoname - list files that provide sonames in RPM package(s)

=head1	SYNOPSIS

B<rpmsoname> [B<-h>] [I<options>] [I<FILE>...] [I<DIR>...]

=head1	DESCRIPTION

B<rpmsoname> produces two-column output (typically one line per each soname).
Column one contains file path; column two contains corresponding soname.
When processing a directory, an additional column is prepended to the
output, which is typically RPM file basename.

Note that the name B<rpmsoname> is probably a misnomer: the script does not
deal with ELF C<DT_SONAME> entries.  What it does is try to map soname-like
entries from RPM C<PROVIDES> list to regular files within the very same RPM
package (using C<BASENAMES>, C<FILENAMES>, and C<FILELINKTOS> lists from RPM
header).

=head1	OPTIONS

Options and arguments manage a set of RPM packages to be processed;
they are those of rpmargs(1).

=head1	AUTHOR

Written by Alexey Tourbin <at at altlinux.org>.

=head1	COPYING

Copyright (c) 2006 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=head1	SEE ALSO

rpmargs(1)

=cut

__EOF__


--- NEW FILE tmpdir.sh.in ---
#!/bin/sh

: ${__real_TMPDIR:=}
if [ -z "$__real_TMPDIR" ]; then
	. @pkgdatadir@/trap.sh
	# NB: don't export __real_TMPDIR
	__real_TMPDIR="${TMPDIR:-/tmp}"
	TMPDIR="$(mktemp -dt "${0##*/}.XXXXXXXX")" || exit
	# TODO: ensure $TMPDIR can be used without quotes
	# pathchk -pP -- "$TMPDIR"
	# NB: traps are executed in reverse order (why?)
	add_trap rm -rf $TMPDIR
	add_trap chmod -Rf u+rwX $TMPDIR
fi

: <<'__EOF__'

=head1	NAME

tmpdir.sh - manage $TMPDIR

=head1	SYNOPSIS

  #!/bin/sh
  . @pkgdatadir@/tmpdir.sh

=head1	DESCRIPTION

When sourced, this script provides private C<$TMPDIR>,
which will be purged upon exit.

=head1	AUTHOR

Written by Alexey Tourbin <at at altlinux.org>.

=head1	COPYING

Copyright (c) 2006 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=head1	SEE ALSO

trap.sh(1)

=cut

__EOF__


--- NEW FILE trap.sh.in ---
#!/bin/sh

: ${__exit_traps:=}

add_trap()
{
	# TODO: quote args
	__exit_traps="$*
$__exit_traps"
}

remove_trap()
{
	# TODO: quote args
	__exit_traps="$(printf %s "$__exit_traps" |grep -Fvx "$*")"
}

trap_atexit()
{
	local t_rc=$?
	trap - EXIT
	eval "$__exit_traps"
	exit $t_rc
}

if [ -z "$__exit_traps" ]; then
	__exit_traps=:
	trap trap_atexit EXIT HUP INT QUIT PIPE TERM
fi

: <<'__EOF__'

=head1	NAME

trap.sh - manage exit traps

=head1	SYNOPSIS

  #!/bin/sh
  . @pkgdatadir@/trap.sh
  lockfile -r0 "$workdir"/lock || exit
  add_trap rm -f "$workdir"/lock

=head1	AUTHOR

Written by Alexey Tourbin <at at altlinux.org>.

=head1	COPYING

Copyright (c) 2006 Alexey Tourbin, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=cut

__EOF__




More information about the fedora-extras-commits mailing list