7 Author : Valentin Kuznetsov <vkuznet@gmail.com> 8 Description: AbstractGenerator class provides basic functionality 9 to generate CMSSW class from given template 11 from __future__
import print_function
20 from FWCore.Skeletons.utils
import parse_word, functor, user_info, tree, template_directory
24 AbstractPkg takes care how to generate code from template/PKG 25 package area. The PKG can be any directory which may include 26 any types of files, e.g. C++ (.cc), python (.py), etc. 27 This class relies on specific logic which we outline here: 29 - each template may use tags defined with double underscores 30 enclosure, e.g. __class__, __record__, etc. 31 - each template may have example tags, such tags should 32 start with @example_. While processing template user may 33 choose to strip them off or keep the code behind those tags 34 - in addition user may specify pure python code which can 35 operate with user defined tags. This code snipped should 36 be enclosed with #python_begin and #python_end lines 37 which declares start and end of python block 50 self.
date = time.strftime(
"%a, %d %b %Y %H:%M:%S GMT", time.gmtime())
55 "Scan template files and return example tags" 57 sdir =
'%s/%s' % (self.
tdir, self.
tmpl)
58 for name
in os.listdir(sdir):
63 fname = os.path.join(sdir, name)
64 with open(fname,
'r') as stream: 65 for line
in stream.readlines():
66 if line.find(
'@example_') != -1:
67 keys += [k
for k
in line.split()
if \
68 k.find(
'@example_') != -1]
72 "Print out template example tags" 77 "Scan template files and return template tags" 79 sdir =
'%s/%s' % (self.
tdir, self.
tmpl)
80 for name
in os.listdir(sdir):
85 fname = os.path.join(sdir, name)
86 with open(fname,
'r') as stream: 87 for line
in stream.readlines():
88 if line.find(
'__') != -1:
93 "Print out template keys" 99 Determine either skip or keep given line based on class tags 103 keep_etags = self.
config.get(
'tmpl_etags', [])
104 for tag
in tmpl_etags:
105 for valid_tag
in keep_etags:
106 if line.find(valid_tag) != -1:
107 line = line.replace(valid_tag,
'')
109 if line.find(tag) != -1:
112 if len(keep_etags) == 0:
113 return line.replace(
'@default',
'')
114 if '@default' in line:
118 def write(self, fname, tmpl_name, kwds):
119 "Create new file from given template name and set of arguments" 122 if os.path.exists(fname):
124 with open(fname,
'w')
as stream:
125 for line
in open(tmpl_name,
'r').readlines(): 129 if line.find(
'#python_begin') != -1:
132 if line.find(
'#python_end') != -1:
136 if code
and not read_code:
142 for key, val
in kwds.items():
143 if isinstance(val, str):
144 line = line.replace(key, val)
148 "Return keyword arguments to be used in methods" 149 kwds = {
'__pkgname__': self.
config.get(
'pkgname',
'Package'),
150 '__author__': self.
author,
151 '__date__': self.
date,
152 '__class__': self.
pname,
153 '__class_lowercase__': self.
pname.lower(),
154 '__class_space__':
" "*len(self.
pname),
155 '__name__': self.
pname,
156 '__subsys__': self.
config.get(
'subsystem',
'Subsystem')}
157 args = self.
config.get(
'args',
None)
160 print(
"Template tags:")
165 "Generate package templates in a given directory" 171 tmpl_files = self.
config.get(
'tmpl_files',
'all')
178 if os.path.isdir(self.
pname):
179 msg =
"Can't create package '%s'\n" % self.
pname 180 msg +=
"Directory %s is already exists" % self.
pname 183 os.makedirs(self.
pname)
187 sdir = os.path.join(self.
tdir, self.
tmpl)
188 sources = [s
for s
in os.listdir(sdir) \
189 if s !=
'Driver.dir' and s.find(
'~') == -1]
190 driver = os.path.join(sdir,
'Driver.dir')
191 if os.path.isfile(driver):
192 sources = [s.replace(
'\n',
'')
for s
in open(driver,
'r').readlines()] 194 sources.remove(
'CVS')
198 names = set([s.split(
'.')[0]
for s
in sources])
199 if names == set([
'Skeleton']):
201 _, ext = os.path.splitext(self.
pname)
202 sources = [s
for s
in sources
if s.rfind(ext) != -1]
206 msg =
'Unable to find skeleton for extension "%s"' % ext
209 bdir = os.environ.get(
'CMSSW_BASE',
'')
211 ldir = os.getcwd().
split(
'/')[-1]
213 subsys = kwds[
'__subsys__']
214 pkgname = kwds[
'__pkgname__']
215 if sources == [
'Skeleton.cc',
'Skeleton.h']:
216 if ldir ==
'interface' and os.getcwd().
find(bdir) != -1:
217 idir =
'%s/%s/interface/' % (subsys, pkgname)
220 elif sources == [
'Skeleton.cc']
and \
221 len(dirs) == 5
and dirs[0] ==
'' and dirs[1] ==
'src':
222 idir =
'%s/%s/interface/' % (subsys, pkgname)
223 elif sources == [
'Skeleton.h']
and ldir ==
'interface' and \
224 len(dirs) == 5
and dirs[0] ==
'' and dirs[1] ==
'src':
225 idir =
'%s/%s/interface/' % (subsys, pkgname)
226 kwds.update({
'__incdir__': idir})
232 if tmpl_files !=
'all':
233 fname, ext = os.path.splitext(src)
234 if tmpl_files != ext:
239 src = src.split(
'/')[-1]
242 items = src.split(
'/')
246 tmpl_name = os.path.join(sdir, items[-1])
247 if os.path.isfile(tmpl_name):
252 if items[-1] ==
'testBuildFile.xml':
253 name2gen =
'/'.
join(src.split(
'/')[:-1])+
'/BuildFile.xml' 254 if -1 !=tname.split(
'.')[0].
find(self.
tmpl):
255 name2gen = name2gen.replace(self.
tmpl, self.
pname)
256 name2gen = os.path.join(os.getcwd(), name2gen)
258 print(
"Create", name2gen)
260 if not os.path.isdir(name2gen):
261 os.makedirs(name2gen)
263 fdir = os.path.dirname(name2gen)
264 if not os.path.isdir(fdir):
266 self.
write(name2gen, tmpl_name, kwds)
267 gen_files.append(name2gen.split(
'/')[-1])
269 msg =
'New package "%s" of %s type is successfully generated' \
272 msg =
'Generated %s file' %
', '.
join(gen_files)
273 if len(gen_files) > 1:
278 if msg.find(
'New package') != -1:
def __init__(self, config=None)
def user_info(ainput=None)
def replace(string, replacements)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
def parse_etags(self, line)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
def split(sequence, size)
static std::string join(char **cmd)
def write(self, fname, tmpl_name, kwds)
def functor(code, kwds, debug=0)