xref: /illumos-gate/usr/src/tools/scripts/ws.sh (revision eb6b10e69fa5ba733da194d3ad71a0e63338be29)
1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22#
23# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26# Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
27#
28#	This script sets up the environment variables for a SunOS
29#	codemgr workspace and spawns a shell with the environment
30#	setup.
31#
32#	The following Environment variables are set:
33#		CODEMGR_WS
34#		ONBLD_DIR
35#		SRC
36#		TSRC
37#		ROOT
38#		PARENT_ROOT
39#		MACH
40#		MAKEFLAGS
41#		ENVCPPFLAGS{1-4}
42#		ENVLDLIBS{1-3}
43#
44#	The MAKEFLAGS environment variable is set to force make
45#	to read default make variables from the environment.
46#
47#	Workspace names can be specified in two forms: pathname
48#	and hostname:pathname.  If the hostname:pathname form is used
49#	the script accesses the environment through the /net automounter
50#	map.
51#
52
53#
54# function to produce a pathname from a workspace name or subdirectory.
55# The workspace name can have hostname:pathname format.
56#
57
58fmtwsname()
59{
60	awk -F: '$1 != $0 { print "/net/"$1$2 } \
61		 $1 == $0 { print $0 }'
62}
63
64#
65# Return a valid proto area, if one exists.
66#
67check_proto()
68{
69	if [[ -z $1 ]]; then
70		return
71	fi
72
73	if [[ "$SCM_MODE" = "teamware" ]]; then
74		# Check for problematic parent specification and adjust
75		proto=`echo $1|fmtwsname`
76		echo "${proto}/root_${MACH}"
77	elif [[ "$SCM_MODE" = "mercurial" ]]; then
78		proto=$1
79		#
80		# If the proto is a local repository then we can use it
81		# to point to the parents proto area. Don't bother to
82		# check if it exists or not, we never did for Teamware,
83		# since it might appear later anyway.
84		#
85		if [[ "${proto##ssh://}" == "$proto" && \
86		     "${proto##http://}" == "$proto" && \
87		     "${proto##https://}" == "$proto" ]]; then
88			echo "${proto}/root_${MACH}"
89		fi
90	elif [[ "$SCM_MODE" = "git" ]]; then
91		#
92                # For git, we make no attempt to deal with the possibility of
93                # remote parent workspaces because, in the protodefs file, we
94                # don't actually acknowledge the concept of a parent workspace
95                # at all, in keeping with the rest of our git support.
96                #
97		echo "${1}/root_${MACH}"
98	fi
99}
100
101cleanup_env()
102{
103	# keep the env. clean when returning
104	unset setenv osbld_flag os_rev wsosdir protofile wsname ofs proto \
105		pwd parent PROTO1 PROTO2 PROTO3 tmpwsname
106	return 0
107}
108
109if [[ "$1" = "-e" ]]; then
110	setenv=true
111	shift
112else
113	setenv=false
114fi
115
116WHICH_SCM=$(/bin/dirname $(whence $0))/which_scm
117if [[ ! -x $WHICH_SCM ]]; then
118	WHICH_SCM=which_scm
119fi
120
121#
122# No workspace/repository path was given, so try and detect one from our
123# current directory we're in
124#
125if [[ $# -lt 1 ]]; then
126	if env CODEMGR_WS="" $WHICH_SCM | read SCM_MODE tmpwsname && \
127	    [[ $SCM_MODE != unknown ]]; then
128		echo "Defaulting to $SCM_MODE repository $tmpwsname"
129	else
130		echo "usage: ws [-e] [workspace_name]" >&2
131		if $setenv; then
132			cleanup_env
133			return 1
134		else
135			exit 1
136		fi
137	fi
138else
139	#
140	# A workspace/repository path was passed in, grab it and pop
141	# it off the stack
142	#
143	tmpwsname=$1
144	shift
145fi
146
147#
148#	This variable displays the nested activations of workspaces.
149#	This is done here to get the exact name the user entered.
150#
151WS_STACK="$tmpwsname $WS_STACK"; export WS_STACK
152
153#
154# Set the workspace name and unset tmpwsname (as we reuse it later)
155#
156wsname=`echo $tmpwsname|fmtwsname`
157unset tmpwsname
158
159#
160# Checking for CODEMGR_WSPATH
161#
162if [[ -n ${CODEMGR_WSPATH} && ( ! -d $wsname ) && \
163     ( `expr "$wsname" : "\/"` = "0" ) ]]
164then
165	ofs=$IFS
166	IFS=": 	"
167	for i in $CODEMGR_WSPATH
168	do
169		if [[ -d ${i}/${wsname} ]]; then
170			wsname=${i}/${wsname}
171			break
172		fi
173	done
174	IFS=$ofs
175fi
176
177#
178# to translate it to an absolute pathname.  We need an
179# absolute pathname in order to set CODEMGR_WS.
180#
181if [[ `expr "$wsname" : "\/"` = "0" ]]
182then
183	pwd=`pwd`
184	wsname="$pwd/$wsname"
185fi
186
187#
188#	Check to see if this is a valid workspace
189#
190if [[ ! -d $wsname ]]; then
191	echo "$wsname . . . no such directory" >&2
192	if $setenv; then
193		cleanup_env
194		return 1
195	else
196		exit 1
197	fi
198fi
199
200#
201# This catches the case of a passed in workspace path
202# Check which type of SCM is in use by $wsname.
203#
204(cd $wsname && env CODEMGR_WS="" $WHICH_SCM) | read SCM_MODE tmpwsname
205if [[ $? != 0 || "$SCM_MODE" == unknown ]]; then
206	echo "Error: Unable to detect a supported SCM repository in $wsname"
207	if $setenv; then
208		cleanup_env
209		return 1
210	else
211		exit 1
212	fi
213fi
214
215wsname=$tmpwsname
216CODEMGR_WS=$wsname ; export CODEMGR_WS
217SRC=$wsname/usr/src; export SRC
218TSRC=$wsname/usr/ontest; export TSRC
219
220if [[ "$SCM_MODE" = "teamware" && -d ${wsname}/Codemgr_wsdata ]]; then
221	CM_DATA="Codemgr_wsdata"
222	wsosdir=$CODEMGR_WS/$CM_DATA/sunos
223	protofile=$wsosdir/protodefs
224elif [[ "$SCM_MODE" = "mercurial" && -d ${wsname}/.hg ]]; then
225	CM_DATA=".hg"
226	wsosdir=$CODEMGR_WS/$CM_DATA
227	protofile=$wsosdir/org.opensolaris.protodefs
228elif [[ "$SCM_MODE" = "git" && -d ${wsname}/.git ]]; then
229	CM_DATA=".git"
230	wsosdir=$CODEMGR_WS/$CM_DATA
231	protofile=$wsosdir/org.opensolaris.protodefs
232else
233	echo "$wsname is not a supported workspace; type is $SCM_MODE" >&2
234	if $setenv; then
235		cleanup_env
236		return 1
237	else
238		exit 1
239	fi
240fi
241
242MACH=`uname -p`
243
244if [[ ! -f $protofile ]]; then
245	if [[ ! -w $CODEMGR_WS/$CM_DATA ]]; then
246		#
247		# The workspace doesn't have a protodefs file and I am
248		# unable to create one.  Tell user and use /tmp instead.
249		#
250		echo "Unable to create the proto defaults file ($protofile)."
251
252		# Just make one in /tmp
253		wsosdir=/tmp
254		protofile=$wsosdir/protodefs
255	fi
256
257	if [[ ! -d $wsosdir ]]; then
258		mkdir $wsosdir
259	fi
260
261	cat << PROTOFILE_EoF > $protofile
262#!/bin/sh
263#
264#	Set default proto areas for this workspace
265#	NOTE: This file was initially automatically generated.
266#
267#	Feel free to edit this file.  If this file is removed
268#	it will be rebuilt containing default values.
269#
270#	The variable CODEMGR_WS is available to this script.
271#
272#	PROTO1 is the first proto area searched and is typically set
273#	to a proto area associated with the workspace.  The ROOT
274#	environment variable is set to the same as PROTO1.  If you
275#	will be doing make installs this proto area needs to be writable.
276#
277#	PROTO2 and PROTO3 are set to proto areas to search before the
278#	search proceeds to the local machine or the proto area specified by
279#	TERMPROTO.
280#
281#	TERMPROTO (if specified) is the last place searched.  If
282#	TERMPROTO is not specified the search will end at the local
283#	machine.
284#
285
286PROTO1=\$CODEMGR_WS/proto
287PROTOFILE_EoF
288
289	if [[ "$SCM_MODE" = "teamware" ]]; then
290		cat << PROTOFILE_EoF >> $protofile
291if [[ -f "\$CODEMGR_WS/Codemgr_wsdata/parent" ]]; then
292   #
293   # If this workspace has an codemgr parent then set PROTO2 to
294   # point to the parents proto space.
295   #
296   parent=\`workspace parent \$CODEMGR_WS\`
297   if [[ -n \$parent ]]; then
298	   PROTO2=\$parent/proto
299   fi
300fi
301PROTOFILE_EoF
302	elif [[ "$SCM_MODE" = "mercurial" ]]; then
303		cat << PROTOFILE_EoF >> $protofile
304parent=\`(cd \$CODEMGR_WS && hg path default 2>/dev/null)\`
305if [[ \$? -eq 0 && -n \$parent ]]; then
306   [[ -n \$(check_proto \$parent/proto) ]] && PROTO2=\$parent/proto
307fi
308PROTOFILE_EoF
309	fi
310fi
311
312. $protofile
313
314# This means you don't have to type make -e all of the time
315
316MAKEFLAGS=e; export MAKEFLAGS
317
318#
319#	Set up the environment variables
320#
321ROOT=/proto/root_${MACH}	# default
322
323ENVCPPFLAGS1=
324ENVCPPFLAGS2=
325ENVCPPFLAGS3=
326ENVCPPFLAGS4=
327ENVLDLIBS1=
328ENVLDLIBS2=
329ENVLDLIBS3=
330
331#
332# Work around folks who have historically used GCC_ROOT and convert it to
333# GNUC_ROOT. We leave GCC_ROOT in the environment for now (though this could
334# mess up the case where multiple different gcc versions are being used to
335# shadow).
336#
337if [[ -n "${GCC_ROOT}" ]]; then
338	export GNUC_ROOT=${GCC_ROOT}
339fi
340
341PROTO1=`check_proto $PROTO1`
342if [[ -n "$PROTO1" ]]; then	# first proto area specifed
343	ROOT=$PROTO1
344	ENVCPPFLAGS1=-I$ROOT/usr/include
345	export ENVCPPFLAGS1
346	ENVLDLIBS1="-L$ROOT/lib -L$ROOT/usr/lib"
347	export ENVLDLIBS1
348
349	PROTO2=`check_proto $PROTO2`
350	if [[ -n "$PROTO2" ]]; then	# second proto area specifed
351		ENVCPPFLAGS2=-I$PROTO2/usr/include
352		export ENVCPPFLAGS2
353		ENVLDLIBS2="-L$PROTO2/lib -L$PROTO2/usr/lib"
354		export ENVLDLIBS2
355
356		PROTO3=`check_proto $PROTO3`
357		if [[ -n "$PROTO3" ]]; then	# third proto area specifed
358			ENVCPPFLAGS3=-I$PROTO3/usr/include
359			export ENVCPPFLAGS3
360			ENVLDLIBS3="-L$PROTO3/lib -L$PROTO3/usr/lib"
361			export ENVLDLIBS3
362		fi
363	fi
364fi
365
366export ROOT
367
368if [[ -n "$TERMPROTO" ]]; then	# fallback area specifed
369	TERMPROTO=`check_proto $TERMPROTO`
370	ENVCPPFLAGS4="-Y I,$TERMPROTO/usr/include"
371	export ENVCPPFLAGS4
372	ENVLDLIBS3="$ENVLDLIBS3 -Y P,$TERMPROTO/lib:$TERMPROTO/usr/lib"
373	export ENVLDLIBS3
374fi
375
376osbld_flag=0
377
378if [[ -z "$ONBLD_DIR" ]]; then
379	ONBLD_DIR=$(/bin/dirname $(whence $0))
380fi
381
382if ! echo ":$PATH:" | grep ":${ONBLD_DIR}:" > /dev/null; then
383	PATH="${ONBLD_DIR}:${ONBLD_DIR}/${MACH}:${PATH}"
384	osbld_flag=1
385fi
386
387export PATH
388
389if [[ -n "$PROTO2" ]]; then
390   # This should point to the parent's proto
391   PARENT_ROOT=$PROTO2
392   export PARENT_ROOT
393else
394   # Clear it in case it's already in the env.
395   PARENT_ROOT=
396fi
397export ONBLD_DIR
398export MACH
399
400os_rev=`uname -r`
401os_name=`uname -s`
402
403if [[ $os_name != "SunOS" || `expr $os_rev : "5\."` != "2" ]]; then
404   #
405   # This is not a SunOS 5.x machine - something is wrong
406   #
407   echo "***WARNING: this script is meant to be run on SunOS 5.x."
408   echo "            This machine appears to be running: $os_name $os_rev"
409fi
410
411echo ""
412echo "Workspace                    : $wsname"
413if [[ -n "$parent" ]]; then
414   echo "Workspace Parent             : $parent"
415fi
416echo "Proto area (\$ROOT)           : $ROOT"
417if [[ -n "$PARENT_ROOT" ]]; then
418   echo "Parent proto area (\$PARENT_ROOT) : $PARENT_ROOT"
419fi
420echo "Root of source (\$SRC)        : $SRC"
421echo "Root of test source (\$TSRC)  : $TSRC"
422if [[ $osbld_flag = "1" ]]; then
423   echo "Prepended to PATH            : $ONBLD_DIR"
424fi
425echo "Current directory (\$PWD)     : $wsname"
426echo ""
427
428cd $wsname
429
430if $setenv; then
431	cleanup_env
432else
433	exec ${SHELL:-sh} "$@"
434fi
435