foamEtcFile 11 KB
Newer Older
Henry's avatar
Henry committed
1
2
3
4
5
#!/bin/sh
#------------------------------------------------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     |
Henry Weller's avatar
Henry Weller committed
6
#   \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
mark's avatar
mark committed
7
#    \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
Henry's avatar
Henry committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#-------------------------------------------------------------------------------
# License
#     This file is part of OpenFOAM.
#
#     OpenFOAM is free software: you can redistribute it and/or modify it
#     under the terms of the GNU General Public License as published by
#     the Free Software Foundation, either version 3 of the License, or
#     (at your option) any later version.
#
#     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
#     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
#     for more details.
#
#     You should have received a copy of the GNU General Public License
#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
#
# Script
#     foamEtcFile
#
# Description
29
#     Locate user/group/other files with semantics similar to the
Henry's avatar
Henry committed
30
31
32
33
34
35
36
#     ~OpenFOAM/fileName expansion.
#
#     The -mode option can be used to allow chaining from
#     personal settings to site-wide settings.
#
#     For example, within the user ~/.OpenFOAM/<VER>/prefs.sh:
#     \code
37
#        eval $(foamEtcFile -sh -mode=go prefs.sh)
Henry's avatar
Henry committed
38
39
#     \endcode
#
40
41
42
43
44
# Environment
#     - WM_PROJECT:         (unset defaults to OpenFOAM)
#     - WM_PROJECT_SITE:    (unset defaults to PREFIX/site)
#     - WM_PROJECT_VERSION: (unset defaults to detect from path)
#
Henry's avatar
Henry committed
45
# Note
46
47
48
49
50
51
#     This script must exist in one of these locations:
#     - $WM_PROJECT_INST_DIR/OpenFOAM-<VERSION>/bin
#     - $WM_PROJECT_INST_DIR/openfoam-<VERSION>/bin
#     - $WM_PROJECT_INST_DIR/OpenFOAM+<VERSION>/bin
#     - $WM_PROJECT_INST_DIR/openfoam+<VERSION>/bin
#     - $WM_PROJECT_INST_DIR/openfoam<VERSION>/bin  (debian version)
Henry's avatar
Henry committed
52
53
#
#-------------------------------------------------------------------------------
mark's avatar
mark committed
54
unset optQuiet optSilent
Henry's avatar
Henry committed
55
56
57
58
59
60
usage() {
    [ "${optQuiet:-$optSilent}" = true ] && exit 1
    exec 1>&2
    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
    cat<<USAGE

61
Usage: foamEtcFile [OPTION] fileName
62
63
       foamEtcFile [OPTION] [-list|-list-test] [fileName]

Henry's avatar
Henry committed
64
options:
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
  -a, -all          Return all files (otherwise stop after the first match)
  -l, -list         List directories or files to be checked
  -list-test        List (existing) directories or files to be checked
  -mode=MODE        Any combination of u(user), g(group), o(other)
  -prefix=DIR       Specify an alternative installation prefix
  -version=VER      Specify alternative OpenFOAM version (eg, 3.0, 1612, ...)
  -csh | -sh        Produce output suitable for a csh or sh 'eval'
  -csh-verbose | -sh-verbose
                    As per -csh | -sh, with additional verbosity
  -q, -quiet        Suppress all normal output
  -s, -silent       Suppress stderr, except -csh-verbose, -sh-verbose output
  -help             Print the usage

Locate user/group/other file with semantics similar to the
~OpenFOAM/fileName expansion.

Single character options must not be grouped. Equivalent options:
    -mode=MODE,   -mode MODE,   -m MODE
    -prefix=DIR,  -prefix DIR,  -p DIR
    -version=VER, -version VER, -v VER

Exit status
    0  when the file is found. Print resolved path to stdout.
    1  for miscellaneous errors.
    2  when the file is not found.
Henry's avatar
Henry committed
90
91
92
93
94

USAGE
    exit 1
}

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# Report error and exit
die()
{
    [ "${optQuiet:-$optSilent}" = true ] && exit 1
    exec 1>&2
    echo
    echo "Error encountered:"
    while [ "$#" -ge 1 ]; do echo "    $1"; shift; done
    echo
    echo "See 'foamEtcFile -help' for usage"
    echo
    exit 1
}

#-------------------------------------------------------------------------------
binDir="${0%/*}"                # The bin dir
projectDir="${binDir%/bin}"     # The project dir
prefixDir="${projectDir%/*}"    # The prefix dir (same as $WM_PROJECT_INST_DIR)
Henry's avatar
Henry committed
113

114
115
116
117
118
119
120
121
# Could not resolve projectDir, prefixDir? (eg, called as ./bin/foamEtcFile)
if [ "$prefixDir" = "$projectDir" ]
then
    binDir="$(cd $binDir && pwd -L)"
    projectDir="${binDir%/bin}"
    prefixDir="${projectDir%/*}"
