File: wmakeBuildInfo

package info (click to toggle)
openfoam 1912.200626-3
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 238,956 kB
  • sloc: cpp: 1,159,641; sh: 15,902; ansic: 5,195; lex: 660; xml: 387; python: 282; awk: 212; makefile: 103; sed: 88; csh: 3
file content (615 lines) | stat: -rwxr-xr-x 15,080 bytes parent folder | download | duplicates (2)
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
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
#!/bin/sh
#------------------------------------------------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     |
#   \\  /    A nd           | www.openfoam.com
#    \\/     M anipulation  |
#------------------------------------------------------------------------------
#     Copyright (C) 2018-2019 OpenCFD Ltd.
#------------------------------------------------------------------------------
# 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
#     wmakeBuildInfo
#
# Description
#     Print the api/version and other build information for the project.
#
# Environment
#     - WM_PROJECT_DIR
#     - WM_PROJECT_VERSION
#     - WM_DIR              (unset defaults to WM_PROJECT_DIR/wmake)
#
# Note
#     Partial logic is also implemented in the bin/foamEtcFile
#     -show-api and -show-patch options.
#     Make sure that any changes here are also reflected there.
#
#------------------------------------------------------------------------------
# Locations
rulesFile="${WM_DIR:-$WM_PROJECT_DIR/wmake}/rules/General/general"
metaInfoDir="$WM_PROJECT_DIR/META-INFO"

usage() {
    exec 1>&2

    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
    cat<<USAGE
Usage: ${0##*/} [OPTION]
       ${0##*/} [-update] -filter FILE
options:
  -cmp, -check  Compare make and meta information (exit 0 for no changes)
  -diff         Display differences between make and meta information
                (exit code 0 for no changes)
  -dry-run      In combination with -update
  -filter FILE  Filter @API@, @BUILD@ tags in file with make information
  -remove       Remove meta-info build information and exit
  -update       Update meta-info from make information
  -query        Report make-info and meta-info
  -query-make   Report make-info values (api, branch, build)
  -query-meta   Report meta-info values (api, branch, build)
  -show-api     Print api value from wmake/rules, or meta-info and exit
  -show-patch   Print patch value from meta-info and exit
  -help         Print the usage

Query/manage status of api,branch,build information.
Default without any arguments is the same as '-query-make'.

USAGE
    exit 1
}

# Report error and exit
die()
{
    exec 1>&2
    echo
    echo "Error encountered:"
    while [ "$#" -ge 1 ]; do echo "    $1"; shift; done
    echo
    echo "See '${0##*/} -help' for usage"
    echo
    exit 1
}

#------------------------------------------------------------------------------
# Parse arguments and options
#------------------------------------------------------------------------------
unset optCheck optDryRun optUpdate optQuery optFilter

while [ "$#" -gt 0 ]
do
    case "$1" in
    -h | -help*)
        usage
        ;;
    -cmp | -check)
        optCheck=true
        ;;
    -diff)
        optCheck=verbose
        ;;
    -dry-run)
        optDryRun=true
        ;;
    -remove)
        optUpdate=remove
        break # Stop now
        ;;
    -update)
        optUpdate=true
        ;;
    -query)
        optQuery="make:meta"
        ;;
    -query-make | -query-meta)
        optQuery="$optQuery:${1##*-}"
        ;;
    -show-api)
        optQuery="api"
        ;;
    -show-patch)
        optQuery="patch"
        ;;
    -filter)
        optFilter=true
        shift # Stop here, a file name follows
        break
        ;;
    *)
        die "unknown option/argument: '$1'"
        ;;
    esac
    shift
done

# Check environment variables
[ -d "$WM_PROJECT_DIR" ] || \
    die "Bad or unset environment variable: \$WM_PROJECT_DIR"

[ -d "$WM_PROJECT_DIR/META-INFO" ] || \
    die "No META-INFO/ directory for project"


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

