def init(self): if self.itdb_exists(): print 'Already initialized issue database in branch \'%s\'.' % \ it.ITDB_BRANCH return # else, initialize the new .it database alongside the .git repo gitrepo = repo.find_git_repo() if not gitrepo: log.printerr('Not a valid Git repository.') else: parent, _ = os.path.split(gitrepo) ticket_dir = os.path.join(parent, it.TICKET_DIR) hold_file = os.path.join(ticket_dir, it.HOLD_FILE) misc.mkdirs(ticket_dir) misc.write_file_contents(hold_file, \ 'This is merely a placeholder file for git-it that prevents ' + \ 'this directory from\nbeing pruned by Git.') # Commit the new itdb to the repo curr_branch = git.current_branch() git.change_head_branch('git-it') git.command_lines('add', [hold_file]) msg = 'Initialized empty ticket database.' git.command_lines('commit', ['-m', msg, hold_file]) os.remove(hold_file) os.rmdir(ticket_dir) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'Initialized empty ticket database.'
def edit(self, sha): i, rel, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(fullsha, 7) # Save the contents of this ticket to a file, so it can be edited i.save(it.EDIT_TMP_FILE) timestamp1 = os.path.getmtime(it.EDIT_TMP_FILE) success = os.system('vim "%s"' % it.EDIT_TMP_FILE) == 0 timestamp2 = os.path.getmtime(it.EDIT_TMP_FILE) if success: if timestamp1 < timestamp2: i = ticket.create_from_file(it.EDIT_TMP_FILE, fullsha, rel) # Now, when the edit has succesfully taken place, switch branches, commit, # and switch back curr_branch = git.current_branch() git.change_head_branch('git-it') msg = 'ticket \'%s\' edited' % sha7 i.save() git.command_lines('commit', ['-m', msg, i.filename()]) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' edited succesfully' % sha7 print '' self.list() else: print 'editing of ticket \'%s\' cancelled' % sha7 else: log.printerr('editing of ticket \'%s\' failed' % sha7) # Remove the temporary file os.remove(it.EDIT_TMP_FILE)
def mv(self, sha, to_rel): self.require_itdb() i, rel, fullsha, src_path = self.get_ticket(sha) sha7 = misc.chop(fullsha, 7) src_dir = os.path.join(repo.find_root(), it.TICKET_DIR, rel) target_dir = os.path.join(repo.find_root(), it.TICKET_DIR, to_rel) target_path = os.path.join(target_dir, fullsha) if src_dir == target_dir: log.printerr('ticket \'%s\' already in \'%s\'' % (sha7, to_rel)) return # Create the target dir, if neccessary if not os.path.isdir(target_dir): misc.mkdirs(target_dir) # Try to move the file into it try: # Commit the new itdb to the repo curr_branch = git.current_branch() git.change_head_branch('git-it') i.save(target_path) if os.path.isfile(src_path): os.remove(src_path) msg = 'moved ticket \'%s\' (%s --> %s)' % (sha7, rel, to_rel) git.command_lines('add', [target_path]) git.command_lines('commit', ['-m', msg, src_path, target_path]) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' moved to release \'%s\'' % (sha7, to_rel) print '' self.list() except OSError, e: log.printerr('could not move ticket \'%s\' to \'%s\':' % (sha7, to_rel)) log.printerr(e)
def rm(self, sha): match = self.match_or_error(sha) _, basename = os.path.split(match) sha7 = misc.chop(basename, 7) # Commit the new itdb to the repo curr_branch = git.current_branch() git.change_head_branch('git-it') msg = 'removed ticket \'%s\'' % sha7 git.command_lines('commit', ['-m', msg, match], from_root=True) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' removed'% sha7
def leave_ticket(self, sha): i, _, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(sha, 7) curr_branch = git.current_branch() git.change_head_branch('git-it') msg = 'ticket \'%s\' left alone' % sha7 i.assigned_to = '-' i.save() git.command_lines('commit', ['-m', msg, match], from_root=True) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' left alone' % sha7
def rm(self, sha): match = self.match_or_error(sha) _, basename = os.path.split(match) sha7 = misc.chop(basename, 7) # Commit the new itdb to the repo curr_branch = git.current_branch() git.change_head_branch('git-it') msg = 'removed ticket \'%s\'' % sha7 git.command_lines('commit', ['-m', msg, match]) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' removed' % sha7
def command_lines(subcmd, opts = [], from_root=False, explicit_git_dir=False): explicit_git_dir_str = '' if explicit_git_dir: git_dir = command_lines('rev-parse', ['--git-dir'], False)[0] explicit_git_dir_str = '--git-dir=%s ' % git_dir if from_root: cwd = os.getcwd() os.chdir(repo.find_root()) cmd = 'git %s%s %s' % (explicit_git_dir_str, subcmd, ' '.join(map(quote_string, opts))) output = os.popen(cmd).read() if from_root: os.chdir(cwd) if output.endswith(os.linesep): output = output[:-len(os.linesep)] return output.split(os.linesep)
def command_lines(subcmd, opts=[], from_root=False, explicit_git_dir=False): explicit_git_dir_str = '' if explicit_git_dir: git_dir = command_lines('rev-parse', ['--git-dir'], False)[0] explicit_git_dir_str = '--git-dir=%s ' % git_dir if from_root: cwd = os.getcwd() os.chdir(repo.find_root()) cmd = 'git %s%s %s' % (explicit_git_dir_str, subcmd, ' '.join( map(quote_string, opts))) output = os.popen(cmd).read() if from_root: os.chdir(cwd) if output.endswith(os.linesep): output = output[:-len(os.linesep)] return output.split(os.linesep)
def command_exitcode_only(subcmd, opts = [], from_root=False, explicit_git_dir=False): explicit_git_dir_str = '' if explicit_git_dir: git_dir = command_lines('rev-parse', ['--git-dir'], False)[0] explicit_git_dir_str = '--git-dir=%s ' % git_dir if from_root: cwd = os.getcwd() os.chdir(repo.find_root()) cmd = 'git %s%s %s' % (explicit_git_dir_str, subcmd, ' '.join(map(quote_string, opts))) p = os.popen(cmd) exitcode = p.close() if from_root: os.chdir(cwd) if exitcode is None: exitcode = 0 return exitcode
def take_ticket(self, sha): i, _, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(sha, 7) curr_branch = git.current_branch() git.change_head_branch('git-it') fullname = os.popen('git config user.name').read().strip() msg = 'ticket \'%s\' taken by %s' % (sha7, fullname) i.assigned_to = fullname i.save() git.command_lines('commit', ['-m', msg, match]) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' taken' % sha7 print '' self.list()
def finish_ticket(self, sha, new_status): i, _, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(fullsha, 7) if i.status not in ['open', 'test']: log.printerr('ticket \'%s\' already %s' % (sha7, i.status)) sys.exit(1) # Now, when the edit has succesfully taken place, switch branches, commit, # and switch back curr_branch = git.current_branch() git.change_head_branch('git-it') i.status = new_status msg = '%s ticket \'%s\'' % (i.status, sha7) i.save() git.command_lines('commit', ['-m', msg, match], from_root=True) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' %s' % (sha7, new_status)
def reopen_ticket(self, sha): i, _, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(sha, 7) if i.status == 'open': log.printerr('ticket \'%s\' already open' % sha7) sys.exit(1) # Now, when the edit has succesfully taken place, switch branches, commit, # and switch back curr_branch = git.current_branch() git.change_head_branch('git-it') msg = 'ticket \'%s\' reopened' % sha7 i.status = 'open' i.save() git.command_lines('commit', ['-m', msg, match], from_root=True) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' reopened' % sha7
def command_exitcode_only(subcmd, opts=[], from_root=False, explicit_git_dir=False): explicit_git_dir_str = '' if explicit_git_dir: git_dir = command_lines('rev-parse', ['--git-dir'], False)[0] explicit_git_dir_str = '--git-dir=%s ' % git_dir if from_root: cwd = os.getcwd() os.chdir(repo.find_root()) cmd = 'git %s%s %s' % (explicit_git_dir_str, subcmd, ' '.join( map(quote_string, opts))) p = os.popen(cmd) exitcode = p.close() if from_root: os.chdir(cwd) if exitcode is None: exitcode = 0 return exitcode
def reject_ticket(self, sha, message): i, _, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(sha, 7) if 'rejected' == i.status: log.printerr('ticket \'%s\' already rejected' % sha7) sys.exit(1) if message is None or message == '': message = ticket.ask_for_pattern('Reason for rejection: ', ticket.not_empty) curr_branch = git.current_branch() git.change_head_branch('git-it') i.status = 'rejected' i.body = 'REJECTED: %s\n\n%s' % (message, i.body) msg = '%s ticket \'%s\'' % (i.status, sha7) i.save() git.command_lines('commit', ['-m', msg, match], from_root=True) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' rejected' % sha7
def reject_ticket(self, sha, message): i, _, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(sha, 7) if 'rejected' == i.status: log.printerr('ticket \'%s\' already rejected' % sha7) sys.exit(1) if message is None or message == '': message = ticket.ask_for_pattern( 'Reason for rejection: ', ticket.not_empty) curr_branch = git.current_branch() git.change_head_branch('git-it') i.status = 'rejected' i.body = 'REJECTED: %s\n\n%s' % (message, i.body) msg = '%s ticket \'%s\'' % (i.status, sha7) i.save() git.command_lines('commit', ['-m', msg, match], from_root=True) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' rejected' % sha7
def edit(self, sha): i, rel, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(fullsha, 7) # Save the contents of this ticket to a file, so it can be edited i.save(it.EDIT_TMP_FILE) timestamp1 = os.path.getmtime(it.EDIT_TMP_FILE) # fetch the editor command from the following sources in this order: # - git config --local core.editor # - git config --global core.editor # - git config --system core.editor # - $GIT_EDITOR # - $EDITOR # - /usr/bin/nano success = os.system('%s "%s"' % (git.get_editor(), it.EDIT_TMP_FILE)) == 0 timestamp2 = os.path.getmtime(it.EDIT_TMP_FILE) if success: if timestamp1 < timestamp2: try: i = ticket.create_from_file(it.EDIT_TMP_FILE, fullsha, rel) except ticket.MalformedTicketFieldException, e: print 'Error parsing ticket: %s' % e sys.exit(1) except ticket.MissingTicketFieldException, e: print 'Error parsing ticket: %s' % e sys.exit(1) # Now, when the edit has succesfully taken place, switch branches, commit, # and switch back curr_branch = git.current_branch() git.change_head_branch('git-it') msg = 'ticket \'%s\' edited' % sha7 i.save() git.command_lines('commit', ['-m', msg, i.filename()]) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' edited succesfully' % sha7
def edit(self, sha): i, rel, fullsha, match = self.get_ticket(sha) sha7 = misc.chop(fullsha, 7) # Save the contents of this ticket to a file, so it can be edited i.save(it.EDIT_TMP_FILE) timestamp1 = os.path.getmtime(it.EDIT_TMP_FILE) # fetch the editor command from the following sources in this order: # - git config --local core.editor # - git config --global core.editor # - git config --system core.editor # - $GIT_EDITOR # - $EDITOR # - /usr/bin/nano success = os.system('%s "%s"' % (git.get_editor(),it.EDIT_TMP_FILE)) == 0 timestamp2 = os.path.getmtime(it.EDIT_TMP_FILE) if success: if timestamp1 < timestamp2: try: i = ticket.create_from_file(it.EDIT_TMP_FILE, fullsha, rel) except ticket.MalformedTicketFieldException, e: print 'Error parsing ticket: %s' % e sys.exit(1) except ticket.MissingTicketFieldException, e: print 'Error parsing ticket: %s' % e sys.exit(1) # Now, when the edit has succesfully taken place, switch branches, commit, # and switch back curr_branch = git.current_branch() git.change_head_branch('git-it') msg = 'ticket \'%s\' edited' % sha7 i.save() git.command_lines('commit', ['-m', msg, i.filename()]) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) print 'ticket \'%s\' edited succesfully' % sha7
def new(self): self.require_itdb() # Create a fresh ticket try: i = ticket.create_interactive() except KeyboardInterrupt: print '' print 'aborting new ticket' return None # Generate a SHA1 id s = sha1_constructor() s.update(i.__str__()) s.update(os.getlogin()) s.update(datetime.datetime.now().__str__()) i.id = s.hexdigest() # Save the ticket to disk i.save() _, ticketname = os.path.split(i.filename()) sha7 = misc.chop(ticketname, 7) print 'new ticket \'%s\' saved' % sha7 # Commit the new ticket to the 'aaa' branch curr_branch = git.current_branch() git.change_head_branch('git-it') git.command_lines('add', [i.filename()]) msg = '%s added ticket \'%s\'' % (i.issuer, sha7) git.command_lines('commit', ['-m', msg, i.filename()]) os.remove(i.filename()) git.command_lines('rm', ['--cached', i.filename()]) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) return i
def new(self): self.require_itdb() # Create a fresh ticket try: i = ticket.create_interactive() except KeyboardInterrupt: print '' print 'aborting new ticket' return None # Generate a SHA1 id s = sha1_constructor() s.update(i.__str__()) s.update(os.getenv('LOGNAME')) s.update(datetime.datetime.now().__str__()) i.id = s.hexdigest() # Save the ticket to disk i.save() _, ticketname = os.path.split(i.filename()) sha7 = misc.chop(ticketname, 7) print 'new ticket \'%s\' saved' % sha7 # Commit the new ticket to the 'aaa' branch curr_branch = git.current_branch() git.change_head_branch('git-it') git.command_lines('add', [i.filename()]) msg = '%s added ticket \'%s\'' % (i.issuer, sha7) git.command_lines('commit', ['-m', msg, i.filename()]) os.remove(i.filename()) git.command_lines('rm', ['--cached', i.filename()]) git.change_head_branch(curr_branch) abs_ticket_dir = os.path.join(repo.find_root(), it.TICKET_DIR) git.command_lines('reset', ['HEAD', abs_ticket_dir]) misc.rmdirs(abs_ticket_dir) return i
def filename(self): file = os.path.join(repo.find_root(), it.TICKET_DIR, self.release, self.id) return file