mirror of
https://github.com/status-im/PyGithub.git
synced 2026-09-01 11:21:16 +00:00
159 lines
6.6 KiB
Python
159 lines
6.6 KiB
Python
#!/usr/bin/env python
|
|
|
|
import subprocess
|
|
import glob
|
|
import re
|
|
import collections
|
|
|
|
class ClassDescription:
|
|
def __init__( self ):
|
|
self.properties = dict()
|
|
self.methods = collections.OrderedDict()
|
|
|
|
class MethodDescription:
|
|
def __init__( self, returnType ):
|
|
self.verb = None
|
|
self.url = None
|
|
self.returnType = returnType
|
|
self.parameters = collections.OrderedDict()
|
|
|
|
class Generator():
|
|
privateClasses = [
|
|
"PaginatedList",
|
|
"PaginatedListBase",
|
|
"GithubObject",
|
|
"BasicGithubObject",
|
|
"_NotSetType",
|
|
"Requester",
|
|
]
|
|
|
|
def getClassDocstring( self, className ):
|
|
if className in self.privateClasses:
|
|
return []
|
|
else:
|
|
return [
|
|
"Please edit this generated docstring for class " + className + ".",
|
|
]
|
|
|
|
def getMemberDocstring( self, className, memberName ):
|
|
if className in self.privateClasses:
|
|
return []
|
|
elif className in self.classDescriptions:
|
|
classDescription = self.classDescriptions[ className ]
|
|
if memberName in classDescription.properties:
|
|
return [
|
|
"Please edit this generated docstring for property " + className + "." + memberName + ".",
|
|
classDescription.properties[ memberName ]
|
|
]
|
|
elif memberName in classDescription.methods:
|
|
return [
|
|
"Please edit this generated docstring for method " + className + "." + memberName + ".",
|
|
"Calls " + ( classDescription.methods[ memberName ].verb or "WTF" ) + " " + ( classDescription.methods[ memberName ].url or "WTF" )
|
|
] + [
|
|
":param " + parameterName + ": " + parameterType for parameterName, parameterType in classDescription.methods[ memberName ].parameters.items()
|
|
] + [
|
|
":return: " + str( classDescription.methods[ memberName ].returnType )
|
|
]
|
|
elif memberName.startswith( "_" ): # private member
|
|
return []
|
|
else:
|
|
print "Unknown member", className, memberName
|
|
return []
|
|
else:
|
|
print "Unknown class", className
|
|
return []
|
|
|
|
def __init__( self ):
|
|
pass
|
|
|
|
def run( self ):
|
|
self.restoreSources()
|
|
self.readReferenceOfClasses()
|
|
self.readReferenceOfApis()
|
|
self.generate()
|
|
|
|
def restoreSources( self ):
|
|
subprocess.check_call( [ "git", "checkout", "--", "github" ] )
|
|
|
|
def readReferenceOfClasses( self ):
|
|
self.classDescriptions = dict()
|
|
with open( "doc/ReferenceOfClasses.md" ) as f:
|
|
for line in f:
|
|
line = line.rstrip()
|
|
if line.startswith( "Class `" ):
|
|
className = line[ 7 : -1 ]
|
|
self.classDescriptions[ className ] = ClassDescription()
|
|
if line.startswith( "*" ):
|
|
if "rate_limiting" in line:
|
|
self.classDescriptions[ className ].properties[ "rate_limiting" ] = "( int, int )"
|
|
elif "(" in line:
|
|
methodName, returnType = re.match( "^\* `(.*)\(.*\)`(?:: (.*))?$", line ).groups()
|
|
self.classDescriptions[ className ].methods[ methodName ] = MethodDescription( returnType )
|
|
else:
|
|
attributeName, attributeType = re.match( "^\* `(.*)`: (.*)$", line ).groups()
|
|
self.classDescriptions[ className ].properties[ attributeName ] = attributeType
|
|
if line.startswith( " *" ):
|
|
parameterName, parameterType = re.match( "^ \* `(.*)`: (.*)$", line ).groups()
|
|
self.classDescriptions[ className ].methods[ methodName ].parameters[ parameterName ] = parameterType
|
|
|
|
def readReferenceOfApis( self ):
|
|
with open( "doc/ReferenceOfApis.md" ) as f:
|
|
for line in f:
|
|
line = line.rstrip()
|
|
if line.startswith( "API" ):
|
|
url = line[ 5 : -1 ]
|
|
if line.startswith( "*" ) and line not in [ "* POST: see API `/markdown`", "* GET: Not implemented, see `Github.rate_limiting`" ]:
|
|
verb, methods = re.match( "^\* (.*): (.*)$", line ).groups()
|
|
for method in methods.split( " or " ):
|
|
className, methodName = re.match( "^`(.*)\.(.*)`", method ).groups()
|
|
self.classDescriptions[ className ].methods[ methodName ].verb = verb
|
|
self.classDescriptions[ className ].methods[ methodName ].url = url
|
|
|
|
def generate( self ):
|
|
for f in glob.glob( "github/*.py" ):
|
|
self.generateForFile( f )
|
|
|
|
def generateForFile( self, fileName ):
|
|
self.writeLines( fileName, self.processLines( self.readLines( fileName ) ) )
|
|
|
|
def processLines( self, lines ):
|
|
nextDefIsStaticMethod = False
|
|
nextDefIsClassMethod = False
|
|
|
|
for line in lines:
|
|
yield line
|
|
if line.startswith( "class" ):
|
|
className = re.match( "^class (.*?)(?:\(.*\))?:$", line ).group( 1 )
|
|
for docStringLine in self.formatDocstring( " ", self.getClassDocstring( className ) ):
|
|
yield docStringLine
|
|
if line.startswith( " def" ):
|
|
if nextDefIsStaticMethod or nextDefIsClassMethod:
|
|
pass
|
|
else:
|
|
memberName = re.match( "^ def (.*?)\( self.* \):$", line ).group( 1 )
|
|
for docStringLine in self.formatDocstring( " ", self.getMemberDocstring( className, memberName ) ):
|
|
yield docStringLine
|
|
|
|
nextDefIsStaticMethod = line == " @staticmethod"
|
|
nextDefIsClassMethod = line == " @classmethod"
|
|
|
|
def formatDocstring( self, indent, lines ):
|
|
if len( lines ) != 0:
|
|
yield indent + '"""'
|
|
for docStringLine in lines:
|
|
yield indent + docStringLine
|
|
yield indent + '"""'
|
|
yield ""
|
|
|
|
def readLines( self, fileName ):
|
|
with open( fileName ) as f:
|
|
return list( line.rstrip() for line in f )
|
|
|
|
def writeLines( self, fileName, lines ):
|
|
with open( fileName, "wb" ) as f:
|
|
for line in lines:
|
|
f.write( line + "\n" )
|
|
|
|
if __name__ == "__main__":
|
|
Generator().run()
|