if [ "$optUpdate" = remove ]
then

    if [ -f "$metaInfoDir/build-info" ]
    then
        echo "Removing project META-INFO/build-info" 1>&2
        rm -f "$metaInfoDir/build-info" 2>/dev/null
    else
        echo "Already removed project META-INFO/build-info" 1>&2
    fi
    exit 0

elif [ "$optFilter" = true ]
then

    [ -f "$1" ] || {
        echo "Error in ${0##*/}: file not found '$1'" 1>&2
        exit 2
    }

    # Disable other methods that generate output to stdout
    unset optCheck optQuery

else

    [ "$#" -eq 0 ] || die "Unexpected option/arguments $@"

    # Nothing specified? Default to -query-make
    if [ -z "$optCheck$optUpdate$optQuery" ]
    then
        optQuery="make"
    fi

fi


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

# Variables - for portability, avoiding bash associative arrays
unset make_info meta_info


# Populate make_* variables
#
#  - api    : from rules/General/general
#  - patch  : cached value from previous make
#  - branch : from git
#  - build  : from git
#
# Failure modes:
# - No api information (can't find file etc).
#   -> FATAL: should never happen.
#
# - No git installed or no git repo
#   -> branch and build are populated as empty strings
#
# - Working on detached head.
#   -> branch has value "HEAD" instead of something more readable.
getMakeInfo()
{
    if [ -n "$make_info" ]
    then
        ##echo "use cached value for make info" 1>&2
        return 0
    fi
    ##echo "get make info" 1>&2

    local api patch build branch
    unset make_api make_patch make_branch make_build

    # (api) from WM_DIR/rules/General/general
    # - extract WM_VERSION = OPENFOAM=<digits>

    api="$(sed -ne '/^ *#/!{ /WM_VERSION.*OPENFOAM=/{ s@^.*OPENFOAM= *\([0-9][0-9]*\).*@\1@p; q }}' $rulesFile 2>/dev/null)"

    if [ -d "$metaInfoDir" ]
    then
        # (patch) from build-info - not from api-info
        patch="$(sed -ne 's@^patch *= *\([0-9][0-9]*\).*@\1@p' $metaInfoDir/build-info 2>/dev/null)"
    fi

    # Build info from git. Use short date format (YYYY-MM-DD) and sed instead
    # of the newer --date='format:%y%m%d'
    build="$(git --git-dir=$WM_PROJECT_DIR/.git log -1 --date=short --format='%h=%ad' 2>/dev/null|sed 's/-//g;s/=/-/')"

    # Branch info from git
    if [ -n "$build" ]
    then
        branch="$(git --git-dir=$WM_PROJECT_DIR/.git rev-parse --abbrev-ref HEAD 2>/dev/null)"
    fi

    make_api="$api"
    make_patch="${patch:-0}"  # Default is 0 (unpatched)
    make_branch="$branch"
    make_build="$build"
    make_info=true
}


# Populate meta_* variables
#
#  - api    : from META-INFO/api-info
#  - patch  : from META-INFO/api-info
#  - branch : from META-INFO/build-info
#  - build  : from META-INFO/build-info
#
# Failure modes:
# - Directory, file or entry not found.
#   -> corresponding entries are empty strings
getMetaInfo()
{
    if [ -n "$meta_info" ]
    then
        ##echo "use cached value for meta info" 1>&2
        return 0
    fi
    ##echo "get meta info" 1>&2

    local api patch build branch
    unset meta_api meta_patch meta_branch meta_build

    if [ -d "$metaInfoDir" ]
    then
        # (api, patch) from api-info
        # (branch, build) from build-info

        api="$(sed -ne 's@^api *= *\([0-9][0-9]*\).*@\1@p' $metaInfoDir/api-info 2>/dev/null)"
        patch="$(sed -ne 's@^patch *= *\([0-9][0-9]*\).*@\1@p' $metaInfoDir/api-info 2>/dev/null)"
        branch="$(sed -ne 's@^branch *= *\([^ ]*\).*@\1@p' $metaInfoDir/build-info 2>/dev/null)"
        build="$(sed -ne 's@^build *= *\([^ ]*\).*@\1@p' $metaInfoDir/build-info 2>/dev/null)"
    fi

    meta_api="$api"
    meta_patch="${patch:-0}"  # Default is 0 (unpatched)
    meta_branch="$branch"
    meta_build="$build"
    meta_info=true
}


