1
1
#!/usr/bin/env python
2
+ """Scans MongoDB source tree for potential error codes and creates multiple outputs"""
3
+
4
+ generateCSV = 'no'
5
+ generateRST = 'no'
6
+ generateJSON = 'no'
7
+ debug = False
8
+ save_to_mongo = False
9
+
2
10
import os
3
11
import sys
4
12
import re
5
13
import ConfigParser
6
14
7
- #sourceroot = "/Users/epc/Documents/github/epc/mongo"
8
- #errorsrst = "/Users/epc/Documents/github/epc/docs/draft/messages/errors.txt"
9
- #errorsCSV = "/Users/epc/Documents/github/epc/docs/draft/messages/errors.csv"
10
- #errorsTitle = "MongoDB Error and Message Codes"
15
+ try :
16
+ import pymongo
17
+ pymongo_flag = True
18
+ except :
19
+ sys .stderr .write ("pymongo unavailable, continuing\n " )
20
+ pymongo_flag = False
11
21
12
- config = ConfigParser .SafeConfigParser ()
13
- config .read ('errorcodes.conf' )
22
+ config_file = 'errorcodes.conf'
14
23
15
- sourceroot = config .get ('errorcodes' ,'source' )
16
- resultsRoot = config .get ('errorcodes' , 'outputDir' )
17
- generateCSV = config .get ('errorcodes' ,'generateCSV' )
18
- errorsTitle = config .get ('errorcodes' , 'Title' )
19
- errorsFormat = config .get ('errorcodes' , 'Format' )
20
- generateJSON = config .get ('errorcodes' ,'generateJSON' )
24
+ config = ConfigParser .SafeConfigParser ()
25
+ config_flag = False
26
+ config_files = [ config_file , 'bin/{}' .format (config_file )]
27
+ try :
28
+ config .read (config_files )
29
+ config_flag = True
30
+ except :
31
+ sys .exit ("Could not read config file, exiting\n " )
32
+
33
+ if config_flag == True :
34
+ sourceroot = config .get ('errorcodes' ,'source' )
35
+ resultsRoot = config .get ('errorcodes' , 'outputDir' )
36
+ errorsTitle = config .get ('errorcodes' , 'Title' )
37
+ if (config .has_option ('errorcodes' ,'Format' )):
38
+ errorsFormat = config .get ('errorcodes' , 'Format' )
39
+ if (config .has_option ('errorcodes' ,'generateCSV' )):
40
+ generateCSV = config .get ('errorcodes' ,'generateCSV' )
41
+ if (config .has_option ('errorcodes' ,'generateJSON' )):
42
+ generateJSON = config .get ('errorcodes' ,'generateJSON' )
43
+ if (config .has_option ('errorcodes' ,'generateRST' )):
44
+ generateRST = config .get ('errorcodes' , 'generateRST' )
45
+ if (config .has_option ('mongodb' , 'persistence' )):
46
+ if (config .get ('mongodb' ,'persistence' ) == 'insert' ):
47
+ save_to_mongo = True
48
+ elif (config .get ('mongodb' ,'persistence' ) == 'update' ):
49
+ sys .exit ("Fatal, updating not supported" )
50
+ else :
51
+ sys .exit ("No configuration data present, exiting\n " )
52
+
53
+ if save_to_mongo == True :
54
+ # why candygram? because there's only so many times you can use mongo and
55
+ # database before going mad. Alt: cf. Blazing Saddles
56
+ fields = ['database' ,'collection' ,'user' ,'password' ,'port' ]
57
+ for field in fields :
58
+ if config .has_option ('mongodb' ,field ):
59
+ candygram [field ] = config .get ('mongodb' ,field )
60
+ if candygram ['database' ] == '' :
61
+ sys .exit ("Fatal: you told me to save to a database but did not configure one." );
62
+ if candygram ['collection' ] == '' :
63
+ sys .exit ("Fatal: you told me to save to a database but did not configure a collection." );
21
64
22
65
default_domain = "\n \n .. default-domain:: mongodb\n \n "
23
66
24
67
sys .path .append (sourceroot + "/buildscripts" )
25
68
69
+ # we only need to scan the mongo source tree not 3rd party
70
+ product_source = sourceroot + '/src/mongo'
71
+
26
72
# get mongodb/buildscripts/utils.py
27
73
import utils
28
74
51
97
'MSGException' : 'MsgException' ,
52
98
'MsgAssertionException' : 'MsgAssertionException' ,
53
99
})
100
+
101
+ # codes is legacy errocodes.py
102
+ codes = []
103
+ # messages is our real structure
104
+ messages = {}
54
105
55
106
def assignErrorCodes ():
56
107
cur = 10000
@@ -73,11 +124,9 @@ def assignErrorCodes():
73
124
out .close ()
74
125
75
126
76
- codes = []
77
- messages = {}
78
-
79
127
def readErrorCodes ():
80
128
"""Open each source file in sourceroot and scan for potential error messages."""
129
+ sys .stderr .write ("Analyzing source tree: {}\n " .format (sourceroot ))
81
130
quick = [ "assert" , "Exception" ]
82
131
83
132
ps = [ re .compile ( "(([wum]asser(t|ted))) *\(( *)(\d+) *,\s*(\" \S[^\" ]+\S\" )\s*,?.*" ) ,
@@ -95,8 +144,9 @@ def readErrorCodes():
95
144
96
145
bad = [ re .compile ( "\sassert *\(" ) ]
97
146
arr = []
98
- for x in utils .getAllSourceFiles (arr ,sourceroot ):
99
- sys .stderr .write ("Analyzing: {}\n " .format (x ))
147
+ for x in utils .getAllSourceFiles (arr ,product_source ):
148
+ if (debug == True ):
149
+ sys .stderr .write ("Analyzing: {}\n " .format (x ))
100
150
needReplace = [False ]
101
151
lines = []
102
152
lastCodes = [0 ]
@@ -116,13 +166,6 @@ def readErrorCodes():
116
166
117
167
if found :
118
168
119
- if x .find ( "src/mongo/" ) >= 0 :
120
- for b in bad :
121
- if len (b .findall ( line )) > 0 :
122
- print ( x )
123
- print ( line )
124
- raise Exception ( "you can't use a bare assert" )
125
-
126
169
for p in ps :
127
170
128
171
def repl ( m ):
@@ -135,17 +178,19 @@ def repl( m ):
135
178
codes .append ( ( x , lineNum , line , code , message , severity ) )
136
179
if x .startswith (sourceroot ):
137
180
fn = x [sourcerootOffset + 1 :].rpartition ("/2" )[2 ]
138
- # fn = f.rpartition("/")[2]
139
181
140
182
msgDICT = {
141
183
'id' : code ,
142
- 'text' :message ,
143
- 'sev' :severity ,
144
- 'user' :'' ,
145
- 'sys' :'' ,
146
- 'ln' :lineNum ,
147
- 'f' :fn ,
148
- 'src' : line .strip (stripChars )
184
+ 'parsed' :message ,
185
+ 'message' :message ,
186
+ 'assert' :severity ,
187
+ 'severity' : returnSeverityText (severity ),
188
+ 'uresp' :'' ,
189
+ 'sysresp' :'' ,
190
+ 'linenum' :lineNum ,
191
+ 'file' :fn ,
192
+ 'src' : line .strip (stripChars ),
193
+ 'altered' : 0
149
194
}
150
195
messages [int (code )] = msgDICT
151
196
@@ -155,7 +200,17 @@ def repl( m ):
155
200
156
201
lineNum = lineNum + 1
157
202
158
-
203
+ def returnSeverityText (s ):
204
+ if not s :
205
+ return ""
206
+ elif s in severityTexts :
207
+ result = severityTexts [s ]
208
+ elif s in exceptionTexts :
209
+ result = exceptionTexts [s ]
210
+ else :
211
+ result = s
212
+ return result
213
+
159
214
160
215
def getNextCode ( lastCodes = [0 ] ):
161
216
highest = [max (lastCodes )]
@@ -278,7 +333,7 @@ def genErrorOutputCSV():
278
333
stripChars = " " + "\n " + '"'
279
334
280
335
281
- codes .sort ( key = lambda x : x [ 0 ] + "-" + x [ 3 ] )
336
+ codes .sort ( key = lambda x : int ( x [ 3 ]) )
282
337
for f ,l ,line ,num ,message ,severity in codes :
283
338
if num in seen :
284
339
continue
@@ -293,16 +348,49 @@ def genErrorOutputCSV():
293
348
out .write ("\n " )
294
349
295
350
out .close ()
351
+
352
+ def writeToMongo ():
353
+ """Pipe the messages array into mongodb"""
354
+ sys .stderr .write ("Saving to db.messages.errors, will not check for duplicates!" )
355
+ from pymongo import Connection
356
+ connection = Connection ()
357
+ db = connection ['messages' ]
358
+ errorcodes = db ['errors' ]
359
+ # errorcodes.insert(messages)
360
+ for errCode in messages .keys ():
361
+ sys .stderr .write ('Inserting code: {}\n ' .format (errCode ))
362
+ result = errorcodes .insert (messages [errCode ])
363
+ sys .stderr .write ('Result: {}\n ' .format (result ))
364
+ # for k in messages:
365
+ # print("{}\t{}".format(k,messages[k]))
366
+ # errorcodes.insert(k,messages[k])
367
+
368
+ #for key in messages.keys()
369
+ # val= 'foo'
370
+ # print("key({})\tvalue({})\n".format(key,val))
371
+
296
372
297
373
if __name__ == "__main__" :
298
374
readErrorCodes ()
299
- genErrorOutput ()
375
+ if (generateRST == 'yes' ):
376
+ genErrorOutput ()
377
+ else :
378
+ sys .stderr .write ("Not generating RST files\n " );
300
379
if (generateCSV == 'yes' ):
301
380
genErrorOutputCSV ()
381
+ else :
382
+ sys .stderr .write ("Not generating CSV file\n " );
302
383
if (generateJSON == 'yes' ):
303
384
import json
304
385
outputFile = "{}/errorcodes.json" .format (resultsRoot )
305
386
out = open (outputFile , 'wb' )
306
387
sys .stderr .write ("Generating JSON file: {}\n " .format (outputFile ))
307
388
out .write (json .dumps (messages ))
308
389
out .close ()
390
+ else :
391
+ sys .stderr .write ("Not generating JSON file\n " );
392
+
393
+ if save_to_mongo == True :
394
+ writeToMongo ()
395
+ else :
396
+ sys .stderr .write ("Not inserting/updating to Mongo\n " );
0 commit comments