/[gentoo-x86]/eclass/bzr.eclass
Gentoo

Diff of /eclass/bzr.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.1 Revision 1.15
1# Copyright 1999-2008 Gentoo Foundation 1# Copyright 1999-2011 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/bzr.eclass,v 1.1 2008/10/25 12:17:23 ulm Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/bzr.eclass,v 1.15 2011/07/26 23:22:35 ulm Exp $
4# 4#
5# @ECLASS: bzr.eclass 5# @ECLASS: bzr.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# Jorge Manuel B. S. Vicetto <jmbsvicetto@gentoo.org>, 7# Jorge Manuel B. S. Vicetto <jmbsvicetto@gentoo.org>,
8# Ulrich Mueller <ulm@gentoo.org>, 8# Ulrich MΓΌller <ulm@gentoo.org>,
9# Christian Faulhammer <fauli@gentoo.org>,
10# Mark Lee <bzr-gentoo-overlay@lazymalevolence.com>,
9# and anyone who wants to help 11# and anyone who wants to help
10# @BLURB: This eclass provides support to use the Bazaar DSCM 12# @BLURB: generic fetching functions for the Bazaar VCS
11# @DESCRIPTION: 13# @DESCRIPTION:
12# The bzr.eclass provides support for apps using the bazaar DSCM 14# The bzr.eclass provides functions to fetch, unpack, patch, and
13# (distributed source control management system). 15# bootstrap sources from repositories of the Bazaar distributed version
14# The eclass was originally derived from the git eclass. 16# control system. The eclass was originally derived from git.eclass.
15# 17#
16# Note: Just set EBZR_REPO_URI to the url of the branch and the src_unpack 18# Note: Just set EBZR_REPO_URI to the URI of the branch and src_unpack()
17# this eclass provides will put an export of the branch in ${WORKDIR}/${PN}. 19# of this eclass will export the branch to ${WORKDIR}/${P}.
18 20
19inherit eutils 21inherit eutils
20 22
21EBZR="bzr.eclass" 23EBZR="bzr.eclass"
22 24
25case "${EAPI:-0}" in
23EXPORT_FUNCTIONS src_unpack 26 0|1) EXPORT_FUNCTIONS src_unpack ;;
27 *) EXPORT_FUNCTIONS src_unpack src_prepare ;;
28esac
24 29
25HOMEPAGE="http://bazaar-vcs.org/" 30HOMEPAGE="http://bazaar-vcs.org/"
26DESCRIPTION="Based on the ${EBZR} eclass" 31DESCRIPTION="Based on the ${EBZR} eclass"
27 32
28DEPEND=">=dev-util/bzr-1.5" 33DEPEND=">=dev-vcs/bzr-2.0.1"
34case "${EAPI:-0}" in
35 0|1) ;;
36 *) [[ ${EBZR_REPO_URI%%:*} = sftp ]] \
37 && DEPEND=">=dev-vcs/bzr-2.0.1[sftp]" ;;
38esac
29 39
30# @ECLASS-VARIABLE: EBZR_STORE_DIR 40# @ECLASS-VARIABLE: EBZR_STORE_DIR
31# @DESCRIPTION: 41# @DESCRIPTION:
32# The dir to store the bzr sources. 42# The directory to store all fetched Bazaar live sources.
33EBZR_STORE_DIR="${PORTAGE_ACTUAL_DISTDIR-${DISTDIR}}/bzr-src" 43: ${EBZR_STORE_DIR:=${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}/bzr-src}
44
45# @ECLASS-VARIABLE: EBZR_INIT_REPO_CMD
46# @DESCRIPTION:
47# The Bazaar command to initialise a shared repository.
48: ${EBZR_INIT_REPO_CMD:="bzr init-repository --no-trees"}
34 49
35# @ECLASS-VARIABLE: EBZR_FETCH_CMD 50# @ECLASS-VARIABLE: EBZR_FETCH_CMD
36# @DESCRIPTION: 51# @DESCRIPTION:
37# The bzr command to fetch the sources. 52# The Bazaar command to fetch the sources.
38EBZR_FETCH_CMD="bzr branch" 53: ${EBZR_FETCH_CMD:="bzr branch --no-tree"}
39 54
40# @ECLASS-VARIABLE: EBZR_UPDATE_CMD 55# @ECLASS-VARIABLE: EBZR_UPDATE_CMD
41# @DESCRIPTION: 56# @DESCRIPTION:
42# The bzr command to update the sources. 57# The Bazaar command to update the sources.
43EBZR_UPDATE_CMD="bzr pull" 58: ${EBZR_UPDATE_CMD:="bzr pull"}
44
45# @ECLASS-VARIABLE: EBZR_DIFFSTAT_CMD
46# @DESCRIPTION:
47# The bzr command to get the diffstat output.
48EBZR_DIFFSTAT_CMD="bzr diff"
49 59
50# @ECLASS-VARIABLE: EBZR_EXPORT_CMD 60# @ECLASS-VARIABLE: EBZR_EXPORT_CMD
51# @DESCRIPTION: 61# @DESCRIPTION:
52# The bzr command to export a branch. 62# The Bazaar command to export a branch.
53EBZR_EXPORT_CMD="bzr export" 63: ${EBZR_EXPORT_CMD:="bzr export"}
54 64
55# @ECLASS-VARIABLE: EBZR_REVNO_CMD 65# @ECLASS-VARIABLE: EBZR_REVNO_CMD
56# @DESCRIPTION: 66# @DESCRIPTION:
57# The bzr command to list revision number of the branch. 67# The Bazaar command to list a revision number of the branch.
58EBZR_REVNO_CMD="bzr revno" 68: ${EBZR_REVNO_CMD:="bzr revno"}
59 69
60# @ECLASS-VARIABLE: EBZR_OPTIONS 70# @ECLASS-VARIABLE: EBZR_OPTIONS
71# @DEFAULT_UNSET
61# @DESCRIPTION: 72# @DESCRIPTION:
62# The options passed to the fetch and update commands. 73# The options passed to the fetch and update commands.
63EBZR_OPTIONS="${EBZR_OPTIONS:-}"
64 74
65# @ECLASS-VARIABLE: EBZR_REPO_URI 75# @ECLASS-VARIABLE: EBZR_REPO_URI
76# @DEFAULT_UNSET
77# @REQUIRED
66# @DESCRIPTION: 78# @DESCRIPTION:
67# The repository uri for the source package. 79# The repository URI for the source package.
68# 80#
69# @CODE 81# Note: If the ebuild uses an sftp:// URI, then in EAPI 0 or 1 it must
70# Supported protocols: 82# make sure that dev-vcs/bzr was built with USE="sftp". In EAPI 2 or
71# - http:// 83# later, the eclass will depend on dev-vcs/bzr[sftp].
72# - https:// 84
73# - sftp:// 85# @ECLASS-VARIABLE: EBZR_INITIAL_URI
74# - rsync:// 86# @DEFAULT_UNSET
75# - lp:// 87# @DESCRIPTION:
76# @CODE 88# The URI used for initial branching of the source repository. If this
89# variable is set, the initial branch will be cloned from the location
90# specified, followed by a pull from ${EBZR_REPO_URI}. This is intended
91# for special cases, e.g. when download from the original repository is
92# slow, but a fast mirror exists but may be out of date.
77# 93#
78# Note: lp = https://launchpad.net 94# Normally, this variable needs not be set.
79EBZR_REPO_URI="${EBZR_REPO_URI:-}"
80 95
81# @ECLASS-VARIABLE: EBZR_BOOTSTRAP 96# @ECLASS-VARIABLE: EBZR_BOOTSTRAP
97# @DEFAULT_UNSET
82# @DESCRIPTION: 98# @DESCRIPTION:
83# Bootstrap script or command like autogen.sh or etc. 99# Bootstrap script or command like autogen.sh or etc.
84EBZR_BOOTSTRAP="${EBZR_BOOTSTRAP:-}"
85 100
86# @ECLASS-VARIABLE: EBZR_PATCHES 101# @ECLASS-VARIABLE: EBZR_PATCHES
102# @DEFAULT_UNSET
87# @DESCRIPTION: 103# @DESCRIPTION:
88# bzr eclass can apply patches in bzr_bootstrap(). 104# bzr.eclass can apply patches in bzr_bootstrap(). You can use regular
89# you can use regexp in this valiable like *.diff or *.patch or etc. 105# expressions in this variable like *.diff or *.patch and the like.
90# NOTE: this patches will applied before EBZR_BOOTSTRAP is processed. 106# Note: These patches will be applied before EBZR_BOOTSTRAP is processed.
91# 107#
92# Patches are searched both in ${PWD} and ${FILESDIR}, if not found in either 108# Patches are searched both in ${PWD} and ${FILESDIR}. If not found in
93# location, the installation dies. 109# either location, the installation dies.
94EBZR_PATCHES="${EBZR_PATCHES:-}" 110
111# @ECLASS-VARIABLE: EBZR_PROJECT
112# @DESCRIPTION:
113# The project name of your ebuild. Normally, the branch will be stored
114# in the ${EBZR_STORE_DIR}/${EBZR_PROJECT} directory.
115#
116# If EBZR_BRANCH is set (see below), then a shared repository will be
117# created in that directory, and the branch will be located in
118# ${EBZR_STORE_DIR}/${EBZR_PROJECT}/${EBZR_BRANCH}.
119: ${EBZR_PROJECT:=${PN}}
95 120
96# @ECLASS-VARIABLE: EBZR_BRANCH 121# @ECLASS-VARIABLE: EBZR_BRANCH
122# @DEFAULT_UNSET
97# @DESCRIPTION: 123# @DESCRIPTION:
98# The branch to fetch in bzr_fetch(). 124# The directory where to store the branch within a shared repository,
125# relative to ${EBZR_STORE_DIR}/${EBZR_PROJECT}.
99# 126#
100# default: trunk 127# This variable should be set if there are several live ebuilds for
101EBZR_BRANCH="${EBZR_BRANCH:-trunk}" 128# different branches of the same upstream project. The branches can
129# then share the same repository in EBZR_PROJECT, which will save both
130# data traffic volume and disk space.
131#
132# If there is only a live ebuild for one single branch, EBZR_BRANCH
133# needs not be set. In this case, the branch will be stored in a
134# stand-alone repository directly in EBZR_PROJECT.
102 135
103# @ECLASS-VARIABLE: EBZR_REVISION 136# @ECLASS-VARIABLE: EBZR_REVISION
137# @DEFAULT_UNSET
104# @DESCRIPTION: 138# @DESCRIPTION:
105# Revision to get, if not latest (see http://bazaar-vcs.org/BzrRevisionSpec) 139# Revision to fetch, defaults to the latest
106EBZR_REVISION="${EBZR_REVISION:-}" 140# (see http://bazaar-vcs.org/BzrRevisionSpec or bzr help revisionspec).
107 141
108# @ECLASS-VARIABLE: EBZR_CACHE_DIR 142# @ECLASS-VARIABLE: EBZR_OFFLINE
109# @DESCRIPTION: 143# @DESCRIPTION:
110# The dir to store the source for the package, relative to EBZR_STORE_DIR. 144# Set this variable to a non-empty value to disable automatic updating
111# 145# of a bzr source tree. This is intended to be set outside the ebuild
112# default: ${PN} 146# by users.
113EBZR_CACHE_DIR="${EBZR_CACHE_DIR:-${PN}}" 147: ${EBZR_OFFLINE=${EVCS_OFFLINE}}
114 148
115# @FUNCTION: bzr_fetch 149# @FUNCTION: bzr_initial_fetch
150# @USAGE: <repository URI> <branch directory>
116# @DESCRIPTION: 151# @DESCRIPTION:
117# Wrapper function to fetch sources from bazaar via bzr fetch or bzr update, 152# Internal function, retrieves the source code from a repository for the
118# depending on whether there is an existing working copy in ${EBZR_BRANCH_DIR}. 153# first time, using ${EBZR_FETCH_CMD}.
119bzr_fetch() { 154bzr_initial_fetch() {
120 local EBZR_BRANCH_DIR 155 local repo_uri=$1 branch_dir=$2
121 156
122 # EBZR_REPO_URI is empty. 157 if [[ -n "${EBZR_OFFLINE}" ]]; then
123 [[ ${EBZR_REPO_URI} ]] || die "${EBZR}: EBZR_REPO_URI is empty." 158 ewarn "EBZR_OFFLINE cannot be used when there is no local branch yet."
124
125 # check for the protocol or pull from a local repo.
126 if [[ -z ${EBZR_REPO_URI%%:*} ]] ; then
127 case ${EBZR_REPO_URI%%:*} in
128 # lp:// is https://launchpad.net
129 http|https|rsync|sftp|lp)
130 ;;
131 *)
132 die "${EBZR}: fetch from ${EBZR_REPO_URI%:*} is not yet implemented."
133 ;;
134 esac
135 fi 159 fi
136 160
137 if [[ ! -d ${EBZR_STORE_DIR} ]] ; then
138 debug-print "${FUNCNAME}: initial branch. creating bzr directory"
139 addwrite /
140 mkdir -p "${EBZR_STORE_DIR}" \
141 || die "${EBZR}: can't mkdir ${EBZR_STORE_DIR}."
142 export SANDBOX_WRITE="${SANDBOX_WRITE%%:/}"
143 fi
144
145 cd -P "${EBZR_STORE_DIR}" || die "${EBZR}: can't chdir to ${EBZR_STORE_DIR}"
146
147 EBZR_BRANCH_DIR="${EBZR_STORE_DIR}/${EBZR_CACHE_DIR}"
148
149 addwrite "${EBZR_STORE_DIR}"
150 addwrite "${EBZR_BRANCH_DIR}"
151
152 debug-print "${FUNCNAME}: EBZR_OPTIONS = ${EBZR_OPTIONS}"
153
154 local repository
155
156 if [[ ${EBZR_REPO_URI} == */* ]]; then
157 repository="${EBZR_REPO_URI}${EBZR_BRANCH}"
158 else
159 repository="${EBZR_REPO_URI}"
160 fi
161
162 if [[ ! -d ${EBZR_BRANCH_DIR} ]] ; then
163 # fetch branch 161 # fetch branch
164 einfo "bzr branch start -->" 162 einfo "bzr branch start -->"
165 einfo " repository: ${repository} => ${EBZR_BRANCH_DIR}" 163 einfo " repository: ${repo_uri} => ${branch_dir}"
166 164
167 ${EBZR_FETCH_CMD} ${EBZR_OPTIONS} "${repository}" "${EBZR_BRANCH_DIR}" \ 165 ${EBZR_FETCH_CMD} ${EBZR_OPTIONS} "${repo_uri}" "${branch_dir}" \
168 || die "${EBZR}: can't branch from ${repository}." 166 || die "${EBZR}: can't branch from ${repo_uri}"
167}
169 168
169# @FUNCTION: bzr_update
170# @USAGE: <repository URI> <branch directory>
171# @DESCRIPTION:
172# Internal function, updates the source code from a repository, using
173# ${EBZR_UPDATE_CMD}.
174bzr_update() {
175 local repo_uri=$1 branch_dir=$2
176
177 if [[ -n "${EBZR_OFFLINE}" ]]; then
178 einfo "skipping bzr pull -->"
179 einfo " repository: ${repo_uri}"
170 else 180 else
171 # update branch 181 # update branch
172 einfo "bzr pull start -->" 182 einfo "bzr pull start -->"
173 einfo " repository: ${repository}" 183 einfo " repository: ${repo_uri}"
174 184
175 cd "${EBZR_BRANCH_DIR}" 185 pushd "${branch_dir}" > /dev/null \
186 || die "${EBZR}: can't chdir to ${branch_dir}"
176 ${EBZR_UPDATE_CMD} ${EBZR_OPTIONS} "${repository}" \ 187 ${EBZR_UPDATE_CMD} ${EBZR_OPTIONS} "${repo_uri}" \
177 || die "${EBZR}: can't merge from ${repository}." 188 || die "${EBZR}: can't pull from ${repo_uri}"
178 ${EBZR_DIFFSTAT_CMD} 189 popd > /dev/null
190 fi
191}
192
193# @FUNCTION: bzr_fetch
194# @DESCRIPTION:
195# Wrapper function to fetch sources from a Bazaar repository with
196# bzr branch or bzr pull, depending on whether there is an existing
197# working copy.
198bzr_fetch() {
199 local repo_dir branch_dir
200
201 [[ -n ${EBZR_REPO_URI} ]] || die "${EBZR}: EBZR_REPO_URI is empty"
202
203 if [[ ! -d ${EBZR_STORE_DIR} ]] ; then
204 local save_sandbox_write=${SANDBOX_WRITE}
205 addwrite /
206 mkdir -p "${EBZR_STORE_DIR}" \
207 || die "${EBZR}: can't mkdir ${EBZR_STORE_DIR}"
208 SANDBOX_WRITE=${save_sandbox_write}
209 fi
210
211 pushd "${EBZR_STORE_DIR}" > /dev/null \
212 || die "${EBZR}: can't chdir to ${EBZR_STORE_DIR}"
213
214 repo_dir=${EBZR_STORE_DIR}/${EBZR_PROJECT}
215 branch_dir=${repo_dir}${EBZR_BRANCH:+/${EBZR_BRANCH}}
216
217 addwrite "${EBZR_STORE_DIR}"
218
219 # Clean up if the existing local copy is a checkout (as was the case
220 # with an older version of bzr.eclass).
221 # This test can be removed after 1 Mar 2012.
222 if [[ ${EBZR_FETCH_CMD} != *checkout* && -d ${repo_dir}/.bzr/checkout ]]
223 then
224 local tmpname=$(mktemp -u "${repo_dir}._old_.XXXXXX")
225 ewarn "checkout from old version of ${EBZR} found, moving it to:"
226 ewarn "${tmpname}"
227 ewarn "you may manually remove it"
228 mv "${repo_dir}" "${tmpname}" \
229 || die "${EBZR}: can't move old checkout out of the way"
230 fi
231
232 if [[ ! -d ${branch_dir}/.bzr ]]; then
233 if [[ ${repo_dir} != "${branch_dir}" && ! -d ${repo_dir}/.bzr ]]; then
234 einfo "creating shared bzr repository"
235 ${EBZR_INIT_REPO_CMD} "${repo_dir}" \
236 || die "${EBZR}: can't create shared repository"
179 fi 237 fi
180 238
181 cd "${EBZR_BRANCH_DIR}" 239 if [[ -z ${EBZR_INITIAL_URI} ]]; then
240 bzr_initial_fetch "${EBZR_REPO_URI}" "${branch_dir}"
241 else
242 # Workaround for faster initial download. This clones the
243 # branch from a fast server (which may be out of date), and
244 # subsequently pulls from the slow original repository.
245 bzr_initial_fetch "${EBZR_INITIAL_URI}" "${branch_dir}"
246 if [[ ${EBZR_REPO_URI} != "${EBZR_INITIAL_URI}" ]]; then
247 EBZR_UPDATE_CMD="${EBZR_UPDATE_CMD} --remember --overwrite" \
248 EBZR_OFFLINE="" \
249 bzr_update "${EBZR_REPO_URI}" "${branch_dir}"
250 fi
251 fi
252 else
253 bzr_update "${EBZR_REPO_URI}" "${branch_dir}"
254 fi
255
256 cd "${branch_dir}" || die "${EBZR}: can't chdir to ${branch_dir}"
257
258 # Save revision number in environment. #311101
259 export EBZR_REVNO=$(${EBZR_REVNO_CMD})
182 260
183 einfo "exporting ..." 261 einfo "exporting ..."
184 ${EBZR_EXPORT_CMD} ${EBZR_REVISION:+-r ${EBZR_REVISION}} "${WORKDIR}/${P}" \ 262 ${EBZR_EXPORT_CMD} ${EBZR_REVISION:+-r ${EBZR_REVISION}} \
185 || die "${EBZR}: export failed" 263 "${WORKDIR}/${P}" . || die "${EBZR}: export failed"
264 einfo "revision ${EBZR_REVISION:-${EBZR_REVNO}} is now in ${WORKDIR}/${P}"
186 265
187 local revision 266 popd > /dev/null
188 if [[ -n "${EBZR_REVISION}" ]]; then
189 revision="${EBZR_REVISION}"
190 else
191 revision=$(${EBZR_REVNO_CMD} "${EBZR_BRANCH_DIR}")
192 fi
193
194 einfo "Revision ${revision} is now in ${WORKDIR}/${P}"
195
196 cd "${WORKDIR}"
197} 267}
198 268
199# @FUNCTION: bzr_bootstrap 269# @FUNCTION: bzr_bootstrap
200# @DESCRIPTION: 270# @DESCRIPTION:
201# Apply patches in ${EBZR_PATCHES} and run ${EBZR_BOOTSTRAP} if specified 271# Apply patches in ${EBZR_PATCHES} and run ${EBZR_BOOTSTRAP} if specified.
202bzr_bootstrap() { 272bzr_bootstrap() {
203 local patch lpatch 273 local patch lpatch
204 274
205 cd "${S}" 275 pushd "${S}" > /dev/null || die "${EBZR}: can't chdir to ${S}"
206 276
207 if [[ -n ${EBZR_PATCHES} ]] ; then 277 if [[ -n ${EBZR_PATCHES} ]] ; then
208 einfo "apply patches -->" 278 einfo "apply patches -->"
209 279
210 for patch in ${EBZR_PATCHES} ; do 280 for patch in ${EBZR_PATCHES} ; do
211 if [[ -f ${patch} ]] ; then 281 if [[ -f ${patch} ]] ; then
212 epatch ${patch} 282 epatch ${patch}
213 else 283 else
284 # This loop takes care of wildcarded patches given via
285 # EBZR_PATCHES in an ebuild
214 for lpatch in "${FILESDIR}"/${patch} ; do 286 for lpatch in "${FILESDIR}"/${patch} ; do
215 if [[ -f ${lpatch} ]] ; then 287 if [[ -f ${lpatch} ]] ; then
216 epatch ${lpatch} 288 epatch ${lpatch}
217 else 289 else
218 die "${EBZR}: ${patch} is not found" 290 die "${EBZR}: ${patch} is not found"
226 einfo "begin bootstrap -->" 298 einfo "begin bootstrap -->"
227 299
228 if [[ -f ${EBZR_BOOTSTRAP} ]] && [[ -x ${EBZR_BOOTSTRAP} ]] ; then 300 if [[ -f ${EBZR_BOOTSTRAP} ]] && [[ -x ${EBZR_BOOTSTRAP} ]] ; then
229 einfo " bootstrap with a file: ${EBZR_BOOTSTRAP}" 301 einfo " bootstrap with a file: ${EBZR_BOOTSTRAP}"
230 "./${EBZR_BOOTSTRAP}" \ 302 "./${EBZR_BOOTSTRAP}" \
231 || die "${EBZR}: can't execute EBZR_BOOTSTRAP." 303 || die "${EBZR}: can't execute EBZR_BOOTSTRAP"
232 else 304 else
233 einfo " bootstrap with commands: ${EBZR_BOOTSTRAP}" 305 einfo " bootstrap with commands: ${EBZR_BOOTSTRAP}"
234 "${EBZR_BOOTSTRAP}" \ 306 "${EBZR_BOOTSTRAP}" \
235 || die "${EBZR}: can't eval EBZR_BOOTSTRAP." 307 || die "${EBZR}: can't eval EBZR_BOOTSTRAP"
236 fi 308 fi
237 fi 309 fi
310
311 popd > /dev/null
238} 312}
239 313
240# @FUNCTION: bzr_src_unpack 314# @FUNCTION: bzr_src_unpack
241# @DESCRIPTION: 315# @DESCRIPTION:
242# default src_unpack. fetch and bootstrap. 316# Default src_unpack(), calls bzr_fetch. For EAPIs 0 and 1, also calls
317# bzr_src_prepare.
243bzr_src_unpack() { 318bzr_src_unpack() {
244 bzr_fetch || die "${EBZR}: unknown problem in bzr_fetch()." 319 bzr_fetch
245 bzr_bootstrap || die "${EBZR}: unknown problem in bzr_bootstrap()." 320 case "${EAPI:-0}" in
321 0|1) bzr_src_prepare ;;
322 esac
246} 323}
324
325# @FUNCTION: bzr_src_prepare
326# @DESCRIPTION:
327# Default src_prepare(), calls bzr_bootstrap.
328bzr_src_prepare() {
329 bzr_bootstrap
330}

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.15

  ViewVC Help
Powered by ViewVC 1.1.20