All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
updateLocalDocumentation.sh
Go to the documentation of this file.
1 #!/usr/bin/env bash
2 #
3 # Generation of icaruscode Doxygen documentation:
4 # * fetches the latest Doxygen tag files for LArSoft and ROOT
5 # (at most once per day)
6 # * sets up the latest UPS version of `icaruscode` (needed for depedencies)
7 # * checks out the latest tag of `icaruscode` `master` branch
8 # * runs Doxygen (output is expected in the ${OutputDir} directory)
9 #
10 # -----------------------------------------------------
11 # Implementation note
12 # -----------------------------------------------------
13 #
14 # This script currently does not support generating documentation from multiple
15 # repositories. To implement such support, a possible way is to have the user
16 # specify a list of repositories including a main one (say, the first one)
17 # which is where the Doxygen configuration file is. Then that configuration file
18 # is processed to include as INPUT all the repositories, instead of just one.
19 # Some additional work is needed to achieve that.
20 #
21 #
22 # Changes
23 # --------
24 #
25 # 20200426 (petrillo@slac.stanford.edu) [v1.0]
26 # first version in `icaruscode`; metadata version: 1
27 # 20200520 (petrillo@slac.stanford.edu) [v1.1]
28 # using GitHub sources
29 # 20201009 (petrillo@slac.stanford.edu) [v1.2]
30 # support additional repositories; metadata version: 2
31 # 20210302 (petrillo@slac.stanford.edu) [v1.3]
32 # support for non-`master` release branches (like in `sbnobj`);
33 # in case of tagged target, use the versions from UPS for all repositories
34 #
35 
36 # -- BEGIN -- boilerplate settings and library loading -------------------------
37 SCRIPTNAME="$(basename "$0")"
38 SCRIPTDIR="$(dirname "$0")"
39 
40 declare LibraryToLoad
41 for LibraryToLoad in 'settings.sh' 'experiment_settings.sh' 'utilities.sh' ; do
42 
43  source "${SCRIPTDIR%/}/${LibraryToLoad}" || exit $?
44 
45 done
46 unset LibraryToLoad
47 # -- END -- boilerplate settings and library loading ---------------------------
48 
49 # ------------------------------------------------------------------------------
50 SCRIPTVERSION="1.3"
51 
52 
53 declare -ri MetadataVersion='2' # integral numbers please
54 
55 
56 # ------------------------------------------------------------------------------
57 function printHelp() {
58 
59  cat <<EOH
60 
61 Generates the documentation of ${ExperimentName}.
62 
63 Usage: ${SCRIPTNAME} [options]
64 
65 Supported options:
66 --experiment=EXPERIMENTNAME [autodetect]
67  the name of the experiment (e.g. 'MicroBooNE')
68 --reponame=REPONAME [autodetect]
69  the name of the repository (e.g. 'uboonecode')
70 --branch=BRANCH , --tag=TAG , --commit=COMMIT
71  use this branch, tag or commit instead of branch '${DefaultBranch}';
72  the content of the repository will be changed
73 --currentbranch , -c
74  do not change the branch of the GIT repository; if the repository is
75  downloaded, its default branch is used ('${DefaultBranch}');
76  otherwise, the current status is used
77 --clean
78  removes the old documentation if present; by default, this does not happen
79 --force-tags
80  forces the update of Doxygen tag files even if they have been downloaded
81  since less than one day
82 --version , -V
83  prints the script version and exits (hint: it's version ${SCRIPTVERSION}
84 --help , -h , -?
85  prints this usage message and exits
86 
87 EOH
88 
89 } # printHelp()
90 
91 
92 function printVersion() {
93  echo "${SCRIPTNAME} version ${SCRIPTVERSION}."
94 } # printVersion()
95 
96 
97 # ------------------------------------------------------------------------------
98 
99 function UpdateTag() {
100  #
101  # Downloads the specified tag file and renames it as directed, if older than Age
102  #
103  # Usage: UpdateTag TagFile URL Description
104  #
105  local -r Age='yesterday'
106 
107  local TagFile="$1"
108  local URL="$2"
109  shift 2
110  local Description="$*"
111 
112  local TempFile="$(mktemp --dry-run )"
113  touch --date="$Age" "$TempFile"
114 
115  if [[ "$TagFile" -nt "$TempFile" ]] && isFlagUnset ForceTags ; then
116  echo "Keeping '${TagFile}' (run with \`--force-tags\` to override)."
117  else
118  echo "Fetching tag file for ${Description} ('${TagFile}' from '${URL}')"
119  wget --output-document "$TagFile" "$URL"
120  touch "$TagFile"
121  fi
122 
123  rm "$TempFile"
124 
125 } # UpdateTag()
126 
127 
128 function UpdateROOTtag() {
129 
130  local ROOTVersion
131  ROOTVersion="$(DetectROOTversion)"
132  LASTFATAL "Can't detect ROOT version!" # did set up fail?
133 
134  local ROOTVersionTag="${ROOTVersion%/*}"
135  ROOTVersionTag="${ROOTVersionTag//.}"
136 
137  echo "Fetching Doxygen tag for ROOT version ${ROOTVersion}"
138  UpdateTag 'ROOT.tag' "https://root.cern/doc/v${ROOTVersionTag}/ROOT.tag" "ROOT"
139 
140 } # UpdateROOTtag()
141 
142 
143 function UpdateLArSoftTag() {
144 
145 # local LArSoftVersion="$(UPSversion 'larsoft')"
146 
147  # Only one documented version: hope you like it
148  UpdateTag 'LArSoft.tag' 'http://nusoft.fnal.gov/larsoft/doxsvn/html/doxytags-larsoft.xml' "LArSoft"
149 
150 } # UpdateLArSoftTag()
151 
152 
153 function PrepareDoxyfile() {
154  local -r DoxyfileTemplate="$1"
155  local -r Doxyfile="$2"
156 
157  # special variables:
158  ALL_REPO_PATHS=
159  local CodeRepo
160  for CodeRepo in "${CodeRepoNames[@]}" ; do
161  ALL_REPO_PATHS+="${ALL_REPO_PATHS:+ }${CodeRepoPaths[$CodeRepo]}"
162  done
163 
164  ReplaceEnvironmentVariables "$DoxyfileTemplate" "$Doxyfile"
165 
166  unset ALL_REPO_PATHS
167 } # PrepareDoxyfile()
168 
169 
170 function RestoreGITrepository() {
171 
172  local Path="$1"
173  local Commit="$2"
174  local -i Stashed="${3:-0}"
175 
176  # restore the status of the repository
177  if [[ -n "$Commit" ]]; then
178  echo "Restoring the repository (to ${Commit})"
179  git -C "$Path" checkout "$Commit"
180  fi
181  if [[ -n "$Commit" ]]; then
182  echo "Restoring unstaged content of repository"
183  isFlagSet Stashed && git -C "$Path" stash pop --quiet
184  fi
185 
186 } # RestoreGITrepository()
187 
188 
189 ################################################################################
190 declare -a CodeRepoNames=( )
191 declare -A CodeRepoPaths=( )
192 declare -Ai NewGITclones=( )
193 declare -Ai GITstashedRepos=( )
194 declare -A GIToldCommits=( )
195 
196 function PrepareRepository() {
197  #
198  # PrepareRepository CodeRepoName RequestedCodeBranch
199  #
200  local -r CodeRepoName="$1"
201  local -r RequestedCodeBranch="$2"
202 
203  # constraint: it needs to be in the current directory
204  local CodeRepoPath="$CodeRepoName"
205  CodeRepoPaths[$CodeRepoName]="$CodeRepoPath"
206 
207  local NewGITclone=0
208  local -i res=0
209  if [[ ! -r "${CodeRepoPath}/.git" ]]; then
210  local -a GitSources=(
211  $(GitHubRemoteURL "$CodeRepoName" "$GitHubExperimentGroup" )
212  $(RedmineGITremoteURL "$CodeRepoName")
213  )
214 
215  for GitSource in "${GitSources[@]}" ; do
216  echo "Attempting to clone the GIT source tree of '${CodeRepoName}' from '${GitSource}'"
217  git clone "$GitSource" "$CodeRepoName" >&2
218  res=$?
219  [[ $res == 0 ]] && break
220  echo " (failed)"
221  done
222 
223  [[ -r "${CodeRepoPath}/.git" ]] || FATAL 1 "Could not download '${CodeRepoName}' code!"
224 
225  NewGITclone=1
226  fi
227  NewGITclones["$CodeRepoName"]="$NewGITclone"
228 
229  local -i GITstashed
230  local GIToldCommit
231  if [[ "$RequestedCodeBranch" != 'HEAD' ]]; then
232 
233  local -r CodeBranch="${RequestedCodeBranch:-${ReleaseBranches[$CodeRepoName]:-${DefaultBranch}}}"
234 
235  if isFlagUnset NewGITclone ; then
236  echo "Fetching updates for the existing GIT source tree of '${CodeRepoPath}'"
237  git -C "$CodeRepoPath" fetch
238  fi
239 
240  # remove everything that could bother our update;
241  # git stash does not tell a script if a stash was created
242  local -i nStashes="$(cd "$CodeRepoPath" && git stash list | wc -l)"
243  git -C "$CodeRepoPath" stash save --quiet -- "${SCRIPTNAME} temporary for Doxygen generation - $(date)"
244  LASTFATAL "Failed to save local changes in '${CodeRepoPath}'. Giving up."
245  local -i nNewStashes="$(cd "$CodeRepoPath" && git stash list | wc -l)"
246  if [[ "$nNewStashes" -gt "$nStashes" ]]; then
247  echo "Changes in GIT repository temporary stashed."
248  GITstashed+=( "$CodeRepoName" )
249  fi
250 
251  # also keep track of where we are
252  GIToldCommit="$(cd "$CodeRepoPath" && git reflog -n 1 --format='format:%H')"
253  local OldScriptChecksum="$(md5sum < "$0")"
254 
255  git -c 'advice.detachedHead=false' -C "$CodeRepoPath" checkout "$CodeBranch"
256  local -i res=$?
257  if [[ $res != 0 ]]; then
258  RestoreGITrepository "$CodeRepoPath" "$GIToldCommit" "$GITstashed"
259  if [[ -n "$RequestedCodeBranch" ]]; then
260  FATAL "$res" "Failed to check out branch '${CodeBranch}' of GIT repository ${CodeRepoPath}."
261  else
262  echo "Failed to check out branch '${CodeBranch}' of GIT repository ${CodeRepoPath}."
263  fi
264  fi
265 
266  if [[ -n "$CodeBranch" ]] && ! hasGITtag "$CodeBranch" ; then
267  echo "Updating the GIT branch..."
268  git -C "$CodeRepoPath" rebase
269  if [[ $res != 0 ]]; then
270  RestoreGITrepository "$CodeRepoPath" "$GIToldCommit" "$GITstashed"
271  echo "Failed to update (rebase) branch '${CodeBranch}' of GIT repository ${CodeRepoPath}."
272  fi
273  fi
274 
275  local GITnewCommit="$(cd "$CodeRepoPath" && git reflog -n 1 --format='format:%H')"
276  [[ "$GITnewCommit" == "$GIToldCommit" ]] && unset GIToldCommit # no change, no need to track
277  local NewScriptChecksum="$(md5sum < "$0")"
278 
279  if [[ "$OldScriptChecksum" != "$NewScriptChecksum" ]]; then
280  FATAL 1 "The attempt to update the repository '${CodeRepoPath}' on the fly caused a change in this script ('${SCRIPTNAME}'). Please update the repository manually and try again."
281  RestoreGITrepository "$CodeRepoPath" "$GIToldCommit" "$GITstashed"
282  fi
283 
284  fi
285  GIToldCommits["$CodeRepoName"]="$GIToldCommit"
286  GITstashedRepos["$CodeRepoName"]="$GITstashed"
287 
288 
289 } # PrepareRepository()
290 
291 
292 function RestoreAllRepositories() {
293  # restore the status of the repositories from stored information
294  local CodeRepoName
295  for CodeRepoName in "${CodeRepoNames[@]}" ; do
296  RestoreGITrepository "${CodeRepoPaths[$CodeRepoName]}" "${GIToldCommits[$CodeRepoName]}" "${GITstashedRepos[$CodeRepoName]:-0}"
297  done
298 } # RestoreAllRepositories()
299 
300 
301 
302 function CheckOutSources() {
303 
304  #
305  # find a Doxygen configuration file
306  #
307  local -r ExperimentName="$1"
308  shift
309  local RepoNames=( "$@" )
310 
311 
312  local MasterDoxyfile
313  MasterDoxyfile="$(FindDoxyfile "$ExperimentName")"
314  LASTFATAL "Can't find a doxygen configuration file for '${ExperimentName}'"
315 
316  [[ -z "${RepoNames[0]}" ]] && RepoNames[0]="$(ExperimentCodeProduct "$ExperimentName" )"
317  local ExperimentCodeName="${RepoNames[0]}"
318 
319  # in the future this constraint can be relaxed:
320  local ExperimentCodeRepoPath="$ExperimentCodeName"
321 
322  local DateTag="$(date '+%Y%m%d')"
323  local DoxygenLog="${LogDir%/}/$(basename "${MasterDoxyfile%.doxy*}")-${DateTag}.log"
324 
325  local -r RequestedCodeBranch="$RequestedExperimentCodeBranch"
326 
327  # all the same branch, just because of the simpler interface
328  local RequestedRepoVersion
329  for CodeRepoName in "${RepoNames[@]}" ; do
330  RequestedRepoVersion="$(UPSversion "$CodeRepoName")"
331  [[ $? == 0 ]] || RequestedRepoVersion="$RequestedCodeBranch"
332  echo " === preparing repository '${CodeRepoName}' (${RequestedRepoVersion}) === "
333  PrepareRepository "$CodeRepoName" "$RequestedRepoVersion"
334  done
335  echo " === all repositories prepared === "
336 
337  local -r ExperimentCodeVersion="$(cd "$ExperimentCodeRepoPath" && git describe --abbrev=0)" # use as tag
338 
339  # special: if no branch was requested in particular, we move to the tagged version of it
340  if [[ -z "$RequestedCodeBranch" ]]; then
341  for CodeRepoName in "${RepoNames[@]}" ; do
342  echo " === Picking tag ${ExperimentCodeVersion} for ${CodeRepoName} ==="
343  local CodeRepoPath="${CodeRepoPaths[$CodeRepoName]}"
344  git -C "$CodeRepoPath" checkout "$ExperimentCodeVersion" || echo "${CodeRepoName} does not have tag '${ExperimentCodeVersion}', we'll use the current branch ($(git -C "$CodeRepoPath" describe))."
345  done
346  echo " === tag ${ExperimentCodeVersion} selection completed ==="
347  fi
348 
349  GitDescription="$(cd "$ExperimentCodeRepoPath" && git describe 2> /dev/null)"
350  [[ $? == 0 ]] && echo "Repository status: ${GitDescription}"
351 
352  return 0
353 } # CheckOutSources()
354 
355 
356 
357 ################################################################################
358 function RunDoxygen() {
359 
360  #
361  # find a Doxygen configuration file
362  #
363  local -r ExperimentName="$1"
364  shift
365  local -a AdditionalRepositories=( "$@" )
366 
367  local MasterDoxyfile
368  # search for a Doxyfile in the current directory first
369  MasterDoxyfile="$(FindDoxyfile "$ExperimentName" "$(pwd)" )"
370  LASTFATAL "Can't find a doxygen configuration file for '${ExperimentName}'"
371 
372  local ExperimentCodeName="$(ExperimentCodeProduct "$ExperimentName" )"
373  CodeRepoNames=( "$ExperimentCodeName" "${AdditionalRepositories[@]}" )
374 
375  local DateTag="$(date '+%Y%m%d')"
376  local DoxygenLog="${LogDir%/}/$(basename "${MasterDoxyfile%.doxy*}")-${DateTag}.log"
377 
378  CheckOutSources "$ExperimentName" "${CodeRepoNames[@]}"
379 
380  # in the future this constraint can be relaxed:
381  local ExperimentCodeRepoPath="${CodeRepoPaths[$ExperimentCodeName]}"
382 
383  local -r ExperimentCodeVersion="$(cd "$ExperimentCodeRepoPath" && git describe --abbrev=0)" # use as tag
384 
385  mkdir -p "$LogDir"
386 
387  local -r Doxyfile="${TMPDIR:-/tmp}/${ExperimentCodeName}-${ExperimentCodeVersion}.doxy"
388  echo "Creating Doxygen configuration from '${MasterDoxyfile}'..."
389  PrepareDoxyfile "$MasterDoxyfile" "$Doxyfile"
390 
391  cat <<EOB
392 
393 Now starting Doxygen (log file: '${DoxygenLog}')
394 --------------------------------------------------------------------------------
395 
396 EOB
397 
398  local ConfiguredOutputDir MetadataFile
399  ConfiguredOutputDir="$(ExtractValueFromDoxyfile 'HTML_OUTPUT' "$Doxyfile")"
400  if [[ $? == 0 ]]; then
401  echo "Directory for HTML output: '${ConfiguredOutputDir}'"
402  MetadataFile="${ConfiguredOutputDir%/}/${MetadataFileRelPath}"
403  local OldRunDate OldExperimentCodeName OldVersion
404  OldRunDate="$(ExtractFromMetadata 'Date' "$MetadataFile")"
405  OldExperimentCodeName="$(ExtractFromMetadata 'ExperimentCode' "$MetadataFile")"
406  OldVersion="$(ExtractFromMetadata 'CodeVersion' "$MetadataFile")"
407  [[ -n "$OldRunDate" ]] && echo "Existing output created or updated on ${OldRunDate} for ${OldExperimentCodeName} ${OldVersion}."
408  else
409  echo "Could not detect the HTML output directory from '${Doxyfile}'"
410  ConfiguredOutputDir='' # probably redundant
411  fi
412 
413  if [[ -n "$ConfiguredOutputDir" ]] && [[ -d "$ConfiguredOutputDir" ]]; then
414  if [[ -n "$OldVersion" ]] && [[ -n "$OldExperimentCodeName" ]] \
415  && [[ "$OldVersion" == "$ExperimentCodeVersion" ]] \
416  && [[ "$OldExperimentCodeName" == "$ExperimentCodeName" ]] \
417  && isFlagUnset CleanOldDocs
418  then
419  echo "Existing output not removed as it is from the same version (run with \`--clean\` to override)."
420  else
421  echo "Removing old output ('${ConfiguredOutputDir}')..."
422  rm -rf "$ConfiguredOutputDir"
423  fi
424  fi
425 
426  local -r DoxygenName='doxygen'
427  local doxygen="$(which "${DoxygenName[@]}")"
428 
429  local -a Cmd=( $doxygen "$Doxyfile" "&>" "$DoxygenLog" )
430  echo "${Cmd[@]}"
431  eval "${Cmd[@]}"
432 
433  local -i ExitCode=$?
434 
435  if [[ -d "$ConfiguredOutputDir" ]]; then
436  mv "$Doxyfile" "$ConfiguredOutputDir" && echo "Doxygen configuration copied into '${ConfiguredOutputDir}'."
437  fi
438 
439  # restore the status of the repository
440  RestoreAllRepositories
441 
442 
443  if [[ -d "$ConfiguredOutputDir" ]]; then
444  mkdir -p "$(dirname "$MetadataFile")"
445  cat <<EOB
446 
447 Writing metadata into '${MetadataFile}'.
448 
449 EOB
450  ### BEGIN metadata version 1:
451  cat <<EOM > "$MetadataFile"
452 MetadataVersion = '${MetadataVersion}'
453 Experiment = '${ExperimentName}'
454 Date = '$(date)'
455 Host = '$(hostname)'
456 User = '$(whoami)'
457 Configuration = '${MasterDoxyfile}'
458 ExperimentCode = '${ExperimentCodeName}'
459 CodeVersion = '${ExperimentCodeVersion:-"n/a"}'
460 GITreference = '${GitDescription:-"n/a"}'
461 WordDirectory = '$(pwd)'
462 CommandLine = '${Cmd[@]}'
463 DoxygenPath = '${doxygen}'
464 DoxygenVersion = '$($doxygen --version)'
465 LogFile = '${DoxygenLog}'
466 ExitCode = '${ExitCode}'
467 EOM
468 
469  ### END metadata version 1
470 
471  ### BEGIN metadata version 2:
472  cat <<EOM >> "$MetadataFile"
473 AdditionalRepos = ( ${AdditionalRepositories[@]} )
474 EOM
475 
476  ### END metadata version 2
477  fi
478 
479 
480  cat <<EOB
481 
482 ${ExperimentCodeVersion:+"This was for ${ExperimentCodeName} ${ExperimentCodeVersion}."}
483 
484 --------------------------------------------------------------------------------
485 Doxygen completed its execution.
486 
487 EOB
488 
489  return $ExitCode
490 
491 } # RunDoxygen()
492 
493 
494 
495 ################################################################################
496 ### Start here!
497 ################################################################################
498 #
499 # parameter parsing
500 #
501 declare -i NoMoreOptions
502 declare -i DoVersion=0 DoHelp=0
503 declare -i CleanOldDocs=0 ForceTags=0 UpdateBranch=1
504 declare RequestedExperimentCodeBranch
505 declare ExitWithCode
506 declare Param
507 for (( iParam = 1 ; iParam <= $# ; ++iParam )); do
508  Param="${!iParam}"
509  if isFlagUnset NoMoreOptions && [[ "${Param:0:1}" == '-' ]]; then
510  case "$Param" in
511  ( '--experiment='* ) ExperimentName="${Param#--*=}" ;;
512  ( '--reponame='* ) ExperimentCodeName="${Param#--*=}" ;;
513  ( '--branch='* | '--tag='* | '--commit='* )
514  RequestedExperimentCodeBranch="${Param#--*=}" ;;
515  ( '--currentbranch' | '-c' ) RequestedExperimentCodeBranch='HEAD' ;;
516  ( '--clean' | '-C' ) CleanOldDocs=1 ;;
517  ( '--force-tags' ) ForceTags=1 ;;
518  ( '--version' | '-V' ) DoVersion=1 ;;
519  ( '--help' | '-h' | '-?' ) DoHelp=1 ;;
520  ( '-' | '--' ) NoMoreOptions=1 ;;
521  ( * )
522  ERROR "Unknown option: '${Param}'."
523  ExitWithCode=1
524  esac
525  else
526  PositionalArguments+=( "$Param" )
527  fi
528 done
529 
530 if [[ "${#PositionalArguments[@]}" -gt 0 ]]; then
531  FATAL 1 "Found ${#PositionalArguments[@]} spurious arguments on command line: ${PositionalArguments[@]}."
532 fi
533 
534 
535 : ${ExperimentName:="$(FindExperiment)"}
536 LASTFATAL "Can't detect the experiment name."
537 
538 : ${ExperimentCodeName:="$(ExperimentCodeProduct "$ExperimentName")"}
539 LASTFATAL "Can't put together the experiment code repository name for '${ExperimentName}'."
540 
541 
542 if isFlagSet DoVersion ; then
543  printVersion
544  [[ -z "$ExitWithCode" ]] && ExitWithCode=0
545 fi
546 if isFlagSet DoHelp ; then
547  printHelp
548  [[ -z "$ExitWithCode" ]] && ExitWithCode=0
549 fi
550 
551 [[ -n "$ExitWithCode" ]] && exit "$ExitWithCode"
552 
553 
554 ################################################################################
555 declare -i nErrors
556 cat <<EOB
557 
558 ================================================================================
559 Set up
560 --------------------------------------------------------------------------------
561 
562 EOB
563 
564 GITrepoName="$(GITrepositoryName)"
565 [[ $? == 0 ]] && [[ "$GITrepoName" == "$ExperimentCodeName" ]] && FATAL 1 "Please do not run this script from within a GIT repository '${ExperimentCodeName}'."
566 
567 ExperimentSetup "$ExperimentName"
568 LASTFATAL "Set up not completed, can't proceed."
569 
570 cat <<EOB
571 
572 ================================================================================
573 ROOT tag
574 --------------------------------------------------------------------------------
575 
576 EOB
577 UpdateROOTtag || let ++nErrors
578 
579 cat <<EOB
580 
581 ================================================================================
582 LArSoft tag
583 --------------------------------------------------------------------------------
584 
585 EOB
586 UpdateLArSoftTag || let ++nErrors
587 
588 cat <<EOB
589 
590 ================================================================================
591 All setup done${nErrors:+" (with ${nErrors})"}
592 --------------------------------------------------------------------------------
593 
594 EOB
595 
596 [[ -z "$nErrors" ]] || exit 1
597 
598 
599 cat <<EOB
600 
601 ================================================================================
602 Now running Doxygen
603 --------------------------------------------------------------------------------
604 
605 EOB
606 
607 RunDoxygen "$ExperimentName" "${AdditionalRepoNames[@]}"
bool printHelp
do source
#define the
SCRIPTNAME
Definition: publish.sh:21
BEGIN_PROLOG V
return match has_match and(match.match_pdg==11 or match.match_pdg==-11)
then echo Cowardly refusing to create a new FHiCL file with the same name as the original one('${SourceName}')." >&2 exit 1 fi echo "'$
if &&[-z"$BASH_VERSION"] then echo Attempting to switch to bash bash shellSwitch exit fi &&["$1"= 'shellSwitch'] shift declare a IncludeDirectives for Dir in
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker options
do i e
then echo fcl name
experiment
Definition: ffttest.sh:3