Bladeren bron

Merge bb9a2ed852bccf6256a7bc1456a1db18d8a7315f into 55c5c285558c410bb35ebf421245d320ab9ee9fa

Gokturk Yuksek 5 jaren geleden
bovenliggende
commit
97b73d7703
Geen account gekoppeld aan de committers e-mail
1 gewijzigde bestanden met toevoegingen van 50 en 47 verwijderingen
  1. 50
    47
      gitstats

+ 50
- 47
gitstats Bestand weergeven

@@ -1,6 +1,9 @@
1
-#!/usr/bin/env python2
1
+#!/usr/bin/env python
2 2
 # Copyright (c) 2007-2014 Heikki Hokkanen <hoxu@users.sf.net> & others (see doc/AUTHOR)
3 3
 # GPLv2 / GPLv3
4
+
5
+from __future__ import print_function
6
+
4 7
 import datetime
5 8
 import getopt
6 9
 import glob
@@ -15,7 +18,7 @@ import time
15 18
 import zlib
16 19
 
17 20
 if sys.version_info < (2, 6):
18
-	print >> sys.stderr, "Python 2.6 or higher is required for gitstats"
21
+	print("Python 2.6 or higher is required for gitstats", file=sys.stderr)
19 22
 	sys.exit(1)
20 23
 
21 24
 from multiprocessing import Pool
@@ -54,12 +57,12 @@ def getpipeoutput(cmds, quiet = False):
54 57
 	global exectime_external
55 58
 	start = time.time()
56 59
 	if not quiet and ON_LINUX and os.isatty(1):
57
-		print '>> ' + ' | '.join(cmds),
60
+		print('>> ' + ' | '.join(cmds), end=' ')
58 61
 		sys.stdout.flush()
59
-	p = subprocess.Popen(cmds[0], stdout = subprocess.PIPE, shell = True)
62
+	p = subprocess.Popen(cmds[0], stdout = subprocess.PIPE, shell = True, universal_newlines = True)
60 63
 	processes=[p]
61 64
 	for x in cmds[1:]:
62
-		p = subprocess.Popen(x, stdin = p.stdout, stdout = subprocess.PIPE, shell = True)
65
+		p = subprocess.Popen(x, stdin = p.stdout, stdout = subprocess.PIPE, shell = True, universal_newlines = True)
63 66
 		processes.append(p)
64 67
 	output = p.communicate()[0]
65 68
 	for p in processes:
@@ -67,8 +70,8 @@ def getpipeoutput(cmds, quiet = False):
67 70
 	end = time.time()
68 71
 	if not quiet:
69 72
 		if ON_LINUX and os.isatty(1):
70
-			print '\r',
71
-		print '[%.5f] >> %s' % (end - start, ' | '.join(cmds))
73
+			print('\r', end=' ')
74
+		print('[%.5f] >> %s' % (end - start, ' | '.join(cmds)))
72 75
 	exectime_external += (end - start)
73 76
 	return output.rstrip('\n')
74 77
 
@@ -86,11 +89,11 @@ def getcommitrange(defaultrange = 'HEAD', end_only = False):
86 89
 	return defaultrange
87 90
 
88 91
 def getkeyssortedbyvalues(dict):
89
-	return map(lambda el : el[1], sorted(map(lambda el : (el[1], el[0]), dict.items())))
92
+	return [el[1] for el in sorted([(el[1], el[0]) for el in list(dict.items())])]
90 93
 
91 94
 # dict['author'] = { 'commits': 512 } - ...key(dict, 'commits')
92 95
 def getkeyssortedbyvaluekey(d, key):
93
-	return map(lambda el : el[1], sorted(map(lambda el : (d[el][key], el), d.keys())))
96
+	return [el[1] for el in sorted([(d[el][key], el) for el in list(d.keys())])]
94 97
 
95 98
 def getstatsummarycounts(line):
96 99
 	numbers = re.findall('\d+', line)
@@ -207,7 +210,7 @@ class DataCollector:
207 210
 	def loadCache(self, cachefile):
208 211
 		if not os.path.exists(cachefile):
209 212
 			return
210
-		print 'Loading cache...'
213
+		print('Loading cache...')
211 214
 		f = open(cachefile, 'rb')
212 215
 		try:
213 216
 			self.cache = pickle.loads(zlib.decompress(f.read()))
@@ -269,7 +272,7 @@ class DataCollector:
269 272
 	##
270 273
 	# Save cacheable data
271 274
 	def saveCache(self, cachefile):
