You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by ns...@apache.org on 2013/03/07 21:05:51 UTC

git commit: Initial commit

Updated Branches:
  refs/heads/master [created] d110c3332


Initial commit


Project: http://git-wip-us.apache.org/repos/asf/couchdb-admin/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-admin/commit/d110c333
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-admin/tree/d110c333
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-admin/diff/d110c333

Branch: refs/heads/master
Commit: d110c333267c9a8fda1bee79015a9a0bd79ae01b
Parents: 
Author: Noah Slater <ns...@apache.org>
Authored: Thu Mar 7 19:59:46 2013 +0000
Committer: Noah Slater <ns...@apache.org>
Committed: Thu Mar 7 19:59:46 2013 +0000

----------------------------------------------------------------------
 email/discuss_committer.txt    |   11 +++
 email/discuss_release.txt      |   19 +++++
 email/reminder_meeting.txt     |   23 ++++++
 email/vote_release.txt         |   27 ++++++
 release/build_candidate.sh     |  149 +++++++++++++++++++++++++++++++++++
 release/build_candidate_aws.sh |   95 ++++++++++++++++++++++
 release/build_cve_list.sh      |   47 +++++++++++
 release/check_docs.sh          |  117 +++++++++++++++++++++++++++
 release/generate_proposal.sh   |   99 +++++++++++++++++++++++
 release/publish_candidate.sh   |  140 ++++++++++++++++++++++++++++++++
 10 files changed, 727 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/email/discuss_committer.txt
