You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@storm.apache.org by bo...@apache.org on 2014/07/25 22:13:13 UTC

[3/7] git commit: Split off dependency libraries, and added in columns for age of pulls/JIRA in days.

Split off dependency libraries, and added in columns for age of pulls/JIRA in days.


Project: http://git-wip-us.apache.org/repos/asf/incubator-storm/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-storm/commit/e3b9d46e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-storm/tree/e3b9d46e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-storm/diff/e3b9d46e

Branch: refs/heads/master
Commit: e3b9d46e31cf72136b7d3e8163ff42c539f3b419
Parents: 4550bbf
Author: Robert (Bobby) Evans <ev...@yahoo-inc.com>
Authored: Mon Jun 9 08:55:22 2014 -0500
Committer: Robert (Bobby) Evans <ev...@yahoo-inc.com>
Committed: Mon Jun 9 08:55:22 2014 -0500

----------------------------------------------------------------------
 dev-tools/github/__init__.py  | 109 +++++++++++++++
 dev-tools/jira-github-join.py | 276 ++-----------------------------------
 dev-tools/jira/__init__.py    | 229 ++++++++++++++++++++++++++++++
 3 files changed, 349 insertions(+), 265 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-storm/blob/e3b9d46e/dev-tools/github/__init__.py
----------------------------------------------------------------------
diff --git a/dev-tools/github/__init__.py b/dev-tools/github/__init__.py
new file mode 100755
index 0000000..c3e734e
--- /dev/null
+++ b/dev-tools/github/__init__.py
@@ -0,0 +1,109 @@
+# -*- coding: utf-8 -*-
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+import getpass
+import base64
+import urllib
+import urllib2
+from datetime import datetime
+try:
+	import json
+except ImportError:
+	import simplejson as json
+
+def mstr(obj):
+	if (obj == None):
+		return ""
+	return unicode(obj)
+
+def gittime(obj):
+	if (obj == None):
+		return None
+	return datetime.strptime(obj[0:19], "%Y-%m-%dT%H:%M:%S")
+
+class GitPullRequest:
+	"""Pull Request from Git"""
+	def __init__(self, data, parent):
+		self.data = data
+		self.parent = parent
+	
+	def html_url(self):
+		return self.data["html_url"]
+	
+	def title(self):
+		return self.data["title"]
+	
+	def number(self):
+		return self.data["number"]
+	
+	#TODO def review_comments
+	
+	def user(self):
+		return mstr(self.data["user"]["login"])
+	
+	def fromBranch(self):
+		return mstr(self.data["head"]["ref"])
+	
+	def fromRepo(self):
+		return mstr(self.data["head"]["repo"]["clone_url"])
+
+	def merged(self):
+		return self.data["merged_at"] != None
+		
+	def raw(self):
+		return self.data
+
+	def created_at(self):
+		return gittime(self.data["created_at"])
+
+	def updated_at(self):
+		return gittime(self.data["updated_at"])
+
+	def merged_at(self):
+		return gittime(self.data["merged_at"])	
+	
+	def __str__(self):
+		return self.html_url()
+	
+	def __repr__(self):
+		return self.html_url()
+
+class GitHub:
+	"""Github API"""
+	def __init__(self, options):
+		self.headers = {}
+		if options.gituser:
+			gitpassword = getpass.getpass("github.com user " + options.gituser+":")
+			authstr = base64.encodestring('%s:%s' % (options.gituser, gitpassword)).replace('\n', '')
+			self.headers["Authorization"] = "Basic "+authstr
+	
+	def pulls(self, user, repo, type="all"):
+		page=1
+		ret = []
+		while True:
+			url = "https://api.github.com/repos/"+user+"/"+repo+"/pulls?state="+type+"&page="+str(page)
+		
+			req = urllib2.Request(url,None,self.headers)
+			result = urllib2.urlopen(req)
+			contents = result.read()
+			if result.getcode() != 200:
+				raise Exception(result.getcode() + " != 200 "+ contents)
+			got = json.loads(contents)
+			for part in got:
+				ret.append(GitPullRequest(part, self))
+			if len(got) == 0:
+				return ret
+			page = page + 1
+			
+	def openPulls(self, user, repo):
+		return self.pulls(user, repo, "open")

