CMS 3D CMS Logo

Public Member Functions | Public Attributes

pkg::AbstractPkg Class Reference

List of all members.

Public Member Functions

def __init__
def generate
def get_kwds
def parse_etags
def print_etags
def print_tags
def tmpl_etags
def tmpl_tags
def write

Public Attributes

 author
 config
 date
 debug
 not_in_dir
 pname
 rcsid
 tdir
 tmpl

Detailed Description

AbstractPkg takes care how to generate code from template/PKG
package area. The PKG can be any directory which may include
any types of files, e.g. C++ (.cc), python (.py), etc.
This class relies on specific logic which we outline here:

    - each template may use tags defined with double underscores
      enclosure, e.g. __class__, __record__, etc.
    - each template may have example tags, such tags should
      start with @example_. While processing template user may
      choose to strip them off or keep the code behind those tags
    - in addition user may specify pure python code which can
      operate with user defined tags. This code snipped should
      be enclosed with #python_begin and #python_end lines
      which declares start and end of python block

Definition at line 21 of file pkg.py.


Constructor & Destructor Documentation

def pkg::AbstractPkg::__init__ (   self,
  config = None 
)

Definition at line 38 of file pkg.py.

00039                                    :
00040         super(AbstractPkg, self).__init__()
00041         if  not config:
00042             self.config = {}
00043         else:
00044             self.config = config
00045         self.pname  = self.config.get('pname', None)
00046         self.tmpl   = self.config.get('tmpl', None)
00047         self.debug  = self.config.get('debug', 0)
00048         self.tdir   = self.config.get('tmpl_dir')
00049         self.author = user_info(self.config.get('author', None))
00050         self.date   = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
00051         self.rcsid  = '$%s$' % 'Id' # CVS commit is too smart
00052         self.not_in_dir = self.config.get('not_in_dir', [])
        

Member Function Documentation

def pkg::AbstractPkg::generate (   self)

Definition at line 160 of file pkg.py.