----------------------------------------------------------------------
diff --git a/email/discuss_committer.txt b/email/discuss_committer.txt
new file mode 100644
index 0000000..808a653
--- /dev/null
+++ b/email/discuss_committer.txt
@@ -0,0 +1,11 @@
+Subject: [DISCUSS] Elect %NAME% as committer
+
+Dear PMC,
+
+I would like to elect %NAME% as committer.
+
+%REASONS%
+
+If there appears to be consensus I will call a vote.
+
+Thanks,

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/email/discuss_release.txt
----------------------------------------------------------------------
diff --git a/email/discuss_release.txt b/email/discuss_release.txt
new file mode 100644
index 0000000..29ffd11
--- /dev/null
+++ b/email/discuss_release.txt
@@ -0,0 +1,19 @@
+Subject: [DISCUSS] Release Apache CouchDB %version%
+
+Dear community,
+
+I would like to propose that we release Apache CouchDB %version%.
+
+The project aims to produce time-based releases. If your favourite feature is not ready for this version, it can be included in the next version. However, if you know of anything that should block the release, please speak up now.
+
+The %version% NEWS entry as it stands:
+
+%news%
+
+The %version% CHANGES entry as it stands:
+
+    %changes%
+
+Are these accurate? Please double check any work you may have done and make sure that the corresponding NEWS and CHANGES entries are up-to-date.
+
+Thanks,

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/email/reminder_meeting.txt
----------------------------------------------------------------------
diff --git a/email/reminder_meeting.txt b/email/reminder_meeting.txt
new file mode 100644
index 0000000..9a956c2
--- /dev/null
+++ b/email/reminder_meeting.txt
@@ -0,0 +1,23 @@
+Subject: [REMINDER] Weekly IRC meeting, Wednesday (tomorrow) at 20:00 GMT
+
+Dear community,
+
+Please join our weekly IRC meeting, Wednesday (tomorrow) at 20:00 GMT.
+
+Everyone is welcome to attend this meeting.
+
+If you have anything to put on the agenda, please reply to this email or mention it at the start of the meeting.
+
+The meeting will take place in:
+
+    irc://irc.freenode.net/couchdb-meeting
+
+You can access the meeting via the web:
+
+    http://webchat.freenode.net/?channels=#couchdb-meeting
+
+For your local time, see:
+
+    http://everytimezone.com/
+
+Thanks,

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/email/vote_release.txt
----------------------------------------------------------------------
diff --git a/email/vote_release.txt b/email/vote_release.txt
new file mode 100644
index 0000000..315b237
--- /dev/null
+++ b/email/vote_release.txt
@@ -0,0 +1,27 @@
+Subject: [VOTE] Release Apache CouchDB %version%-rc.%candidate%
+
+Dear community,
+
+I would like to call a vote on Apache CouchDB %version%-rc.%candidate%.
+
+Changes since last round:
+
+ * [LIST CHANGES]
+
+We encourage the whole community to download and test these release artefacts so that any critical issues can be resolved before the release is made. Everyone is free to vote on this release, so get stuck in!
+
+The release artefacts we are voting on are available here:
+
+    %candidate_url%/%package%.tar.gz
+    %candidate_url%/%package%.tar.gz.asc
+    %candidate_url%/%package%.tar.gz.ish
+    %candidate_url%/%package%.tar.gz.md5
+    %candidate_url%/%package%.tar.gz.sha
+
+Please follow the test procedure here:
+
+    http://wiki.apache.org/couchdb/Test_procedure
+
+Please remember that "rc.%candidate%" is an annotation. If the vote passes, these artefacts will be released as Apache CouchDB %version%.
+
+Thanks,

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/release/build_candidate.sh
----------------------------------------------------------------------
diff --git a/release/build_candidate.sh b/release/build_candidate.sh
new file mode 100755
index 0000000..ed09fb6
--- /dev/null
+++ b/release/build_candidate.sh
@@ -0,0 +1,149 @@
+#!/bin/sh -e
+
+if test -n "$1"; then
+    branch=$1
+else
+	echo "error: no branch"
+    exit 1
+fi
+
+if test -n "$2"; then
+    version=$2
+else
+	echo "error: no version"
+    exit 1
+fi
+
+log () {
+    printf "\033[1;31m$1\033[0m\n"
+}
+
+basename=`basename $0`
+
+if test -n "$3"; then
+    tmp_dir=$3
+else
+    log "Creating temporary directory..."
+    tmp_dir=`mktemp -d /tmp/$basename.XXXXXX` || exit 1
+    echo $tmp_dir
+fi
+
+diff_file=$tmp_dir/diff.txt
+
+cat > $diff_file <<EOF
+^Only in $tmp_dir/1.3.x: .gitignore\$
+^Only in $tmp_dir/1.3.x: .mailmap\$
+^Only in $tmp_dir/1.3.x: .travis.yml\$
+^Only in $tmp_dir/1.3.x: acinclude.m4.in\$
+^Only in $tmp_dir/1.3.x: bootstrap\$
+^Only in $tmp_dir/1.3.x: THANKS.in\$
+^Only in $tmp_dir/apache-couchdb-1.3.0: acinclude.m4\$
+^Only in $tmp_dir/apache-couchdb-1.3.0: aclocal.m4\$
+^Only in $tmp_dir/apache-couchdb-1.3.0: config.h.in\$
+^Only in $tmp_dir/apache-couchdb-1.3.0: configure\$
+^Only in $tmp_dir/apache-couchdb-1.3.0: INSTALL\$
+^Only in $tmp_dir/apache-couchdb-1.3.0: m4\$
+^Only in $tmp_dir/apache-couchdb-1.3.0: Makefile.in\$
+^Only in $tmp_dir/apache-couchdb-1.3.0: THANKS\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/.*: Makefile.in\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/bin: couchdb.1\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/build-aux: config.guess\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/build-aux: config.sub\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/build-aux: depcomp\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/build-aux: install-sh\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/build-aux: ltmain.sh\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/build-aux: missing\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/share/doc/build: html\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/share/doc/build: latex\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/share/doc/build: texinfo\$
+^Only in $tmp_dir/apache-couchdb-1.3.0/src/couchdb/priv: couchjs.1\$
+EOF
+
+build_file=build.mk
+
+cat > $build_file <<EOF
+URL=https://git-wip-us.apache.org/repos/asf/couchdb.git
+
+TMP_DIR=$tmp_dir
+
+SRC_DIR=\$(TMP_DIR)/git
+
+DIFF_FILE=$diff_file
+
+BRANCH=$branch
+
+VERSION=$version
+
+PACKAGE=apache-couchdb-\$(VERSION)
+
+SRC_FILE=\$(SRC_DIR)/\$(PACKAGE).tar.gz
+
+TGZ_FILE=\$(TMP_DIR)/\$(PACKAGE).tar.gz
+
+all: \$(TMP_DIR)/\$(PACKAGE).tar.gz
+
+\$(TMP_DIR)/\$(PACKAGE).tar.gz: \$(TGZ_FILE).ish
+	cd \$(SRC_DIR) && \
+	    ./bootstrap
+	cd \$(SRC_DIR) && \
+	    ./configure --enable-strictness --disable-tests
+	cd \$(SRC_DIR) && \
+	    DISTCHECK_CONFIGURE_FLAGS="--disable-tests" make -j distcheck
+	mv \$(SRC_FILE) \$(TGZ_FILE)
+
+\$(TGZ_FILE).ish: \$(SRC_DIR)
+	cd \$(SRC_DIR) && git show HEAD | head -n 1 | cut -d " " -f 2 > \$@
+
+\$(SRC_DIR): \$(TMP_DIR)
+	git clone \$(URL) \$@
+	cd \$(SRC_DIR) && git checkout -b \$(BRANCH) origin/\$(BRANCH)
+
+\$(TMP_DIR):
+	mkdir \$@
+
+check: check-files
+
+check-files: check-diff
+	cd \$(TMP_DIR)/\$(PACKAGE) && \
+	    grep "not released" NEWS CHANGES; test "\$\$?" -eq 1
+	cd \$(TMP_DIR)/\$(PACKAGE) && \
+	    grep "build" acinclude.m4; test "\$\$?" -eq 1
+	cd \$(TMP_DIR)/\$(PACKAGE) && \
+	    grep `date +%Y` NOTICE
+	cd \$(TMP_DIR)/\$(PACKAGE) && \
+	    grep `date +%Y` share/doc/src/conf.py
+
+check-diff: check-file-size
+	cd \$(SRC_DIR) && git archive \
+	    --prefix=\$(BRANCH)/ -o ../\$(BRANCH).tar \
+	    \`cat \$(TGZ_FILE).ish\`
+	cd \$(TMP_DIR) && tar -xf \$(TMP_DIR)/\$(BRANCH).tar
+	cd \$(TMP_DIR) && tar -xzf \$(TGZ_FILE)
+	diff -r \$(TMP_DIR)/\$(PACKAGE) \$(TMP_DIR)/\$(BRANCH) \
+	    | grep --include= -vEf \$(DIFF_FILE); \
+	test "\$\$?" -eq 1
+
+check-file-size:
+	test -s \$(TGZ_FILE)
+	test -s \$(TGZ_FILE).ish
+EOF
+
+log_file=$tmp_dir/log.txt
+
+echo "Build started `date`" > $log_file
+
+log "Executing build instructions..."
+
+make -f $build_file | tee -a $log_file
+
+time_finish=`date "+%s"`
+
+echo "Build finished `date`" >> $log_file
+
+log "Checking build..."
+
+make -f $build_file check
+
+log "Check complete..."
+
+echo "Files in $tmp_dir"

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/release/build_candidate_aws.sh
----------------------------------------------------------------------
diff --git a/release/build_candidate_aws.sh b/release/build_candidate_aws.sh
new file mode 100755
index 0000000..c37f9a0
--- /dev/null
+++ b/release/build_candidate_aws.sh
@@ -0,0 +1,95 @@
+#!/bin/sh -e
+
+if test -n "$1"; then
+    identity_file=$1
+else
+	echo "error: no identity file"
+    exit 1
+fi
+
+if test -n "$2"; then
+    connection=$2
+else
+	echo "error: no connection string"
+    exit 1
+fi
+
+if test -n "$3"; then
+    branch=$3
+else
+	echo "error: no branch"
+    exit 1
+fi
+
+if test -n "$4"; then
+    version=$4
+else
+	echo "error: no version"
+    exit 1
+fi
+
+log () {
+    printf "\033[1;31m$1\033[0m\n"
+}
+
+basename=`basename $0`
+
+log "Creating temporary directory..."
+
+tmp_dir=`mktemp -d /tmp/$basename.XXXXXX` || exit 1
+
+echo $tmp_dir
+
+log "Building candidate on remote host..."
+
+ssh -i $identity_file $connection "sh -e" <<EOF
+sudo apt-get update
+
+sudo apt-get install -y \
+    git \
+    libtool \
+    automake \
+    autoconf \
+    autoconf-archive \
+    pkg-config \
+    help2man \
+    python-sphinx \
+    texlive-latex-base \
+    texlive-latex-recommended \
+    texlive-latex-extra \
+    texlive-fonts-recommended \
+    texinfo \
+    build-essential \
+    erlang-base-hipe \
+    erlang-dev \
+    erlang-manpages \
+    erlang-eunit \
+    erlang-nox \
+    libicu-dev \
+    libmozjs-dev \
+    libcurl4-openssl-dev
+
+rm -rf couchdb-pmc
+
+git clone https://github.com/nslater-asf/couchdb-pmc.git
+
+tmp_dir=\`mktemp -d /tmp/$basename.XXXXXX\` || exit 1
+
+./couchdb-pmc/release/build_candidate.sh $branch $version \$tmp_dir
+
+echo \$tmp_dir > ~/tmp_dir.txt
+EOF
+
+log "Fetching candidate from remote host..."
+
+remote_tmp_dir=`ssh -i $identity_file $connection "cat ~/tmp_dir.txt"`
+
+tgz_file=$remote_tmp_dir/apache-couchdb-$version.tar.gz
+
+ish_file=$remote_tmp_dir/apache-couchdb-$version.tar.gz.ish
+
+scp -i $identity_file $connection:$tgz_file $tmp_dir
+
+scp -i $identity_file $connection:$ish_file $tmp_dir
+
+echo "Files in $tmp_dir"

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/release/build_cve_list.sh
----------------------------------------------------------------------
diff --git a/release/build_cve_list.sh b/release/build_cve_list.sh
new file mode 100755
index 0000000..17c1585
--- /dev/null
+++ b/release/build_cve_list.sh
@@ -0,0 +1,47 @@
+#!/bin/sh -e
+
+basename=`basename $0`
+
+ssh people.apache.org "sh -e" <<EOF
+
+tmp_dir=\`mktemp -d /tmp/$basename.XXXXXX\` || exit 1
+
+mbox_export_file=\$tmp_dir/mbox
+
+cve_list_file=\$tmp_dir/cve_list.txt
+
+log () {
+    printf "\033[1;31m\$1\033[0m\n"
+}
+
+log "Adding mails to export..."
+
+find /home/apmail/private-arch/security -type f | while read mbox_file; do
+    compressed=\`echo \$mbox_file | grep -E "\.gz" || true\`
+    if test -n "\$compressed"; then
+        echo "Adding" \$mbox_file "(compressed)"
+        cat \$mbox_file >> \$mbox_export_file
+     else
+        echo "Adding" \$mbox_file
+        cat \$mbox_file | gzip >> \$mbox_export_file
+    fi
+done
+
+log "Finding CVE numbers..."
+
+zgrep "CVE" \$mbox_export_file | \
+    grep "Apache CouchDB" | \
+    sed "s,.*CVE,CVE," | \
+    cut -c1-13 | \
+    grep -E "CVE-[0-9]{4}-[0-9]{4}" | \
+    grep -v "CVE-2008-2370" | \
+    sort | \
+    uniq | \
+    tee \$cve_list_file
+
+rm \$mbox_export_file
+
+log "Writing CVE numbers..."
+
+echo \$cve_list_file
+EOF

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/release/check_docs.sh
----------------------------------------------------------------------
diff --git a/release/check_docs.sh b/release/check_docs.sh
new file mode 100755
index 0000000..4537ab7
--- /dev/null
+++ b/release/check_docs.sh
@@ -0,0 +1,117 @@
+#!/bin/sh -e
+
+if test -n "$1"; then
+    cve_list_file=$1
+else
+	echo "error: no remote CVE list file"
+    exit 1
+fi
+
+log () {
+    printf "\033[1;31m$1\033[0m\n"
+}
+
+basename=`basename $0`
+
+if test -n "$2"; then
+    tmp_dir=$2
+else
+    log "Creating temporary directory..."
+    tmp_dir=`mktemp -d /tmp/$basename.XXXXXX` || exit 1
+    echo $tmp_dir
+fi
+
+log "Fetching CVE list file..."
+
+if test ! -f $tmp_dir/cve_list.txt; then
+    scp people.apache.org:$cve_list_file $tmp_dir/cve_list.txt
+fi
+
+log "Cloning or fetching Git repository..."
+
+if test ! -d $tmp_dir/git/.git; then
+    git clone https://git-wip-us.apache.org/repos/asf/couchdb.git $tmp_dir/git
+    cd $tmp_dir/git
+else
+    cd $tmp_dir/git
+    git fetch
+fi
+
+rm -rf $tmp_dir/branch
+
+branches=`git branch -r | grep -E 'origin/[0-9]+\.[0-9]+\.x$'`" master"
+
+for branch in $branches; do
+    version=`echo $branch | sed 's,origin/,,'`
+    dir=$tmp_dir/branch/$version
+    mkdir -p $dir
+    git cat-file blob $branch:NEWS > $dir/NEWS
+    git cat-file blob $branch:CHANGES > $dir/CHANGES
+done
+
+python > $tmp_dir/versions.txt << EOF
+import re
+
+versions="""
+`ls $tmp_dir/branch`
+""".split()
+
+def num(s):
+    try:
+        return int(s)
+    except:
+        return s
+
+versions.sort(key=lambda i: [num(i) for i in re.split("([0-9]+)", i)])
+
+for version in versions:
+    print version
+EOF
+
+log "Checking CVEs in NEWS..."
+
+cat $tmp_dir/cve_list.txt | while read cve; do
+    exists=`grep -r $cve $tmp_dir/branch/*/NEWS || true`
+    if test ! -n "$exists"; then
+        echo $cve "(missing)"
+    fi
+done
+
+log "Checking CVEs in CHANGES..."
+
+cat $tmp_dir/cve_list.txt | while read cve; do
+    exists=`grep -r $cve $tmp_dir/branch/*/CHANGES || true`
+    if test ! -n "$exists"; then
+        echo $cve "(missing)"
+    fi
+done
+
+function compare () {
+    log "Comparing NEWS, $1 to $2..."
+    diff $tmp_dir/branch/$1/NEWS $tmp_dir/branch/$2/NEWS | \
+        grep -E "^< [^#]" || true
+    log "Comparing CHANGES, $1 to $2..."
+    diff $tmp_dir/branch/$1/CHANGES $tmp_dir/branch/$2/CHANGES | \
+        grep -E "^< [^#]" || true
+}
+
+function scan () {
+    log "Scanning $1..."
+    grep "released" $tmp_dir/branch/$1/NEWS || true
+    grep "released" $tmp_dir/branch/$1/CHANGES || true
+}
+
+versions=`cat $tmp_dir/versions.txt`
+
+last_version=""
+
+for version in $versions; do
+    if test -n "$last_version"; then
+        compare $last_version $version
+    fi
+    last_version=$version
+done
+
+for version in $versions; do
+    scan $version
+done

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/release/generate_proposal.sh
----------------------------------------------------------------------
diff --git a/release/generate_proposal.sh b/release/generate_proposal.sh
new file mode 100755
index 0000000..f1bbd86
--- /dev/null
+++ b/release/generate_proposal.sh
@@ -0,0 +1,99 @@
+#!/bin/sh -e
+
+GIT_URL=https://git-wip-us.apache.org/repos/asf?p=couchdb.git;a=blob_plain;
+
+EMAIL_TPL=email/discuss_release.txt
+
+if test -n "$1"; then
+    cache_dir=$1
+else
+	echo "error: no cache directory"
+    exit 1
+fi
+
+if test -n "$2"; then
+    branch=$2
+else
+	echo "error: no branch"
+    exit 1
+fi
+
+if test -n "$3"; then
+    version=$3
+else
+	echo "error: no version"
+    exit 1
+fi
+
+log () {
+    printf "\033[1;31m$1\033[0m\n"
+}
+
+basename=`basename $0`
+
+tmp_dir=`mktemp -d /tmp/$basename.XXXXXX` || exit 1
+
+log "Parsing documentation..."
+
+email_in_file=$tmp_dir/email.txt.in
+
+cat $EMAIL_TPL > $email_in_file
+
+python <<EOF
+def get_section(doc_path, version):
+    doc_file = open(doc_path)
+    copy = False
+    section = ""
+    for line in doc_file.readlines():
+        if line.startswith("Version"):
+            if line == "Version $version\n":
+                copy = True
+                continue
+            else:
+                if copy:
+                    break
+        if line.startswith("-"):
+            continue
+        if copy:
+            if line.strip():
+                section += line
+    return section.rstrip()
+
+news = get_section("$cache_dir/branch/$branch/NEWS", "$version")
+
+email_in_file = open("$email_in_file")
+
+email_in_file_content = email_in_file.read()
+
+email_in_file_content = email_in_file_content.replace("%news%", news)
+
+email_in_file = open("$email_in_file", "w")
+
+email_in_file.write(email_in_file_content)
+EOF
+
+email_file=$tmp_dir/email.txt
+
+changes=$GIT_URL"f=CHANGES;hb=$branch"
+
+sed -e "s|%version%|$version|g" \
+    -e "s|%changes%|$changes|g" \
+    < $email_in_file > $email_file
+
+echo "Email text written to:" $email_file
+
+if test -n `which pbcopy`; then
+    cat $email_file | pbcopy && copied=1
+elif test -n `which xclip`; then
+    cat $email_file | xclip -selection c && copied=1
+elif test -n `which clip`; then
+    cat $email_file | clip && copied=1
+fi
+
+if test -n "$copied"; then
+    echo "Copied to your clipboard..."
+fi
+
+echo "Send the email to: dev@couchdb.apache.org"
+
+echo "Files in $tmp_dir"

http://git-wip-us.apache.org/repos/asf/couchdb-admin/blob/d110c333/release/publish_candidate.sh
----------------------------------------------------------------------
diff --git a/release/publish_candidate.sh b/release/publish_candidate.sh
new file mode 100755
index 0000000..4a6d3a0
--- /dev/null
+++ b/release/publish_candidate.sh
@@ -0,0 +1,140 @@
+#!/bin/sh -e
+
+EMAIL_TPL=email/vote_release.txt
+
+if test -n "$1"; then
+    candidate_dir=$1
+else
+	echo "error: no candidate directory"
+    exit
+fi
+
+if test -n "$2"; then
+    version=$2
+else
+	echo "error: no version"
+    exit
+fi
+
+if test -n "$3"; then
+    candidate=$3
+else
+	echo "error: no candidate number"
+    exit
+fi
+
+log () {
+    printf "\033[1;31m$1\033[0m\n"
+}
+
+basename=`basename $0`
+
+log "Creating temporary directory..."
+
+tmp_dir=`mktemp -d /tmp/$basename.XXXXXX` || exit 1
+
+echo $tmp_dir
+
+build_file=build.mk
+
+cat > $build_file <<EOF
+# SVN_URL=https://dist.apache.org/repos/dist/dev/couchdb
+
+SVN_URL=https://svn.apache.org/repos/asf/couchdb/site/test
+
+TMP_DIR=$tmp_dir
+
+SVN_DIR=\$(TMP_DIR)/svn
+
+EMAIL_TPL=$EMAIL_TPL
+
+EMAIL_FILE=\$(TMP_DIR)/email.txt
+
+VERSION=$version
+
+CANDIDATE=$candidate
+
+CANDIDATE_DIR=$candidate_dir
+
+CANDIDATE_URL=\$(SVN_URL)/source/\$(VERSION)/rc.\$(CANDIDATE)
+
+PACKAGE=apache-couchdb-\$(VERSION)
+
+CANDIDATE_TGZ_FILE=\$(CANDIDATE_DIR)/\$(PACKAGE).tar.gz
+
+SVN_TGZ_FILE=\$(SVN_DIR)/\$(PACKAGE).tar.gz
+
+COMMIT_MSG_DIR="Add \$(VERSION) rc.\$(CANDIDATE) dir"
+
+COMMIT_MSG_FILES="Add \$(VERSION) rc.\$(CANDIDATE) files"
+
+GPG=gpg --armor --detach-sig \$(GPG_ARGS)
+
+all: checkin
+
+checkin: sign
+	cd \$(SVN_DIR) && svn add \$(SVN_TGZ_FILE)
+	cd \$(SVN_DIR) && svn add \$(SVN_TGZ_FILE).asc
+	cd \$(SVN_DIR) && svn add \$(SVN_TGZ_FILE).ish
+	cd \$(SVN_DIR) && svn add \$(SVN_TGZ_FILE).md5
+	cd \$(SVN_DIR) && svn add \$(SVN_TGZ_FILE).sha
+	cd \$(SVN_DIR) && svn status
+	sleep 10
+	cd \$(SVN_DIR) && svn ci -m \$(COMMIT_MSG_FILES)
+
+sign: copy
+	\$(GPG) < \$(SVN_TGZ_FILE) > \$(SVN_TGZ_FILE).asc
+	md5sum \$(SVN_TGZ_FILE) > \$(SVN_TGZ_FILE).md5
+	sha1sum \$(SVN_TGZ_FILE) > \$(SVN_TGZ_FILE).sha
+
+copy: check
+	cp \$(CANDIDATE_TGZ_FILE) \$(SVN_TGZ_FILE)
+	cp \$(CANDIDATE_TGZ_FILE).ish \$(SVN_TGZ_FILE).ish
+
+check: \$(SVN_DIR)
+	test -s \$(CANDIDATE_TGZ_FILE)
+	test -s \$(CANDIDATE_TGZ_FILE).ish
+
+\$(SVN_DIR):
+	svn mkdir --parents \$(CANDIDATE_URL) -m \$(COMMIT_MSG_DIR)
+	sleep 10
+	svn co \$(CANDIDATE_URL) \$@
+
+email: \$(EMAIL_FILE)
+	cat \$(EMAIL_FILE)
+
+\$(EMAIL_FILE): \$(EMAIL_TPL)
+	sed -e "s|%version%|\$(VERSION)|g" \
+	    -e "s|%candidate%|\$(CANDIDATE)|g"  \
+	    -e "s|%candidate_url%|\$(CANDIDATE_URL)|g" \
+	    -e "s|%package%|\$(PACKAGE)|g" > \
+	    \$@ < \$<
+EOF
+
+log "Checking candidate into Subversion..."
+
+make -f $build_file
+
+log "Generating email template..."
+
+make -f $build_file email
+
+email_file=$tmp_dir/email.txt
+
+echo "Email text written to:" $email_file
+
+if test -n `which pbcopy`; then
+    cat $email_file | pbcopy && copied=1
+elif test -n `which xclip`; then
+    cat $email_file | xclip -selection c && copied=1
+elif test -n `which clip`; then
+    cat $email_file | clip && copied=1
+fi
+
+if test -n "$copied"; then
+    echo "Copied to your clipboard..."
+fi
+
+echo "Send the email to: dev@couchdb.apache.org"
+
+echo "Files in $tmp_dir"