| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
merge_files.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2
3 # @file: GaudiPolicy/cmt/fragments/merge_files.py
4 # @purpose: merge_files <fragment> file into a 'per-project' <merged> file
5 # @author: Sebastien Binet <binet@cern.ch>
6
7 import os
8 import sys
9 from datetime import datetime
10 import locker
11
12 def mergeFiles( fragFileNames, mergedFileName, commentChar, doMerge, ignoreMissing ):
13
14 startMark = "%s --Beg " % commentChar
15 timeMark = "%s --Date inserted: %s" % (commentChar, datetime.now())
16 endMark = "%s --End " % commentChar
17 nameOffset = len(startMark)
18
19 basenames = map(os.path.basename, fragFileNames)
20
21 isNewFile = not os.path.exists(mergedFileName)
22
23 # create an empty file if it does not exist
24 # "append mode" ensures that, in case of two processes trying to
25 # create the file, they do not truncate each other file
26 if isNewFile:
27 # check if the destination directory exists
28 path_to_file = os.path.split(mergedFileName)[0]
29 if path_to_file and not os.path.isdir(path_to_file):
30 # if doesn't exist, create it
31 os.makedirs(path_to_file)
32 open(mergedFileName,'a')
33
34 mergedFile = open( mergedFileName, 'r+' )
35
36 # locking file, gaining exclusive access to it
37 lock = locker.lock( mergedFile )
38 try:
39
40 newLines = [ ]
41 skipBlock = ""
42 for line in mergedFile.readlines():
43 if line.startswith(startMark) and line[nameOffset:].strip() in basenames:
44 skipBlock = endMark + line[nameOffset:].strip()
45 # remove all the empty lines occurring before the start mark
46 while (len(newLines) > 0) and (newLines[-1].strip() == ''):
47 newLines.pop()
48 if not skipBlock:
49 newLines.append(line)
50 if line.startswith(skipBlock):
51 skipBlock = ""
52 if skipBlock:
53 print "WARNING: missing end mark ('%s')" % skipBlock
54
55 if doMerge:
56 for f in fragFileNames:
57 if ignoreMissing and not os.path.exists(f):
58 print "WARNING: '%s' does not exist, I'm ignoring it" % f
59 continue
60 # I do not want to add 2 empty lines at the beginning of a file
61 if newLines:
62 newLines.append('\n\n')
63 bf = os.path.basename(f)
64 newLines.append(startMark + bf + '\n')
65 newLines.append(timeMark + '\n')
66 fileData = open(f, 'r').read()
67 newLines.append(fileData)
68 if fileData and fileData[-1] != '\n':
69 newLines.append('\n')
70 newLines.append(endMark + bf + '\n')
71
72 mergedFile.seek(0)
73 mergedFile.truncate(0)
74 mergedFile.writelines(newLines)
75
76 finally:
77 # unlock file
78 locker.unlock( mergedFile )
79
80 return 0
81
82 if __name__ == "__main__":
83
84 from optparse import OptionParser
85 parser = OptionParser(usage="usage: %prog [options]")
86 parser.add_option(
87 "-i",
88 "--input-file",
89 action = "append",
90 dest = "fragFileNames",
91 default = [],
92 help = "The path and name of the file one wants to merge into the 'master' one"
93 )
94 parser.add_option(
95 "-m",
96 "--merged-file",
97 dest = "mergedFileName",
98 default = None,
99 help = "The path and name of the 'master' file which will hold the content of all the other fragment files"
100 )
101 parser.add_option(
102 "-c",
103 "--comment-char",
104 dest = "commentChar",
105 default = "#",
106 help = "The type of the commenting character for the type of files at hand (this is an attempt at handling the largest possible use cases)"
107 )
108 parser.add_option(
109 "--do-merge",
110 dest = "doMerge",
111 action = "store_true",
112 default = True,
113 help = "Switch to actually carry on with the merging procedure"
114 )
115 parser.add_option(
116 "--un-merge",
117 dest = "unMerge",
118 action = "store_true",
119 default = False,
120 help = "Switch to remove our fragment file from the 'master' file"
121 )
122 parser.add_option(
123 "--stamp-dir",
124 dest = "stampDir",
125 action = "store",
126 default = None,
127 help = "Create the stamp file in the specified directory. If not specified"
128 +" the directory of the source file is used."
129 )
130 parser.add_option(
131 "--no-stamp",
132 action = "store_true",
133 help = "Do no create stamp files."
134 )
135 parser.add_option(
136 "--ignore-missing",
137 dest = "ignoreMissing",
138 action = "store_true",
139 help = "Print a warning if a fragment file is missing, but do not fail."
140 )
141
142 (options, args) = parser.parse_args()
143
144 # ensure consistency...
145 options.doMerge = not options.unMerge
146
147 # allow command line syntax as
148 # merge_files.py [options] <fragment file1> [<fragment file2>...] <merged file>
149 if args:
150 options.mergedFileName = args[-1]
151 options.fragFileNames += args[:-1]
152
153 sc = 1
154 if not options.fragFileNames or \
155 not options.mergedFileName :
156 str(parser.print_help() or "")
157 print "*** ERROR ***",sys.argv
158 sys.exit(sc)
159 pass
160
161 if options.stampDir is None:
162 stampFileName = lambda x: x + ".stamp"
163 else:
164 stampFileName = lambda x: os.path.join(options.stampDir,
165 os.path.basename(x)
166 + ".stamp")
167 # Configure Python logging
168 import logging
169 logging.basicConfig(level = logging.INFO)
170
171 if "GAUDI_BUILD_LOCK" in os.environ:
172 globalLock = locker.LockFile(os.environ["GAUDI_BUILD_LOCK"], temporary = True)
173 else:
174 globalLock = None
175
176 if True: #try:
177 sc = mergeFiles( options.fragFileNames, options.mergedFileName,
178 options.commentChar,
179 doMerge = options.doMerge,
180 ignoreMissing = options.ignoreMissing)
181 if not options.no_stamp:
182 for stamp in map(stampFileName, options.fragFileNames):
183 open(stamp, 'w')
184 #except IOError, err:
185 # print "ERROR:",err
186 #except Exception, err:
187 # print "ERROR:",err
188 #except:
189 # print "ERROR: unknown error !!"
190
191 del globalLock
192
193 sys.exit( sc )