jw-pkg/scripts/pkg.sh
Jan Lindemann ca7a5a5265 pkg.sh: Evaluate pkg.run on Debian
pkg.run is not evaluated on Debian, fix that. For now it's hacked
into pkg.sh, which is bound to be replaced by Python. The limited
hassle is still worth the detour.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-02-28 13:15:05 +00:00

1322 lines
27 KiB
Bash

#!/bin/bash
log()
{
echo $@
}
goodbye()
{
:
rm -f $tmp_mkdef_sh scm_status.tmp
}
quit()
{
goodbye
exit $1
}
usage()
{
cat << EOT | sed 's/^ |//'
|usage: $myname cmd
EOT
[ "$1" ] && {
quit $1
}
}
fatal()
{
log "$@"
log "Giving up."
quit 1
}
os()
{
/bin/bash $JWB_SCRIPT_DIR/get-os.sh
}
os_cascade()
{
/usr/bin/python3 $JWB_SCRIPT_DIR/jw-pkg.py projects os-cascade
}
cfg_section()
{
ini_section "$inifile" $@
}
cfg_escape()
{
sed 's/\\/\\\\/g; s/\$/\\$/g; s/`/\\`/g'
}
scm_commit()
{
case $SCM in
cvs)
cvs commit "$@"
;;
git)
git commit -uno "$@"
;;
*)
fatal "tried to commit with unknown source code management tool $SCM"
;;
esac
}
platform()
{
echo `os`/$RPM_ARCH
}
abspath()
{
(cd $1; /bin/pwd)
}
read_map()
{
cmd_version -p `platform` $@ read | sed 's/-dev//'
}
write_map()
{
cmd_version -p `platform` $1 write $2
}
find_path()
{
local p
for p in $@; do
[ -e "$p" ] && {
echo $p
return 0
}
done
fatal "none of the paths \"$@\" exists"
}
scm_files()
{
(
cd $TOPDIR
/bin/bash $JWB_SCRIPT_DIR/scm.sh ls-files -f "$@"
)
}
calculate_hash()
{
(
cd $TOPDIR
scm_files -z | \
grep -vz "CHANGES\|VERSION\|HASH\|MD5SUMS\|RELEASES" | \
xargs -0 md5sum | md5sum | sed 's/ .*//'
)
}
check_scm()
{
if [ -d .git ]; then
log + checking git
git pull --no-edit || fatal "git pull failed, giving up"
git submodule update --init --recursive || fatal "git submodule update failed, giving up"
git status --porcelain | grep -v '^??' | grep -q . && {
git status
fatal "git has locally modified files, giving up"
}
else
log + checking cvs
cvs update -dP
cvs status > scm_status.tmp 2>&1
if [ $? != 0 ]; then
cat scm_status.tmp
fatal "\n======== cvs status failed, giving up."
fi
grep -qi "locally modified" scm_status.tmp && \
fatal "cvs copy has locally modified files, giving up"
grep -qi "needs" scm_status.tmp && \
fatal "+ cvs copy is out-of-date, giving up"
fi
}
check_cwd()
{
pwd | grep -q $HOME/local/src
}
create_empty_dir()
{
[ $# != 2 ] && \
fatal "Unable to create empty directory \"$@\"."
local dir="$1"
shift
local desc="$@"
mkdir -p "$dir"
[ -w "$dir" ] ||
fatal "No write-access to $desc \"$dir\""
[ `ls "$dir" | wc -l` -eq 0 ] ||
fatal "$desc \"$dir\" isn't empty"
}
increase_build_no()
{
local build_no=`echo $1 | sed 's/.*-\([0-9]\+\)\(-dev\)*/\1/'`
build_no=`expr $build_no + 1`
echo $1 | sed "s/-\([0-9]\+\)\(-dev\)*/-$build_no\2/"
}
check_next_version()
{
local v=`read_map $TOPDIR/VERSION | sed 's/-dev//'`
local n=`read_map -n $TOPDIR/RELEASES | sed 's/-dev//'`
if [ "$n" != "$v" ]; then
echo "+ $RPM_PROJECT version is already at $v, no need to increase for release" >&2
echo $v
return
fi
local h=`calculate_hash`
if [ ! -f $TOPDIR/HASH ]; then
echo "+ $RPM_PROJECT has no HASH file, needs release" >&2
echo $v
return
fi
if ! read_map $TOPDIR/HASH | grep -q $h; then
echo "+ $RPM_PROJECT has no matching HASH value, needs release" >&2
increase_build_no $v
return
fi
echo "+ $RPM_PROJECT has unchanged source" >&2
if [ "$reinstall_check_failed" = 1 ]; then
echo "version $v is uninstallable, needs release" >&2
increase_build_no $v
return
fi
if [ "$reinstall_check_succeeded" = 1 ]; then
echo $v
return
fi
if ! check_pkg_reinstall >&2; then
echo "version $v is uninstallable, needs release" >&2
increase_build_no $v
return
fi
echo "version $v doesn't match any release criteria, not releasing" >&2
echo $v
}
check_pkg_install()
{
[ "$1" = -c ] && {
shift
[ ! -f "$1" ] && return 0
}
local sudo
[ "$UID" = 0 ] || sudo=/usr/bin/sudo
echo "+ installing $1"
$sudo $RPM -U $1 || {
echo "failed to install $1"
return 1
}
}
check_pkg_reinstall()
{
local v=`read_map $TOPDIR/VERSION`
local s
for s in devel run; do
if $RPM -q $RPM_PROJECT-$s > /dev/null 2>&1 ; then
echo + removing $RPM_PROJECT-$s
sudo $RPM -e $RPM_PROJECT-$s --nodeps --allmatches || {
echo "failed to uninstall $RPM_PROJECT-$s, ignored"
}
fi
done
local suffix
case "$PKG_FORMAT" in
rpm)
suffix=-$v.$RPM_ARCH.rpm
;;
*)
suffix=_$v""_$RPM_ARCH.deb
;;
esac
check_pkg_install $TOPDIR/$DIST_PCKG_DIR/$RPM_PROJECT-run$suffix || return 1
check_pkg_install -c $TOPDIR/$DIST_PCKG_DIR/$RPM_PROJECT-devel$suffix || return 1;
}
check_release_is_current()
{
local reinstall_pkg=
local next=`check_next_version`
local v=`read_map $TOPDIR/VERSION`
set -- `getopt 'r' $*`
while [ "$1" != -- ] ; do
case "$1" in
-r)
reinstall_pkg=1
;;
esac
shift
done
shift
if ! read_map -n $TOPDIR/RELEASES | grep -Fq $next; then
echo "next version $next is not in RELEASES, needs release" >&2
return 1
fi
if [ "$reinstall_pkg" ]; then
if ! check_pkg_reinstall; then
echo "version $v is uninstallable, needs release" >&2
reinstall_check_failed=1
return 1
fi
reinstall_check_succeeded=1
fi
return 0
}
check_update_version()
{
local comment="Start version"
set -- `getopt 'c:' "$@"`
while [ "$1" != -- ] ; do
case "$1" in
-c)
comment="$2"
shift
esac
shift
done
shift
(
cd $TOPDIR
local v=`read_map VERSION`
local next=`check_next_version`
[ "$next" ] || fatal "Failed to get next version."
if [ "$next" != "$v" ]; then
echo "$next-dev" > VERSION
scm_commit -m "$comment: $next" VERSION
return 0
fi
return 1
)
}
cmd_version()
{
cmd_version_usage()
{
cat <<- EOT | sed 's/ |//'
|usage: $myname version filename cmd [args]
EOT
[ "$1" ] && exit $1
}
cmd_version_strip_dev_dummy()
{
cat
}
cmd_version_strip_dev_real()
{
sed 's/-dev//'
}
# -- here we go
local strip_dev=cmd_version_strip_dev_dummy
local platform_patt="\(^debian-[0-9.]\+\|^suse-\([0-9.]\+\|tumbleweed\)\)/\(i.86\|x86_64\|amd64\): *"
local no_compat=
local platform=`platform`
[ $# -lt 2 ] && cmd_version_usage 1
set -- `getopt 'hsnp:' "$@"`
while [ "$1" != -- ] ; do
case "$1" in
-n)
no_compat=true;;
-s)
strip_dev=cmd_version_strip_dev_real;;
-p)
platform="$2"; shift;;
-h)
cmd_version_usage 0;;
*)
cmd_version_usage 1;;
esac
shift
done
shift
local file="$1"
shift
local cmd=$1
shift
case $cmd in
read)
local p=`echo $platform | sed 's%/%\\\/%g'`
local v=`sed "/$p:/ !d; s/$p: *//" $file`
[ "$v" ] && {
echo "$v" | $strip_dev
return
}
[ "$no_compat" = true ] && {
return
}
grep -q "$platform_patt" $file || {
cat $file | $strip_dev
return
}
local pp=`echo $platform_patt | sed 's%/%\\\/%g'`
sed "/$pp/ !d; s/$pp//; 2,$ d" $file | $strip_dev
;;
write)
local val=$1
local p=$platform
[ -f $file ] || {
echo "$p: $val" > $file
return
}
grep -q "$platform_patt" $file || {
echo "$p: $val" > $file
return
}
grep -q "^$p:" $file || {
echo "$p: $val" >> $file
return
}
p=`echo $p | sed 's%/%\\\/%g'`
val=`echo $val | sed 's%/%\\\/%g'`
sed "s/$p:.*/$p: $val/" $file > $file.tmp
mv $file.tmp $file
;;
*)
echo unknown command $cmd >&2
cmd_version_usage 1;;
esac
}
build_pkg()
{
local scm_files_opts=""
eval set -- `getopt -o a -l include-vcs-files -- "$@"`
while [ "$1" != -- ]; do
case $1 in
-a|--include-vcs-files)
scm_files_opts="$scm_files_opts -a"
;;
*)
echo -e "Unexpected argument >$1<\n" >&2
exit 1
;;
esac
shift
done
shift
set -e
local version=`read_map $TOPDIR/VERSION | sed 's/-dev//'`
local src_base=$RPM_PROJECT-$version
local src_tree=$DIST_SRC_DIR/$src_base
local tar_archive=$src_base.tar.bz2
local tar_archive_orig=$src_base.orig.tar.bz2
local distribution=`os`
expand_version_macros() {
echo $@ | sed "s/__NEXT_VERSION__/$version/g; s/VERSION-REVISION/$version/g; s/VERSION/$version/g"
}
local rpm_requires_run=`expand_version_macros $RPM_REQUIRES_RUN`
local rpm_requires_devel=`expand_version_macros $RPM_REQUIRES_DEVEL`
local rpm_conflicts_run=`expand_version_macros $RPM_CONFLICTS_RUN`
local rpm_conflicts_devel=`expand_version_macros $RPM_CONFLICTS_DEVEL`
local rpm_provides_run=`expand_version_macros $RPM_PROVIDES_RUN`
local rpm_provides_devel=`expand_version_macros $RPM_PROVIDES_DEVEL`
# --- create source directory tree
create_empty_dir $src_tree "Source files compilation directory"
# --- copy source files over
scm_files $scm_files_opts |
grep -v VERSION |
cpio -o -H newc |
( cd $src_tree; cpio -m --make-directories -i)
echo $version > $src_tree/VERSION
local pkgfmt
for pkgfmt in $PKG_FORMAT; do
local deffmt
case $pkgfmt in
rpm)
# historical mess:
# pkg.sh -> mkspec-wrapper.sh -> create-mkspec.sh -> mkspec.sh -> spec -> rpmbuild spec > /var/tmp/xy.sh -> pkg.sh milk-install-log
deffmt=spec;;
debian|deb)
deffmt=debian;;
*)
;;
esac
# --- generate spec file
local mkdef_sh=$TOPDIR/make/mk$deffmt.sh
local mkdef_wrapper_sh=$JWB_SCRIPT_DIR/mkspec-wrapper.sh
[ ! -r $mkdef_wrapper_sh ] && \
fatal "Failed to read package definition deffmt wrapper script \"$mkdef_wrapper_sh\"."
scm_files | grep -q make/mk$deffmt.sh || {
local create_mkdef_sh=$JWB_SCRIPT_DIR/create-mk$deffmt.sh
[ ! -r "$PROJECT_DESCR_FILE" ] && \
fatal "Failed to read project description file \"$PROJECT_DESCR_FILE\"."
[ ! -r "$create_mkdef_sh" ] && \
fatal "Failed to read package build definition creation script \"$create_mkdef_sh\"."
PATH=$JWB_SCRIPT_DIR:$PATH /bin/bash $create_mkdef_sh $PROJECT_DESCR_FILE > $mkdef_sh.tmp
mv $mkdef_sh.tmp $mkdef_sh
tmp_mkdef_sh="$tmp_mkdef_sh $mkdef_sh"
}
mkdef_sh=`readlink -f $mkdef_sh`
mkdef_wrapper_sh=`readlink -f $mkdef_wrapper_sh`
(
cd $src_tree
PATH=$JWB_SCRIPT_DIR:$PATH /bin/bash $mkdef_wrapper_sh $mkdef_sh \
-V $version \
-S $tar_archive \
-N $RPM_PROJECT \
-R "$rpm_requires_run" \
-X "$rpm_conflicts_run" \
-D "$rpm_requires_devel" \
-Y "$rpm_conflicts_devel" \
--provides-run "$rpm_provides_run" \
--provides-devel "$rpm_provides_devel" \
-P $PROJECT \
-d $distribution \
> $RPM_PROJECT.$deffmt
)
done
# --- tar up source directory tree
create_empty_dir $DIST_PCKG_DIR "Package directory"
tar --anchored -czvf $DIST_PCKG_DIR/$tar_archive -C $DIST_SRC_DIR `basename $src_tree`
case "$PKG_FORMAT" in
rpm)
# --- build RPMs and copy them to source directory
rpmbuild -ta $DIST_PCKG_DIR/$tar_archive
cp $SRPMS_DIR/$src_base.src.rpm $DIST_PCKG_DIR/
cp $RPMS_DIR/$RPM_PROJECT-*-$version.$RPM_ARCH.rpm $DIST_PCKG_DIR/
;;
*)
#exit
#cp $DIST_PCKG_DIR/$tar_archive $src_tree/../$tar_archive_orig
(
local mod_script_dir=`readlink -f $JWB_SCRIPT_DIR`
cd $src_tree
#export ENV_PREFIX=`readlink -f $TOPDIR`/$DIST_INST_DIR
#export INSTALL_LOG=blah
#strace -f -s 128 -o /tmp/strace.out debuild --no-tgz-check --prepend-path=$mod_script_dir -us -uc
debuild --no-tgz-check --prepend-path=$mod_script_dir -us -uc
)
cp $DIST_SRC_DIR/*.deb $DIST_PCKG_DIR/
;;
esac
}
upload_file()
{
local quiet=false
if [ "$1" = -q ]; then
quiet=true
shift
fi
local f="$1"
local t="$2"
[ -f $DIST_PCKG_DIR/$f ] || {
if [ "$quiet" = true ]; then return 0; fi
"+ $DIST_PCKG_DIR/$f doesn't exist, can't upload"
return 1
}
local os_name=`os | sed 's/-.*//'`
local os_version=`os | sed 's/[^-]\+-//'`
local target_base=rsync_ssh://root@pkg.janware.com:/srv/dav/pub/packages/linux/$os_name/$os_version
[ "$upload_urlbase" ] && target_base="$upload_urlbase"
local upload_attrib=644:755:`id -un`.207
[ "$upload_file_attrib" ] && upload_attrib="$upload_file_attrib"
local target
case "$t" in
tgz)
target=$target_base/$t/$f:$upload_attrib
;;
src)
case $os_name in
centos)
target=$target_base/Source/SPackages/$f:$upload_attrib
#/srv/ftp/pub/packages/jw-foss/centos/7/Source/SPackages/tecla-1.6.3-7.1.src.rpm
;;
*)
target=$target_base/rpm/$t/$f:$upload_attrib
#/srv/ftp/pub/packages/jw-foss/suse/tumbleweed/rpm/src/jw-pkg-1.0.0-74.src.rpm
;;
esac
;;
*)
case $os_name in
centos)
target=$target_base/$t/Packages/$f:$upload_attrib
#/srv/ftp/pub/packages/jw-foss/centos/7/x86_64/Packages/tecla-devel-1.6.3-7.1.x86_64.rpm
;;
*)
target=$target_base/rpm/$t/$f:$upload_attrib
#/srv/ftp/pub/packages/jw-foss/suse/tumbleweed/rpm/x86_64/jw-pkg-run-1.0.0-74.x86_64.rpm
;;
esac
esac
echo "+ uploading $target"
RSYNC_RSH=$SSH /bin/bash $JWB_SCRIPT_DIR/upload.sh $DIST_PCKG_DIR/$f $target
}
upload_pkg()
{
local server
set -e
local p
local v=`read_map $TOPDIR/VERSION | sed 's/-dev//'`
local h=`calculate_hash`
case $PKG_FORMAT in
rpm)
server=pkg.janware.com
upload_file $RPM_PROJECT-$v.tar.bz2 tgz
upload_file $RPM_PROJECT-$v.src.rpm src
upload_file $RPM_PROJECT-run-$v.$RPM_ARCH.rpm $RPM_ARCH
upload_file -q $RPM_PROJECT-devel-$v.$RPM_ARCH.rpm $RPM_ARCH
;;
debian|deb)
server=apt.janware.com
local conf=`mktemp "/tmp/$myname"_XXXXXX`
cat <<-EOT > $conf
[DEFAULT]
default_host = janware-debian
[janware-debian]
fqdn = $server
# login =
incoming = /srv/dav/pub/packages/jw-foss/debian/mini-dinstall/incoming/
method = rsync
hash = sha
allow_unsigned_uploads = yes
distributions = debian-8
allowed_distributions = `os`
delayed =
run_lintian = no
run_dinstall = no
check_version = yes
passive_ftp = yes
#progress_indicator
scp_compress = yes
ssh_config_options = ForwardAgent=yes,Compression=yes,ServerAliveInterval=30,ConnectTimeout=120
#post_upload_command =
#pre_upload_command =
#default_host_main =
EOT
dput -c $conf janware-debian dist/src/"$RPM_PROJECT"_"$v"_"$RPM_ARCH".changes
rm -f $conf
;;
*)
fatal "Tried to upload with unknown package format \"$PKG_FORMAT\""
;;
esac
write_map $TOPDIR/RELEASES $v
$SCM add $TOPDIR/RELEASES || true
write_map $TOPDIR/HASH $h
$SCM add $TOPDIR/HASH || true
echo "+ scheduling rebuild"
$SSH -l root $server /opt/packager-server/bin/packager-server schedule-rebuild
scm_commit -m "Release $v@`platform`" $TOPDIR/RELEASES $TOPDIR/HASH
if [ "$SCM" = git ]; then
git push || true
fi
}
install_exe_wrapper()
{
local from="`readlink -fm $1`"
local to="$2"
local ext=${from##*.}
local tmp=$to.tmp
case $ext in
py)
cat << EOT | sed 's/^ *|//' > "$tmp"
|#!/usr/bin/python3
|
|import sys
|import subprocess
|args=sys.argv
|args[0] = "$from"
|if subprocess.call([ '/usr/bin/python3' ] + args) != 0:
| print("subprocess failed")
| exit(1)
EOT
;;
pl)
echo -e "#!/bin/bash\n\nexec /usr/bin/perl \"$from\" \"\$@\"" > "$tmp"
#echo -e "#!/bin/bash\n\nexec /usr/bin/perl \"$from\"" > "$tmp"
;;
sh)
echo -e "#!/bin/bash\n\nexec /bin/bash \"$from\" \"\$@\"" > "$tmp"
;;
*)
if file "$from" | grep -qi executable && [[ "$from" =~ "\.so$\|\.so\.[0-9.]*" ]]; then
echo -e "#!/bin/bash\n\nexec \"$from\" \"\$@\"" > "$tmp"
else
ln -sf $from $to
return
fi
;;
esac
chmod 755 "$tmp"
mv "$tmp" $to
}
cmd_build()
{
build_pkg "$@"
}
cmd_upload()
{
upload_pkg
}
check_create_parent()
{
[ "$1" != "true" ] && return 0
local dir=`dirname -z "$2" | xargs -0 readlink -fm`
local path=`readlink -fm "$2"`
if [ "$dir" -a "$dir" != "$path" ]; then
mkdir -p "$dir" || {
echo "failed to create parent dir of \"$1\""
exit 1
}
fi
return 0
}
cmd_log_install()
{
local args="$*"
local c_format=rpm
local c_logfile=install.log
local c_mode_dir=false
local c_create_leading_dirs=false
local c_group=`id -gn`
local c_owner=`whoami`
local c_suffix=
local c_prefix=
local c_opmode=opmode_install
local c_absolute=0
local c_wrap=0
local c_no_log_dirs=0
local install_opts
set -- `getopt 'DLWi:a:f:l:bg:cdm:o:psS:vAN' $*`
cfgfile_macro()
{
case "$c_format" in
rpm)
if echo "$*" | grep -qe '/etc/\|\.conf$\|\.leases$'; then
echo "%config(noreplace) "
fi
;;
deb|debian)
if echo "$*" | grep -qe '/etc/\|\.conf$\|\.leases$'; then
echo "%config "
fi
;;
*)
;;
esac
}
while [ "$1" != -- ]; do
case $1 in
-f)
c_format=$2
shift;;
-l)
c_logfile=$2
shift;;
-a)
c_use_attr=true
;;
-i)
c_ignore_prefix=$2
shift
;;
-b)
install_opts="$install_opts $1"
;;
-c)
install_opts="$install_opts $1"
;;
-d)
c_mode_dir=true;;
-D)
c_create_leading_dirs=true;;
-g)
c_group=$2
shift;;
-m)
c_mode=$2
shift;;
-o)
c_owner=$2
shift;;
-p)
install_opts="$install_opts $1"
;;
-s)
install_opts="$install_opts $1"
;;
-S)
c_suffix=$2
shift;;
-v)
install_opts="$install_opts $1"
;;
-L)
c_opmode=opmode_link;;
-W)
c_opmode=opmode_link
c_wrap=1;;
-A)
c_absolute=1;;
-N)
c_no_log_dirs=1;;
*)
echo unknown option \"$1\". Exiting. >&2
exit 1;;
esac
shift
done
shift
local args="`echo " $args" | sed -e 's/ -l *[^ ]*//g; s/ -f *[^ ]*//g; s/ -a / /g; s/ -N / /g'`"
if [ -z "$c_use_attr" ]; then
#args="`echo " $args" | sed -e 's/ -g *[^ ]*//g; s/ -m *[^ ]*//g; s/ -o *[^ ]*//g;'`"
args="`echo " $args" | sed -e 's/ -g *[^ ]*//g; s/ -o *[^ ]*//g;'`"
fi
local c_target="`echo $* | awk '{$1=""; print $0}' | sed 's/^ *//'`"
local c_source="`echo $* | awk '{print $1}'`"
case $c_opmode in
opmode_install)
if [ -L "$c_source" ]; then
check_create_parent $c_create_leading_dirs $c_target
cp -d $c_source $c_target || exit $?
else
[ "$c_create_leading_dirs" ] && local install_opts="$install_opts -D"
install $install_opts $args || exit $?
fi
;;
opmode_link)
if [ "$c_mode_dir" = true ]; then
echo "ignoring directory $c_source during link creation"
exit 0
fi
if [ "$c_absolute" != 0 ]; then
c_logfile=""
c_source=`readlink -f $c_source`
else
c_source=`basename $c_source`
fi
check_create_parent $c_create_leading_dirs $c_target
cd `dirname $c_target`
if [ "$c_wrap" = 1 ]; then
install_exe_wrapper $c_source $c_target
else
ln -sf $c_source `basename $c_target`
fi
;;
*)
echo "Mode \"$c_opmode\" not implemented. Exiting." >&2
exit 1
;;
esac
[ "$c_logfile" ] || {
exit 0
}
local file mode installd_file cfgfile dir attr
if [ "$c_mode_dir" = true ]; then
for file in $*; do
[ "$c_no_log_dirs" = 0 ] || continue
mode=$c_mode
[ -L "$file" ] && mode="LINK"
attr=" %attr($mode,$c_owner,$c_group)"
echo "%dir$attr $file" >> $c_logfile
done
else
if [ -f "$c_target" -o -L "$c_target" ]; then
installed_file="$c_target"
cfgfile=""
if [ "$c_mode" ]; then
mode=$c_mode
cfgfile=`cfgfile_macro "$installed_file"`
else
if [ -d "$c_source" ]; then
dir="%dir "
mode=0755
else
cfgfile=`cfgfile_macro "$installed_file"`
dir=""
mode=0644
fi
fi
[ -L "$c_target" ] && mode="LINK"
attr="%attr($mode,$c_owner,$c_group)"
if [ -z "$dir" -o "$c_no_log_dirs" != 0 ]; then
echo "$dir$attr $cfgfile$c_target" | sed "s/^$c_ignore_prefix//" >> $c_logfile
fi
elif [ -d "$c_target" ]; then
for file in $c_source; do
installed_file="$c_target/`basename $file`"
cfgfile=""
if [ "$c_mode" ]; then
mode=$c_mode
cfgfile=`cfgfile_macro "$installed_file"`
else
if [ -d "$file" ]; then
[ "$c_no_log_dirs" = 0 ] || continue
dir="%dir "
mode=0755
else
cfgfile=`cfgfile_macro "$installed_file"`
dir=""
mode=0644
fi
fi
[ -L "$file" ] && mode="LINK"
attr="%attr($mode,$c_owner,$c_group)"
echo "$dir$attr $cfgfile$installed_file" |
sed "s/^$c_ignore_prefix//" >> $c_logfile
done
fi
fi
}
cmd_milk_install_log()
{
milk_install_log_usage()
{
echo "usage: $myname milk-install-log [-h] [-n pkg-name] [-t rpm|deb] [-p remove-prefix] [-s subpackages] install-log output-dir"
[ "$1" ] && exit $1
}
milk_install_log_spec_attr()
{
local attr=$1
shift
#echo "extracting attribute $attr from \"$@\"" >&2
echo "$*" | sed "s/.*attr(\(LINK\|[0-9]\+\),\([^,]\+\),\([^,)]\+\)).*/\\$attr/"
}
cat_log()
{
cat $in | sed '
/\/usr\/bin$/ d
/\/usr\/sbin$/ d
/\/usr\/lib$/ d
/\/usr\/lib64$/ d
/\/usr\/lib\/pkgconfig$/ d
/\/usr\/lib64\/pkgconfig$/ d
' | $user_filter
}
compress()
{
sed ':a;N;$!ba;s/\n//g'
}
make_unique()
{
sed 's/ \+/\n/g' | sort -u | grep .
}
make_alt()
{
make_unique | sed 's/$/$\\|/' | compress
}
local type name prefix in out subpackages
local subpackages="run devel"
local user_filter=cat
eval set -- `getopt -- ht:p:n:s:F: "$@"`
while [ "$1" != -- ]; do
case $1 in
-h)
usage 0;;
-t)
type="$2"; shift;;
-n)
name="$2"; shift;;
-p)
prefix="$2"; shift;;
-s)
subpackages="$2"; shift;;
-F)
user_filter="$2"; shift;;
*)
echo -e "Unexpected argument >$1<\n" >&2
milk_install_log_usage 1;;
esac
shift
done
shift
[ $# != 2 ] && {
echo -e "Too many arguments >$*<\n" >&2
milk_install_log_usage 1
}
local in=$1
local out=$2
local re_hpp_file="[^/]\+\.\(h\|hpp\)$"
local include_dirs=`cat_log | grep "/include/\(.*/\)*$re_hpp_file" | sed "s%.*/include/%/include/%; s%/$re_hpp_file%%"`
include_dirs=`echo /include /include/$name $include_dirs | make_unique`
local include_h_re=`echo $include_dirs | sed 's/ \\+/\\n/g' | sed 's%$%/[^/]\\\\+\\\\.h\\\\(pp\\\\)*%' | make_alt`
local include_dirs_re=`echo $include_dirs | make_alt`
filter_devel="$filter_devel$include_h_re"
filter_devel="$filter_devel$include_dirs_re"
filter_devel="$filter_devel""devel\|make\|/lib[^/]\+\.a$\|/lib[^/]\+\.so$\|/[^/]\+\.exp$\|/[^/]\+\.def$\|/[^/]\+\.lib$\|/[^/]\+\.pc$\|"
filter_devel="$filter_devel/usr/lib[^/]*/pkgconfig"
# TODO: simplify this
case $type in
rpm)
cleanup_line_rpm() {
sed "s% $prefix% %; s/%attr(LINK,[^)]\+)//; s/^\s*//"
}
cat_log | cleanup_line_rpm | grep -ve $filter_devel > $in.$name-run
cat_log | cleanup_line_rpm | grep -e $filter_devel > $in.$name-devel
# TODO: this is unimplemented for debian packages
echo $subpackages | grep -q devel || cat $in.$name-devel >> $in.$name-run
;;
deb)
cleanup_line_deb() {
sed "s|%config\s*||g; s% $prefix% %; s%//*%/%g; s/.*) *//"
}
cat_log | grep -v "%dir" | cleanup_line_deb | grep -ve $filter_devel | sed 's/\(.*\)\/\([^/]\+\) *$/inst-root\1\/\2 \1/' > $out/$name-run.install
cat_log | grep -v "%dir" | cleanup_line_deb | grep -e $filter_devel | sed 's/\(.*\)\/\([^/]\+\) *$/inst-root\1\/\2 \1/' > $out/$name-devel.install
cat_log | grep "%dir" | cleanup_line_deb | grep -ve $filter_devel | sed 's/\(.*\)\/\([^/]\+\) *$/\1\/\2/; s%^/%%' | sort -u > $out/$name-run.dirs
cat_log | grep "%dir" | cleanup_line_deb | grep -e $filter_devel | sed 's/\(.*\)\/\([^/]\+\) *$/\1\/\2/; s%^/%%' | sort -u > $out/$name-devel.dirs
cat_log | grep "%config" | cleanup_line_deb | grep -ve $filter_devel > $out/conffiles.$name-run
cat_log | grep "%config" | cleanup_line_deb | grep -e $filter_devel > $out/conffiles.$name-devel
# Create maintainer scripts
for p in run devel; do
local stage
for stage in pre preun post postun; do
case $stage in
pre) deb_stage=preinst;;
post) deb_stage=postinst;;
preun) deb_stage=prerm;;
postun) deb_stage=postrm;;
esac
local script=$out/$name-$p.$deb_stage
cat <<- EOT > $script
#!/bin/sh
EOT
chmod 755 $script
case $stage in
post)
cat $out/$name-$p.dirs $out/$name-$p.install | grep . | while read file dir; do
#echo read file \"$file\" >&2
file=`echo /$file | sed 's/inst-root\///; s%^//*%/%'`
#echo file is now \"$file\" >&2
#echo grep \"$prefix/*$file$\" $in >&2
line=`grep $file$ $in`
perm=`milk_install_log_spec_attr 1 "$line"`
owner=`milk_install_log_spec_attr 2 "$line"`
group=`milk_install_log_spec_attr 3 "$line"`
echo "chown $owner:$group $file" >> $script
[ "$perm" = "LINK" ] || echo "chmod $perm $file" >> $script
done
;;
*)
;;
esac
echo "== processing stage $stage: cfg_section pkg.$p.$stage" >&2
local os content=""
for os in '' `os_cascade`; do
local sec=pkg.$p.$stage head=""
if [ "$os" ]; then
sec="$sec.$os"
head="\n# --- $os\n"
fi
cfg_section $sec | grep -q . || continue
content="$content$head`cfg_section $sec`"
done
if [ "$content" ]; then
echo -e "$content" >&2
echo -e "\n$content" | cfg_escape >> $script
fi
cat $script | grep -v '^#!/bin\|^$' | grep -q . || rm $script
done
done
;;
*)
milk_install_log_usage 1
;;
esac
}
# ---- here we go
umask 0022
trap goodbye SIGINT SIGKILL
# -- default values
TOPDIR=.
CHECK_CVS_SYNC_BEFORE_RPM_RELEASE=false
myname="${0##*/}"
cmdline="$0 $@"
tmp_mkdef_sh=""
PROJECT_DESCR_FILE=$TOPDIR/make/project.conf
DIST_SRC_DIR=dist/src
DIST_INST_DIR=dist/src
DIST_PCKG_DIR=dist/pckg
RPM_PROJECT="$PROJECT"
RPM_REQUIRES_RUN=""
RPM_REQUIRES_DEVEL=""
RPM_ARCH=$HOSTTYPE
PKG_FORMAT=rpm
SSH=ssh
SCM=cvs
[ "$RSYNC_RSH" ] && SSH=$RSYNC_RSH
[ "$CVS_RSH" ] && SSH=$CVS_RSH
[ -d .git ] && SCM=git
while [ ${1:0:1} = - ]; do
case "$1" in
-h)
usage 0;;
-t)
eval DIST_SRC_DIR=\"$2\"
shift
;;
-p)
eval DIST_PCKG_DIR=\"$2\"
shift
;;
-m)
eval JWB_SCRIPT_DIR=\"$2\"
shift
;;
-N)
eval RPM_PROJECT=\"$2\"
shift
;;
-R)
eval RPM_REQUIRES_RUN=\"$2\"
shift
;;
-X)
eval RPM_CONFLICTS_RUN=\"$2\"
shift
;;
-D)
eval RPM_REQUIRES_DEVEL=\"$2\"
shift
;;
-Y)
eval RPM_CONFLICTS_DEVEL=\"$2\"
shift
;;
--provides-run)
eval RPM_PROVIDES_RUN=\"$2\"
shift
;;
--provides-devel)
eval RPM_PROVIDES_DEVEL=\"$2\"
shift
;;
-P)
eval PROJECT=\"$2\"
shift
;;
-a)
eval RPM_ARCH=\"$2\"
shift
;;
-F)
eval PKG_FORMAT=\"$2\"
shift
;;
-B)
eval upload_urlbase=\"$2\"
shift
;;
-A)
eval upload_file_attrib=\"$2\"
shift
;;
*)
echo "unrecognized option $1, giving up" >&2
usage 1
;;
esac
shift
done
[ "$JWB_SCRIPT_DIR" ] || JWB_SCRIPT_DIR="$(dirname $0)"
[ "$PROJECT" ] || PROJECT=`abspath $TOPDIR | xargs basename`
inifile=$PROJECT_DESCR_FILE
. $JWB_SCRIPT_DIR/ini-tools.sh
cmd=$1
shift
export JWB_SCRIPT_DIR=`readlink -f $JWB_SCRIPT_DIR`
export PKG_SH=`readlink -f $0`
if [ `whoami` = root ]; then
RPMS_BUILD_DIR=/usr/src/packages
else
RPMS_BUILD_DIR=$HOME/rpmbuild
fi
SRPMS_DIR=$RPMS_BUILD_DIR/SRPMS
RPMS_DIR=$RPMS_BUILD_DIR/RPMS/$RPM_ARCH
# shift
[ ! "$cmd" ] && {
echo "missing command, giving up" >&2
usage 1
}
case $PKG_FORMAT in
rpm)
RPM=/bin/rpm
;;
deb|debian)
RPM="/bin/bash $JWB_SCRIPT_DIR/dpm.sh"
;;
*)
fatal "Unknown package format \"$PKG_FORMAT\""
;;
esac
case $cmd in
check-release)
cmd_check_release
;;
need-release)
if check_release_is_current; then
echo no >&2
exit 1
else
echo yes >&1
exit 0
fi
;;
update-version)
check_update_version "@" || exit 0
;;
version)
cmd_version "$@"
;;
build)
check_cwd
rm -rf ./$DIST_SRC_DIR ./$DIST_PCKG_DIR
cmd_build "$@"
;;
release-reinstall)
check_update_version -c "Start version"
cmd_build "$@"
cmd_upload
;;
release)
cd $TOPDIR
check_scm
check_release_is_current -r || {
set -e
check_cwd
rm -rf ./$DIST_SRC_DIR ./$DIST_PCKG_DIR
check_update_version || true
cmd_build "$@"
check_pkg_reinstall
cmd_upload
}
;;
upload)
cmd_upload
;;
reinstall)
check_pkg_reinstall
;;
release)
;;
hash)
calculate_hash
;;
log-install)
cmd_log_install "$@"
;;
milk-install-log)
cmd_milk_install_log "$@"
;;
*)
usage 1
;;
esac
goodbye