1#!/bin/sh
2# $FreeBSD$
3#
4# Usage: cd /usr/src/contrib/jemalloc
5#        ./FREEBSD-upgrade <command> [args]
6#
7# At least the following ports are required when importing jemalloc:
8# - devel/autoconf
9# - devel/git
10# - devel/gmake
11# - textproc/docbook-xsl
12# - textproc/libxslt
13#
14# The normal workflow for importing a new release is:
15#
16#   cd /usr/src/contrib/jemalloc
17#
18# Merge local changes that were made since the previous import:
19#
20#   ./FREEBSD-upgrade merge-changes
21#   ./FREEBSD-upgrade rediff
22#
23# Extract latest jemalloc release.
24#
25#   ./FREEBSD-upgrade extract <rev>
26#
27# Fix patch conflicts as necessary, then regenerate diffs to update line
28# offsets:
29#
30#   ./FREEBSD-upgrade rediff
31#   ./FREEBSD-upgrade extract <rev>
32#
33# Do multiple buildworld/installworld rounds.  If problems arise and patches
34# are needed, edit the code in ${work} as necessary, then:
35#
36#   ./FREEBSD-upgrade rediff
37#   ./FREEBSD-upgrade extract <rev>
38#
39# The rediff/extract order is important because rediff saves the local
40# changes, then extract blows away the work tree and re-creates it with the
41# diffs applied.
42#
43# Finally, to clean up:
44#
45#  ./FREEBSD-upgrade clean
46
47set -e
48set -x
49
50if [ ! -x "FREEBSD-upgrade" ] ; then
51  echo "Run from within src/contrib/jemalloc/" >&2
52  exit 1
53fi
54
55if [ "x${JEMALLOC_REPO}" = "x" ] ; then
56  JEMALLOC_REPO=https://github.com/jemalloc/jemalloc.git
57fi
58
59src=`pwd`
60
61jemalloc_tmp="jemalloc.tmp"
62tmpdir="${src}/../${jemalloc_tmp}"
63bare_repo="${tmpdir}/jemalloc_bare.git"
64work="jemalloc_work.git"
65work_repo="${tmpdir}/${work}"
66namespace_repo="${tmpdir}/jemalloc_namespace.git"
67changes="${src}/FREEBSD-changes"
68
69do_fetch() {
70  local rev=$1
71  if [ ! -d "${bare_repo}" ] ; then
72    mkdir -p "${bare_repo}"
73    git clone --bare ${JEMALLOC_REPO} ${bare_repo}
74  fi
75  (
76    cd ${bare_repo}
77    git fetch origin ${rev}
78  )
79}
80
81do_extract_helper() {
82  local rev=$1
83  local repo=$2
84  do_fetch ${rev}
85  rm -rf ${repo}
86  git clone ${bare_repo} ${repo}
87  (
88    cd ${repo}
89    if [ "x${rev}" != "x" ] ; then
90      # Use optional rev argument to check out a revision other than HEAD on
91      # master.
92      git checkout ${rev}
93    fi
94  )
95}
96
97do_autogen() {
98  ./autogen.sh --enable-xmalloc --enable-utrace \
99    --with-malloc-conf=abort_conf:false \
100    --with-xslroot=/usr/local/share/xsl/docbook --with-private-namespace=__ \
101    --with-lg-page-sizes=12,13,14,16
102}
103
104do_extract_diff() {
105  local rev=$1
106  local repo=$2
107  do_extract_helper ${rev} ${repo}
108  (
109    cd ${repo}
110    # Apply diffs before generating files.
111    patch -p1 < "${src}/FREEBSD-diffs"
112    find . -name '*.orig' -delete
113    # Generate files.
114    do_autogen
115    gmake dist
116  )
117}
118
119do_extract_namespace() {
120  local rev=$1
121  local repo=$2
122  do_extract_helper ${rev} ${repo}
123  (
124    cd ${repo}
125    # Generate files.
126    do_autogen
127    gmake include/jemalloc/internal/private_namespace.h
128  )
129}
130
131do_extract() {
132  local rev=$1
133  do_fetch ${rev}
134  do_extract_diff ${rev} ${work_repo}
135  do_extract_namespace ${rev} ${namespace_repo}
136}
137
138do_diff() {
139  (
140    cd ${work_repo}
141    find . -name '*.orig' -delete
142    find . -name '*.rej' -delete
143    git add -A
144    git diff --cached
145  ) > FREEBSD-diffs
146}
147
148command=$1
149shift
150case "${command}" in
151  merge-changes) # Merge local changes that were made since the previous import.
152    rev=`cat VERSION |tr 'g' ' ' |awk '{print $2}'`
153    # Extract code corresponding to most recent import.
154    do_extract ${rev}
155    # Compute local differences to the upstream+patches and apply them.
156    (
157      cd ${tmpdir}
158      diff -ru -X ${src}/FREEBSD-Xlist ${work} ../jemalloc > ${changes} || true
159    )
160    (
161      cd ${work_repo}
162      patch -p1 < ${changes} || true
163      find . -name '*.orig' -delete
164    )
165    # Update diff.
166    do_diff
167    ;;
168  extract) # Extract upstream sources, apply patches, copy to contrib/jemalloc.
169    rev=$1
170    do_extract ${rev}
171    # Delete existing files so that cruft doesn't silently remain.
172    rm -rf ChangeLog COPYING VERSION doc include src
173    # Copy files over.
174    tar cf - -C ${work_repo} -X FREEBSD-Xlist . |tar xvf -
175    internal_dir="include/jemalloc/internal"
176    grep -v ' isthreaded ' \
177      "${namespace_repo}/${internal_dir}/private_namespace.h" \
178      > "${internal_dir}/private_namespace.h"
179    ;;
180  rediff) # Regenerate diffs based on working tree.
181    do_diff
182    ;;
183  clean) # Remove working tree and temporary files.
184    rm -rf ${tmpdir} ${changes}
185    ;;
186  *)
187    echo "Unsupported command: \"${command}\"" >&2
188    exit 1
189    ;;
190esac
191