xref: /illumos-gate/usr/src/tools/scripts/flg.flp.sh (revision eb9a1df2aeb866bf1de4494433b6d7e5fa07b3ae)
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 2010 Sun Microsystems, Inc.  All rights reserved.
24# Use is subject to license terms.
25#
26#
27# Generates the list of source files that would get brought over with the
28# specified subtree as a result of inc.flg and req.flg files.  If no subtree
29# is named, then the current directory is assumed.
30#
31# Based loosely on ON's version of Teamware's def.dir.flp.
32#
33
34ONBLDDIR=$(dirname $(whence $0))
35
36PATH=/usr/bin:${BUILD_TOOLS:-/opt}/teamware/bin:$ONBLDDIR
37export PATH
38PROG=`basename $0`
39
40#
41# The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout
42# under certain circumstances, which will screw up consumers of incflg()
43# (and perhaps other things as well); unset it.
44#
45unset CDPATH
46
47#
48# Print the usage message and exit with an error.
49#
50usage()
51{
52	echo "usage: $PROG [-r] [<dir>]" > /dev/stderr
53	exit 1
54}
55
56#
57# Print the provided failure message and exit with an error.
58#
59fail()
60{
61	echo $PROG: $@ > /dev/stderr
62	exit 1
63}
64
65# Find the files matching the pattern specified by the first argument in the
66# directories named by the remaining arguments.  Unlike def.dir.flp, print
67# the name of the source file since we want to make a list of source files,
68# not SCCS files.
69#
70find_files()
71{
72   	pat=$1
73   	shift
74
75	if [[ "$SCM_MODE" = "teamware" ]]; then
76		for dir; do
77			if [[ -d $CODEMGR_WS/$dir ]]; then
78				cd $CODEMGR_WS
79				find $dir -name "$pat" | \
80					sed -n s:/SCCS/s.:/:p | prpath
81				cd - > /dev/null
82			fi
83		done
84	elif [[ "$SCM_MODE" = "mercurial" || "$SCM_MODE" == "git" ]]; then
85		dirs=""
86		for dir; do
87			if [[ -d $CODEMGR_WS/$dir ]]; then
88				dirs="$dirs|${dir%/}"
89			fi
90		done
91
92		# Remove leading pipe before it can confuse egrep
93		dirs=${dirs#\|}
94		echo "$FILELIST" | egrep "^($dirs)/.*/${pat#s.}\$" | prpath
95	fi
96}
97
98#
99# Echo the filename if it exists in the workspace.
100#
101echo_file()
102{
103	[ -f $CODEMGR_WS/$1 ] && echo $1 | prpath
104}
105
106#
107# Source the named script, specified as either a full path or a path relative
108# to $CODEMGR_WS.  Although def.dir.flp allows for situations in which the
109# script is actually executed (rather than sourced), this feature has never
110# been used in ON, since it precludes use of echo_file() and find_files().
111#
112exec_file()
113{
114	if [[ "${1##/}" = "$1" ]]; then
115		. $CODEMGR_WS/$1
116	else
117		. $1
118	fi
119}
120
121#
122# Iterate up through all directories below the named directory, and
123# execute any inc.flg's that may exist.
124#
125incflg()
126{
127	cd $1
128	for i in * .*; 	do
129    		case $i in
130		'*'|.|..)
131			;;
132		inc.flg)
133			exec_file $1/$i
134			;;
135		*)
136			if [[ -d $i && ! -h $i ]]; then
137				incflg $1/$i
138				cd $1
139			fi
140			;;
141		esac
142	done
143}
144
145#
146# Convert the absolute pathnames named on input to relative pathnames (if
147# necessary) and print them.
148#
149prpath()
150{
151	#
152	# $CURTREE may be a subdirectory of $CODEMGR_WS, or it
153	# may be the root of $CODEMGR_WS.  We want to strip it
154	# and end up with a relative path in either case, so the
155	# ?(/) pattern is important.  If we don't do that, the
156	# dots/tree loop will go on forever.
157	#
158	reltree=${CURTREE##$CODEMGR_WS?(/)}
159
160	while read srcfile; do
161		if [[ "$RELPATHS" != y ]]; then
162			echo $srcfile
163			continue
164		fi
165
166		dots=
167		tree=$reltree
168		while [[ "${srcfile##$tree}" = "$srcfile" ]]; do
169			dots=../$dots
170			tree=`dirname $tree`
171			[ "$tree" = "." ] && break
172		done
173		echo ${dots}${srcfile##$tree/}
174	done
175}
176
177which_scm | read SCM_MODE CODEMGR_WS || exit 1
178
179if [[ $SCM_MODE == "unknown" ]]; then
180	fail "Unable to determine SCM type currently in use."
181elif [[ $SCM_MODE == "mercurial" ]]; then
182	FILELIST=$(hg manifest)
183elif [[ $SCM_MODE == "git" ]]; then
184	FILELIST=$(cd $(dirname $(git rev-parse --git-dir)) && git ls-files)
185elif [[ $SCM_MODE != "teamware" ]]; then
186	fail "Unsupported SCM in use: $SCM_MODE"
187fi
188
189while getopts r flag; do
190	case $flag in
191	r)
192		RELPATHS=y
193		;;
194	\?)
195		usage
196		;;
197	esac
198done
199
200shift $((OPTIND - 1))
201
202[ $# -gt 1 ] && usage
203
204CURTREE=`/bin/pwd`
205
206#
207# Determine the subtree being examined.
208#
209if [[ $# -eq 0 ]]; then
210	SUBTREE=$CURTREE
211elif [[ -d $1 ]]; then
212	SUBTREE=$1
213elif [[ -d $CODEMGR_WS/$1 ]]; then
214	SUBTREE=$CODEMGR_WS/$1
215else
216	fail "neither \$CODEMGR_WS/$1 nor $1 exists as a directory"
217fi
218
219#
220# Get the canonical path to the subtree.
221#
222cd $SUBTREE
223SUBTREE=`/bin/pwd`
224
225#
226# Get the canonical path to the current directory.
227#
228cd $CURTREE
229CURTREE=`/bin/pwd`
230
231#
232# Get the canonical path to the workspace.
233#
234cd $CODEMGR_WS
235CODEMGR_WS=`/bin/pwd`
236
237if [[ "${SUBTREE##$CODEMGR_WS}" = "$SUBTREE" ]]; then
238	fail "$SUBTREE is not a subtree of \$CODEMGR_WS"
239fi
240
241if [[ "${CURTREE##$CODEMGR_WS}" = "$CURTREE" ]]; then
242	fail "$CURTREE is not a subtree of \$CODEMGR_WS"
243fi
244
245#
246# Find and execute all inc.flg's below our subtree.
247#
248incflg $SUBTREE
249
250#
251# Find and execute all req.flg's at or above our subtree.
252#
253TREE=$SUBTREE
254while [[ $TREE != $CODEMGR_WS ]]; do
255	[[ -f $TREE/req.flg ]] && exec_file $TREE/req.flg
256	TREE=`dirname $TREE`
257done
258
259exit 0
260