aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbe2
-rw-r--r--becommands/comment.py10
-rw-r--r--becommands/depend.py2
-rw-r--r--becommands/tag.py2
-rw-r--r--doc/be.1.sgml119
-rw-r--r--libbe/arch.py4
-rw-r--r--libbe/bug.py2
-rw-r--r--libbe/bzr.py4
-rw-r--r--libbe/cmdutil.py8
-rw-r--r--libbe/comment.py22
-rw-r--r--libbe/git.py4
-rw-r--r--libbe/hg.py4
-rw-r--r--libbe/rcs.py24
-rwxr-xr-xxml/be-xml-to-mbox11
14 files changed, 69 insertions, 149 deletions
diff --git a/be b/be
index fbe964f..ed1d7d7 100755
--- a/be
+++ b/be
@@ -27,7 +27,7 @@ if len(sys.argv) == 1 or sys.argv[1] in ('--help', '-h'):
elif sys.argv[1] == '--complete':
for command, module in cmdutil.iter_commands():
print command
- print '\n'.join(["--help","--complete","--options"])
+ print '\n'.join(["--help","--complete","--options","--version"])
elif sys.argv[1] == '--version':
print _version.version_info["revision_id"]
else:
diff --git a/becommands/comment.py b/becommands/comment.py
index f7459dd..b31a6e7 100644
--- a/becommands/comment.py
+++ b/becommands/comment.py
@@ -93,9 +93,13 @@ def execute(args, test=False):
raise cmdutil.UserError("No comment entered.")
body = body.decode('utf-8')
elif args[1] == '-': # read body from stdin
- body = sys.stdin.read()
- if not body.endswith('\n'):
- body+='\n'
+ binary = not options.content_type.startswith("text/")
+ if not binary:
+ body = sys.stdin.read()
+ if not body.endswith('\n'):
+ body+='\n'
+ else: # read-in without decoding
+ body = sys.__stdin__.read()
else: # body = arg[1]
body = args[1]
if not body.endswith('\n'):
diff --git a/becommands/depend.py b/becommands/depend.py
index 8dbb2eb..0e9ee97 100644
--- a/becommands/depend.py
+++ b/becommands/depend.py
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""Add/remove bug dependencies."""
+"""Add/remove bug dependencies"""
from libbe import cmdutil, bugdir
import os, copy
__desc__ = __doc__
diff --git a/becommands/tag.py b/becommands/tag.py
index 5a18a7c..ab0324e 100644
--- a/becommands/tag.py
+++ b/becommands/tag.py
@@ -13,7 +13,7 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-"""Tag a bug, or search bugs for tags."""
+"""Tag a bug, or search bugs for tags"""
from libbe import cmdutil, bugdir
import os, copy
__desc__ = __doc__
diff --git a/doc/be.1.sgml b/doc/be.1.sgml
index 5e6efc3..a2df21f 100644
--- a/doc/be.1.sgml
+++ b/doc/be.1.sgml
@@ -18,7 +18,7 @@ be.1: be.1.sgml
<!ENTITY dhfirstname "<firstname>Ben</firstname>">
<!ENTITY dhsurname "<surname>Finney</surname>">
<!-- Please adjust the date whenever revising the manpage. -->
- <!ENTITY dhdate "<date>2008-04-21</date>">
+ <!ENTITY dhdate "<date>2009-06-25</date>">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1). -->
<!ENTITY dhsection "<manvolnum>1</manvolnum>">
@@ -45,7 +45,7 @@ be.1: be.1.sgml
&dhsurname;
</author>
<copyright>
- <year>2008</year>
+ <year>2009</year>
<holder>&dhusername;</holder>
</copyright>
&dhdate;
@@ -88,125 +88,12 @@ be.1: be.1.sgml
</refsect1>
<refsect1>
<title>COMMANDS</title>
-
<variablelist>
<varlistentry>
- <term><command>assign</command>
- </term>
- <listitem>
- <para>Assign an individual or group to fix a bug
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>close</command>
- </term>
- <listitem>
- <para>Close a bug
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>comment</command>
- </term>
- <listitem>
- <para>Add a comment to a bug
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>diff</command>
- </term>
- <listitem>
- <para>Compare bug reports with older tree
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
<term><command>help</command>
</term>
<listitem>
- <para>Print help for given subcommand
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>inprogress</command>
- </term>
- <listitem>
- <para>Bug fixing in progress
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>list</command>
- </term>
- <listitem>
- <para>List bugs
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>new</command>
- </term>
- <listitem>
- <para>Create a new bug
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>open</command>
- </term>
- <listitem>
- <para>Re-open a bug
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>set</command>
- </term>
- <listitem>
- <para>Change tree settings
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>set-root</command>
- </term>
- <listitem>
- <para>Assign the root directory for bug tracking
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>severity</command>
- </term>
- <listitem>
- <para>Show or change a bug's severity level
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>show</command>
- </term>
- <listitem>
- <para>Show a particular bug
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>target</command>
- </term>
- <listitem>
- <para>Show or change a bug's target for fixing
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><command>upgrade</command>
- </term>
- <listitem>
- <para>Upgrade the bugs to the latest format
+ <para>Print help for be and a list of all available commands.
</para>
</listitem>
</varlistentry>
diff --git a/libbe/arch.py b/libbe/arch.py
index cd0f3b2..441c5a9 100644
--- a/libbe/arch.py
+++ b/libbe/arch.py
@@ -240,9 +240,9 @@ class Arch(RCS):
self._u_invoke_client("delete-id", path)
def _rcs_update(self, path):
pass
- def _rcs_get_file_contents(self, path, revision=None):
+ def _rcs_get_file_contents(self, path, revision=None, binary=False):
if revision == None:
- return RCS._rcs_get_file_contents(self, path, revision)
+ return RCS._rcs_get_file_contents(self, path, revision, binary=binary)
else:
status,output,error = \
self._invoke_client("file-find", path, revision)
diff --git a/libbe/bug.py b/libbe/bug.py
index 28f5253..4f297f9 100644
--- a/libbe/bug.py
+++ b/libbe/bug.py
@@ -288,7 +288,7 @@ class Bug(settings_object.SavedSettingsObject):
if show_comments == True:
comout = self.comment_root.xml_thread(auto_name_map=True,
bug_shortname=shortname)
- ret += comout
+ ret += comout+'\n'
ret += '</bug>'
return ret
diff --git a/libbe/bzr.py b/libbe/bzr.py
index 98ca571..21030e2 100644
--- a/libbe/bzr.py
+++ b/libbe/bzr.py
@@ -56,9 +56,9 @@ class Bzr(RCS):
self._u_invoke_client("remove", "--force", path)
def _rcs_update(self, path):
pass
- def _rcs_get_file_contents(self, path, revision=None):
+ def _rcs_get_file_contents(self, path, revision=None, binary=False):
if revision == None:
- return RCS._rcs_get_file_contents(self, path, revision)
+ return RCS._rcs_get_file_contents(self, path, revision, binary=binary)
else:
status,output,error = \
self._u_invoke_client("cat","-r",revision,path)
diff --git a/libbe/cmdutil.py b/libbe/cmdutil.py
index 6be7540..5873607 100644
--- a/libbe/cmdutil.py
+++ b/libbe/cmdutil.py
@@ -79,11 +79,17 @@ def help(cmd=None):
for name, module in iter_commands():
cmdlist.append((name, module.__desc__))
longest_cmd_len = max([len(name) for name,desc in cmdlist])
- ret = ["Bugs Everywhere - Distributed bug tracking\n",
+ ret = ["Bugs Everywhere - Distributed bug tracking",
+ "",
+ "usage: be [command] [command_options ...] [command_args ...]",
+ "or: be help",
+ "or: be help [command]",
+ "",
"Supported commands"]
for name, desc in cmdlist:
numExtraSpaces = longest_cmd_len-len(name)
ret.append("be %s%*s %s" % (name, numExtraSpaces, "", desc))
+
return "\n".join(ret)
def completions(cmd):
diff --git a/libbe/comment.py b/libbe/comment.py
index df5a63f..9fa4a30 100644
--- a/libbe/comment.py
+++ b/libbe/comment.py
@@ -16,6 +16,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA
+import email.mime.base, email.encoders
import os
import os.path
import time
@@ -150,11 +151,13 @@ class Comment(Tree, settings_object.SavedSettingsObject):
def _get_comment_body(self):
if self.rcs != None and self.sync_with_disk == True:
import rcs
- return self.rcs.get_file_contents(self.get_path("body"))
+ binary = not self.content_type.startswith("text/")
+ return self.rcs.get_file_contents(self.get_path("body"), binary=binary)
def _set_comment_body(self, old=None, new=None, force=False):
if (self.rcs != None and self.sync_with_disk == True) or force==True:
assert new != None, "Can't save empty comment"
- self.rcs.set_file_contents(self.get_path("body"), new)
+ binary = not self.content_type.startswith("text/")
+ self.rcs.set_file_contents(self.get_path("body"), new, binary=binary)
@Property
@change_hook_property(hook=_set_comment_body)
@@ -236,13 +239,21 @@ class Comment(Tree, settings_object.SavedSettingsObject):
"""
if shortname == None:
shortname = self.uuid
+ if self.content_type.startswith("text/"):
+ body = (self.body or "").rstrip('\n')
+ else:
+ maintype,subtype = self.content_type.split('/',1)
+ msg = email.mime.base.MIMEBase(maintype, subtype)
+ msg.set_payload(self.body or "")
+ email.encoders.encode_base64(msg)
+ body = msg.as_string()
info = [("uuid", self.uuid),
("short-name", shortname),
("in-reply-to", self.in_reply_to),
("from", self._setting_attr_string("From")),
("date", self.time_string),
("content-type", self.content_type),
- ("body", (self.body or "").rstrip('\n'))]
+ ("body", body)]
lines = ["<comment>"]
for (k,v) in info:
if v not in [settings_object.EMPTY, None]:
@@ -276,7 +287,10 @@ class Comment(Tree, settings_object.SavedSettingsObject):
lines.append("")
#lines.append(textwrap.fill(self.body or "",
# width=(79-indent)))
- lines.extend((self.body or "").splitlines())
+ if self.content_type.startswith("text/"):
+ lines.extend((self.body or "").splitlines())
+ else:
+ lines.append("Content type %s not printable. Try XML output instead" % self.content_type)
# some comments shouldn't be wrapped...
istring = ' '*indent
diff --git a/libbe/git.py b/libbe/git.py
index 401b5e5..5da1f86 100644
--- a/libbe/git.py
+++ b/libbe/git.py
@@ -70,9 +70,9 @@ class Git(RCS):
self._u_invoke_client("rm", "-f", path)
def _rcs_update(self, path):
self._rcs_add(path)
- def _rcs_get_file_contents(self, path, revision=None):
+ def _rcs_get_file_contents(self, path, revision=None, binary=False):
if revision == None:
- return RCS._rcs_get_file_contents(self, path, revision)
+ return RCS._rcs_get_file_contents(self, path, revision, binary=binary)
else:
arg = "%s:%s" % (revision,path)
status,output,error = self._u_invoke_client("show", arg)
diff --git a/libbe/hg.py b/libbe/hg.py
index a7413af..9b566b9 100644
--- a/libbe/hg.py
+++ b/libbe/hg.py
@@ -59,9 +59,9 @@ class Hg(RCS):
self._u_invoke_client("rm", path)
def _rcs_update(self, path):
pass
- def _rcs_get_file_contents(self, path, revision=None):
+ def _rcs_get_file_contents(self, path, revision=None, binary=False):
if revision == None:
- return RCS._rcs_get_file_contents(self, path, revision)
+ return RCS._rcs_get_file_contents(self, path, revision, binary=binary)
else:
status,output,error = \
self._u_invoke_client("cat","-r",revision,path)
diff --git a/libbe/rcs.py b/libbe/rcs.py
index c0b92e7..9c2defe 100644
--- a/libbe/rcs.py
+++ b/libbe/rcs.py
@@ -40,8 +40,7 @@ def _get_matching_rcs(matchfn):
rcs = module.new()
if matchfn(rcs) == True:
return rcs
- else:
- del(rcs)
+ del(rcs)
return RCS()
def rcs_by_name(rcs_name):
@@ -173,14 +172,17 @@ class RCS(object):
at path.
"""
pass
- def _rcs_get_file_contents(self, path, revision=None):
+ def _rcs_get_file_contents(self, path, revision=None, binary=False):
"""
Get the file contents as they were in a given revision.
Revision==None specifies the current revision.
"""
assert revision == None, \
"The %s RCS does not support revision specifiers" % self.name
- f = codecs.open(os.path.join(self.rootdir, path), "r", self.encoding)
+ if binary == False:
+ f = codecs.open(os.path.join(self.rootdir, path), "r", self.encoding)
+ else:
+ f = open(path, "rb")
contents = f.read()
f.close()
return contents
@@ -205,7 +207,8 @@ class RCS(object):
except OSError, e:
if e.errno == errno.ENOENT:
return False
- raise e
+ except CommandError:
+ return False
def detect(self, path="."):
"""
Detect whether a directory is revision controlled with this RCS.
@@ -290,7 +293,7 @@ class RCS(object):
at path.
"""
self._rcs_update(self._u_rel_path(path))
- def get_file_contents(self, path, revision=None, allow_no_rcs=False):
+ def get_file_contents(self, path, revision=None, allow_no_rcs=False, binary=False):
"""
Get the file as it was in a given revision.
Revision==None specifies the current revision.
@@ -299,18 +302,21 @@ class RCS(object):
raise NoSuchFile(path)
if self._use_rcs(path, allow_no_rcs):
relpath = self._u_rel_path(path)
- contents = self._rcs_get_file_contents(relpath,revision)
+ contents = self._rcs_get_file_contents(relpath,revision,binary=binary)
else:
f = codecs.open(path, "r", self.encoding)
contents = f.read()
f.close()
return contents
- def set_file_contents(self, path, contents, allow_no_rcs=False):
+ def set_file_contents(self, path, contents, allow_no_rcs=False, binary=False):
"""
Set the file contents under version control.
"""
add = not os.path.exists(path)
- f = codecs.open(path, "w", self.encoding)
+ if binary == False:
+ f = codecs.open(path, "w", self.encoding)
+ else:
+ f = open(path, "wb")
f.write(contents)
f.close()
diff --git a/xml/be-xml-to-mbox b/xml/be-xml-to-mbox
index b0a4cba..e5fec3b 100755
--- a/xml/be-xml-to-mbox
+++ b/xml/be-xml-to-mbox
@@ -116,14 +116,17 @@ class Comment (LimitedAttrDict):
print "Message-ID: <%s@%s>" % (self["uuid"], DEFAULT_DOMAIN)
print "Date: %s" % self["date"]
print "From: %s" % self["from"]
- print "Content-Type: %s; charset=%s" % (self["content-type"], DEFAULT_ENCODING)
- print "Content-Transfer-Encoding: 8bit"
print "Subject: %s: %s" % (self["short-name"], bug["summary"])
if "in-reply-to" not in self.keys():
self["in-reply-to"] = bug["uuid"]
print "In-Reply-To: <%s@%s>" % (self["in-reply-to"], DEFAULT_DOMAIN)
- print ""
- print self["body"]
+ if self["content-type"].startswith("text/"):
+ print "Content-Transfer-Encoding: 8bit"
+ print "Content-Type: %s; charset=%s" % (self["content-type"], DEFAULT_ENCODING)
+ print ""
+ print self["body"]
+ else: # content type and transfer encoding already in XML MIME output
+ print self["body"]
print ""
class BE_list_handler (ContentHandler):