fi
projectDirName="${projectDir##*/}"      # The project directory name
Henry's avatar
Henry committed
122

123
projectVersion="$WM_PROJECT_VERSION"    # Empty? - will be treated later
124
userDir="$HOME/.OpenFOAM"               # Hard-coded as per foamVersion.H
Henry's avatar
Henry committed
125

126
#-------------------------------------------------------------------------------
Henry's avatar
Henry committed
127

128
# Guess project version or simply get the stem part of the projectDirName.
129
# Handle standard and debian naming conventions.
Henry's avatar
Henry committed
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
# - projectVersion: update unless already set
#
# Helper variables:
# - dirBase (for reassembling name) == projectDirName without the version
# - versionNum (debian packaging)
unset dirBase versionNum
guessVersion()
{
    local version

    case "$projectDirName" in
    (OpenFOAM-* | openfoam-*)
        # Standard naming: OpenFOAM-<VERSION> or openfoam-<VERSION>
        dirBase="${projectDirName%%-*}-"
        version="${projectDirName#*-}"
        version="${version%%*-}" # Extra safety, eg openfoam-version-packager
        ;;

    (OpenFOAM+* | openfoam+*)
        # Alternative naming: OpenFOAM+<VERSION> or openfoam+<VERSION>
        dirBase="${projectDirName%%+*}+"
        version="${projectDirName#*+}"
        version="${version%%*-}" # Extra safety, eg openfoam-version-packager
        ;;

    (openfoam[0-9]*)
        # Debian naming: openfoam<VERSION>
        dirBase="openfoam"
        version="${projectDirName#openfoam}"
        versionNum="$version"

        # Convert digits version number to decimal delineated
        case "${#versionNum}" in (2|3|4)
            version=$(echo "$versionNum" | sed -e 's@\([0-9]\)@\1.@g')
            version="${version%.}"
            ;;
        esac
Henry's avatar
Henry committed
168

169
170
        # Ignore special treatment if no decimals were inserted.
        [ "${#version}" -gt "${#versionNum}" ] || unset versionNum
Henry's avatar
Henry committed
171
        ;;
mark's avatar
mark committed
172

173
174
    (*)
        die "unknown/unsupported naming convention for '$projectDirName'"
Henry's avatar
Henry committed
175
176
177
        ;;
    esac

178
179
180
    # Set projectVersion if required
    : ${projectVersion:=$version}
}
Henry's avatar
Henry committed
181
182


183
# Set projectVersion and update versionNum, projectDirName accordingly
184
185
setVersion()
{
186
    projectVersion="$1"
187

188
189
    # Need dirBase when reassembling projectDirName
    [ -n "$dirBase" ] || guessVersion
190

191
192
193
194
195
196
197
    # Debian: update x.y.z -> xyz version
    if [ -n "$versionNum" ]
    then
        versionNum=$(echo "$projectVersion" | sed -e 's@\.@@g')
    fi

    projectDirName="$dirBase${versionNum:-$projectVersion}"
198
199
200
}


201
202
optMode=ugo         # Default mode is always 'ugo'
unset optAll optList optShell optVersion
Henry's avatar
Henry committed
203

204
# Parse options
Henry's avatar
Henry committed
205
206
207
208
209
210
211
212
while [ "$#" -gt 0 ]
do
    case "$1" in
    -h | -help)
        usage
        ;;
    -a | -all)
        optAll=true
213
        unset optShell
Henry's avatar
Henry committed
214
215
216
        ;;
    -l | -list)
        optList=true
217
218
        unset optShell
        ;;
219
220
221
222
    -list-test)
        optList='test'
        unset optShell
        ;;
223
224
225
    -csh | -sh | -csh-verbose | -sh-verbose)
        optShell="${1#-}"
        unset optAll
Henry's avatar
Henry committed
226
        ;;
mark's avatar
mark committed
227
    -mode=[ugo]*)
228
        optMode="${1#*=}"