# Get api from rules/General/general
#
# Failure modes:
# - No api information (can't find file etc).
#   -> Fatal for building, but could be OK for a stripped down version
#
# Fallback. Get from api-info
getApi()
{
    getMakeInfo

    # Local copy
    local api="${make_api}"

    if [ -z "$api" ]
    then
        getMetaInfo
        api="${meta_api}"
    fi

    if [ -n "$api" ]
    then
        echo "$api"
    else
        return 1
    fi
}


# Get patch from meta-info / api-info
#
# Failure modes:
# - No patch information (can't find file etc).
getPatchLevel()
{
    getMetaInfo

    # Local copy
    local patch="${meta_patch}"

    if [ -n "$patch" ]
    then
        echo "$patch"
    else
        return 1
    fi
}


#
# Report make info
#
reportMakeInfo()
{
    getMakeInfo
    getMetaInfo

    echo "make"
    echo "    api = ${make_api}"
    echo "    patch = ${meta_patch:-0}"  # <- From meta-info only
    echo "    branch = ${make_branch}"
    echo "    build = ${make_build}"
}


#
# Report meta info
#
reportMetaInfo()
{
    getMetaInfo

    echo "meta"
    echo "    api = ${meta_api}"
    echo "    patch = ${meta_patch:-0}"  # <- From meta-info only
    echo "    branch = ${meta_branch}"
    echo "    build = ${meta_build}"
}


# Report diff between make and meta info (single key).
# Set diff_header prior to the first call.
# $1 == key
# $2 == make value
# $3 == meta value
unset diff_header
_reportDiff()
{
    if [ -n "$diff_header" ]
    then
        echo "$diff_header"
        unset diff_header
    fi
    echo "$1:"
    echo "    make $2"
    echo "    meta $3"
}


# Test make vs meta info.
# Return 0 for no differences, 1 otherwise
# $1 == verbose, print as diff. Silent otherwise
checkDiff()
{
    local diff verbose

    if [ "$1" = "verbose" ]
    then
        diff_header="Differences"
        verbose=true
    fi

    getMakeInfo
    getMetaInfo

    # api
    if [ "${make_api}" != "${meta_api}" ]
    then
        diff=true

        if [ -n "$verbose" ]
        then
            _reportDiff "api" "${make_api}" "${meta_api}"
        fi
    fi

    # patch
    if [ "${make_patch}" != "${meta_patch}" ]
    then
        diff=true

        if [ -n "$verbose" ]
        then
            _reportDiff "patch" "${make_patch}" "${meta_patch}"
        fi
    fi

    # branch - only test when make info is non-empty
    if [ -n "${make_branch}" ] && [ "${make_branch}" != "${meta_branch}" ]
    then
        diff=true

        if [ -n "$verbose" ]
        then
            _reportDiff "branch" "${make_branch}" "${meta_branch}"
        fi
    fi

    # build - only test when make info is non-empty
    if [ -n "${make_build}" ] && [ "${make_build}" != "${meta_build}" ]
    then
        diff=true

        if [ -n "$verbose" ]
        then
            _reportDiff "build" "${make_build}" "${meta_build}"
        fi
    fi

    # No diffs, but never permit entirely empty values for build.
    test -z "$diff" || test -z "${make_build}${meta_build}"
}


