mirror of
ssh://git.janware.com/janware/proj/jw-pkg
synced 2026-04-25 09:35:54 +02:00
jw-pkg supports more than RPM-based package managers, but for historic reasons, lots of its Makefile variables still have "RPM" in their names. This is misleading. Replace "RPM" in variable names by the more generic "PKG" where appropriate. Signed-off-by: Jan Lindemann <jan@janware.com>
1317 lines
27 KiB
Bash
1317 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
|
|
}
|
|
|
|
distro_info()
|
|
{
|
|
/usr/bin/python3 $JWB_SCRIPT_DIR/jw-pkg.py distro info --format "$1"
|
|
}
|
|
|
|
get_os()
|
|
{
|
|
[ "$__get_os" ] || __get_os=`distro_info '%{id}-%{codename}'`
|
|
echo $__get_os
|
|
}
|
|
|
|
cfg_section()
|
|
{
|
|
ini_section "$inifile" $@
|
|
}
|
|
|
|
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 `get_os`/$PKG_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 "+ $PKG_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 "+ $PKG_PROJECT has no HASH file, needs release" >&2
|
|
echo $v
|
|
return
|
|
fi
|
|
if ! read_map $TOPDIR/HASH | grep -q $h; then
|
|
echo "+ $PKG_PROJECT has no matching HASH value, needs release" >&2
|
|
increase_build_no $v
|
|
return
|
|
fi
|
|
echo "+ $PKG_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 $PKG_PROJECT-$s > /dev/null 2>&1 ; then
|
|
echo + removing $PKG_PROJECT-$s
|
|
sudo $RPM -e $PKG_PROJECT-$s --nodeps --allmatches || {
|
|
echo "failed to uninstall $PKG_PROJECT-$s, ignored"
|
|
}
|
|
fi
|
|
done
|
|
|
|
local suffix
|
|
case "$PKG_FORMAT" in
|
|
rpm)
|
|
suffix=-$v.$PKG_ARCH.rpm
|
|
;;
|
|
*)
|
|
suffix=_$v""_$PKG_ARCH.deb
|
|
;;
|
|
esac
|
|
|
|
check_pkg_install $TOPDIR/$DIST_PCKG_DIR/$PKG_PROJECT-run$suffix || return 1
|
|
check_pkg_install -c $TOPDIR/$DIST_PCKG_DIR/$PKG_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=$PKG_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=`get_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 $PKG_REQUIRES_RUN`
|
|
local rpm_requires_devel=`expand_version_macros $PKG_REQUIRES_DEVEL`
|
|
local rpm_conflicts_run=`expand_version_macros $PKG_CONFLICTS_RUN`
|
|
local rpm_conflicts_devel=`expand_version_macros $PKG_CONFLICTS_DEVEL`
|
|
local rpm_provides_run=`expand_version_macros $PKG_PROVIDES_RUN`
|
|
local rpm_provides_devel=`expand_version_macros $PKG_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 $PKG_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 \
|
|
> $PKG_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
|
|
local rpmbuild_root=$HOME/rpmbuild
|
|
[ `id -u` = 0 ] && rpmbuild_root=/usr/src/packages
|
|
local rpmbuild_srpms=$rpmbuild_root/SRPMS
|
|
local rpmbuild_rpms=$rpmbuild_root/RPMS/$PKG_ARCH
|
|
rpmbuild -ta $DIST_PCKG_DIR/$tar_archive
|
|
cp $rpmbuild_srpms/$src_base.src.rpm $DIST_PCKG_DIR/
|
|
cp $rpmbuild_rpms/$PKG_PROJECT-*-$version.$PKG_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=`get_os | sed 's/-.*//'`
|
|
local os_version=`get_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 $PKG_PROJECT-$v.tar.bz2 tgz
|
|
upload_file $PKG_PROJECT-$v.src.rpm src
|
|
upload_file $PKG_PROJECT-run-$v.$PKG_ARCH.rpm $PKG_ARCH
|
|
upload_file -q $PKG_PROJECT-devel-$v.$PKG_ARCH.rpm $PKG_ARCH
|
|
;;
|
|
debian|deb)
|
|
local -r server=apt.janware.com
|
|
local -r distro_subdir=$(distro_info '%{id}/%{codename}')
|
|
local conf=`mktemp "/tmp/$myname"_XXXXXX`
|
|
cat <<-EOT > $conf
|
|
[DEFAULT]
|
|
default_host = janware-debian
|
|
[janware-debian]
|
|
fqdn = $server
|
|
# login =
|
|
incoming = /var/lib/packager-server/packages/jw-foss/$distro_subdir/incoming/
|
|
method = rsync
|
|
hash = sha
|
|
allow_unsigned_uploads = yes
|
|
distributions = debian-8
|
|
allowed_distributions = `get_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/"$PKG_PROJECT"_"$v"_"$PKG_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 '' `distro_info '%{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" >> $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=.
|
|
PKG_CHECK_VCS_SYNC_BEFORE_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
|
|
PKG_PROJECT="$PROJECT"
|
|
PKG_REQUIRES_RUN=""
|
|
PKG_REQUIRES_DEVEL=""
|
|
PKG_ARCH=$HOSTTYPE
|
|
PKG_FORMAT=rpm
|
|
SSH=ssh
|
|
SCM=cvs
|
|
__get_os=""
|
|
|
|
[ "$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 PKG_PROJECT=\"$2\"
|
|
shift
|
|
;;
|
|
-R)
|
|
eval PKG_REQUIRES_RUN=\"$2\"
|
|
shift
|
|
;;
|
|
-X)
|
|
eval PKG_CONFLICTS_RUN=\"$2\"
|
|
shift
|
|
;;
|
|
-D)
|
|
eval PKG_REQUIRES_DEVEL=\"$2\"
|
|
shift
|
|
;;
|
|
-Y)
|
|
eval PKG_CONFLICTS_DEVEL=\"$2\"
|
|
shift
|
|
;;
|
|
--provides-run)
|
|
eval PKG_PROVIDES_RUN=\"$2\"
|
|
shift
|
|
;;
|
|
--provides-devel)
|
|
eval PKG_PROVIDES_DEVEL=\"$2\"
|
|
shift
|
|
;;
|
|
-P)
|
|
eval PROJECT=\"$2\"
|
|
shift
|
|
;;
|
|
-a)
|
|
eval PKG_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`
|
|
|
|
|
|
# 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
|