summaryrefslogtreecommitdiff
blob: 974a6f5ac1330a48a5f0adff012541d3f024e0fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# Copyright 1999-2000 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License v2
# Author Dan Armak <danarmak@gentoo.org>
# $Header: /var/cvsroot/gentoo-x86/eclass/cvs.eclass,v 1.28 2002/11/30 19:44:18 danarmak Exp $
# This eclass provides the generic cvs fetching functions.

ECLASS=cvs
INHERITED="$INHERITED $ECLASS"

# You shouldn't change these settings yourself! The ebuild/eclass inheriting this eclass
# will take care of that. If you want to set the global KDE cvs ebuilds' settings,
# see the comments in kde-source.eclass.

# --- begin ebuild-configurable settings

# cvs command to run. you can set fex. "cvs -t" for extensive debug information
# on the cvs onnection. the default of "cvs -q -f -z4" means to be quiet, to disregard
# the ~/.cvsrc config file and to use maximum compression.
[ -z "$ECVS_CVS_COMMAND" ] && ECVS_CVS_COMMAND="cvs -q -f -z4"

# cvs options given after the command (i.e. cvs update foo)
# don't remove -dP or things won't work
[ -z "$ECVS_CVS_OPTIONS" ] && ECVS_CVS_OPTIONS="-dP"

# set this for the module/subdir to be fetched non-recursively
#[ -n "$ECVS_LOCAL" ] && ECVS_CVS_OPTIONS="$ECVS_CVS_OPTIONS -l"

# Where the cvs modules are stored/accessed
[ -z "$ECVS_TOP_DIR" ] && ECVS_TOP_DIR="${DISTDIR}/cvs-src"

# Name of cvs server, set to "offline" to disable fetching
# (i.e. to assume module is checked out already and don't update it).
# Format is server:/dir e.g. "anoncvs.kde.org:/home/kde". remove the other
# parts of the full CVSROOT (which looks like
# ":pserver:anonymous@anoncvs.kde.org:/home/kde"); these are added from
# other settings
[ -z "$ECVS_SERVER" ] && ECVS_SERVER="offline"

# Anonymous cvs login?
# if 'yes' uses :pserver: with empty password, if 'no' uses :ext: with $ECVS_PASS, other values not allowed
[ -z "$ECVS_ANON" ] && ECVS_ANON="yes"

# Authentication method to use on ECVS_ANON="no" - possible values are "pserver" and "ext"
[ -z "$ECVS_AUTH" ] && ECVS_AUTH="ext"

# Use su to run cvs as user
[ -z "$ECVS_RUNAS" ] && ECVS_RUNAS="`whoami`"

# Username to use
[ -z "$ECVS_USER" ] && ECVS_USER="anonymous"

# Password to use if anonymous login is off
[ -z "$ECVS_PASS" ] && ECVS_PASS=""

# Module to be fetched, must be set explicitly -
# I don't like the former ="$PN" default setting
[ -z "$ECVS_MODULE" ] && debug-print "$ECLASS: error: ECVS_MODULE not set, cannot continue"

# Branch/tag to use, default is HEAD
# uncomment the following line to enable the reset-branch-to-HEAD behaviour
[ -z "$ECVS_BRANCH" ] && ECVS_BRANCH="HEAD"

# Subdirectory in module to be fetched, default is not defined = whole module
# DO NOT set default to "", if it's defined at all code will break!
# don't uncomment following line!
#[ -z "$ECVS_SUBDIR" ] && ECVS_SUBDIR=""

# --- end ebuild-configurable settings ---

# add cvs to deps
DEPEND="$DEPEND dev-util/cvs dev-python/pexpect"

