artemis.py
changeset 49 248ec36cef5f
parent 35 2e7575352ef3
parent 48 7897c850150f
child 50 10fa939a4a3e
equal deleted inserted replaced
35:2e7575352ef3 49:248ec36cef5f
     1 # Author: Dmitriy Morozov <hg@foxcub.org>, 2007 -- 2009
     1 # Author: Dmitriy Morozov <hg@foxcub.org>, 2007 -- 2009
     2         
     2 
     3 """A very simple and lightweight issue tracker for Mercurial."""
     3 """A very simple and lightweight issue tracker for Mercurial."""
     4 
     4 
     5 from mercurial import hg, util
     5 from mercurial import hg, util
     6 from mercurial.i18n import _
     6 from mercurial.i18n import _
     7 import os, time, random, mailbox, glob, socket, ConfigParser
     7 import os, time, random, mailbox, glob, socket, ConfigParser
    64         for property,value in properties:
    64         for property,value in properties:
    65             if value:
    65             if value:
    66                 property_match = property_match and (mbox[root][property] == value)
    66                 property_match = property_match and (mbox[root][property] == value)
    67             else:
    67             else:
    68                 property_match = property_match and (property not in mbox[root])
    68                 property_match = property_match and (property not in mbox[root])
    69         
    69 
    70         if not show_all and (not properties or not property_match) and (properties or mbox[root]['State'].upper() in [f.upper() for f in state['fixed']]): continue
    70         if not show_all and (not properties or not property_match) and (properties or mbox[root]['State'].upper() in [f.upper() for f in state['fixed']]): continue
    71         if match_date and not date_match(util.parsedate(mbox[root]['date'])[0]): continue
    71         if match_date and not date_match(util.parsedate(mbox[root]['date'])[0]): continue
    72 
    72 
    73         if not list_properties:
    73         if not list_properties:
    74             ui.write("%s (%3d) [%s]: %s\n" % (issue[len(issues_path)+1:], # +1 for trailing /
    74             ui.write("%s (%3d) [%s]: %s\n" % (issue[len(issues_path)+1:], # +1 for trailing /
   112     default_issue_text +=         "Detailed description."
   112     default_issue_text +=         "Detailed description."
   113 
   113 
   114     # Get properties, and figure out if we need an explicit comment
   114     # Get properties, and figure out if we need an explicit comment
   115     properties = _get_properties(opts['property'])
   115     properties = _get_properties(opts['property'])
   116     no_comment = id and properties and opts['no_property_comment']
   116     no_comment = id and properties and opts['no_property_comment']
       
   117     message = opts['message']
   117 
   118 
   118     # Create the text
   119     # Create the text
   119     if not no_comment:
   120     if message:
       
   121         if not id:
       
   122             state_str = 'State: %s\n' % state['default']
       
   123         else:
       
   124             state_str = ''
       
   125         issue = "From: %s\nDate: %s\nSubject: %s\n%s" % \
       
   126                 (user, util.datestr(format=date_format), message, state_str)
       
   127     elif not no_comment:
   120         issue = ui.edit(default_issue_text, user)
   128         issue = ui.edit(default_issue_text, user)
   121 
   129 
   122         if issue.strip() == '':
   130         if issue.strip() == '':
   123             ui.warn('Empty issue, ignoring\n')
   131             ui.warn('Empty issue, ignoring\n')
   124             return
   132             return
   125         if issue.strip() == default_issue_text:
   133         if issue.strip() == default_issue_text:
   126             ui.warn('Unchanged issue text, ignoring\n')
   134             ui.warn('Unchanged issue text, ignoring\n')
   127             return
   135             return
   128     else:
   136     else:
   129         # Write down a comment about updated properties
   137         # Write down a comment about updated properties
   130         properties_subject = ', '.join(['%s=%s' % (property, value) for (property, value) in properties])            
   138         properties_subject = ', '.join(['%s=%s' % (property, value) for (property, value) in properties])
   131     
   139 
   132         issue =     "From: %s\nDate: %s\nSubject: changed properties (%s)\n" % \
   140         issue =     "From: %s\nDate: %s\nSubject: changed properties (%s)\n" % \
   133                      (user, util.datestr(format = date_format), properties_subject)
   141                      (user, util.datestr(format = date_format), properties_subject)
   134 
   142 
   135     # Create the message
   143     # Create the message
   136     msg = mailbox.MaildirMessage(issue)
   144     msg = mailbox.MaildirMessage(issue)
   185 def ishow(ui, repo, id, comment = 0, **opts):
   193 def ishow(ui, repo, id, comment = 0, **opts):
   186     """Shows issue ID, or possibly its comment COMMENT"""
   194     """Shows issue ID, or possibly its comment COMMENT"""
   187 
   195 
   188     comment = int(comment)
   196     comment = int(comment)
   189     issue, id = _find_issue(ui, repo, id)
   197     issue, id = _find_issue(ui, repo, id)
   190     if not issue: return
   198     if not issue:
       
   199         return ui.warn('No such issue\n')
   191     
   200     
   192     issues_dir = ui.config('artemis', 'issues', default = default_issues_dir)
   201     issues_dir = ui.config('artemis', 'issues', default = default_issues_dir)
   193     _create_missing_dirs(os.path.join(repo.root, issues_dir), issue)
   202     _create_missing_dirs(os.path.join(repo.root, issues_dir), issue)
   194 
   203 
       
   204     if opts.get('mutt'):
       
   205         return util.system('mutt -R -f %s' % issue)
       
   206 
   195     mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage)
   207     mbox = mailbox.Maildir(issue, factory=mailbox.MaildirMessage)
   196 
   208 
   197     if opts['all']:
   209     if opts['all']:
   198         ui.write('='*70 + '\n')
   210         ui.write('='*70 + '\n')
   199         i = 0
   211         i = 0
   200         keys = _order_keys_date(mbox) 
   212         keys = _order_keys_date(mbox)
   201         for k in keys:
   213         for k in keys:
   202             _write_message(ui, mbox[k], i, skip = opts['skip'])
   214             _write_message(ui, mbox[k], i, skip = opts['skip'])
   203             ui.write('-'*70 + '\n')
   215             ui.write('-'*70 + '\n')
   204             i += 1
   216             i += 1
   205         return
   217         return
   393                   ('p', 'property', [],
   405                   ('p', 'property', [],
   394                    'list issues with specific field values (e.g., -p state=fixed); lists all possible values of a property if no = sign'),
   406                    'list issues with specific field values (e.g., -p state=fixed); lists all possible values of a property if no = sign'),
   395                   ('d', 'date', '', 'restrict to issues matching the date (e.g., -d ">12/28/2007)"'),
   407                   ('d', 'date', '', 'restrict to issues matching the date (e.g., -d ">12/28/2007)"'),
   396                   ('f', 'filter', '', 'restrict to pre-defined filter (in %s/%s*)' % (default_issues_dir, filter_prefix))],
   408                   ('f', 'filter', '', 'restrict to pre-defined filter (in %s/%s*)' % (default_issues_dir, filter_prefix))],
   397                  _('hg ilist [OPTIONS]')),
   409                  _('hg ilist [OPTIONS]')),
   398     'iadd':       (iadd, 
   410     'iadd':       (iadd,
   399                  [('a', 'attach', [],
   411                  [('a', 'attach', [],
   400                    'attach file(s) (e.g., -a filename1 -a filename2)'),
   412                    'attach file(s) (e.g., -a filename1 -a filename2)'),
   401                   ('p', 'property', [],
   413                   ('p', 'property', [],
   402                    'update properties (e.g., -p state=fixed)'),
   414                    'update properties (e.g., -p state=fixed)'),
   403                   ('n', 'no-property-comment', None,
   415                   ('n', 'no-property-comment', None,
   404                    'do not add a comment about changed properties')], 
   416                    'do not add a comment about changed properties'),
       
   417                   ('m', 'message', '',
       
   418                    'use <text> as an issue subject')],
   405                  _('hg iadd [OPTIONS] [ID] [COMMENT]')),
   419                  _('hg iadd [OPTIONS] [ID] [COMMENT]')),
   406     'ishow':      (ishow,
   420     'ishow':      (ishow,
   407                  [('a', 'all', None, 'list all comments'),
   421                  [('a', 'all', None, 'list all comments'),
   408                   ('s', 'skip', '>', 'skip lines starting with a substring'),
   422                   ('s', 'skip', '>', 'skip lines starting with a substring'),
   409                   ('x', 'extract', [], 'extract attachments (provide attachment number as argument)')],
   423                   ('x', 'extract', [], 'extract attachments (provide attachment number as argument)'),
       
   424                   ('', 'mutt', False, 'use mutt to show issue')],
   410                  _('hg ishow [OPTIONS] ID [COMMENT]')),
   425                  _('hg ishow [OPTIONS] ID [COMMENT]')),
   411 }
   426 }
   412 
   427 
   413 # vim: expandtab
   428 # vim: expandtab