mark's avatar
mark committed
229
230
        ;;
    -prefix=/*)
231
        prefixDir="${1#*=}"
mark's avatar
mark committed
232
233
234
        prefixDir="${prefixDir%/}"
        ;;
    -version=*)
235
        optVersion="${1#*=}"
mark's avatar
mark committed
236
        ;;
Henry's avatar
Henry committed
237
    -m | -mode)
238
239
        optMode="$2"
        shift
mark's avatar
mark committed
240
        # Sanity check. Handles missing argument too.
241
242
        case "$optMode" in
        ([ugo]*)
mark's avatar
mark committed
243
            ;;
244
245
        (*)
            die "invalid mode '$optMode'"
mark's avatar
mark committed
246
            ;;
Henry's avatar
Henry committed
247
248
249
        esac
        ;;
    -p | -prefix)
250
        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
mark's avatar
mark committed
251
        prefixDir="${2%/}"
Henry's avatar
Henry committed
252
253
254
255
256
257
258
259
260
        shift
        ;;
    -q | -quiet)
        optQuiet=true
        ;;
    -s | -silent)
        optSilent=true
        ;;
    -v | -version)
261
262
        [ "$#" -ge 2 ] || die "'$1' option requires an argument"
        optVersion="$2"
Henry's avatar
Henry committed
263
264
265
266
267
268
269
        shift
        ;;
    --)
        shift
        break
        ;;
    -*)
270
        die "unknown option: '$1'"
Henry's avatar
Henry committed
271
272
273
274
275
276
277
278
        ;;
    *)
        break
        ;;
    esac
    shift
done

279
280
281
282
283
284
285
286
287
288
289
290
291

#-------------------------------------------------------------------------------

if [ -n "$optVersion" ]
then
    setVersion $optVersion
elif [ -z "$projectVersion" ]
then
    guessVersion
fi

# Updates:
# - projectDir  for changes via -prefix or -version
292
# - groupDir    for changes via -prefix
293
projectDir="$prefixDir/$projectDirName"
294
groupDir="${WM_PROJECT_SITE:-$prefixDir/site}"
295

mark's avatar
mark committed
296

297
298
# Debugging:
# echo "Installed locations:" 1>&2
299
# for i in projectDir prefixDir projectDirName projectVersion
Henry's avatar
Henry committed
300
# do
301
#     eval echo "$i=\$$i" 1>&2
Henry's avatar
Henry committed
302
303
304
305
306
307
308
309
310
311
# done


# Save the essential bits of information
# silently remove leading ~OpenFOAM/ (used in Foam::findEtcFile)
nArgs=$#
fileName="${1#~OpenFOAM/}"

# Define the various places to be searched:
unset dirList
312
case "$optMode" in (*u*) # (U)ser
313
    dirList="$dirList $userDir/$projectVersion $userDir"
Henry's avatar
Henry committed
314
315
316
    ;;
esac

317
case "$optMode" in (*g*) # (G)roup == site
318
    dirList="$dirList $groupDir/$projectVersion $groupDir"
Henry's avatar
Henry committed
319
320
321
    ;;
esac

322
case "$optMode" in (*o*) # (O)ther == shipped
mark's avatar
mark committed
323
    dirList="$dirList $projectDir/etc"
Henry's avatar
Henry committed
324
325
326
327
328
329
330
331
332
333
    ;;
esac
set -- $dirList


#
# The main routine
#

exitCode=0
334
if [ -n "$optList" ]
Henry's avatar
Henry committed
335
336
then

337
    # List directories, or potential file locations
338
339
    [ "$nArgs" -le 1 ] || \
    die "-list expects 0 or 1 filename, but $nArgs provided"
Henry's avatar
Henry committed
340

341
    # A silly combination, but -quiet does have precedence
342
    [ -n "$optQuiet" ] && exit 0
Henry's avatar
Henry committed
343

344
345
346
347
348
    # Test for directory or file too?
    if [ "$optList" = "test" ]
    then
        exitCode=2  # Fallback to a general error (file not found)

Henry's avatar
Henry committed
349
350
        if [ "$nArgs" -eq 1 ]
        then
351
352
353
354
355
356
357
358
359
            for dir
            do
                resolved="$dir/$fileName"
                if [ -f "$resolved" ]
                then
                    echo "$resolved"
                    exitCode=0  # OK
                fi
            done
Henry's avatar
Henry committed
360
        else
361
362
363
364
365
366
367
368
            for dir
            do
                if [ -d "$dir" ]
                then
                    echo "$dir"
                    exitCode=0  # OK
                fi
            done
Henry's avatar
Henry committed
369
        fi
370
371
372
373
374
375
    else
        for dir
        do
            echo "$dir${fileName:+/}$fileName"
        done
    fi
Henry's avatar
Henry committed
376
377
378

else

379
    [ "$nArgs" -eq 1 ] || die "One filename expected - $nArgs provided"
Henry's avatar
Henry committed
380

381
    exitCode=2  # Fallback to a general error (file not found)
Henry's avatar
Henry committed
382
383
384
385
386
387

    for dir
    do
        if [ -f "$dir/$fileName" ]
        then
            exitCode=0
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
            [ -n "$optQuiet" ] && break

            case "$optShell" in
            (*verbose)
                echo "Using: $dir/$fileName" 1>&2
                ;;
            esac

            case "$optShell" in
            csh*)
                echo "source $dir/$fileName"
                break
                ;;
            sh*)
                echo ". $dir/$fileName"
                break
                ;;
            *)
                echo "$dir/$fileName"
                [ -n "$optAll" ] || break
                ;;
            esac
Henry's avatar
Henry committed
410
411
412
413
414
415
416
417
        fi
    done

fi

exit $exitCode

#------------------------------------------------------------------------------