diff --git a/bin/Makefile b/bin/Makefile new file mode 100644 index 00000000..7a30976e --- /dev/null +++ b/bin/Makefile @@ -0,0 +1,35 @@ +######################################################################## +# # +# development utilities # +# (c) 2001 jannet it services # +# Authors: Jan Lindemann # +# contact@jannet.de # +# patches, bugfixes and comments are welcome at patch@jannet.de # +# # +# $Id$ +# # +# This program is free software; permission to use, copy, modify, # +# distribute, and sell this software and its documentation under the # +# terms of the GNU Public license as published by the Free Software # +# Foundation, either version 2 or any later version of the license, is # +# hereby granted without fee, provided that (i) the above copyright # +# notices and this permission notice appear in all copies of the # +# software and related documentation, and (ii) the name of jannet may # +# not be used in any advertising or publicity relating to the software # +# without the specific, prior written permission of jannet. # +# # +# This program is distributed in the hope that it will be useful, but # +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- # +# TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # +# Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program; if not, write to the Free Software Founda- # +# tion, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # +# # +######################################################################## + +TOPDIR = .. + +include $(TOPDIR)/make/proj.mk +include $(JWBDIR)/make/bin.mk diff --git a/make/bin.mk b/make/bin.mk new file mode 100644 index 00000000..863cb660 --- /dev/null +++ b/make/bin.mk @@ -0,0 +1,11 @@ +# generic utility modules +# (c) 2005 jannet it services +# contact@jannet.de +# $Id$ + +include $(JWBDIR)/make/defs.mk + +all install: +clean distclean: + $(RM) -rf $(filter-out $(LOCAL_MKFILES) CVS debug release,$(wildcard *)) +test: diff --git a/make/tag-defs.mk b/make/tag-defs.mk new file mode 100644 index 00000000..add2d1cb --- /dev/null +++ b/make/tag-defs.mk @@ -0,0 +1 @@ +TAG_VERSION = V_$(shell echo $(VERSION) | $(SED) 's/[\.-]/_/g') diff --git a/make/tag-rules.mk b/make/tag-rules.mk new file mode 100644 index 00000000..2dd83517 --- /dev/null +++ b/make/tag-rules.mk @@ -0,0 +1,7 @@ +ifeq ($(VCS),cvs) +tag.dist: + cvs tag $(TAG_VERSION) + +ftag.dist: + cvs tag -F $(TAG_VERSION) +endif diff --git a/make/upload-defs-rpm.mk b/make/upload-defs-rpm.mk new file mode 100644 index 00000000..ccbb2596 --- /dev/null +++ b/make/upload-defs-rpm.mk @@ -0,0 +1,45 @@ +# this makefile needs +# PCKG_ROOT +# VERSION +# JWB_SCRIPT_DIR + +#UPLOAD_SH = $(JWB_SCRIPT_DIR)/upload.sh +#MKSPEC_SH = $(JWB_SCRIPT_DIR)/mkspec-wrapper.sh $(TOPDIR)/make/mkspec.sh + +#FTP_FILE_MODE ?= 640 +#FTP_DIR_MODE ?= 750 +#FTP_SRC_GROUP ?= spidsrc +#FTP_SRC_USER ?= $(shell whoami) +#FTP_RUN_GROUP ?= spidrun +#FTP_RUN_USER ?= $(shell whoami) +#FTP_DEV_GROUP ?= spiddev +#FTP_DEV_USER ?= $(shell whoami) +#FTP_HOST ?= pkg.janware.com +#FTP_HOST_LOGIN ?= root +# +#OS_NAME = $(shell echo $(OS_NAME_VERSION) | sed 's/-.*//') +#OS_VERSION = $(shell echo $(OS_NAME_VERSION) | sed 's/[^-]\+-//') +# +## $(FTP_PCKG_DIR)/linux/$(OS_NAME)/$(OS_VERSION)/rpm/src +#FTP_PCKG_DIR ?= /pub/packages +#PCKG_ROOT ?= $(FTP_PCKG_DIR)/linux/$(OS_NAME)/$(OS_VERSION) +##PCKG_ROOT = $(FTP_PCKG_DIR)/$(RPM_PROJECT) +#CURRENT_SRC = $(warning PCKG_ROOT=$(PCKG_ROOT))$(PCKG_ROOT)/tgz/$(PCKG_TAR) +#CURRENT_RPM_RUN_I386 = $(PCKG_ROOT)/$(RPM_ARCH)/$(PCKG_RPM_RUN_I386) +#CURRENT_RPM_DEVEL_I386 = $(PCKG_ROOT)/$(RPM_ARCH)/$(PCKG_RPM_DEVEL_I386) +#CURRENT_RPM_SRC = $(PCKG_ROOT)/src/$(PCKG_RPM_SRC) +#REMOTE_TARGET_PREFIX = rsync_ssh://$(FTP_HOST_LOGIN)@$(FTP_HOST):/srv/ftp +#REMOTE_TARGETS = \ +# $(REMOTE_TARGET_PREFIX)$(CURRENT_SRC):$(FTP_FILE_MODE):$(FTP_DIR_MODE):$(FTP_SRC_USER).$(FTP_SRC_GROUP) \ +# $(REMOTE_TARGET_PREFIX)$(CURRENT_RPM_RUN_I386):$(FTP_FILE_MODE):$(FTP_DIR_MODE):$(FTP_RUN_USER).$(FTP_RUN_GROUP)\ +# $(REMOTE_TARGET_PREFIX)$(CURRENT_RPM_SRC):$(FTP_FILE_MODE):$(FTP_DIR_MODE):$(FTP_SRC_USER).$(FTP_SRC_GROUP) +# +#ifeq ($(CREATE_DEVEL),true) +#REMOTE_TARGETS += \ +# $(REMOTE_TARGET_PREFIX)$(CURRENT_RPM_DEVEL_I386):$(FTP_FILE_MODE):$(FTP_DIR_MODE):$(FTP_DEV_USER).$(FTP_DEV_GROUP) +#endif + +# $(REMOTE_TARGET_PREFIX)$(PCKG_ROOT)/CURRENT_SRC:$(FTP_FILE_MODE):$(FTP_DIR_MODE):$(FTP_SRC_USER).$(FTP_SRC_GROUP) \ +# $(REMOTE_TARGET_PREFIX)$(PCKG_ROOT)/CURRENT_RPM_SRC:$(FTP_FILE_MODE):$(FTP_DIR_MODE):$(FTP_SRC_USER).$(FTP_SRC_GROUP) +# $(REMOTE_TARGET_PREFIX)$(PCKG_ROOT)/CURRENT_RPM_RUN_I386:$(FTP_FILE_MODE):$(FTP_DIR_MODE):$(FTP_RUN_USER).$(FTP_RUN_GROUP) \ +# $(REMOTE_TARGET_PREFIX)$(PCKG_ROOT)/CURRENT_RPM_DEVEL_I386:$(FTP_FILE_MODE):$(FTP_DIR_MODE):$(FTP_DEV_USER).$(FTP_DEV_GROUP) diff --git a/make/upload-rules.mk b/make/upload-rules.mk new file mode 100644 index 00000000..9b1c645b --- /dev/null +++ b/make/upload-rules.mk @@ -0,0 +1,17 @@ +all: +upload.dist: + if [ -f configure -o -f configure.ac -o -f configure.ac.tmpl ]; then make config; fi + make $(REMOTE_TARGETS) + touch $@.done + +yupdate.%.dist: + sudo -u root $(HOME)/bin/yupdate.sh -f $(HOME)/.yupdaterc -s $* + touch $@ + +CURRENT_%: + echo $($(notdir $@)) > $@ + +clean: upload.clean + +upload.clean: + $(RM) -f upload.dist yupdate.*.dist diff --git a/scripts/create-mkspec.sh b/scripts/create-mkspec.sh new file mode 100644 index 00000000..ad18c092 --- /dev/null +++ b/scripts/create-mkspec.sh @@ -0,0 +1,168 @@ +#!/bin/bash + +_cat() +{ + sed 's/^ *|//' +} + +cfg_section() +{ + ini_section "$inifile" $@ +} + +cfg_value() +{ + ini_value "$inifile" $@ +} + +cfg_escape() +{ + sed 's/\\/\\\\/g; s/\$/\\$/g; s/`/\\`/g' +} + +# unneeded but kept, because it might come in handy in the future +have_pkg() +{ + echo "$subpackages" | grep -q "\(^[ ]*\|[ ]\+\)$1\([ ]\+\|$\)" + return $? +} + +subpackage_description() +{ + case $1 in + run) + echo "Runtime files" + ;; + devel) + echo "Development files" + ;; + esac +} + +os_cascade() +{ + # might want to run python3 path/to/projects.py --os=suse-tumbleweed os-cascade + # or turn this into a python script and use projects.py as a module. + + if [ "$DISTRIBUTION" ]; then + echo os linux $DISTRIBUTION | sed 's/\([^-]\+\)-\([^-]\+\)/\1 \1-\2/g' + else + echo os linux + fi +} + +# -- here we go + +echo "== running $0" "$@" >&2 + +export LANG=POSIX +dir=`dirname $0` +inifile="$1" +. $dir/ini-tools.sh + +subpackages=`cfg_value global.subpackages` +license=`cfg_value global.license` +[ "$license" ] || license="janware GmbH proprietary license" +vendor=`cfg_value global.vendor` +[ "$vendor" ] || vendor="janware GmbH" +url=`cfg_value global.url` +[ "$url" ] || url="https://janware.com" + +_cat <<- EOT + |echo "%define debug_package %{nil}" + |# --------------------------------------- + |echo "Name: \$NAME" + |echo "Summary: `cfg_value summary`" + |echo "Version: \$VERSION" + |echo "Release: \$RELEASE" + |echo "License: $license" + |echo "Group: System/Libraries" + |[ -n "\$SOURCE" ] && echo "Source: \$SOURCE" + |echo "Vendor: $vendor" + |echo "URL: $url" + |echo "BuildRoot: /var/tmp/%{name}-buildroot" + |echo "Distribution: jw / openSUSE Tumbleweed" + |echo "" + |echo "%description" + |echo "`cfg_value description`" + |echo "" + |# --------------------------------------- + |echo "%prep" + |echo "%setup -q -n \$NAME-\$V" + |echo "" + |echo "%build" + |echo 'pwd' + |echo 'make config' + |echo 'make' + |echo "" + |echo "%install" + |echo 'rm -rf \$RPM_BUILD_ROOT' + |echo "export ENV_PREFIX=\\\$RPM_BUILD_ROOT" + |echo "export INSTALL_LOG=\$INSTALL_LOG" + |echo "mkdir -p \`dirname \$INSTALL_LOG\`" + |echo "> \$INSTALL_LOG" + |echo "make install" + |echo "export PATH=$JWB_SCRIPT_DIR:\\\$PATH" + |echo "/bin/bash pkg.sh milk-install-log -p \\\$ENV_PREFIX -n \$NAME -t rpm -s \\"$subpackages\\" \$INSTALL_LOG \`dirname \$INSTALL_LOG\`" + |echo "exit 0" # <- Cut short CentOS magic appended to install scriptlet, which would generate .pyo files and other cruft. +EOT + +for p in $subpackages; do + + P=${p^^} + + _cat <<- EOT + |echo "" + |echo "# --------------------------------------- subpackage $p" + |echo "" + |echo "%package -n \$NAME-$p" + |echo "Summary: `cfg_value summary`" + |echo "Group: `cfg_value global.group`" + |[ "\$REQUIRES_$P" ] && echo "Requires: \$REQUIRES_$P" + |[ "\$CONFLICTS_$P" ] && echo "Conflicts: \$CONFLICTS_$P" + |[ "\$PROVIDES_$P" ] && echo "Provides: \$PROVIDES_$P" + |echo "" + EOT + + descr=`subpackage_description $p` + if [ "$descr" ]; then + _cat <<- EOT + |echo "" + |echo "%description -n \$NAME-$p" + |echo "$descr" + EOT + fi + + for stage in pre preun post postun; do + echo "== processing stage $stage: cfg_section pkg.$p.$stage" >&2 + out="" + #for os in '' `os_cascade | sed 's/\(^\| \)/ ./g'`; do + for os in '' `os_cascade`; do + sec=pkg.$p.$stage + if [ "$os" ]; then + sec="$sec.$os" + head="\n# --- $os\n" + else + head="" + fi + cfg_section $sec | grep -q . || continue + out="$out$head`cfg_section $sec`" + done + if [ "$out" ]; then + echo -e "$out" >&2 + _cat <<- EOT + |echo "" + |echo "%$stage -n \$NAME-$p" + EOT + echo "cat << EOT" + echo -e "$out" | cfg_escape + echo "EOT" + fi + done + + _cat <<- EOT + |echo "" + |echo "%files -n \$NAME-$p -f \$INSTALL_LOG.\$NAME-$p" + |echo '%defattr (-, root, root)' + EOT +done diff --git a/scripts/ini-tools.sh b/scripts/ini-tools.sh new file mode 100644 index 00000000..d84e2d0d --- /dev/null +++ b/scripts/ini-tools.sh @@ -0,0 +1,56 @@ +ini_section() +{ + local inifile="$1" + local sec="$2" + cat "$inifile" | + cut -d\# -f1 | + tr -s '\n' '\n' | + sed -n "/^ *\[$sec\]/,/^ *\[/ p" | + grep -v '^ *\[' | + sed '/^ *$/ d' +} + +ini_value() +{ + local inifile="$1" + local path="$2" + local sec=`echo "$path" | sed 's/\.[^.]\+$//'` + local key=`echo "$path" | sed 's/.*\.//'` + +# echo "path=>$path<" +# echo "sec=>$sec<" +# echo "key=>$key<" + + if [ "$key" = "$path" ]; then + ini_section "$inifile" "$path" + return 0 + fi + + ini_section "$inifile" "$sec" | sed " + /^ *$key *=/ !d + s/^ *$key *= *// + s/ *$// + /^ *$/ d + " +} + +ini_has_section() +{ + local inifile="$1" + local sec="$2" + grep -q "^ *\[$sec\]" $inifile || return 1 +} + +ini_has_value() +{ + ini_value $@ | grep -q . +} + +ini_escape() +{ + cat | sed ' + s/\$/\\$/g + s/`/\\\`/g + ' +} + diff --git a/scripts/mkspec-wrapper.sh b/scripts/mkspec-wrapper.sh new file mode 100644 index 00000000..87fb9dfe --- /dev/null +++ b/scripts/mkspec-wrapper.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +usage() +{ + echo usage: $MYNAME /path/to/mkspec.sh -h [-N name] [-T topdir] [-V version] [-S source] [-R requires] [-P project] >&2 + [ "$1" ] && exit $1 +} + +append() +{ + local var=$1 + shift + local tmp=`eval echo \"\\$$var $@\" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//'` + eval $var=\"$tmp\" +} + +# -- here we go + +#set -x + +MYNAME=`basename $0` +ID=`whoami` +[ ! "$INSTALL_LOG" ] && INSTALL_LOG=/tmp/rpmbuild-$ID/install.log + +eval set -- `getopt -l "provides-run:" -l "provides-devel:" -o "P:T:V:S:N:hR:D:X:Y:d:" -- "$@"` + +while [ "$1" != -- ]; do +echo checking "$1=$2" >&2 +case $1 in + -h) + usage 0;; + -T) + TOPDIR="$2" + shift;; + -V) + V="$2" + shift;; + -S) + SOURCE="$2" + shift;; + -N) + NAME="$2" + shift;; + -R) + append REQUIRES_RUN "$2" + shift + ;; + -X) + append CONFLICTS_RUN "$2" + shift + ;; + -D) + append REQUIRES_DEVEL "$2" + shift + ;; + -Y) + append CONFLICTS_DEVEL "$2" + shift + ;; + --provides-run) + append PROVIDES_RUN "$2" + shift + ;; + --provides-devel) + append PROVIDES_DEVEL "$2" + shift + ;; + -P) + PROJECT="$2" + shift;; + -d) + DISTRIBUTION="$2" + shift;; + *) + usage 1;; +esac +shift +done +shift + +MKSPEC_SH="$1" +shift + +[ -z "$TOPDIR" ] && TOPDIR=. + +if [ -z "$V" ]; then + if [ -f $TOPDIR/VERSION ]; then + VERSION="`cat $TOPDIR/VERSION | cut -d- -f1`" + RELEASE="`cat $TOPDIR/VERSION | cut -d- -f2- | sed 's/[-_].*//'`" + else + VERSION=noversion + RELEASE=norelease + fi +else + VERSION="`echo $V | cut -d- -f1`" + RELEASE="`cat $TOPDIR/VERSION | cut -d- -f2- | sed 's/[-_].*//'`" +fi + +if [ -z "$NAME" ]; then + NAME=`pwd | xargs basename` +fi + +REQUIRES="$REQUIRES_RUN $REQUIRES_DEVEL" +CONFLICTS="$CONFLICTS_RUN $CONFLICTS_DEVEL" +#if [ -n "$REQUIRES" ]; then +# REQUIRES_RUN=`echo $REQUIRES | +# sed -e ' +# s/\([a-zA-Z-]\+\) *\([<>=]*\) *\([a-zA-Z0-9\.-]*\)/\1-run \2 \3,/g +# s/,$// +# s/-run-run/-run/ +# '` +# REQUIRES_DEVEL="$REQUIRES_RUN, $NAME-run = $VERSION-$RELEASE, `echo $REQUIRES_RUN | sed -e 's/-run/-devel/g'`" +#fi + +#echo "REQUIRES_RUN=\"$REQUIRES_RUN\"" +#exit + +export \ + REQUIRES REQUIRES_RUN REQUIRES_DEVEL \ + CONFLICTS CONFLICTS_RUN CONFLICTS_DEVEL \ + PROVIDES PROVIDES_RUN PROVIDES_DEVEL \ + TOPDIR \ + PROJECT NAME \ + SOURCE \ + VERSION RELEASE V \ + INSTALL_LOG \ + DISTRIBUTION + +bash $MKSPEC_SH + diff --git a/scripts/pkg.sh b/scripts/pkg.sh new file mode 100644 index 00000000..8e19cee1 --- /dev/null +++ b/scripts/pkg.sh @@ -0,0 +1,1237 @@ +#!/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 +} + +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() +{ + 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 | + 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-build-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-build-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() + { + if echo "$*" | grep -qe '/etc/\|\.conf$\|\.leases$'; then + echo "%config(noreplace) " + fi + } + + 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 + attr=" %attr($c_mode,$c_owner,$c_group)" + [ -L "$file" ] && attr="" + 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 + attr="%attr($mode,$c_owner,$c_group)" + [ -L "$c_target" ] && attr="" + 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 + attr="%attr($mode,$c_owner,$c_group)" + [ -L "$file" ] && attr="" + 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(\([0-9]\+\),\([^,]\+\),\([^,)]\+\)).*/\\$attr/" + } + + milk_install_log_init_postinst() + { + cat <<- EOT > $1 + #!/bin/sh + + EOT + chmod 755 $1 + } + + 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) + cat_log | sed "s% $prefix% %" | grep -ve $filter_devel > $in.$name-run + cat_log | sed "s% $prefix% %" | 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) + cat_log | grep -v "%dir" | sed "s% $prefix% %; s%//*%/%g; s/.*) *//" | grep -ve $filter_devel | sed 's/\(.*\)\/\([^/]\+\) *$/inst-root\1\/\2 \1/' > $out/$name-run.install + cat_log | grep -v "%dir" | sed "s% $prefix% %; s%//*%/%g; s/.*) *//" | grep -e $filter_devel | sed 's/\(.*\)\/\([^/]\+\) *$/inst-root\1\/\2 \1/' > $out/$name-devel.install + cat_log | grep "%dir" | sed "s% $prefix% %; s%//*%/%g; s/.*) *//" | grep -ve $filter_devel | sed 's/\(.*\)\/\([^/]\+\) *$/\1\/\2/; s%^/%%' | sort -u > $out/$name-run.dirs + cat_log | grep "%dir" | sed "s% $prefix% %; s%//*%/%g; s/.*) *//" | grep -e $filter_devel | sed 's/\(.*\)\/\([^/]\+\) *$/\1\/\2/; s%^/%%' | sort -u > $out/$name-devel.dirs + #cat_log | sed "/%config/ !d; s% $prefix% %; s%//*%/%g; s/.*) *//" | grep -ve $filter_devel > $out/conffiles + cat_log | sed "/%config/ !d; s% $prefix% %; s%//*%/%g; s/.*) *//" | grep -ve $filter_devel > $out/conffiles.$name-run + cat_log | sed "/%config/ !d; s% $prefix% %; s%//*%/%g; s/.*) *//" | grep -e $filter_devel > $out/conffiles.$name-devel + + for p in run devel; do + postinst=$out/$name-$p.postinst + milk_install_log_init_postinst $postinst + 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" >> $postinst + echo "chmod $perm $file" >> $postinst + 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` + +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 + diff --git a/scripts/scm.sh b/scripts/scm.sh new file mode 100644 index 00000000..7b6201a8 --- /dev/null +++ b/scripts/scm.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +cmd_mv() +{ + local from="$1" + local to="$2" + case $scm in + cvs) + cp "$from" "$to" + cvs add "$to" + cvs remove -f "$from" + ;; + git) + git mv "$from" "$to" + ;; + esac +} + +cmd_commit() +{ + C='' + for i in "$@"; do + C="$C \"${i//\"/\\\"}\"" + done + eval $scm commit "$C" +} + +cmd_add() +{ + $scm add "$@" +} + +cmd_rm() +{ + case $scm in + cvs) + cvs remove "$@" + ;; + git) + git rm "$@" + ;; + esac +} + +cmd_clean() +{ + case $scm in + cvs) + while [ "${1:0:1}" = - ]; do + shift + done + set +e + local file + for file in $@; do + if ! grep -q "/$file/" CVS/Entries; then + rm -f $file + fi + done + ;; + git) + git clean -x "$@" + ;; + esac +} + +cmd_ls_files() +{ + filter_deleted() + { + local rc_file="$1" + shift + local cand + for cand in "$@"; do + grep -q "^R ./$cand/" $rc_file && continue + echo $cand + done + } + + output() + { + if [ "$zero_terminate" = 1 ]; then + echo -en "$*\x00" + else + echo "$*" + fi + } + + list_dirents_cvs() + { + local dirs=`sed '/^D\// !d; s%^D/%%; s%/.*%%' $1/CVS/Entries` + dirs="`filter_deleted $1/CVS/Entries $dirs`" + local cands + if [ -f $1/CVS/Entries.Log ]; then + cands="`sed '/^A D\// !d; s%^A D/%%; s%/.*%%' $1/CVS/Entries.Log`" + dirs="$dirs `filter_deleted $1/CVS/Entries.Log $cands`" + fi + local files=`sed '/^\// !d; s%/%%; s%/.*%%; s%^%%' $1/CVS/Entries` + files="`filter_deleted $1/CVS/Entries $files`" + local d f + for f in $files; do + output "$1/$f" + done + for d in $dirs; do + [ "$opt_only_regular_files" = 1 ] || output $1/$d + list_dirents_cvs $1/$d + done + } + + list_dirents_git() + { + local opts="$git_ls_files_opts" + git --version | grep -q "version *1" && opt_no_submodules=1 + [ "$opt_no_submodules" = 1 ] || opts="$opts --recurse-submodules" + git ls-files --recurse-submodules $opts $1 + } + + list_dirents() + { + if [ -d $1/CVS ]; then + list_dirents_cvs $1 + return + fi + git status >/dev/null 2>&1 || { + echo "failed to list versioned files in $1: no VCS" >&2 + exit 1 + } + list_dirents_git $1 + } + + set -- `getopt fnzt "$@"` + + while [ "$1" != -- ]; do + case $1 in + -f) + opt_only_regular_files=1 + ;; + -n) + opt_no_submodules=1 + ;; + -z) + zero_terminate=1 + git_ls_files_opts="$git_ls_files_opts -z" + opt_sort="$opt_sort -z" + ;; + -t) + text_files=1 + ;; + esac + shift + done + shift + + proj_dir="$1" + [ "$proj_dir" ] && cd $proj_dir + + if [ "$text_files" ]; then + list_dirents . | sort $opt_sort | xargs file -N | grep ":.*text" | cut -d: -f1 + else + list_dirents . | sort $opt_sort + fi +} + +# ------- here we go +export LANG=POSIX +myname=`basename $0` +cmd=cmd_${1//-/_} +shift +if [ -d "CVS" ]; then + scm=cvs +else + scm=git +fi + +$cmd "$@"