From 649109909952108445536e071dcbe04ebcf79090 Mon Sep 17 00:00:00 2001 From: Fabien Benureau Date: Thu, 27 Jun 2013 16:50:23 +0200 Subject: [PATCH] update pit with python3 support --- pit | 112 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/pit b/pit index e06c3a4..02a6480 100755 --- a/pit +++ b/pit @@ -5,16 +5,26 @@ pit : python issue tracker. pit is a simple issue tracker written in python """ -__version__ = '0.3' +from __future__ import print_function + +__version__ = '0.4' import sys, os import shutil -import ConfigParser + from hashlib import sha1 -import StringIO import subprocess import datetime +if sys.version_info[0] == 2: + import ConfigParser as configparser + import StringIO as io + input = raw_input +else: + import configparser + import io + + # Searching for the pit dir pitdir = None @@ -30,9 +40,9 @@ def find_pitdir(): curdir = '' else: curdir = os.path.split(curdir)[0] - + if pitdir is None: - print 'No pit repo found in this directory or in any parent directory.' + print('No pit repo found in this directory or in any parent directory.') exit(0) # Reading Writing issues @@ -53,13 +63,14 @@ def get_author(): author = author.strip('\n') mail = mail.strip('\n') return author, mail - except OSError, subprocess.CalledProcessError: + except OSError as xxx_todo_changeme: + subprocess.CalledProcessError = xxx_todo_changeme return 'anonymous', 'unknow' def get_issue_date(issue): try: return datetime.datetime.strptime(issue.get('header', 'date'), '%Y-%m-%d at %H:%M UCT') - except ConfigParser.NoOptionError: + except configparser.NoOptionError: return datetime.datetime(2012, 8, 7, 0, 36, 32, 0) def issue_file(digest): @@ -80,7 +91,7 @@ def find_issue_file(digest): def read_issue(digest): f = find_issue_file(digest) if os.path.exists(f): - issue = ConfigParser.ConfigParser() + issue = configparser.ConfigParser() issue.read(f) return issue else: @@ -121,7 +132,7 @@ grey = '\033[0;37m' bblack = '\033[1;30m' bred = '\033[1;31m' bgreen = '\033[1;32m' -byellow = '\033[1;33m' +byellow = '\033[1;33m' bblue = '\033[1;34m' bpurple = '\033[1;35m' bcyan = '\033[1;36m' @@ -149,19 +160,19 @@ def show_issues(filtered_status): if filename.startswith('pit-'): issue = read_issue(filename[4:]) status = issue.get('header', 'status') - if filtered_status is None or status in filtered_status: + if filtered_status is None or status in filtered_status: relevant_issues.append((get_issue_date(issue), oneline(issue))) relevant_issues.sort() for _, line in relevant_issues: #print _ - print line - + print(line) + # Commands def init_cmd(): """Create a .pit directory""" pitdir = os.getcwd() + '/.pit' - print "initializing pit in %s" % (pitdir,) + print("initializing pit in %s" % (pitdir,)) if not os.path.exists(pitdir): os.makedirs(pitdir) @@ -170,38 +181,38 @@ def add_cmd(title): # finding type t = None while t not in set(['b', 'f', 't', '', 'bug', 'feature', 'task']): - print "bug (b), feature (f) or task (t) ? [b]: ", + print("bug (b), feature (f) or task (t) ? [b]: ", end=' ') sys.stdout.flush() - t = raw_input() + t = input() if t == '': t = 'b' extend = {'b':'bug', 'f':'feature', 't':'task'} if t in extend: t = extend[t] - # finding the digest + # finding the digest issue = setup_issue('', title, t) - s = StringIO.StringIO() + s = io.StringIO() issue.write(s) digest = sha1digest(s.getvalue()) # creating the issue values filepath = issue_file(digest) if os.path.exists(filepath): - print '{}error{}: an issue by this name already exists; exiting.'.format(red, end) + print('{}error{}: an issue by this name already exists; exiting.'.format(red, end)) exit(1) issue.set('header', 'id', digest) - issue.set('eventlog', 'opened[0]', 'opened the {} by {}'.format(issue.get('header', 'date'), + issue.set('eventlog', 'opened[0]', 'opened the {} by {}'.format(issue.get('header', 'date'), issue.get('header', 'author'))) - + # writing the issue on file try: - with open(filepath, 'w') as f: + with open(filepath, 'w') as f: issue.write(f) except IOError as e: - print 'IOError : impossible to write on issue file {:s}'.format(issue_file(digest)) - print 'Verify file permissions' - print oneline(issue) + print('IOError : impossible to write on issue file {:s}'.format(issue_file(digest))) + print('Verify file permissions') + print(oneline(issue)) def close_cmd(digest): """Close issue n""" @@ -209,25 +220,25 @@ def close_cmd(digest): status = issue.get('header', 'status') digest = issue.get('header', 'id')[:sha1_length] if status == 'closed': - print "{}warning{}: issue {}{}{} already closed".format(red, end, bold, digest, end) + print("{}warning{}: issue {}{}{} already closed".format(red, end, bold, digest, end)) else: issue.set('header','status','closed') now = datetime.datetime.utcnow() - + author, mail = get_author() try: issue.add_section('eventlog') except ConfigParser.DuplicateSectionError: pass - issue.set('eventlog', - 'closed[{}]'.format(len(issue.options('eventlog'))), + issue.set('eventlog', + 'closed[{}]'.format(len(issue.options('eventlog'))), 'closed the {} at {}(UCT) by {}'.format(now.date().isoformat(), now.time().strftime("%H:%M"), author)) try: - with open(issue_file(digest), 'w') as f: + with open(issue_file(digest), 'w') as f: issue.write(f) except IOError as e: - print 'IOError : impossible to write on issue file {:s}'.format(issue_file(digest)) - print 'Verify file permissions' + print('IOError : impossible to write on issue file {:s}'.format(issue_file(digest))) + print('Verify file permissions') def open_cmd(): """Show opened issues""" @@ -242,18 +253,18 @@ def all_cmd(): show_issues(None) def install_cmd(): - + """Install command on the system""" - print 'File to install :', __file__ + print('File to install :', __file__) default = '/usr/local/bin' - print "Folder to install the pit command [{:s}] : ".format(default), + print("Folder to install the pit command [{:s}] : ".format(default), end=' ') sys.stdout.flush() - path = raw_input() + path = input() if path == '': path = default - + if not os.path.exists(path): - print "error: {:s} does not exist. Installation aborted.".format(path) + print("error: {:s} does not exist. Installation aborted.".format(path)) else: if os.path.exists(path+'/pit'): if os.path.samefile(path+'/pit', __file__): @@ -267,7 +278,7 @@ def update_cmd(): if filename.startswith('pit00'): issue = ConfigParser.ConfigParser() issue.read(pitdir + '/' + filename) - s = StringIO.StringIO() + s = io.StringIO() issue.write(s) digest = sha1digest(s.getvalue()) @@ -275,7 +286,7 @@ def update_cmd(): assert not os.path.exists(filepath) issue.set('header', 'id', digest) - with open(filepath, 'w') as f: + with open(filepath, 'w') as f: issue.write(f) # Handling command line arguments @@ -299,7 +310,7 @@ manual = """pit manual pit is designed to be simple, self-contained, and compatible with git branching. -{b}BASIC USAGE{e} +{b}BASIC USAGE{e} $ {b}pit init{e} initializing pit in /Users/fabien/Perso/sync/projects/pit/.pit $ {b}pit add{e} 'bug description' @@ -309,7 +320,7 @@ pit is designed to be simple, self-contained, and compatible with git branching. 0001 b [ open ] bug description $ {b}pit close 1{e} $ {b}pit open{e} - $ {b}pit closed{e} + $ {b}pit closed{e} 0001 b [closed] bug description {b}DISTRIBUTION{e} @@ -321,18 +332,18 @@ pit is designed to be simple, self-contained, and compatible with git branching. Each issue is stored in its own file in the .pit directory. At creation, the checksum of the file is computed, and it designates the issue for there on. This is particularly useful when using pit under git : collision - between issues created in different branch are vanishingly unlikely, and when + between issues created in different branch are vanishingly unlikely, and when they happen, overwhelming chances are the bug are exactly the same. "If all 6.5 billion humans on Earth were programming, and every second, each one - was producing code that was the equivalent of the entire Linux kernel history - (1 million Git objects) and pushing it into one enormous Git repository, it + was producing code that was the equivalent of the entire Linux kernel history + (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50%% probability of a single SHA-1 object collision." -- Pro Git book. """.format(b=bold, e=end) if len(sys.argv) == 1 or len(sys.argv) > 3: - print usage + print(usage) exit(0) cmd = sys.argv[1] @@ -341,15 +352,15 @@ if cmd not in ['init', 'install', 'man', 'version']: if len(sys.argv) == 2: if cmd not in ['init', 'open', 'install', 'man', 'version', 'closed', 'all', 'update']: - print usage + print(usage) elif cmd == 'init': init_cmd() elif cmd == 'install': install_cmd() elif cmd == 'man': - print manual + print(manual) elif cmd == 'version': - print __version__ + print(__version__) elif cmd == 'open': open_cmd() elif cmd == 'closed': @@ -360,11 +371,10 @@ if len(sys.argv) == 2: update_cmd() if len(sys.argv) == 3: if cmd not in ['add', 'close']: - print usage + print(usage) elif cmd == 'add': - title = sys.argv[2] + title = sys.argv[2] add_cmd(title) elif cmd == 'close': digest = sys.argv[2] close_cmd(digest) - \ No newline at end of file