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