272
-		print 'Saving cache...'
275
+		print('Saving cache...')
273 276
 		tempfile = cachefile + '.tmp'
274 277
 		f = open(tempfile, 'wb')
275 278
 		#pickle.dump(self.cache, f)
@@ -308,7 +311,7 @@ class GitDataCollector(DataCollector):
308 311
 				self.tags[tag] = { 'stamp': stamp, 'hash' : hash, 'date' : datetime.datetime.fromtimestamp(stamp).strftime('%Y-%m-%d'), 'commits': 0, 'authors': {} }
309 312
 
310 313
 		# collect info on tags, starting from latest
311
-		tags_sorted_by_date_desc = map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), self.tags.items()))))
314
+		tags_sorted_by_date_desc = [el[1] for el in reversed(sorted([(el[1]['date'], el[0]) for el in list(self.tags.items())]))]
312 315
 		prev = None
313 316
 		for tag in reversed(tags_sorted_by_date_desc):
314 317
 			cmd = 'git shortlog -s "%s"' % tag
@@ -444,10 +447,10 @@ class GitDataCollector(DataCollector):
444 447
 			time, rev = revline.split(' ')
445 448
 			#if cache empty then add time and rev to list of new rev's
446 449
 			#otherwise try to read needed info from cache
447
-			if 'files_in_tree' not in self.cache.keys():
450
+			if 'files_in_tree' not in list(self.cache.keys()):
448 451
 				revs_to_read.append((time,rev))
449 452
 				continue
450
-			if rev in self.cache['files_in_tree'].keys():
453
+			if rev in list(self.cache['files_in_tree'].keys()):
451 454
 				lines.append('%d %d' % (int(time), self.cache['files_in_tree'][rev]))
452 455
 			else:
453 456
 				revs_to_read.append((time,rev))
@@ -474,7 +477,7 @@ class GitDataCollector(DataCollector):
474 477
 			try:
475 478
 				self.files_by_stamp[int(stamp)] = int(files)
476 479
 			except ValueError:
477
-				print 'Warning: failed to parse line "%s"' % line
480
+				print('Warning: failed to parse line "%s"' % line)
478 481
 
479 482
 		# extensions and size of files
480 483
 		lines = getpipeoutput(['git ls-tree -r -l -z %s' % getcommitrange('HEAD', end_only = True)]).split('\000')
@@ -505,10 +508,10 @@ class GitDataCollector(DataCollector):
505 508
 			self.extensions[ext]['files'] += 1
506 509
 			#if cache empty then add ext and blob id to list of new blob's
507 510
 			#otherwise try to read needed info from cache
508
-			if 'lines_in_blob' not in self.cache.keys():
511
+			if 'lines_in_blob' not in list(self.cache.keys()):
509 512
 				blobs_to_read.append((ext,blob_id))
510 513
 				continue
511
-			if blob_id in self.cache['lines_in_blob'].keys():
514
+			if blob_id in list(self.cache['lines_in_blob'].keys()):
512 515
 				self.extensions[ext]['lines'] += self.cache['lines_in_blob'][blob_id]
513 516
 			else:
514 517
 				blobs_to_read.append((ext,blob_id))
@@ -563,21 +566,21 @@ class GitDataCollector(DataCollector):
563 566
 
564 567
 						files, inserted, deleted = 0, 0, 0
565 568
 					except ValueError:
566
-						print 'Warning: unexpected line "%s"' % line
569
+						print('Warning: unexpected line "%s"' % line)
567 570
 				else:
568
-					print 'Warning: unexpected line "%s"' % line
571
+					print('Warning: unexpected line "%s"' % line)
569 572
 			else:
570 573
 				numbers = getstatsummarycounts(line)
571 574
 
572 575
 				if len(numbers) == 3:
573
-					(files, inserted, deleted) = map(lambda el : int(el), numbers)
576
+					(files, inserted, deleted) = [int(el) for el in numbers]
574 577
 					total_lines += inserted
575 578
 					total_lines -= deleted
576 579
 					self.total_lines_added += inserted
577 580
 					self.total_lines_removed += deleted
578 581
 
579 582
 				else:
580
-					print 'Warning: failed to handle line "%s"' % line
583
+					print('Warning: failed to handle line "%s"' % line)
581 584
 					(files, inserted, deleted) = (0, 0, 0)
582 585
 				#self.changes_by_date[stamp] = { 'files': files, 'ins': inserted, 'del': deleted }
583 586
 		self.total_lines += total_lines
@@ -622,16 +625,16 @@ class GitDataCollector(DataCollector):
622 625
 						self.changes_by_date_by_author[stamp][author]['commits'] = self.authors[author]['commits']