#
# Update meta info (on disk) based on the make info
#
performUpdate()
{
    getMakeInfo
    getMetaInfo

    # Local copies of the make info
    local api="${make_api}"
    local branch="${make_branch}"
    local build="${make_build}"
    local patch="${make_patch}"

    # If any of the make-info are empty (bad),
    # use the meta-info to avoid spurious changes
    [ -n "$api" ] || api="${meta_api}"
    [ -n "$branch" ] || branch="${meta_branch}"
    [ -n "$build" ] || build="${meta_build}"

    # Fallback to WM_PROJECT_VERSION alone
    [ -n "$build" ] || build="${WM_PROJECT_VERSION:-unknown}"

    local outputFile

    # build-info
    outputFile="$metaInfoDir/build-info"
    if [ "$branch" != "${meta_branch}" ] || \
       [ "$build" != "${meta_build}" ] || \
       [ "$patch" != "${meta_patch}" ]
    then
        patch="${meta_patch:-0}"        # <- From meta-info only

        if [ -n "$optDryRun" ]
        then
            echo "dry-run (update) ${outputFile##*/} branch=${branch}" 1>&2
            echo "dry-run (update) ${outputFile##*/} build=${build}" 1>&2
            echo "dry-run (update) ${outputFile##*/} patch=${patch}" 1>&2
        else
            echo "branch=${branch}" >| "$outputFile"
            echo "build=${build}"   >> "$outputFile"
            echo "patch=${patch}"   >> "$outputFile"
        fi
    fi


    # api-info
    outputFile="$metaInfoDir/api-info"
    if [ "$api" != "${meta_api}" ]
    then
        patch="${meta_patch:-0}"        # <- From meta-info only

        if [ -n "$optDryRun" ]
        then
            echo "dry-run (update) ${outputFile##*/} api=${api}" 1>&2
            echo "dry-run (update) ${outputFile##*/} patch=${patch}" 1>&2
        else
            echo "api=${api}"     >| "$outputFile"
            echo "patch=${patch}" >> "$outputFile"
        fi
    fi

    return 0
}


#
# Update meta info (on disk) based on the make info
#
performFiltering()
{
    local input="$1"

    [ -f "$input" ] || {
        echo "Error in ${0##*/}: file not found '$1'" 1>&2
        exit 2
    }

    getMakeInfo
    getMetaInfo

    # Local copies of the make info
    local api="${make_api}"
    local branch="${make_branch}"
    local build="${make_build}"
    local patch="${meta_patch:-0}"  # <- From meta-info only


    # If any of the make-info are empty (bad),
    # conjure up something from the meta-info

    # api is not normally needed (available directly from -Ddefine)
    # but we may wish to filter other types of files

    if [ -z "$api" ]
    then
        api="${meta_api}"
        api="${api:-0}"  # integer value
    fi

    # branch/build could be missing for non-git
    if [ -z "$branch" ]
    then
        branch="${meta_branch}"
        branch="${branch:-unknown}"
    fi

    if [ -z "$build" ]
    then
        build="${meta_build}"
        # Fallback to WM_PROJECT_VERSION
        build="${build:-${WM_PROJECT_VERSION:-unknown}}"
    fi

    sed \
        -e 's!@API@!'"${api}"'!g' \
        -e 's!@PATCH@!'"${patch:-0}"'!g' \
        -e 's!@BRANCH@!'"${branch}"'!g' \
        -e 's!@BUILD@!'"${build}"'!g' \
        -e 's!@VERSION@!'"${WM_PROJECT_VERSION}"'!g' \
        "$input"

    return 0
}


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

# Dispatch

if [ -n "$optCheck" ]
then
    checkDiff $optCheck
    exit $?
elif [ "$optQuery" = api ]
then
    # Show API and exit
    getApi
    exit $?
elif [ "$optQuery" = patch ]
then
    # Show patch level and exit
    getPatchLevel
    exit $?
else
    # Other queries
    case "$optQuery" in (*make*) reportMakeInfo ;; esac
    case "$optQuery" in (*meta*) reportMetaInfo ;; esac
fi

[ -n "$optUpdate" ] && performUpdate

if [ -n "$optFilter" ]
then
    # Perform filter on file
    performFiltering "$1"
fi

exit 0  # clean exit

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