http://git-wip-us.apache.org/repos/asf/incubator-storm/blob/e3b9d46e/dev-tools/jira-github-join.py
----------------------------------------------------------------------
diff --git a/dev-tools/jira-github-join.py b/dev-tools/jira-github-join.py
index 88630ba..2308641 100755
--- a/dev-tools/jira-github-join.py
+++ b/dev-tools/jira-github-join.py
@@ -12,270 +12,14 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-import getpass
-import base64
+from jira import JiraRepo
+from github import GitHub, mstr
 import re
-import sys
 from optparse import OptionParser
-import httplib
-import urllib
-import urllib2
-try:
-	import json
-except ImportError:
-	import simplejson as json
+from datetime import datetime
 
-def mstr(obj):
-	if (obj == None):
-		return ""
-	return unicode(obj)
-
-githubUser = re.compile("Git[Hh]ub user (\w+)")
-githubPull = re.compile("https://github.com/[^/\s]+/[^/\s]+/pull/[0-9]+")
-hasVote = re.compile("\s+([-+][01])\s*")
-isDiff = re.compile("--- End diff --")
-
-def searchGroup(reg, txt, group):
-	m = reg.search(txt)
-	if m == None:
-		return None
-	return m.group(group)
-
-class JiraComment:
-	"""A comment on a JIRA"""
-
-	def __init__(self, data):
-		self.data = data
-		self.author = mstr(self.data['author']['name'])
-		self.githubAuthor = None
-		self.githubPull = None
-		self.githubComment = (self.author == "githubbot")
-		body = self.getBody()
-		if isDiff.search(body) != None:
-			self.vote = None
-		else:
-			self.vote = searchGroup(hasVote, body, 1)
-
-		if self.githubComment:
-			self.githubAuthor = searchGroup(githubUser, body, 1)
-			self.githubPull = searchGroup(githubPull, body, 0)
-			
-
-	def getAuthor(self):
-		if self.githubAuthor != None:
-			return self.githubAuthor
-		return self.author
-
-	def getBody(self):
-		return mstr(self.data['body'])
-
-	def getPull(self):
-		return self.githubPull
-
-	def hasVote(self):
-		return self.vote != None
-
-	def getVote(self):
-		return self.vote
-
-class Jira:
-	"""A single JIRA"""
-	
-	def __init__(self, data, parent):
-		self.key = data['key']
-		self.fields = data['fields']
-		self.parent = parent
-		self.notes = None
-		self.comments = None
-	
-	def getId(self):
-		return mstr(self.key)
-	
-	def getDescription(self):
-		return mstr(self.fields['description'])
-	
-	def getReleaseNote(self):
-		if (self.notes == None):
-			field = self.parent.fieldIdMap['Release Note']
-			if (self.fields.has_key(field)):
-				self.notes=mstr(self.fields[field])
-			else:
-				self.notes=self.getDescription()
-		return self.notes
-	
-	def getPriority(self):
-		ret = ""
-		pri = self.fields['priority']
-		if(pri != None):
-			ret = pri['name']
-		return mstr(ret)
-	
-	def getAssigneeEmail(self):
-		ret = ""
-		mid = self.fields['assignee']
-		if mid != None:
-			ret = mid['emailAddress']
-		return mstr(ret)
-
-	
-	def getAssignee(self):
-		ret = ""
-		mid = self.fields['assignee']
-		if(mid != None):
-			ret = mid['displayName']
-		return mstr(ret)
-	
-	def getComponents(self):
-		return " , ".join([ comp['name'] for comp in self.fields['components'] ])
-	
-	def getSummary(self):
-		return self.fields['summary']
-	
-	def getType(self):
-		ret = ""
-		mid = self.fields['issuetype']
-		if(mid != None):
-			ret = mid['name']
-		return mstr(ret)
-	
-	def getReporter(self):
-		ret = ""
-		mid = self.fields['reporter']
-		if(mid != None):
-			ret = mid['displayName']
-		return mstr(ret)
-	
-	def getProject(self):
-		ret = ""
-		mid = self.fields['project']
-		if(mid != None):
-			ret = mid['key']
-		return mstr(ret)
-	
-	def getComments(self):
-		if self.comments == None:
-			jiraId = self.getId()
-			comments = []
-			at=0
-			end=1
-			count=100
-			while (at < end):
-				params = urllib.urlencode({'startAt':at, 'maxResults':count})
-				resp = urllib2.urlopen(self.parent.baseUrl+"/issue/"+jiraId+"/comment?"+params)
-				data = json.loads(resp.read())
-				if (data.has_key('errorMessages')):
-					raise Exception(data['errorMessages'])
-				at = data['startAt'] + data['maxResults']
-				end = data['total']
-				for item in data['comments']:
-					j = JiraComment(item)
-					comments.append(j)
-			self.comments = comments
-		return self.comments
-	
-	def raw(self):
-		return self.fields
-
-class JiraRepo:
-	"""A Repository for JIRAs"""
-	
-	def __init__(self, baseUrl):
-		self.baseUrl = baseUrl
-		resp = urllib2.urlopen(baseUrl+"/field")
-		data = json.loads(resp.read())
-		
-		self.fieldIdMap = {}
-		for part in data:
-			self.fieldIdMap[part['name']] = part['id']
-	
-	def get(self, id):
-		resp = urllib2.urlopen(self.baseUrl+"/issue/"+id)
-		data = json.loads(resp.read())
-		if (data.has_key('errorMessages')):
-			raise Exception(data['errorMessages'])
-		j = Jira(data, self)
-		return j
-	
-	def openJiras(self, project):
-		jiras = {}
-		at=0
-		end=1
-		count=100
-		while (at < end):
-			params = urllib.urlencode({'jql': "project = "+project+" AND resolution = Unresolved", 'startAt':at, 'maxResults':count})
-			#print params
-			resp = urllib2.urlopen(self.baseUrl+"/search?%s"%params)
-			data = json.loads(resp.read())
-			if (data.has_key('errorMessages')):
-				raise Exception(data['errorMessages'])
-			at = data['startAt'] + data['maxResults']
-			end = data['total']
-			for item in data['issues']:
-					j = Jira(item, self)
-					jiras[j.getId()] = j
-		return jiras
-
-class GitPullRequest:
-	"""Pull Request from Git"""
-	def __init__(self, data, parent):
-		self.data = data
-		self.parent = parent
-	
-	def html_url(self):
-		return self.data["html_url"]
-	
-	def title(self):
-		return self.data["title"]
-	
-	def number(self):
-		return self.data["number"]
-	
-	#TODO def review_comments
-	
-	def user(self):
-		return mstr(self.data["user"]["login"])
-	
-	def fromBranch(self):
-		return mstr(self.data["head"]["ref"])
-	
-	def fromRepo(self):
-		return mstr(self.data["head"]["repo"]["clone_url"])
-	
-	def __str__(self):
-		return self.html_url()
-	
-	def __repr__(self):
-		return self.html_url()
-
-class GitHub:
-	"""Github API"""
-	def __init__(self, options):
-		self.headers = {}
-		if options.gituser:
-			gitpassword = getpass.getpass("github.com user " + options.gituser+":")
-			authstr = base64.encodestring('%s:%s' % (options.gituser, gitpassword)).replace('\n', '')
-			self.headers["Authorization"] = "Basic "+authstr
-	
-	def pulls(self, user, repo, type="all"):
-		page=1
-		ret = []
-		while True:
-			url = "https://api.github.com/repos/"+user+"/"+repo+"/pulls?state="+type+"&page="+str(page)
-		
-			req = urllib2.Request(url,None,self.headers)
-			result = urllib2.urlopen(req)
-			contents = result.read()
-			if result.getcode() != 200:
-				raise Exception(result.getcode() + " != 200 "+ contents)
-			got = json.loads(contents)
-			for part in got:
-				ret.append(GitPullRequest(part, self))
-			if len(got) == 0:
-				return ret
-			page = page + 1
-			
-	def openPulls(self, user, repo):
-		return self.pulls(user, repo, "open")
+def daydiff(a, b):
+	return (a - b).days
 
 def main():
 	parser = OptionParser(usage="usage: %prog [options]")
