| The Gaudi Framework v27r1

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

- File List
- File Members

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 fcntl
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 lockFile = open( mergedFileName + '.lock', 'a' )
35
36 # locking file, gaining exclusive access to it
37 # code from locker.py, only posix relevant part - we don't support NT - did we ever ??
38 # Lock with a simple call to lockf() - this blocks until the lock is aquired
39 try:
40 fcntl.lockf( lockFile, fcntl.LOCK_EX )
41 except IOError, exc_value:
42 print "Problem when trying to lock {0}, IOError {1}".format(mergedFile, exc_value[0])
43 raise
44
45 mergedFile = open( mergedFileName, 'r' )
46
47 try:
48
49 newLines = [ ]
50 skipBlock = ""
51 for line in mergedFile.readlines():
52 if line.startswith(startMark) and line[nameOffset:].strip() in basenames:
53 skipBlock = endMark + line[nameOffset:].strip()
54 # remove all the empty lines occurring before the start mark
55 while (len(newLines) > 0) and (newLines[-1].strip() == ''):
56 newLines.pop()
57 if not skipBlock:
58 newLines.append(line)
59 if line.startswith(skipBlock):
60 skipBlock = ""
61 if skipBlock:
62 print "WARNING: missing end mark ('%s')" % skipBlock
63
64 if doMerge:
65 for f in fragFileNames:
66 if ignoreMissing and not os.path.exists(f):
67 print "WARNING: '%s' does not exist, I'm ignoring it" % f
68 continue
69 # I do not want to add 2 empty lines at the beginning of a file
70 if newLines:
71 newLines.append('\n\n')
72 bf = os.path.basename(f)
73 newLines.append(startMark + bf + '\n')
74 newLines.append(timeMark + '\n')
75 fileData = open(f, 'r').read()
76 newLines.append(fileData)
77 if fileData and fileData[-1] != '\n':
78 newLines.append('\n')
79 newLines.append(endMark + bf + '\n')
80
81 #mergedFile.seek(0)
82 #mergedFile.truncate(0)
83 #mergedFile.writelines(newLines)
84
85 newFile = open( mergedFileName + ".new" , 'w' )
86 newFile.writelines(newLines)
87 newFile.close()
88 os.rename(mergedFileName + ".new",mergedFileName)
89
90 finally:
91 # unlock file
92 fcntl.lockf( lockFile, fcntl.LOCK_UN )
93
94 return 0
95
96 if __name__ == "__main__":
97
98 from optparse import OptionParser
99 parser = OptionParser(usage="usage: %prog [options]")
100 parser.add_option(
101 "-i",
102 "--input-file",
103 action = "append",
104 dest = "fragFileNames",
105 default = [],
106 help = "The path and name of the file one wants to merge into the 'master' one"
107 )
108 parser.add_option(
109 "-m",
110 "--merged-file",
111 dest = "mergedFileName",
112 default = None,
113 help = "The path and name of the 'master' file which will hold the content of all the other fragment files"
114 )
115 parser.add_option(
116 "-c",
117 "--comment-char",
118 dest = "commentChar",
119 default = "#",
120 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)"
121 )
122 parser.add_option(
123 "--do-merge",
124 dest = "doMerge",
125 action = "store_true",
126 default = True,
127 help = "Switch to actually carry on with the merging procedure"
128 )
129 parser.add_option(
130 "--un-merge",
131 dest = "unMerge",
132 action = "store_true",
133 default = False,
134 help = "Switch to remove our fragment file from the 'master' file"
135 )
136 parser.add_option(
137 "--stamp-dir",
138 dest = "stampDir",
139 action = "store",
140 default = None,
141 help = "Create the stamp file in the specified directory. If not specified"
142 +" the directory of the source file is used."
143 )
144 parser.add_option(
145 "--no-stamp",
146 action = "store_true",
147 help = "Do no create stamp files."
148 )
149 parser.add_option(
150 "--ignore-missing",
151 dest = "ignoreMissing",
152 action = "store_true",
153 help = "Print a warning if a fragment file is missing, but do not fail."
154 )
155
156 (options, args) = parser.parse_args()
157
158 # ensure consistency...
159 options.doMerge = not options.unMerge
160
161 # allow command line syntax as
162 # merge_files.py [options] <fragment file1> [<fragment file2>...] <merged file>
163 if args:
164 options.mergedFileName = args[-1]
165 options.fragFileNames += args[:-1]
166
167 sc = 1
168 if not options.fragFileNames or \
169 not options.mergedFileName :
170 str(parser.print_help() or "")
171 print "*** ERROR ***",sys.argv
172 sys.exit(sc)
173 pass
174
175 if options.stampDir is None:
176 stampFileName = lambda x: x + ".stamp"
177 else:
178 stampFileName = lambda x: os.path.join(options.stampDir,
179 os.path.basename(x)
180 + ".stamp")
181 # Configure Python logging
182 import logging
183 logging.basicConfig(level = logging.INFO)
184
185 if "GAUDI_BUILD_LOCK" in os.environ:
186 import locker
187 globalLock = locker.LockFile(os.environ["GAUDI_BUILD_LOCK"], temporary = True)
188 else:
189 globalLock = None
190
191 if True: #try:
192 sc = mergeFiles( options.fragFileNames, options.mergedFileName,
193 options.commentChar,
194 doMerge = options.doMerge,
195 ignoreMissing = options.ignoreMissing)
196 if not options.no_stamp:
197 for stamp in map(stampFileName, options.fragFileNames):
198 open(stamp, 'w')
199 #except IOError, err:
200 # print "ERROR:",err
201 #except Exception, err:
202 # print "ERROR:",err
203 #except:
204 # print "ERROR: unknown error !!"
205
206 del globalLock
207
208 sys.exit( sc )
format
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
Containers::map
struct GAUDI_API map
Parametrisation class for map-like implementation.
Definition: KeyedObjectManager.h:25
merge_files.mergeFiles
def mergeFiles(fragFileNames, mergedFileName, commentChar, doMerge, ignoreMissing)
Definition: merge_files.py:12
locker.LockFile
Lock a file.
Definition: locker.py:63