623 626
 						files, inserted, deleted = 0, 0, 0
624 627
 					except ValueError:
625
-						print 'Warning: unexpected line "%s"' % line
628
+						print('Warning: unexpected line "%s"' % line)
626 629
 				else:
627
-					print 'Warning: unexpected line "%s"' % line
630
+					print('Warning: unexpected line "%s"' % line)
628 631
 			else:
629 632
 				numbers = getstatsummarycounts(line);
630 633
 
631 634
 				if len(numbers) == 3:
632
-					(files, inserted, deleted) = map(lambda el : int(el), numbers)
635
+					(files, inserted, deleted) = [int(el) for el in numbers]
633 636
 				else:
634
-					print 'Warning: failed to handle line "%s"' % line
637
+					print('Warning: failed to handle line "%s"' % line)
635 638
 					(files, inserted, deleted) = (0, 0, 0)
636 639
 	
637 640
 	def refine(self):
@@ -642,7 +645,7 @@ class GitDataCollector(DataCollector):
642 645
 		for i, name in enumerate(self.authors_by_commits):
643 646
 			self.authors[name]['place_by_commits'] = i + 1
644 647
 
645
-		for name in self.authors.keys():
648
+		for name in list(self.authors.keys()):
646 649
 			a = self.authors[name]
647 650
 			a['commits_frac'] = (100 * float(a['commits'])) / self.getTotalCommits()
648 651
 			date_first = datetime.datetime.fromtimestamp(a['first_commit_stamp'])
@@ -678,7 +681,7 @@ class GitDataCollector(DataCollector):
678 681
 		return self.domains[domain]
679 682
 
680 683
 	def getDomains(self):
681
-		return self.domains.keys()
684
+		return list(self.domains.keys())
682 685
 	
683 686
 	def getFirstCommitDate(self):
684 687
 		return datetime.datetime.fromtimestamp(self.first_commit_stamp)
@@ -744,7 +747,7 @@ class HTMLReportCreator(ReportCreator):
744 747
 					shutil.copyfile(src, path + '/' + file)
745 748
 					break
746 749
 			else:
747
-				print 'Warning: "%s" not found, so not copied (searched: %s)' % (file, basedirs)
750
+				print('Warning: "%s" not found, so not copied (searched: %s)' % (file, basedirs))
748 751
 
749 752
 		f = open(path + "/index.html", 'w')
750 753
 		format = '%Y-%m-%d %H:%M:%S'
@@ -942,7 +945,7 @@ class HTMLReportCreator(ReportCreator):
942 945
 		f.write('<th>Timezone</th><th>Commits</th>')
943 946
 		f.write('</tr>')
944 947
 		max_commits_on_tz = max(data.commits_by_timezone.values())
945
-		for i in sorted(data.commits_by_timezone.keys(), key = lambda n : int(n)):
948
+		for i in sorted(list(data.commits_by_timezone.keys()), key = lambda n : int(n)):
946 949
 			commits = data.commits_by_timezone[i]
947 950
 			r = 127 + int((float(commits) / max_commits_on_tz) * 128)
948 951
 			f.write('<tr><th>%s</th><td style="background-color: rgb(%d, 0, 0)">%d</td></tr>' % (i, r, commits))
@@ -1006,7 +1009,7 @@ class HTMLReportCreator(ReportCreator):
1006 1009
 			fgl.write('%d' % stamp)
1007 1010
 			fgc.write('%d' % stamp)
1008 1011
 			for author in self.authors_to_plot:
1009
-				if author in data.changes_by_date_by_author[stamp].keys():
1012
+				if author in list(data.changes_by_date_by_author[stamp].keys()):
1010 1013
 					lines_by_authors[author] = data.changes_by_date_by_author[stamp][author]['lines_added']
1011 1014
 					commits_by_authors[author] = data.changes_by_date_by_author[stamp][author]['commits']
1012 1015
 				fgl.write(' %d' % lines_by_authors[author])
@@ -1153,7 +1156,7 @@ class HTMLReportCreator(ReportCreator):
1153 1156
 		f.write('<table class="tags">')
1154 1157
 		f.write('<tr><th>Name</th><th>Date</th><th>Commits</th><th>Authors</th></tr>')
1155 1158
 		# sort the tags by date desc
1156
-		tags_sorted_by_date_desc = map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), data.tags.items()))))
1159
+		tags_sorted_by_date_desc = [el[1] for el in reversed(sorted([(el[1]['date'], el[0]) for el in list(data.tags.items())]))]
1157 1160
 		for tag in tags_sorted_by_date_desc:
