Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:03:46

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