# since we now longer have src_fetch as a redefinable ebuild function,
# we are forced to call this function from cvs_src_unpack
cvs_fetch() {

	debug-print-function $FUNCNAME $*

	debug-print "$FUNCNAME: init:
ECVS_CVS_COMMAND=$ECVS_CVS_COMMAND
ECVS_CVS_OPTIONS=$ECVS_CVS_OPTIONS
ECVS_TOP_DIR=$ECVS_TOP_DIR
ECVS_SERVER=$ECVS_SERVER
ECVS_ANON=$ECVS_ANON
ECVS_USER=$ECVS_USER
ECVS_PASS=$ECVS_PASS
ECS_MODULE=$ECVS_MODULE
ECVS_SUBDIR=$ECVS_SUBDIR
ECVS_LOCAL=$ECVS_LOCAL
DIR=$DIR"

	# a shorthand
	DIR="${ECVS_TOP_DIR}/${ECVS_MODULE}/${ECVS_SUBDIR}"
	debug-print "$FUNCNAME: now DIR=$DIR"

	if [ "$ECVS_SERVER" == "offline" ]; then
		# we're not required to fetch anything, the module already exists and shouldn't be updated
		if [ -d "$DIR" ]; then
			debug-print "$FUNCNAME: offline mode, exiting"
			return 0
		else
			einfo "ERROR: Offline mode specified, but module/subdir not found. Aborting."
			debug-print "$FUNCNAME: offline mode specified but module/subdir not found, exiting with error"
			return 1
		fi
	fi

	# create target directory as needed
	if [ ! -d "$DIR" ]; then
		debug-print "$FUNCNAME: creating cvs directory $DIR"
		#export SANDBOX_WRITE="$SANDBOX_WRITE:/foobar:/"
		addwrite /foobar
		addwrite /
		mkdir -p "/$DIR"
		export SANDBOX_WRITE="${SANDBOX_WRITE//:\/foobar:\/}"
	fi

	# in case ECVS_TOP_DIR is a symlink to a dir, get the real dir's path,
	# otherwise addwrite() doesn't work.
	cd -P "$ECVS_TOP_DIR" > /dev/null
	ECVS_TOP_DIR="`/bin/pwd`"
	DIR="${ECVS_TOP_DIR}/${ECVS_MODULE}/${ECVS_SUBDIR}"
	cd "$OLDPWD"
	
	debug-print "$FUNCNAME: now DIR=$DIR"
	
	# disable the sandbox for this dir
	# not just $DIR because we want to create moduletopdir/CVS too
	addwrite "$ECVS_TOP_DIR/$ECVS_MODULE"

	# add option for local (non-recursive) fetching
	[ -n "$ECVS_LOCAL" ] && ECVS_CVS_OPTIONS="$ECVS_CVS_OPTIONS -l"
	
	# prepare a cvspass file just for this session so that cvs thinks we're logged
	# in at the cvs server. we don't want to mess with ~/.cvspass.
	echo ":pserver:${ECVS_SERVER} A" > "${T}/cvspass"
	export CVS_PASSFILE="${T}/cvspass"
	chown $ECVS_RUNAS "${T}/cvspass"
	#export CVSROOT=:pserver:${ECVS_USER}@${ECVS_SERVER}
	
	# Note: cvs update and checkout commands are unified.
	# we make sure a CVS/ dir exists in our module subdir with the right
	# Root and Repository entries in it and cvs update.
	
	[ "${ECVS_ANON}" == "yes" ] && \
		newserver=":pserver:${ECVS_USER}@${ECVS_SERVER}" || \
		newserver=":${ECVS_AUTH}:${ECVS_USER}@${ECVS_SERVER}" 
		
	
	# CVS/Repository files can't (I think) contain two concatenated slashes
	if [ -n "$ECVS_SUBDIR" ]; then
		repository="${ECVS_MODULE}/${ECVS_SUBDIR}"
	else
		repository="${ECVS_MODULE}"
	fi
	
	debug-print "$FUNCNAME: Root<-$newserver, Repository<-$repository"
	debug-print "$FUNCNAME: entering directory $DIR"
	cd "/$DIR"
	
	if [ ! -d "CVS" ]; then
		# create a new CVS/ directory (checkout)
		debug-print "$FUNCNAME: creating new cvs directory"
		
		mkdir CVS
		echo $newserver > CVS/Root
		echo $repository > CVS/Repository
		touch CVS/Entries
		
		# if we're checking out a subdirectory only, create a CVS/ dir
		# in the module's top dir so that the user (and we) can cvs update
		# from there to get the full module.
		if [ ! -d "$ECVS_TOP_DIR/$ECVS_MODULE/CVS" ]; then
			debug-print "$FUNCNAME: Copying CVS/ directory to module top-level dir"
			cp -r CVS "$ECVS_TOP_DIR/$ECVS_MODULE/"
			echo $ECVS_MODULE > "$ECVS_TOP_DIR/$ECVS_MODULE/CVS/Repository"
		fi
		
	else
		#update existing module
		debug-print "$FUNCNAME: updating existing module/subdir"
		
		# Switch servers if needed
		# cvs keeps the server info in the CVS/Root file in every checked-out dir;
		# we can fix those files to point to the new server
		oldserver="`cat CVS/Root`"
		if [ "$newserver" != "$oldserver" ]; then

			einfo "Changing CVS server from $oldserver to $newserver:"
			debug-print "$FUNCNAME: Changing CVS server from $oldserver to $newserver:"

			einfo "Searching for CVS dirs..."
			cvsdirs="`find . -iname CVS -print`"
			debug-print "$FUNCNAME: CVS dirs found:"
			debug-print "$cvsdirs"

			einfo "Modifying CVS dirs..."
			for x in $cvsdirs; do
				debug-print "In $x"
				echo $newserver > "$x/Root"
			done

		fi

	fi

	# cvs auto-switches branches, how nice
	# warning: if we do it this way we get multiple -rX options - harmless i think
	[ -n "$ECVS_BRANCH" ] && ECVS_CVS_OPTIONS="$ECVS_CVS_OPTIONS -r$ECVS_BRANCH"

	# Chowning the directory
	if [ "${ECVS_RUNAS}" != "root" ]; then
		chown -R "$ECVS_RUNAS" "/$DIR"
	fi

	# finally run the cvs update command
	debug-print "$FUNCNAME: is in dir `/bin/pwd`"
	debug-print "$FUNCNAME: running $ECVS_CVS_COMMAND update $ECVS_CVS_OPTIONS with $ECVS_SERVER for module $ECVS_MODULE subdir $ECVS_SUBDIR"
	einfo "Running $ECVS_CVS_COMMAND update $ECVS_CVS_OPTIONS with $ECVS_SERVER for $ECVS_MODULE/$ECVS_SUBDIR..."

	if [ "${ECVS_ANON}" == "no" ]; then
	
		debug-print "$FUNCNAME: starting non-anonymous cvs login..."
		# CVS Login - written in python :: the right way ;)
		# Tilman Klar, <phoenix@gentoo.org>

		export CVS_RSH="/usr/bin/ssh"

############################## inline-python #####################################
/usr/bin/env python << EndOfFile

import pexpect,os

mypasswd  = "${ECVS_PASS}"
myauth    = "${ECVS_AUTH}"
mytimeout = 10

if myauth == "ext":
	mycommand = "su ${ECVS_RUNAS} -c \"${ECVS_CVS_COMMAND} update ${ECVS_CVS_OPTIONS}\""
	child = pexpect.spawn(mycommand)

	index = child.expect(['continue connecting','word:'], mytimeout)
	if index == 0:
		child.sendline('yes')
		## Added server to ~/.ssh/known_hosts
		child.expect('word:', mytimeout)
	else:
		## Server already is in ~/.ssh/known_hosts
		pass

	child.sendline(mypasswd)
	child.expect(pexpect.EOF)	

elif myauth == "pserver":
	mycommand = "su ${ECVS_RUNAS} -c \"cvs login\""
	child = pexpect.spawn(mycommand)
	child.expect("CVS password:",mytimeout)
	child.sendline(mypasswd)
	child.expect(pexpect.EOF)

	# Logged in - checking out
	os.system("su ${ECVS_RUNAS} -c \"${ECVS_CVS_COMMAND} update ${ECVS_CVS_OPTIONS}\" &> /dev/null")
EndOfFile
########################### End of inline-python ##################################
	else
		debug-print "$FUNCNAME: using anonymous cvs login"
		$ECVS_CVS_COMMAND update $ECVS_CVS_OPTIONS || die "died running cvs update"
	fi

	# log out and restore ownership
	su $ECVS_RUNAS -c "cvs logout" &> /dev/null
	chown `whoami` "${T}/cvspass"
}