@@ -308,20 +52,22 @@ def main():
 		else:
 			pullWithoutJira.append(pull);
 	
+	now = datetime.utcnow()
 	print "Pull requests that need a JIRA:"
 	for pull in pullWithoutJira:
-		print ("%s\t%s"%(pull.html_url(), pull.title())).encode("UTF-8")
+		print ("%s\t%s\t%s\t%s"%(pull.html_url(), pull.title(), daydiff(now, pull.created_at()), daydiff(now, pull.updated_at()))).encode("UTF-8")
 	
 	print "\nPull with bad JIRA:"
 	for pull in pullWithBadJira:
-		print ("%s\t%s"%(pull.html_url(), pull.title())).encode("UTF-8")
+		print ("%s\t%s\t%s\t%s"%(pull.html_url(), pull.title(), daydiff(now, pull.created_at()), daydiff(now, pull.updated_at()))).encode("UTF-8")
 	
 	print "\nOpen JIRA to Pull Requests and Votes:"
 	for key, value in jira2Pulls.items():
-		print ("%s\t%s\t%s"%(key, mstr(value),openJiras[key].getSummary())).encode("UTF-8")
+		print ("%s\t%s\t%s\t%s\t%s"%(key, mstr(value),openJiras[key].getSummary(), daydiff(now, openJiras[key].getCreated()), daydiff(now, value[0].created_at()))).encode("UTF-8")
 		for comment in openJiras[key].getComments():
