Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:28:55

0001 #!/bin/bash
0002 
0003 # Deep-searches CMSSW config python files, and displays the tree structure of all imported files in it.
0004 # K. Banicz
0005 
0006 function findFileFor(){
0007     # Return 0 if a file given by absolute path exists, or it converts a python name 
0008     # to a file name and returns 0 if it finds it in CMSSW_SEARCH_PATH. 
0009 
0010     # argument 1: the sought file, or the python name to seek the corresponding file for
0011 
0012     local FILE_NAME
0013     if [ ${1:0:1} == "/" ]; then
0014         [ -f $1 ] && FOUND_FILE=$1 && return 0
0015     else
0016         FILE_NAME=$( echo $1 | sed -n -e 's:\([[:alnum:]_]\+\)[/.]\([[:alnum:]_]\+\)[/.]\([[:alnum:]_/.]\+\)$:\1/\2/python/\3:p' | sed -e 's:[\.]:/:g' ).py
0017         IFS=:
0018         for SEARCH_PATH in $CMSSW_SEARCH_PATH; do
0019             [ -f $SEARCH_PATH/$FILE_NAME ] && FOUND_FILE=$SEARCH_PATH/$FILE_NAME && return 0
0020         done    
0021     fi
0022 
0023 
0024     # Not found.
0025     FOUND_FILE=""
0026     return 1
0027 }
0028 
0029 function findInFile(){
0030     # Finds all occurrences of the sought expression in the file.
0031     # Invokes itself on all included files too.
0032     # argument 1: indent
0033     # argument 2: the searched file
0034     # argument 3: the sought expression
0035 
0036     #
0037     # Load 'import'-s and 'load'-s into an array (discard FWCore.ParameterSet as it leads to an infinite loop)
0038     #
0039     # sed'd regex below will extract the word in capital from the following example lines ('...' means any string):
0040     #    import FINDS.THIS.WORD ...
0041     #    from FINDS.THIS.WORD ...
0042     #    execfile("FINDS/THIS/WORD")
0043     #    process.load("FINDS.THIS/WORD")
0044     # And the same things inside an 'exec' statement, too:
0045     #    exec 'import FINDS.THIS.WORD ...'
0046     #    exec "from FINDS.THIS.WORD ..."
0047     #    exec 'execfile("FINDS/THIS/WORD")'
0048     #    exec 'process.load("FINDS.THIS/WORD")'
0049 
0050     IFS="
0051 "
0052     local -a IMPORTS_AND_LOADS_ARRAY
0053     IMPORTS_AND_LOADS_ARRAY=( $( sed -n -e "s:^[[:space:]]*\(exec[[:space:]]\+[\"']\)\?\(from[[:space:]]\+\|import[[:space:]]\+\|process\.load[[:space:]]*([[:space:]]*[\"']\|execfile[[:space:]]*([[:space:]]*[\"']\)[[:space:]]*\(\([^[:space:])\"'#]\+[/.]\)\+[^[:space:])\"'#]\+\).*:\3:p" $2 | grep -v "^FWCore.ParameterSet" ) )
0054 
0055     #
0056     # First list all occurrences in this file:
0057     #
0058     if [ ${#3} -ne 0 ]; then
0059         if [ $EDMCONFIGTREE_TREE == "false" ]; then
0060             grep -H -n $3 $2
0061         else
0062             grep $3 $2 | while read LINE_WITH_MATCH; do
0063                 if [ $EDMCONFIGTREE_COLOR == "false" ]; then
0064                     [ ${#IMPORTS_AND_LOADS_ARRAY[@]} -gt 0 ] && echo -n "$1  |" || echo -n "$1  "
0065                     echo "     $LINE_WITH_MATCH" | grep $3
0066                 else
0067                     [ ${#IMPORTS_AND_LOADS_ARRAY[@]} -gt 0 ] && echo -n "$1  |" || echo -n "$1  "
0068                     echo "     $LINE_WITH_MATCH" | grep --color $3
0069                 fi
0070             done
0071         fi
0072     fi
0073 
0074     #
0075     # Now find all 'import'-ed and 'process.load'-ed files and search them too
0076     #
0077     local I
0078     for (( I=0; I<${#IMPORTS_AND_LOADS_ARRAY[@]}; I++ )); do
0079         local PYTHON_NAME=${IMPORTS_AND_LOADS_ARRAY[$I]}
0080         local INDENT
0081         local II
0082         ((II=I+1))
0083         if [ $EDMCONFIGTREE_TREE == "false" ]; then
0084             if findFileFor "$PYTHON_NAME"; then
0085                 [ $SHOW_ABSOLUTE_PATH == "true" ] && echo "$FOUND_FILE" || echo "$PYTHON_NAME"
0086                 findInFile "" "$FOUND_FILE" "$3"
0087             else
0088                 echo "${PYTHON_NAME} *** not found in CMSSW_SEARCH_PATH ***"
0089             fi
0090         else
0091             if findFileFor "$PYTHON_NAME"; then
0092                 [ $SHOW_ABSOLUTE_PATH == "true" ] && NAME_TO_SHOW=FOUND_FILE || NAME_TO_SHOW=PYTHON_NAME
0093                 if [ $EDMCONFIGTREE_COLOR == "false" ]; then
0094                     echo "$1  |- ${!NAME_TO_SHOW}"
0095                     [ $II -ge ${#IMPORTS_AND_LOADS_ARRAY[@]} ] && INDENT="$1   " || INDENT="$1  |"
0096                 else
0097                     [[ $SHOW_ABSOLUTE_PATH == "true" || ${PYTHON_NAME:0:1} == "/" ]] && echo "$1    ${FOUND_FILE%%*([^/])}${FOUND_FILE##*/}" || echo "$1    ${PYTHON_NAME%%*([^.])}${PYTHON_NAME##*.}"
0098                     [ $II -ge ${#IMPORTS_AND_LOADS_ARRAY[@]} ] && INDENT="$1   " || INDENT="$1  |"
0099                 fi
0100                 findInFile "$INDENT" "$FOUND_FILE" "$3"
0101             else
0102                 if [ $EDMCONFIGTREE_COLOR == "false" ]; then
0103                     echo "$1  |- ${PYTHON_NAME} *** not found in CMSSW_SEARCH_PATH ***"
0104                 else
0105                     [ ${PYTHON_NAME:0:1} == "/" ] && echo "$1    ${PYTHON_NAME%%*([^/])}${PYTHON_NAME##*/}" || echo -n "$1    ${PYTHON_NAME%%*([^.])}${PYTHON_NAME##*.} "
0106                     echo " not found in CMSSW_SEARCH_PATH "
0107                 fi
0108             fi
0109         fi
0110     done
0111 
0112 }
0113 
0114 # Take care of the relevant shell variables.
0115 ${EDMCONFIGTREE_COLOR:=true}
0116 ${EDMCONFIGTREE_TREE:=true}
0117 [ $EDMCONFIGTREE_TREE == "false" ] && EDMCONFIGTREE_COLOR=false
0118 
0119 # Invoked with a wrong number of arguments. Give help.
0120 if [ $# -eq 0 ] || [ $# -gt 2 ]; then
0121     cat <<EOF
0122 edmConfigTree displays the complete tree of imported files in a given CMSSW configuration file,
0123 and optionally searches them recursively for a regular expression.
0124 
0125 Usage:
0126            edmConfigTree [regex] configuration_file
0127                regex             :    regular expression, as with grep
0128                configuration_file:    CMSSW configuration python file
0129                                       (Give absolute path to display imported files' resolved absolute path.)
0130 
0131            Note that the shell variable CMSSW_SEARCH_PATH must be set before edmConfigTree is invoked.
0132 
0133            To suppress colors, set the shell variable EDMCONFIGTREE_COLOR=false
0134            To suppress the tree structure (and the colors), set the shell variable EDMCONFIGTREE_TREE=false
0135 
0136 Examples:
0137            Display the tree of all imported files in FullChainExample_cfg.py:
0138                  edmConfigTree FullChainExample_cfg.py
0139            Display with absolute paths the tree of all imported files in FullChainExample_cfg.py:
0140                  edmConfigTree /full/path/to/FullChainExample_cfg.py
0141            Recursively search all imported files for "Verbosity":
0142                  edmConfigTree Verbosity FullChainExample_cfg.py
0143            Recursively search all imported files for "Time" or "time":
0144                  edmConfigTree "[Tt]ime" FullChainExample_cfg.py
0145 EOF
0146     exit 1
0147 fi
0148 
0149 # Exit if CMSSW_SEARCH_PATH is not set.
0150 if [ ${#CMSSW_SEARCH_PATH} -eq 0 ]; then
0151     echo "CMSSW_SEARCH_PATH is not set. Exiting."
0152     exit 1
0153 fi
0154 
0155 # Set extglob for extended pattern matching features in parameter expansion.
0156 shopt -s extglob
0157 
0158 # If invoked with one argument, list files.
0159 if [ $# -eq 1 ]; then
0160     FILE=$1
0161     [ ${FILE:0:1} == "/" ] && SHOW_ABSOLUTE_PATH=true || SHOW_ABSOLUTE_PATH=false
0162     [ $EDMCONFIGTREE_COLOR == "false" ] && echo "$FILE" || echo "  ${FILE%%*([^/])}${FILE##*/}"
0163     findInFile " " $1
0164 fi
0165 
0166 # If invoked with two arguments, list files and search them.
0167 if [ $# -eq 2 ]; then
0168     FILE=$2
0169     [ ${FILE:0:1} == "/" ] && SHOW_ABSOLUTE_PATH=true || SHOW_ABSOLUTE_PATH=false
0170     [ $EDMCONFIGTREE_COLOR == "false" ] && echo "$FILE" || echo "  ${FILE%%*([^/])}${FILE##*/}"
0171     findInFile " " $2 "$1"
0172 fi