cvs_src_unpack() {

	debug-print-function $FUNCNAME $*
	cvs_fetch || die "died running cvs_fetch"

	einfo "Copying $ECVS_MODULE/$ECVS_SUBDIR from $ECVS_TOP_DIR..."
	debug-print "Copying module $ECVS_MODULE subdir $ECVS_SUBDIR local_mode=$ECVS_LOCAL from $ECVS_TOP_DIR..."
	
	# probably redundant, but best to make sure
	mkdir -p "$WORKDIR/$ECVS_MODULE/$ECVS_SUBDIR"
	
	if [ -n "$ECVS_SUBDIR" ]; then
		if [ -n "$ECVS_LOCAL" ]; then
			cp -f "$ECVS_TOP_DIR/$ECVS_MODULE/$ECVS_SUBDIR"/* "$WORKDIR/$ECVS_MODULE/$ECVS_SUBDIR"
		else
			cp -Rf "$ECVS_TOP_DIR/$ECVS_MODULE/$ECVS_SUBDIR" "$WORKDIR/$ECVS_MODULE/$ECVS_SUBDIR/.."
		fi    
	else
		if [ -n "$ECVS_LOCAL" ]; then
			cp -f "$ECVS_TOP_DIR/$ECVS_MODULE"/* $WORKDIR/$ECVS_MODULE
		else
			cp -Rf "$ECVS_TOP_DIR/$ECVS_MODULE" "$WORKDIR"
		fi
	fi
	
	# if the directory is empty, remove it; empty directories cannot exist in cvs.
	# this happens when fex. kde-source requests module/doc/subdir which doesn't exist.
	# still create the empty directory in workdir though.
	if [ "`ls -A \"$DIR\"`" == "CVS" ]; then
		debug-print "$FUNCNAME: removing cvs-empty directory $ECVS_MODULE/$ECVS_SUBDIR"
		rm -rf "$DIR"
	fi
	    
	# implement some of base_src_unpack's functionality;
	# note however that base.eclass may not have been inherited!
	if [ -n "$PATCHES" ]; then
		debug-print "$FUNCNAME: PATCHES=$PATCHES, S=$S, autopatching"
		cd "$S"
		for x in $PATCHES; do
			debug-print "patching from $x"
			patch -p0 < "$x"
		done
		# make sure we don't try to apply patches more than once, since
		# cvs_src_unpack is usually called several times from e.g. kde-source_src_unpack
		export PATCHES=""
	fi

}

EXPORT_FUNCTIONS src_unpack