1158 1161
 			authorinfo = []
1159 1162
 			self.authors_by_commits = getkeyssortedbyvalues(data.tags[tag]['authors'])
@@ -1168,7 +1171,7 @@ class HTMLReportCreator(ReportCreator):
1168 1171
 		self.createGraphs(path)
1169 1172
 	
1170 1173
 	def createGraphs(self, path):
1171
-		print 'Generating graphs...'
1174
+		print('Generating graphs...')
1172 1175
 
1173 1176
 		# hour of day
1174 1177
 		f = open(path + '/hour_of_day.plot', 'w')
@@ -1370,7 +1373,7 @@ plot """
1370 1373
 		for f in files:
1371 1374
 			out = getpipeoutput([gnuplot_cmd + ' "%s"' % f])
1372 1375
 			if len(out) > 0:
1373
-				print out
1376
+				print(out)
1374 1377
 
1375 1378
 	def printHeader(self, f, title = ''):
1376 1379
 		f.write(
@@ -1401,7 +1404,7 @@ plot """
1401 1404
 """)
1402 1405
 		
1403 1406
 def usage():
1404
-	print """
1407
+	print("""
1405 1408
 Usage: gitstats [options] <gitpath..> <outputpath>
1406 1409
 
1407 1410
 Options:
@@ -1411,7 +1414,7 @@ Default config values:
1411 1414
 %s
1412 1415
 
1413 1416
 Please see the manual page for more details.
1414
-""" % conf
1417
+""" % conf)
1415 1418
 
1416 1419
 
1417 1420
 class GitStats:
@@ -1442,48 +1445,48 @@ class GitStats:
1442 1445
 		except OSError:
1443 1446
 			pass
1444 1447
 		if not os.path.isdir(outputpath):
1445
-			print 'FATAL: Output path is not a directory or does not exist'
1448
+			print('FATAL: Output path is not a directory or does not exist')
1446 1449
 			sys.exit(1)
1447 1450
 
1448 1451
 		if not getgnuplotversion():
1449
-			print 'gnuplot not found'
1452
+			print('gnuplot not found')
1450 1453
 			sys.exit(1)
1451 1454
 
1452
-		print 'Output path: %s' % outputpath
1455
+		print('Output path: %s' % outputpath)
1453 1456
 		cachefile = os.path.join(outputpath, 'gitstats.cache')
1454 1457
 
1455 1458
 		data = GitDataCollector()
1456 1459
 		data.loadCache(cachefile)
1457 1460
 
1458 1461
 		for gitpath in args[0:-1]:
1459
-			print 'Git path: %s' % gitpath
1462
+			print('Git path: %s' % gitpath)
1460 1463
 
1461 1464
 			prevdir = os.getcwd()
1462 1465
 			os.chdir(gitpath)
1463 1466
 
1464
-			print 'Collecting data...'
1467
+			print('Collecting data...')
1465 1468
 			data.collect(gitpath)
1466 1469
 
1467 1470
 			os.chdir(prevdir)
1468 1471
 
1469
-		print 'Refining data...'
1472
+		print('Refining data...')
1470 1473
 		data.saveCache(cachefile)
1471 1474
 		data.refine()
1472 1475
 
1473 1476
 		os.chdir(rundir)
1474 1477
 
1475
-		print 'Generating report...'
1478
+		print('Generating report...')
1476 1479
 		report = HTMLReportCreator()
1477 1480
 		report.create(data, outputpath)
1478 1481
 
1479 1482
 		time_end = time.time()
1480 1483
 		exectime_internal = time_end - time_start
1481
-		print 'Execution time %.5f secs, %.5f secs (%.2f %%) in external commands)' % (exectime_internal, exectime_external, (100.0 * exectime_external) / exectime_internal)
1484
+		print('Execution time %.5f secs, %.5f secs (%.2f %%) in external commands)' % (exectime_internal, exectime_external, (100.0 * exectime_external) / exectime_internal))
1482 1485
 		if sys.stdin.isatty():
1483
-			print 'You may now run:'
1484
-			print
1485
-			print '   sensible-browser \'%s\'' % os.path.join(outputpath, 'index.html').replace("'", "'\\''")
1486
-			print
1486
+			print('You may now run:')
1487
+			print()
1488
+			print('   sensible-browser \'%s\'' % os.path.join(outputpath, 'index.html').replace("'", "'\\''"))
1489
+			print()
1487 1490
 
1488 1491
 if __name__=='__main__':
1489 1492
 	g = GitStats()