Skip to content

Commit 149cdde

Browse files
author
Ed Costello
committed
DOCS335 checkpoint of script to parse and format error codes
1 parent 432fd81 commit 149cdde

File tree

3 files changed

+141
-38
lines changed

3 files changed

+141
-38
lines changed

bin/errorcodes.conf

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
# used by docs/bin/errorcodes.py
22
[errorcodes]
3+
# set source to the root of the mongo source tree (eg the git root)
34
source = /Users/epc/Documents/github/mongo
5+
# set outputDir to the directory to place all generated output
46
outputDir = /Users/epc/Documents/github/epc/docs/draft/reference/error
5-
generateCSV = yes
67
# errorsFormat = separate | single
78
Format = separate
89
Title = "MongoDB Error and Message Codes"
910
defaultDomain = 'mongodb'
10-
generateJSON = yes
11+
generateJSON = no
12+
generateRST = no
13+
generateCSV = no
14+
15+
[mongodb]
16+
# defaults to unauthenticated mongodb on localhost
17+
# host = ""
18+
#port = ""
19+
#user = ""
20+
#password = ""
21+
database = "messages"
22+
collection = "errors"
23+
# persistence = insert or update or none (to turn off save)
24+
persistence = none
25+

bin/errorcodes.py

Lines changed: 123 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,74 @@
11
#!/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+
210
import os
311
import sys
412
import re
513
import ConfigParser
614

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
1121

12-
config = ConfigParser.SafeConfigParser()
13-
config.read('errorcodes.conf')
22+
config_file = 'errorcodes.conf'
1423

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.");
2164

2265
default_domain = "\n\n.. default-domain:: mongodb\n\n"
2366

2467
sys.path.append(sourceroot+"/buildscripts")
2568

69+
# we only need to scan the mongo source tree not 3rd party
70+
product_source = sourceroot + '/src/mongo'
71+
2672
# get mongodb/buildscripts/utils.py
2773
import utils
2874

@@ -51,6 +97,11 @@
5197
'MSGException': 'MsgException',
5298
'MsgAssertionException': 'MsgAssertionException',
5399
})
100+
101+
# codes is legacy errocodes.py
102+
codes = []
103+
# messages is our real structure
104+
messages = {}
54105

55106
def assignErrorCodes():
56107
cur = 10000
@@ -73,11 +124,9 @@ def assignErrorCodes():
73124
out.close()
74125

75126

76-
codes = []
77-
messages = {}
78-
79127
def readErrorCodes():
80128
"""Open each source file in sourceroot and scan for potential error messages."""
129+
sys.stderr.write("Analyzing source tree: {}\n".format(sourceroot))
81130
quick = [ "assert" , "Exception"]
82131

83132
ps = [ re.compile( "(([wum]asser(t|ted))) *\(( *)(\d+) *,\s*(\"\S[^\"]+\S\")\s*,?.*" ) ,
@@ -95,8 +144,9 @@ def readErrorCodes():
95144

96145
bad = [ re.compile( "\sassert *\(" ) ]
97146
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))
100150
needReplace = [False]
101151
lines = []
102152
lastCodes = [0]
@@ -116,13 +166,6 @@ def readErrorCodes():
116166

117167
if found:
118168

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-
126169
for p in ps:
127170

128171
def repl( m ):
@@ -135,17 +178,19 @@ def repl( m ):
135178
codes.append( ( x , lineNum , line , code, message, severity ) )
136179
if x.startswith(sourceroot):
137180
fn = x[sourcerootOffset+1:].rpartition("/2")[2]
138-
# fn = f.rpartition("/")[2]
139181

140182
msgDICT = {
141183
'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
149194
}
150195
messages[int(code)] = msgDICT
151196

@@ -155,7 +200,17 @@ def repl( m ):
155200

156201
lineNum = lineNum + 1
157202

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+
159214

160215
def getNextCode( lastCodes = [0] ):
161216
highest = [max(lastCodes)]
@@ -278,7 +333,7 @@ def genErrorOutputCSV():
278333
stripChars = " " + "\n" + '"'
279334

280335

281-
codes.sort( key=lambda x: x[0]+"-"+x[3] )
336+
codes.sort( key=lambda x: int(x[3]) )
282337
for f,l,line,num,message,severity in codes:
283338
if num in seen:
284339
continue
@@ -293,16 +348,49 @@ def genErrorOutputCSV():
293348
out.write("\n")
294349

295350
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+
296372

297373
if __name__ == "__main__":
298374
readErrorCodes()
299-
genErrorOutput()
375+
if (generateRST == 'yes'):
376+
genErrorOutput()
377+
else:
378+
sys.stderr.write("Not generating RST files\n");
300379
if (generateCSV == 'yes'):
301380
genErrorOutputCSV()
381+
else:
382+
sys.stderr.write("Not generating CSV file\n");
302383
if (generateJSON== 'yes'):
303384
import json
304385
outputFile = "{}/errorcodes.json".format(resultsRoot)
305386
out = open(outputFile, 'wb')
306387
sys.stderr.write("Generating JSON file: {}\n".format(outputFile))
307388
out.write(json.dumps(messages))
308389
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");

draft/reference/error/errorcodes.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)