00161                       :
00162         "Generate package templates in a given directory"
00163 
00164         # keep current location, since generate will switch directories
00165         cdir = os.getcwd()
00166 
00167         # read from configutation which template files to create
00168         tmpl_files = self.config.get('tmpl_files', 'all')
00169 
00170         # setup keyword arguments which we'll pass to write method
00171         kwds = self.get_kwds()
00172 
00173         # create template package dir and cd into it
00174         if  tmpl_files == 'all' and self.tmpl not in self.not_in_dir:
00175             if  os.path.isdir(self.pname):
00176                 msg  = "Can't create package '%s'\n" % self.pname
00177                 msg += "Directory %s is already exists" % self.pname
00178                 print msg
00179                 sys.exit(1)
00180             os.makedirs(self.pname)
00181             os.chdir(self.pname)
00182 
00183         # read directory driver information and create file list to generate
00184         sdir    = os.path.join(self.tdir, self.tmpl)
00185         sources = [s for s in os.listdir(sdir) \
00186                 if s != 'Driver.dir' and s.find('~') == -1]
00187         driver  = os.path.join(sdir, 'Driver.dir')
00188         if  os.path.isfile(driver):
00189             sources = [s.replace('\n', '') for s in open(driver, 'r').readlines()]
00190         if  'CVS' in sources:
00191             sources.remove('CVS')
00192 
00193         # special case of Skeleton, which requires to generate only given
00194         # file type if self.pname has extension of that type
00195         names = set([s.split('.')[0] for s in sources])
00196         if  names == set(['Skeleton']):
00197             if  self.pname.find('.') != -1:
00198                 _, ext = os.path.splitext(self.pname)
00199                 sources = [s for s in sources if s.rfind(ext) != -1]
00200                 self.pname = self.pname.replace(ext, '')
00201                 kwds = self.get_kwds()
00202                 if  not sources:
00203                     msg = 'Unable to find skeleton for extension "%s"' % ext
00204                     print msg
00205                     sys.exit(1)
00206             bdir = os.environ.get('CMSSW_BASE', '')
00207             dirs = os.getcwd().replace(bdir, '').split('/')
00208             ldir = os.getcwd().split('/')[-1]
00209             idir = ''
00210             subsys  = kwds['__subsys__']
00211             pkgname = kwds['__pkgname__']
00212             if  sources == ['Skeleton.cc', 'Skeleton.h']:
00213                 if  ldir == 'interface' and os.getcwd().find(bdir) != -1:
00214                     idir = '%s/%s/interface/' % (subsys, pkgname)
00215             # run within some directory of the Sybsystem/Pkg area
00216             # and only for mkskel <file>.cc
00217             elif sources == ['Skeleton.cc'] and \
00218                 len(dirs) == 5 and dirs[0] == ''  and dirs[1] == 'src':
00219                 idir = '%s/%s/interface/' % (subsys, pkgname)
00220             elif sources == ['Skeleton.h'] and ldir == 'interface' and \
00221                 len(dirs) == 5 and dirs[0] == ''  and dirs[1] == 'src':
00222                 idir = '%s/%s/interface/' % (subsys, pkgname)
00223             kwds.update({'__incdir__': idir})
00224 
00225         # loop over source files, create dirs as necessary and generate files
00226         # names for writing templates
00227         gen_files = []
00228         for src in sources:
00229             if  tmpl_files != 'all':
00230                 fname, ext = os.path.splitext(src)
00231                 if  tmpl_files != ext:
00232                     continue
00233                 src = src.split('/')[-1]
00234             if  self.debug:
00235                 print "Read", src
00236             items = src.split('/')
00237             if  items[-1] == '/':
00238                 items = items[:-1]
00239             tname     = items[-1] # template file name
00240             tmpl_name = os.path.join(sdir, items[-1]) # full tmpl file name
00241             if  os.path.isfile(tmpl_name):
00242                 ftype = 'file'
00243             else:
00244                 ftype = 'dir'
00245             name2gen  = src # new file we'll create
00246             if  tname.split('.')[0] == self.tmpl: # need to substitute
00247                 name2gen  = name2gen.replace(self.tmpl, self.pname)
00248             name2gen  = os.path.join(os.getcwd(), name2gen)
00249             if  self.debug:
00250                 print "Create", name2gen
00251             if  ftype == 'dir':
00252                 if  not os.path.isdir(name2gen):
00253                     os.makedirs(name2gen)
00254                 continue # we're done with dir
00255             fdir = os.path.dirname(name2gen)
00256             if  not os.path.isdir(fdir):
00257                 os.makedirs(fdir)
00258             self.write(name2gen, tmpl_name, kwds)
00259             gen_files.append(name2gen.split('/')[-1])
00260         if  tmpl_files == 'all' and self.tmpl not in self.not_in_dir:
00261             msg  = 'New package "%s" of %s type is successfully generated' \
00262                     % (self.pname, self.tmpl)
00263         else:
00264             msg = 'Generated %s file' % ', '.join(gen_files)
00265             if  len(gen_files) > 1:
00266                 msg += 's'
00267         print msg
00268         # return back where we started
00269         os.chdir(cdir)
00270         if  msg.find('New package') != -1:
00271             tree(self.pname)
def pkg::AbstractPkg::get_kwds (   self)

Definition at line 143 of file pkg.py.

00144                       :
00145         "Return keyword arguments to be used in methods"
00146         kwds  = {'__pkgname__': self.config.get('pkgname', 'Package'),
00147                  '__author__': self.author,
00148                  '__user__': os.getlogin(),
00149                  '__date__': self.date,
00150                  '__class__': self.pname,
00151                  '__name__': self.pname,
00152                  '__rcsid__': self.rcsid,
00153                  '__subsys__': self.config.get('subsystem', 'Subsystem')}
00154         args = self.config.get('args', None)
00155         kwds.update(args)
00156         if  self.debug:
00157             print "Template tags:"
00158             pprint.pprint(kwds)
00159         return kwds