+			#print comment.raw()
 			if comment.hasVote():
-				print (("\t%s\t%s\t%s")%(comment.getVote(), comment.getAuthor(), comment.getPull())).encode("UTF-8")
+				print (("\t%s\t%s\t%s\t%s")%(comment.getVote(), comment.getAuthor(), comment.getPull(), daydiff(now, comment.getCreated()))).encode("UTF-8")
 
 if __name__ == "__main__":
 	main()

http://git-wip-us.apache.org/repos/asf/incubator-storm/blob/e3b9d46e/dev-tools/jira/__init__.py
----------------------------------------------------------------------
diff --git a/dev-tools/jira/__init__.py b/dev-tools/jira/__init__.py
new file mode 100755
index 0000000..225d95d
--- /dev/null
+++ b/dev-tools/jira/__init__.py
@@ -0,0 +1,229 @@
+# -*- coding: utf-8 -*-
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+import re
+import urllib
+import urllib2
+from datetime import datetime
+try:
+	import json
+except ImportError:
+	import simplejson as json
+
+def mstr(obj):
+	if (obj == None):
+		return ""
+	return unicode(obj)
+
+def jiratime(obj):
+	if (obj == None):
+		return None
+	return datetime.strptime(obj[0:19], "%Y-%m-%dT%H:%M:%S")
+
+githubUser = re.compile("Git[Hh]ub user (\w+)")
+githubPull = re.compile("https://github.com/[^/\s]+/[^/\s]+/pull/[0-9]+")
+hasVote = re.compile("\s+([-+][01])\s*")
+isDiff = re.compile("--- End diff --")
+
+def searchGroup(reg, txt, group):
+	m = reg.search(txt)
+	if m == None:
+		return None
+	return m.group(group)
+
+class JiraComment:
+	"""A comment on a JIRA"""
+
+	def __init__(self, data):
+		self.data = data
+		self.author = mstr(self.data['author']['name'])
+		self.githubAuthor = None
+		self.githubPull = None
+		self.githubComment = (self.author == "githubbot")
+		body = self.getBody()
+		if isDiff.search(body) != None:
+			self.vote = None
+		else:
+			self.vote = searchGroup(hasVote, body, 1)
+
+		if self.githubComment:
+			self.githubAuthor = searchGroup(githubUser, body, 1)
+			self.githubPull = searchGroup(githubPull, body, 0)
+			
+
+	def getAuthor(self):
+		if self.githubAuthor != None:
+			return self.githubAuthor
+		return self.author
+
+	def getBody(self):
+		return mstr(self.data['body'])
+
+	def getPull(self):
+		return self.githubPull
+
+	def raw(self):
+		return self.data
+
+	def hasVote(self):
+		return self.vote != None
+
+	def getVote(self):
+		return self.vote
+
+	def getCreated(self):
+		return jiratime(self.data['created'])
+
+class Jira:
+	"""A single JIRA"""
+	
+	def __init__(self, data, parent):
+		self.key = data['key']
+		self.fields = data['fields']
+		self.parent = parent
+		self.notes = None
+		self.comments = None
+	
+	def getId(self):
+		return mstr(self.key)
+	
+	def getDescription(self):
+		return mstr(self.fields['description'])
+	
+	def getReleaseNote(self):
+		if (self.notes == None):
+			field = self.parent.fieldIdMap['Release Note']
+			if (self.fields.has_key(field)):
+				self.notes=mstr(self.fields[field])
+			else:
+				self.notes=self.getDescription()
+		return self.notes
+	
+	def getPriority(self):
+		ret = ""
+		pri = self.fields['priority']
+		if(pri != None):
+			ret = pri['name']
+		return mstr(ret)
+	
+	def getAssigneeEmail(self):
+		ret = ""
+		mid = self.fields['assignee']
+		if mid != None:
+			ret = mid['emailAddress']
+		return mstr(ret)
+
+	
+	def getAssignee(self):
+		ret = ""
+		mid = self.fields['assignee']
+		if(mid != None):
+			ret = mid['displayName']
+		return mstr(ret)
+	
+	def getComponents(self):
+		return " , ".join([ comp['name'] for comp in self.fields['components'] ])
+	
+	def getSummary(self):
+		return self.fields['summary']
+	
+	def getType(self):
+		ret = ""
+		mid = self.fields['issuetype']
+		if(mid != None):
+			ret = mid['name']
+		return mstr(ret)
+	
+	def getReporter(self):
+		ret = ""
+		mid = self.fields['reporter']
+		if(mid != None):
+			ret = mid['displayName']
+		return mstr(ret)
+	
+	def getProject(self):
+		ret = ""
+		mid = self.fields['project']
+		if(mid != None):
+			ret = mid['key']
+		return mstr(ret)
+
+	def getCreated(self):
+		return jiratime(self.fields['created'])
+	
+	def getComments(self):
+		if self.comments == None:
+			jiraId = self.getId()
+			comments = []
+			at=0
+			end=1
+			count=100
+			while (at < end):
+				params = urllib.urlencode({'startAt':at, 'maxResults':count})
+				resp = urllib2.urlopen(self.parent.baseUrl+"/issue/"+jiraId+"/comment?"+params)
+				data = json.loads(resp.read())
+				if (data.has_key('errorMessages')):
+					raise Exception(data['errorMessages'])
+				at = data['startAt'] + data['maxResults']
+				end = data['total']
+				for item in data['comments']:
+					j = JiraComment(item)
+					comments.append(j)
+			self.comments = comments
+		return self.comments
+	
+	def raw(self):
+		return self.fields
+
+class JiraRepo:
+	"""A Repository for JIRAs"""
+	
+	def __init__(self, baseUrl):
+		self.baseUrl = baseUrl
+		resp = urllib2.urlopen(baseUrl+"/field")
+		data = json.loads(resp.read())
+		
+		self.fieldIdMap = {}
+		for part in data:
+			self.fieldIdMap[part['name']] = part['id']
+	
+	def get(self, id):
+		resp = urllib2.urlopen(self.baseUrl+"/issue/"+id)
+		data = json.loads(resp.read())
+		if (data.has_key('errorMessages')):
+			raise Exception(data['errorMessages'])
+		j = Jira(data, self)
+		return j
+	
+	def query(self, query):
+		jiras = {}
+		at=0
+		end=1
+		count=100
+		while (at < end):
+			params = urllib.urlencode({'jql': query, 'startAt':at, 'maxResults':count})
+			#print params
+			resp = urllib2.urlopen(self.baseUrl+"/search?%s"%params)
+			data = json.loads(resp.read())
+			if (data.has_key('errorMessages')):
+				raise Exception(data['errorMessages'])
+			at = data['startAt'] + data['maxResults']
+			end = data['total']
+			for item in data['issues']:
+					j = Jira(item, self)
+					jiras[j.getId()] = j
+		return jiras
+	
+	def openJiras(self, project):
+		return self.query("project = "+project+" AND resolution = Unresolved");
+