Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-01 23:40:21

0001 #-*- coding: utf-8 -*-
0002 #pylint: disable-msg=W0122,R0914
0003 
0004 """
0005 File       : utils.py
0006 Author     : Valentin Kuznetsov <vkuznet@gmail.com>
0007 Description: Utilities module
0008 """
0009 
0010 # system modules
0011 from builtins import range
0012 import os
0013 import re
0014 import sys
0015 import pwd
0016 import pprint
0017 import subprocess
0018 
0019 # template tag pattern
0020 TAG = re.compile(r'[a-zA-Z0-9]')
0021 
0022 def template_directory():
0023     "Return location of template directory"
0024     mkTemplates = "src/FWCore/Skeletons/mkTemplates"
0025     # Check developer area first
0026     if "CMSSW_BASE" in os.environ:
0027         ret = os.path.join(os.environ["CMSSW_BASE"], mkTemplates)
0028         if os.path.exists(ret):
0029             return ret
0030     # Then release area
0031     ret = os.path.join(os.environ["CMSSW_RELEASE_BASE"], mkTemplates)
0032     if not os.path.exists(ret):
0033         raise Exception("Did not find 'FWCore/Skeletons/mkTemplates' directory in the developer area nor in the release area")
0034     return ret
0035 
0036 def parse_word(word):
0037     "Parse word which contas double underscore tag"
0038     output = set()
0039     words  = word.split()
0040     for idx in range(0, len(words)):
0041         pat = words[idx]
0042         if  pat and len(pat) > 4 and pat[:2] == '__': # we found enclosure
0043             tag = pat[2:pat.rfind('__')]
0044             if  tag.find('__') != -1: # another pattern
0045                 for item in tag.split('__'):
0046                     if  TAG.match(item):
0047                         output.add('__%s__' % item)
0048             else:
0049                 output.add('__%s__' % tag)
0050     return output
0051 
0052 def test_env(tdir, tmpl):
0053     """
0054     Test user environment, look-up if user has run cmsenv, otherwise
0055     provide meaningful error message back to the user.
0056     """
0057     if  not tdir or not os.path.isdir(tdir):
0058         print("Unable to access template dir: %s" % tdir)
0059         sys.exit(1)
0060     if  not os.listdir(tdir):
0061         print("No template files found in template dir %s" % tdir)
0062         sys.exit(0)
0063     if  not tmpl:
0064         msg  = "No template type is provided, "
0065         msg += "see available templates via --templates option"
0066         print(msg)
0067         sys.exit(1)
0068 
0069 def functor(code, kwds, debug=0):
0070     """
0071     Auto-generate and execute function with given code and configuration
0072     For details of compile/exec/eval see
0073     http://lucumr.pocoo.org/2011/2/1/exec-in-python/
0074     """
0075     args  = []
0076     for key, val in kwds.items():
0077         if  isinstance(val, str):
0078             arg = '%s="%s"' % (key, val)
0079         elif isinstance(val, list):
0080             arg = '%s=%s' % (key, val)
0081         else:
0082             msg = 'Unsupported data type "%s" <%s>' % (val, type(val)) 
0083             raise Exception(msg)
0084         args.append(arg)
0085     func  = '\nimport sys'
0086     func += '\nimport io'
0087     func += "\ndef func(%s):\n" % ','.join(args)
0088     func += code
0089     func += """
0090 def capture():
0091     "Capture snippet printous"
0092     old_stdout = sys.stdout
0093     sys.stdout = io.StringIO()
0094     func()
0095     out = sys.stdout.getvalue()
0096     sys.stdout = old_stdout
0097     return out\n
0098 capture()\n"""
0099     if  debug:
0100         print("\n### generated code\n")
0101         print(func)
0102     # compile python code as exec statement
0103     obj   = compile(func, '<string>', 'exec')
0104     # define execution namespace
0105     namespace = {}
0106     # execute compiled python code in given namespace
0107     exec(obj, namespace)
0108     # located generated function object, run it and return its results
0109     return namespace['capture']()
0110 
0111 def user_info(ainput=None):
0112     "Return user name and office location, based on UNIX finger"
0113     if  ainput:
0114         return ainput
0115     pwdstr = pwd.getpwnam(os.getlogin())
0116     author = pwdstr.pw_gecos
0117     if  author and isinstance(author, str):
0118         author = author.split(',')[0]
0119     return author
0120 
0121 def code_generator(kwds):
0122     """
0123     Code generator function, parse user arguments, load and
0124     return appropriate template generator module.
0125     """
0126     debug = kwds.get('debug', None)
0127     if  debug:
0128         print("Configuration:")
0129         pprint.pprint(kwds)
0130     try:
0131         klass  = kwds.get('tmpl')
0132         mname  = 'FWCore.Skeletons.%s' % klass.lower()
0133         module = __import__(mname, fromlist=[klass])
0134     except ImportError as err:
0135         klass  = 'AbstractPkg'
0136         module = __import__('FWCore.Skeletons.pkg', fromlist=[klass])
0137         if  debug:
0138             print("%s, will use %s" % (str(err), klass))
0139     obj = getattr(module, klass)(kwds)
0140     return obj
0141 
0142 def tree(idir):
0143     "Print directory content, similar to tree UNIX command"
0144     if  idir[-1] == '/':
0145         idir = idir[-1]
0146     dsep = ''
0147     fsep = ''
0148     dtot = -1 # we'll not count initial directory
0149     ftot = 0
0150     for root, dirs, files in os.walk(idir):
0151         dirs  = root.split('/')
0152         ndirs = len(dirs)
0153         if  ndirs > 1:
0154             dsep  = '|  '*(ndirs-1)
0155         print('%s%s/' % (dsep, dirs[-1]))
0156         dtot += 1
0157         for fname in files:
0158             fsep = dsep + '|--'
0159             print('%s %s' % (fsep, fname))
0160             ftot += 1
0161     if  dtot == -1 or not dtot:
0162         dmsg = ''
0163     else:
0164         dmsg = '%s directories,' % dtot
0165     if  ftot:
0166         fmsg = '%s file' % ftot
0167         if  ftot > 1:
0168             fmsg += 's'
0169     else:
0170         fmsg = ''
0171     if  dmsg and fmsg:
0172         print("Total: %s %s" % (dmsg, fmsg))
0173     else:
0174         print("No directories/files in %s" % idir)