def pkg::AbstractPkg::parse_etags (   self,
  line 
)
Determine either skip or keep given line based on class tags 
meta-strings

Definition at line 96 of file pkg.py.

00097                                :
00098         """
00099         Determine either skip or keep given line based on class tags 
00100         meta-strings
00101         """
00102         tmpl_etags = self.tmpl_etags()
00103         keep_etags = self.config.get('tmpl_etags', [])
00104         for tag in tmpl_etags:
00105             if  keep_etags:
00106                 for valid_tag in keep_etags:
00107                     if  line.find(valid_tag) != -1:
00108                         line = line.replace(valid_tag, '')
00109                         return line
00110             else:
00111                 if  line.find(tag) != -1:
00112                     line = line.replace(tag, '')
00113                     line = ''
00114                     return line
00115         return line

def pkg::AbstractPkg::print_etags (   self)

Definition at line 70 of file pkg.py.

00071                          :
00072         "Print out template example tags"
00073         for key in self.tmpl_etags():
00074             print key

def pkg::AbstractPkg::print_tags (   self)

Definition at line 91 of file pkg.py.

00092                         :
00093         "Print out template keys"
00094         for key in self.tmpl_tags():
00095             print key

def pkg::AbstractPkg::tmpl_etags (   self)

Definition at line 53 of file pkg.py.

00054                         :
00055         "Scan template files and return example tags"
00056         keys = []
00057         sdir = '%s/%s' % (self.tdir, self.tmpl)
00058         for name in os.listdir(sdir):
00059             if  name[-1] == '~':
00060                 continue
00061             if  name == 'CVS':
00062                 continue
00063             fname = os.path.join(sdir, name)
00064             with open(fname, 'r') as stream:
00065                 for line in stream.readlines():
00066                     if  line.find('@example_') != -1: # possible tag
00067                         keys += [k for k in line.split() if \
00068                                     k.find('@example_') != -1]
00069         return set(keys)

def pkg::AbstractPkg::tmpl_tags (   self)

Definition at line 75 of file pkg.py.

00076                        :
00077         "Scan template files and return template tags"
00078         keys = []
00079         sdir = '%s/%s' % (self.tdir, self.tmpl)
00080         for name in os.listdir(sdir):
00081             if  name[-1] == '~':
00082                 continue
00083             if  name == 'CVS':
00084                 continue
00085             fname = os.path.join(sdir, name)
00086             with open(fname, 'r') as stream:
00087                 for line in stream.readlines():
00088                     if  line.find('__') != -1: # possible key
00089                         keys += [k for k in parse_word(line)]
00090         return set(keys)

def pkg::AbstractPkg::write (   self,
  fname,
  tmpl_name,
  kwds 
)

Definition at line 116 of file pkg.py.

00117                                            :
00118         "Create new file from given template name and set of arguments"
00119         code = ""
00120         read_code = False
00121         with open(fname, 'w') as stream:
00122             for line in open(tmpl_name, 'r').readlines():
00123                 line = self.parse_etags(line)
00124                 if  not line:
00125                     continue
00126                 if  line.find('#python_begin') != -1:
00127                     read_code = True
00128                     continue
00129                 if  line.find('#python_end') != -1:
00130                     read_code = False
00131                 if  read_code:
00132                     code += line
00133                 if  code and not read_code:
00134                     res   = functor(code, kwds, self.debug)
00135                     stream.write(res)
00136                     code  = ""
00137                     continue
00138                 if  not read_code:
00139                     for key, val in kwds.items():
00140                         if  isinstance(val, basestring):
00141                             line = line.replace(key, val)
00142                     stream.write(line)


Member Data Documentation

Definition at line 38 of file pkg.py.

Definition at line 38 of file pkg.py.

Definition at line 38 of file pkg.py.

Definition at line 38 of file pkg.py.

Definition at line 38 of file pkg.py.

Definition at line 38 of file pkg.py.

Definition at line 38 of file pkg.py.

Definition at line 38 of file pkg.py.

Definition at line 38 of file pkg.py.