aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values37
-rw-r--r--.be/bugs/02223264-e28a-4720-9f20-1e7a27a7041d/values25
-rw-r--r--.be/bugs/09f84059-fc8e-4954-b24d-a2b33ef21bf4/values31
-rw-r--r--.be/bugs/0ca2d112-b5bb-4df1-8ac0-e46db6cdd442/values25
-rw-r--r--.be/bugs/0cad2ac6-76ef-4a88-abdf-b2e02de76f5c/values31
-rw-r--r--.be/bugs/0e0c806c-5443-4839-aa60-9615c8c10853/values25
-rw-r--r--.be/bugs/2103f60c-36e5-4b05-b57c-8c6fee2d80d4/values31
-rw-r--r--.be/bugs/27bb8bc2-05c2-417a-9d09-928471380d7a/values31
-rw-r--r--.be/bugs/2929814b-2163-45d0-87ba-f7d1ef0a32a9/values31
-rw-r--r--.be/bugs/31cd490d-a1c2-4ab3-8284-d80395e34dd2/values31
-rw-r--r--.be/bugs/3613e6e9-db9e-4775-8914-f31f0b4b81ac/values25
-rw-r--r--.be/bugs/372f8a5c-a1ce-4b07-a7b1-f409033a7eec/values25
-rw-r--r--.be/bugs/381555eb-f2e3-4ef0-8303-d759c00b390a/values31
-rw-r--r--.be/bugs/40dac9af-951e-4b98-8779-9ba02c37f8a1/values31
-rw-r--r--.be/bugs/496edad5-1484-413a-bc68-4b01274a65eb/values31
-rw-r--r--.be/bugs/4f7a4c3b-31e3-4023-8c9d-e67f627a34f0/values31
-rw-r--r--.be/bugs/508ea95e-7bc6-4b9b-9e36-a3a87014423d/values31
-rw-r--r--.be/bugs/597a7386-643f-4559-8dc4-6871924229b6/values31
-rw-r--r--.be/bugs/62a74b85-0d4b-49f5-8794-74bafd871cd4/values31
-rw-r--r--.be/bugs/65776f00-34d8-4b58-874d-333196a5e245/values31
-rw-r--r--.be/bugs/6622c06a-ed84-4d45-8011-a082fca219b6/values31
-rw-r--r--.be/bugs/6eb8141f-b0b1-4d5b-b4e6-d0860d844ada/values32
-rw-r--r--.be/bugs/73a767f4-75e7-4cde-9e24-91bff99ab428/values25
-rw-r--r--.be/bugs/74cccfbf-069d-4e99-8cab-adaa35f9a2eb/values25
-rw-r--r--.be/bugs/7ba4bc51-b251-483a-a67a-f1b89c83f6af/values25
-rw-r--r--.be/bugs/7bfc591e-584a-476e-8e11-b548f1afcaa6/values31
-rw-r--r--.be/bugs/7d182ab9-9c0c-4b4f-885e-c5762d7a2437/values25
-rw-r--r--.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/comments/80780fa9-69f8-438c-8fbf-5a702b3badc1/body2
-rw-r--r--.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/comments/80780fa9-69f8-438c-8fbf-5a702b3badc1/values8
-rw-r--r--.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/values2
-rw-r--r--.be/bugs/8e1bbda4-35b6-4579-849d-117b1596ee99/values31
-rw-r--r--.be/bugs/8e83da06-26f1-4763-a972-dae7e7062233/values31
-rw-r--r--.be/bugs/9daa72ee-0721-4f68-99ee-f06fec0b340e/values31
-rw-r--r--.be/bugs/9f910ee0-ff0f-4fa3-b1e3-79a4118e48e9/values25
-rw-r--r--.be/bugs/a403de79-8f39-41f2-b9ec-15053b175ee2/values31
-rw-r--r--.be/bugs/a4d38ba7-ec28-4096-a4f3-eb8c9790ffb2/values31
-rw-r--r--.be/bugs/a63bd76a-cd43-4f97-88ba-2323546d4572/values31
-rw-r--r--.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values37
-rw-r--r--.be/bugs/b1bc6f39-8166-46c5-a724-4c4a3e1e7d74/values25
-rw-r--r--.be/bugs/b3c6da51-3a30-42c9-8c75-587c7a1705c5/values31
-rw-r--r--.be/bugs/b8d95763-1825-4e09-bf52-cbd884b916af/values31
-rw-r--r--.be/bugs/c45e5ece-63e3-4fd2-b33f-0bfd06820cf4/values31
-rw-r--r--.be/bugs/c4ea43d5-4964-49ea-a1eb-2bab2bde8e2e/values31
-rw-r--r--.be/bugs/c592a1e8-f2c8-4dfb-8550-955123073947/values25
-rw-r--r--.be/bugs/c894f10f-197d-4b22-9c5b-19f394df40d4/values31
-rw-r--r--.be/bugs/cb56c990-a757-4aef-9888-a30918a7b3d7/values31
-rw-r--r--.be/bugs/cf77c72d-b099-413a-802e-a8892ac8c26b/values31
-rw-r--r--.be/bugs/dac91856-cb6a-4f69-8c03-38ff0b29aab2/values31
-rw-r--r--.be/bugs/dba25cfd-aa15-457c-903a-b53ecb5a3b2c/values32
-rw-r--r--.be/bugs/e0155831-499f-421a-ad02-cd15fc3fecf1/values25
-rw-r--r--.be/bugs/e2f6514c-5f9f-4734-a537-daf3fbe7e9a0/values31
-rw-r--r--.be/bugs/ecc91b94-7f3f-44a7-af58-03191d327a7f/values31
-rw-r--r--.be/bugs/ee681951-f254-43d3-a53a-1b36ae415d5c/values31
-rw-r--r--.be/bugs/f51dc5a7-37b7-4ce1-859a-b7cb58be6494/values25
-rw-r--r--.be/bugs/f5c06914-dc64-4658-8ec7-32a026a53f55/values31
-rw-r--r--.be/bugs/f65b680b-4309-43a2-ae2d-e65811c9d107/values25
-rw-r--r--.be/bugs/f7ccd916-b5c7-4890-a2e3-8c8ace17ae3a/values31
-rw-r--r--becommands/depend.py83
-rw-r--r--becommands/list.py16
-rw-r--r--becommands/tag.py132
-rw-r--r--libbe/bug.py22
-rw-r--r--libbe/bugdir.py4
-rw-r--r--libbe/comment.py8
-rw-r--r--libbe/mapfile.py2
-rw-r--r--libbe/properties.py173
-rw-r--r--libbe/settings_object.py72
66 files changed, 745 insertions, 1377 deletions
diff --git a/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values b/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values
index 05961db..a2d65ff 100644
--- a/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values
+++ b/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values
@@ -1,42 +1,17 @@
+assigned: Ben Finney <ben+python@benfinney.id.au>
+creator: benf
-assigned=Ben Finney <ben+python@benfinney.id.au>
+severity: minor
+status: closed
-
-creator=benf
-
-
-
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Address is outdated for FSF offices
-
-
-
-
-
-
-time=Fri, 18 Apr 2008 11:18:58 +0000
+summary: Address is outdated for FSF offices
+time: Fri, 18 Apr 2008 11:18:58 +0000
diff --git a/.be/bugs/02223264-e28a-4720-9f20-1e7a27a7041d/values b/.be/bugs/02223264-e28a-4720-9f20-1e7a27a7041d/values
index ac2fa4e..afa7cb1 100644
--- a/.be/bugs/02223264-e28a-4720-9f20-1e7a27a7041d/values
+++ b/.be/bugs/02223264-e28a-4720-9f20-1e7a27a7041d/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Needs more test cases
-
-
+summary: Needs more test cases
diff --git a/.be/bugs/09f84059-fc8e-4954-b24d-a2b33ef21bf4/values b/.be/bugs/09f84059-fc8e-4954-b24d-a2b33ef21bf4/values
index 9f3c7ac..bb41d02 100644
--- a/.be/bugs/09f84059-fc8e-4954-b24d-a2b33ef21bf4/values
+++ b/.be/bugs/09f84059-fc8e-4954-b24d-a2b33ef21bf4/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: Support RST
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Support RST
-
-
-
-
-
-
-time=Thu, 06 Apr 2006 16:45:52 +0000
-
-
+time: Thu, 06 Apr 2006 16:45:52 +0000
diff --git a/.be/bugs/0ca2d112-b5bb-4df1-8ac0-e46db6cdd442/values b/.be/bugs/0ca2d112-b5bb-4df1-8ac0-e46db6cdd442/values
index 4602e29..e710dd8 100644
--- a/.be/bugs/0ca2d112-b5bb-4df1-8ac0-e46db6cdd442/values
+++ b/.be/bugs/0ca2d112-b5bb-4df1-8ac0-e46db6cdd442/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Organize list by target, and whether it's assigned to current be id
-
-
+summary: Organize list by target, and whether it's assigned to current be id
diff --git a/.be/bugs/0cad2ac6-76ef-4a88-abdf-b2e02de76f5c/values b/.be/bugs/0cad2ac6-76ef-4a88-abdf-b2e02de76f5c/values
index 84e14f1..1f20dfb 100644
--- a/.be/bugs/0cad2ac6-76ef-4a88-abdf-b2e02de76f5c/values
+++ b/.be/bugs/0cad2ac6-76ef-4a88-abdf-b2e02de76f5c/values
@@ -1,35 +1,14 @@
+creator: hubert
+severity: minor
-creator=hubert
+status: fixed
+summary: set-root in git repository fails
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=set-root in git repository fails
-
-
-
-
-
-
-time=Mon, 23 Jun 2008 04:57:22 +0000
-
-
+time: Mon, 23 Jun 2008 04:57:22 +0000
diff --git a/.be/bugs/0e0c806c-5443-4839-aa60-9615c8c10853/values b/.be/bugs/0e0c806c-5443-4839-aa60-9615c8c10853/values
index 05f3eba..3237861 100644
--- a/.be/bugs/0e0c806c-5443-4839-aa60-9615c8c10853/values
+++ b/.be/bugs/0e0c806c-5443-4839-aa60-9615c8c10853/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=fix up command listings
-
-
+summary: fix up command listings
diff --git a/.be/bugs/2103f60c-36e5-4b05-b57c-8c6fee2d80d4/values b/.be/bugs/2103f60c-36e5-4b05-b57c-8c6fee2d80d4/values
index cf41641..25dbaca 100644
--- a/.be/bugs/2103f60c-36e5-4b05-b57c-8c6fee2d80d4/values
+++ b/.be/bugs/2103f60c-36e5-4b05-b57c-8c6fee2d80d4/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: target (and others?) aren't parsed properly
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=target (and others?) aren't parsed properly
-
-
-
-
-
-
-time=Sat, 01 Apr 2006 18:29:33 +0000
-
-
+time: Sat, 01 Apr 2006 18:29:33 +0000
diff --git a/.be/bugs/27bb8bc2-05c2-417a-9d09-928471380d7a/values b/.be/bugs/27bb8bc2-05c2-417a-9d09-928471380d7a/values
index ce4108a..7082a38 100644
--- a/.be/bugs/27bb8bc2-05c2-417a-9d09-928471380d7a/values
+++ b/.be/bugs/27bb8bc2-05c2-417a-9d09-928471380d7a/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: Are dates still a problem?
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Are dates still a problem?
-
-
-
-
-
-
-time=Tue, 20 Dec 2005 19:37:03 +0000
-
-
+time: Tue, 20 Dec 2005 19:37:03 +0000
diff --git a/.be/bugs/2929814b-2163-45d0-87ba-f7d1ef0a32a9/values b/.be/bugs/2929814b-2163-45d0-87ba-f7d1ef0a32a9/values
index 68b730d..df80422 100644
--- a/.be/bugs/2929814b-2163-45d0-87ba-f7d1ef0a32a9/values
+++ b/.be/bugs/2929814b-2163-45d0-87ba-f7d1ef0a32a9/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: More types of closed bugs
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=More types of closed bugs
-
-
-
-
-
-
-time=Wed, 04 Jan 2006 21:03:27 +0000
-
-
+time: Wed, 04 Jan 2006 21:03:27 +0000
diff --git a/.be/bugs/31cd490d-a1c2-4ab3-8284-d80395e34dd2/values b/.be/bugs/31cd490d-a1c2-4ab3-8284-d80395e34dd2/values
index 02f718a..5c9594e 100644
--- a/.be/bugs/31cd490d-a1c2-4ab3-8284-d80395e34dd2/values
+++ b/.be/bugs/31cd490d-a1c2-4ab3-8284-d80395e34dd2/values
@@ -1,35 +1,14 @@
+creator: wking
+severity: minor
-creator=wking
+status: fixed
+summary: elementtree module moved in Python 2.5
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=elementtree module moved in Python 2.5
-
-
-
-
-
-
-time=Thu, 13 Nov 2008 16:45:24 +0000
-
-
+time: Thu, 13 Nov 2008 16:45:24 +0000
diff --git a/.be/bugs/3613e6e9-db9e-4775-8914-f31f0b4b81ac/values b/.be/bugs/3613e6e9-db9e-4775-8914-f31f0b4b81ac/values
index f9e418d..9da9004 100644
--- a/.be/bugs/3613e6e9-db9e-4775-8914-f31f0b4b81ac/values
+++ b/.be/bugs/3613e6e9-db9e-4775-8914-f31f0b4b81ac/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=auto-add files to revision control
-
-
+summary: auto-add files to revision control
diff --git a/.be/bugs/372f8a5c-a1ce-4b07-a7b1-f409033a7eec/values b/.be/bugs/372f8a5c-a1ce-4b07-a7b1-f409033a7eec/values
index 08c3ae4..ec315a3 100644
--- a/.be/bugs/372f8a5c-a1ce-4b07-a7b1-f409033a7eec/values
+++ b/.be/bugs/372f8a5c-a1ce-4b07-a7b1-f409033a7eec/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=implement severity on bug creation
-
-
+summary: implement severity on bug creation
diff --git a/.be/bugs/381555eb-f2e3-4ef0-8303-d759c00b390a/values b/.be/bugs/381555eb-f2e3-4ef0-8303-d759c00b390a/values
index dc0b6b0..f59cf90 100644
--- a/.be/bugs/381555eb-f2e3-4ef0-8303-d759c00b390a/values
+++ b/.be/bugs/381555eb-f2e3-4ef0-8303-d759c00b390a/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: Ensure .be is source in Arch
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Ensure .be is source in Arch
-
-
-
-
-
-
-time=Tue, 17 May 2005 13:39:02 +0000
-
-
+time: Tue, 17 May 2005 13:39:02 +0000
diff --git a/.be/bugs/40dac9af-951e-4b98-8779-9ba02c37f8a1/values b/.be/bugs/40dac9af-951e-4b98-8779-9ba02c37f8a1/values
index 4d1cded..59d0695 100644
--- a/.be/bugs/40dac9af-951e-4b98-8779-9ba02c37f8a1/values
+++ b/.be/bugs/40dac9af-951e-4b98-8779-9ba02c37f8a1/values
@@ -1,35 +1,14 @@
+creator: wking
+severity: minor
-creator=wking
+status: fixed
+summary: Popen OSErrors not caught
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Popen OSErrors not caught
-
-
-
-
-
-
-time=Thu, 13 Nov 2008 15:54:45 +0000
-
-
+time: Thu, 13 Nov 2008 15:54:45 +0000
diff --git a/.be/bugs/496edad5-1484-413a-bc68-4b01274a65eb/values b/.be/bugs/496edad5-1484-413a-bc68-4b01274a65eb/values
index 96c0708..2ef6ea3 100644
--- a/.be/bugs/496edad5-1484-413a-bc68-4b01274a65eb/values
+++ b/.be/bugs/496edad5-1484-413a-bc68-4b01274a65eb/values
@@ -1,35 +1,14 @@
+creator: W. Trevor King <wking@drexel.edu>
+severity: minor
-creator=W. Trevor King <wking@drexel.edu>
+status: fixed
+summary: Early del-cleanup with Arch backend
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Early del-cleanup with Arch backend
-
-
-
-
-
-
-time=Sat, 22 Nov 2008 18:38:32 +0000
-
-
+time: Sat, 22 Nov 2008 18:38:32 +0000
diff --git a/.be/bugs/4f7a4c3b-31e3-4023-8c9d-e67f627a34f0/values b/.be/bugs/4f7a4c3b-31e3-4023-8c9d-e67f627a34f0/values
index 85cf442..b97cb07 100644
--- a/.be/bugs/4f7a4c3b-31e3-4023-8c9d-e67f627a34f0/values
+++ b/.be/bugs/4f7a4c3b-31e3-4023-8c9d-e67f627a34f0/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: Automatically set .be as source for arch
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Automatically set .be as source for arch
-
-
-
-
-
-
-time=Thu, 07 Apr 2005 16:07:51 +0000
-
-
+time: Thu, 07 Apr 2005 16:07:51 +0000
diff --git a/.be/bugs/508ea95e-7bc6-4b9b-9e36-a3a87014423d/values b/.be/bugs/508ea95e-7bc6-4b9b-9e36-a3a87014423d/values
index f530d63..9b17373 100644
--- a/.be/bugs/508ea95e-7bc6-4b9b-9e36-a3a87014423d/values
+++ b/.be/bugs/508ea95e-7bc6-4b9b-9e36-a3a87014423d/values
@@ -1,35 +1,14 @@
+creator: jelmer
+severity: minor
-creator=jelmer
+status: closed
+summary: should check not just EDITOR but also VISUAL.
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=should check not just EDITOR but also VISUAL.
-
-
-
-
-
-
-time=Sun, 15 Jul 2007 13:33:03 +0000
-
-
+time: Sun, 15 Jul 2007 13:33:03 +0000
diff --git a/.be/bugs/597a7386-643f-4559-8dc4-6871924229b6/values b/.be/bugs/597a7386-643f-4559-8dc4-6871924229b6/values
index 823e2bc..b0bfcf3 100644
--- a/.be/bugs/597a7386-643f-4559-8dc4-6871924229b6/values
+++ b/.be/bugs/597a7386-643f-4559-8dc4-6871924229b6/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: RST test
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=RST test
-
-
-
-
-
-
-time=Thu, 06 Apr 2006 16:52:46 +0000
-
-
+time: Thu, 06 Apr 2006 16:52:46 +0000
diff --git a/.be/bugs/62a74b85-0d4b-49f5-8794-74bafd871cd4/values b/.be/bugs/62a74b85-0d4b-49f5-8794-74bafd871cd4/values
index 509920e..9f7616b 100644
--- a/.be/bugs/62a74b85-0d4b-49f5-8794-74bafd871cd4/values
+++ b/.be/bugs/62a74b85-0d4b-49f5-8794-74bafd871cd4/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: Indicate presence of Comments
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Indicate presence of Comments
-
-
-
-
-
-
-time=Wed, 25 Jan 2006 15:18:58 +0000
-
-
+time: Wed, 25 Jan 2006 15:18:58 +0000
diff --git a/.be/bugs/65776f00-34d8-4b58-874d-333196a5e245/values b/.be/bugs/65776f00-34d8-4b58-874d-333196a5e245/values
index 79c65e2..435c733 100644
--- a/.be/bugs/65776f00-34d8-4b58-874d-333196a5e245/values
+++ b/.be/bugs/65776f00-34d8-4b58-874d-333196a5e245/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: Select severity filter
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Select severity filter
-
-
-
-
-
-
-time=Wed, 04 Jan 2006 21:07:08 +0000
-
-
+time: Wed, 04 Jan 2006 21:07:08 +0000
diff --git a/.be/bugs/6622c06a-ed84-4d45-8011-a082fca219b6/values b/.be/bugs/6622c06a-ed84-4d45-8011-a082fca219b6/values
index 772b490..ba3304f 100644
--- a/.be/bugs/6622c06a-ed84-4d45-8011-a082fca219b6/values
+++ b/.be/bugs/6622c06a-ed84-4d45-8011-a082fca219b6/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: Better word wrapping in comments. (kill <pre>.)
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Better word wrapping in comments. (kill <pre>.)
-
-
-
-
-
-
-time=Mon, 30 Jan 2006 20:03:25 +0000
-
-
+time: Mon, 30 Jan 2006 20:03:25 +0000
diff --git a/.be/bugs/6eb8141f-b0b1-4d5b-b4e6-d0860d844ada/values b/.be/bugs/6eb8141f-b0b1-4d5b-b4e6-d0860d844ada/values
index cbc94a8..fcc0b22 100644
--- a/.be/bugs/6eb8141f-b0b1-4d5b-b4e6-d0860d844ada/values
+++ b/.be/bugs/6eb8141f-b0b1-4d5b-b4e6-d0860d844ada/values
@@ -1,35 +1,15 @@
+creator: abentley
+severity: serious
-creator=abentley
+status: closed
+summary: On a new bug, if I add or edit a comment, then click "Update", the Summary
+ goes missing.
-
-severity=serious
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=On a new bug, if I add or edit a comment, then click "Update", the Summary goes missing.
-
-
-
-
-
-
-time=Fri, 27 Jan 2006 14:29:51 +0000
-
-
+time: Fri, 27 Jan 2006 14:29:51 +0000
diff --git a/.be/bugs/73a767f4-75e7-4cde-9e24-91bff99ab428/values b/.be/bugs/73a767f4-75e7-4cde-9e24-91bff99ab428/values
index 4622bc6..9bd84b0 100644
--- a/.be/bugs/73a767f4-75e7-4cde-9e24-91bff99ab428/values
+++ b/.be/bugs/73a767f4-75e7-4cde-9e24-91bff99ab428/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: serious
-creator=abentley
+status: fixed
-
-
-
-severity=serious
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=implement comments
-
-
+summary: implement comments
diff --git a/.be/bugs/74cccfbf-069d-4e99-8cab-adaa35f9a2eb/values b/.be/bugs/74cccfbf-069d-4e99-8cab-adaa35f9a2eb/values
index 921528e..473f9a7 100644
--- a/.be/bugs/74cccfbf-069d-4e99-8cab-adaa35f9a2eb/values
+++ b/.be/bugs/74cccfbf-069d-4e99-8cab-adaa35f9a2eb/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Can't close bugs
-
-
+summary: Can't close bugs
diff --git a/.be/bugs/7ba4bc51-b251-483a-a67a-f1b89c83f6af/values b/.be/bugs/7ba4bc51-b251-483a-a67a-f1b89c83f6af/values
index 35cfede..94a1f9f 100644
--- a/.be/bugs/7ba4bc51-b251-483a-a67a-f1b89c83f6af/values
+++ b/.be/bugs/7ba4bc51-b251-483a-a67a-f1b89c83f6af/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: serious
-creator=abentley
+status: closed
-
-
-
-severity=serious
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Add test cases
-
-
+summary: Add test cases
diff --git a/.be/bugs/7bfc591e-584a-476e-8e11-b548f1afcaa6/values b/.be/bugs/7bfc591e-584a-476e-8e11-b548f1afcaa6/values
index 685c112..d05eed6 100644
--- a/.be/bugs/7bfc591e-584a-476e-8e11-b548f1afcaa6/values
+++ b/.be/bugs/7bfc591e-584a-476e-8e11-b548f1afcaa6/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: no tests for --help, -h, help, etc.
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=no tests for --help, -h, help, etc.
-
-
-
-
-
-
-time=Tue, 17 May 2005 13:27:18 +0000
-
-
+time: Tue, 17 May 2005 13:27:18 +0000
diff --git a/.be/bugs/7d182ab9-9c0c-4b4f-885e-c5762d7a2437/values b/.be/bugs/7d182ab9-9c0c-4b4f-885e-c5762d7a2437/values
index 5d6b845..ae215bc 100644
--- a/.be/bugs/7d182ab9-9c0c-4b4f-885e-c5762d7a2437/values
+++ b/.be/bugs/7d182ab9-9c0c-4b4f-885e-c5762d7a2437/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=BEweb fails to set bug creation date
-
-
+summary: BEweb fails to set bug creation date
diff --git a/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/comments/80780fa9-69f8-438c-8fbf-5a702b3badc1/body b/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/comments/80780fa9-69f8-438c-8fbf-5a702b3badc1/body
new file mode 100644
index 0000000..f1ce046
--- /dev/null
+++ b/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/comments/80780fa9-69f8-438c-8fbf-5a702b3badc1/body
@@ -0,0 +1,2 @@
+Arbitrary tagging now supported via `be tag'.
+Dependencies supported via `be depend'.
diff --git a/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/comments/80780fa9-69f8-438c-8fbf-5a702b3badc1/values b/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/comments/80780fa9-69f8-438c-8fbf-5a702b3badc1/values
new file mode 100644
index 0000000..cd3e2bf
--- /dev/null
+++ b/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/comments/80780fa9-69f8-438c-8fbf-5a702b3badc1/values
@@ -0,0 +1,8 @@
+Content-type: text/plain
+
+
+Date: Thu, 25 Jun 2009 12:39:26 +0000
+
+
+From: W. Trevor King <wking@drexel.edu>
+
diff --git a/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/values b/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/values
index 07811f7..1059e1b 100644
--- a/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/values
+++ b/.be/bugs/7ec2c071-9630-42b0-b08a-9854616f9144/values
@@ -4,7 +4,7 @@ creator: abentley
severity: minor
-status: open
+status: closed
summary: Arbitrary tags
diff --git a/.be/bugs/8e1bbda4-35b6-4579-849d-117b1596ee99/values b/.be/bugs/8e1bbda4-35b6-4579-849d-117b1596ee99/values
index f88ca6c..73915d5 100644
--- a/.be/bugs/8e1bbda4-35b6-4579-849d-117b1596ee99/values
+++ b/.be/bugs/8e1bbda4-35b6-4579-849d-117b1596ee99/values
@@ -1,35 +1,14 @@
+creator: W. Trevor King <wking@drexel.edu>
+severity: serious
-creator=W. Trevor King <wking@drexel.edu>
+status: fixed
+summary: be <cmmd> <argopt> --options doesn't raise GetOptions
-
-severity=serious
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=be <cmmd> <argopt> --options doesn't raise GetOptions
-
-
-
-
-
-
-time=Thu, 27 Nov 2008 13:39:25 +0000
-
-
+time: Thu, 27 Nov 2008 13:39:25 +0000
diff --git a/.be/bugs/8e83da06-26f1-4763-a972-dae7e7062233/values b/.be/bugs/8e83da06-26f1-4763-a972-dae7e7062233/values
index 38ad221..93c746c 100644
--- a/.be/bugs/8e83da06-26f1-4763-a972-dae7e7062233/values
+++ b/.be/bugs/8e83da06-26f1-4763-a972-dae7e7062233/values
@@ -1,35 +1,14 @@
+creator: W. Trevor King <wking@drexel.edu>
+severity: minor
-creator=W. Trevor King <wking@drexel.edu>
+status: fixed
+summary: test.py removes path to bzrlib
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=test.py removes path to bzrlib
-
-
-
-
-
-
-time=Fri, 21 Nov 2008 18:41:03 +0000
-
-
+time: Fri, 21 Nov 2008 18:41:03 +0000
diff --git a/.be/bugs/9daa72ee-0721-4f68-99ee-f06fec0b340e/values b/.be/bugs/9daa72ee-0721-4f68-99ee-f06fec0b340e/values
index e6f6827..f110a26 100644
--- a/.be/bugs/9daa72ee-0721-4f68-99ee-f06fec0b340e/values
+++ b/.be/bugs/9daa72ee-0721-4f68-99ee-f06fec0b340e/values
@@ -1,35 +1,14 @@
+assigned: abentley
+creator: abentley
-assigned=abentley
+severity: minor
+status: closed
-
-creator=abentley
-
-
-
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Organize list by whether it's assigned to the current target
-
-
+summary: Organize list by whether it's assigned to the current target
diff --git a/.be/bugs/9f910ee0-ff0f-4fa3-b1e3-79a4118e48e9/values b/.be/bugs/9f910ee0-ff0f-4fa3-b1e3-79a4118e48e9/values
index 1655f99..d305d6c 100644
--- a/.be/bugs/9f910ee0-ff0f-4fa3-b1e3-79a4118e48e9/values
+++ b/.be/bugs/9f910ee0-ff0f-4fa3-b1e3-79a4118e48e9/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=prevent collisions in different branches
-
-
+summary: prevent collisions in different branches
diff --git a/.be/bugs/a403de79-8f39-41f2-b9ec-15053b175ee2/values b/.be/bugs/a403de79-8f39-41f2-b9ec-15053b175ee2/values
index c80f16e..db04837 100644
--- a/.be/bugs/a403de79-8f39-41f2-b9ec-15053b175ee2/values
+++ b/.be/bugs/a403de79-8f39-41f2-b9ec-15053b175ee2/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: Beweb should support declaring username
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Beweb should support declaring username
-
-
-
-
-
-
-time=Wed, 04 Jan 2006 21:07:25 +0000
-
-
+time: Wed, 04 Jan 2006 21:07:25 +0000
diff --git a/.be/bugs/a4d38ba7-ec28-4096-a4f3-eb8c9790ffb2/values b/.be/bugs/a4d38ba7-ec28-4096-a4f3-eb8c9790ffb2/values
index d79a55a..5de8e08 100644
--- a/.be/bugs/a4d38ba7-ec28-4096-a4f3-eb8c9790ffb2/values
+++ b/.be/bugs/a4d38ba7-ec28-4096-a4f3-eb8c9790ffb2/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: be diff doesn't work with bzr in directories that have no commits
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=be diff doesn't work with bzr in directories that have no commits
-
-
-
-
-
-
-time=Mon, 10 Apr 2006 23:22:17 +0000
-
-
+time: Mon, 10 Apr 2006 23:22:17 +0000
diff --git a/.be/bugs/a63bd76a-cd43-4f97-88ba-2323546d4572/values b/.be/bugs/a63bd76a-cd43-4f97-88ba-2323546d4572/values
index 7801138..e5e6b0b 100644
--- a/.be/bugs/a63bd76a-cd43-4f97-88ba-2323546d4572/values
+++ b/.be/bugs/a63bd76a-cd43-4f97-88ba-2323546d4572/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: 'Beweb: New comment button should save any changes'
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Beweb: New comment button should save any changes
-
-
-
-
-
-
-time=Wed, 04 Jan 2006 21:05:20 +0000
-
-
+time: Wed, 04 Jan 2006 21:05:20 +0000
diff --git a/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values b/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values
index 2fa1905..4dc6a1e 100644
--- a/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values
+++ b/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values
@@ -1,42 +1,17 @@
+assigned: benf
+creator: benf
-assigned=benf
+severity: minor
+status: fixed
-
-creator=benf
-
-
-
-
-
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Manual page for 'be' command
-
-
-
-
-
-
-time=Mon, 21 Apr 2008 03:21:35 +0000
+summary: Manual page for 'be' command
+time: Mon, 21 Apr 2008 03:21:35 +0000
diff --git a/.be/bugs/b1bc6f39-8166-46c5-a724-4c4a3e1e7d74/values b/.be/bugs/b1bc6f39-8166-46c5-a724-4c4a3e1e7d74/values
index 0de7aaf..eda617b 100644
--- a/.be/bugs/b1bc6f39-8166-46c5-a724-4c4a3e1e7d74/values
+++ b/.be/bugs/b1bc6f39-8166-46c5-a724-4c4a3e1e7d74/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Comments do not appear in web UI
-
-
+summary: Comments do not appear in web UI
diff --git a/.be/bugs/b3c6da51-3a30-42c9-8c75-587c7a1705c5/values b/.be/bugs/b3c6da51-3a30-42c9-8c75-587c7a1705c5/values
index d1a7029..ab12d24 100644
--- a/.be/bugs/b3c6da51-3a30-42c9-8c75-587c7a1705c5/values
+++ b/.be/bugs/b3c6da51-3a30-42c9-8c75-587c7a1705c5/values
@@ -1,35 +1,14 @@
+creator: W. Trevor King <wking@drexel.edu>
+severity: critical
-creator=W. Trevor King <wking@drexel.edu>
+status: fixed
+summary: Slow be commands due to bugdir loading, go back to lazy bug loading.
-
-severity=critical
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Slow be commands due to bugdir loading, go back to lazy bug loading.
-
-
-
-
-
-
-time=Sun, 23 Nov 2008 13:48:01 +0000
-
-
+time: Sun, 23 Nov 2008 13:48:01 +0000
diff --git a/.be/bugs/b8d95763-1825-4e09-bf52-cbd884b916af/values b/.be/bugs/b8d95763-1825-4e09-bf52-cbd884b916af/values
index 3c4e210..594433d 100644
--- a/.be/bugs/b8d95763-1825-4e09-bf52-cbd884b916af/values
+++ b/.be/bugs/b8d95763-1825-4e09-bf52-cbd884b916af/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: support multi-rcs configurations
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=support multi-rcs configurations
-
-
-
-
-
-
-time=Thu, 07 Apr 2005 16:09:10 +0000
-
-
+time: Thu, 07 Apr 2005 16:09:10 +0000
diff --git a/.be/bugs/c45e5ece-63e3-4fd2-b33f-0bfd06820cf4/values b/.be/bugs/c45e5ece-63e3-4fd2-b33f-0bfd06820cf4/values
index 857c816..90fedbc 100644
--- a/.be/bugs/c45e5ece-63e3-4fd2-b33f-0bfd06820cf4/values
+++ b/.be/bugs/c45e5ece-63e3-4fd2-b33f-0bfd06820cf4/values
@@ -1,35 +1,14 @@
+creator: j
+severity: minor
-creator=j
+status: fixed
+summary: use python instead of python2.4 in Bugs-Everywhere-Web/start-beweb.py
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=use python instead of python2.4 in Bugs-Everywhere-Web/start-beweb.py
-
-
-
-
-
-
-time=Mon, 14 Apr 2008 16:42:37 +0000
-
-
+time: Mon, 14 Apr 2008 16:42:37 +0000
diff --git a/.be/bugs/c4ea43d5-4964-49ea-a1eb-2bab2bde8e2e/values b/.be/bugs/c4ea43d5-4964-49ea-a1eb-2bab2bde8e2e/values
index 483916d..354de99 100644
--- a/.be/bugs/c4ea43d5-4964-49ea-a1eb-2bab2bde8e2e/values
+++ b/.be/bugs/c4ea43d5-4964-49ea-a1eb-2bab2bde8e2e/values
@@ -1,35 +1,14 @@
+creator: wking
+severity: minor
-creator=wking
+status: fixed
+summary: Usage of be/test.py is unclear
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Usage of be/test.py is unclear
-
-
-
-
-
-
-time=Thu, 13 Nov 2008 16:31:41 +0000
-
-
+time: Thu, 13 Nov 2008 16:31:41 +0000
diff --git a/.be/bugs/c592a1e8-f2c8-4dfb-8550-955123073947/values b/.be/bugs/c592a1e8-f2c8-4dfb-8550-955123073947/values
index 7e7f554..e8ba31c 100644
--- a/.be/bugs/c592a1e8-f2c8-4dfb-8550-955123073947/values
+++ b/.be/bugs/c592a1e8-f2c8-4dfb-8550-955123073947/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Needs ability to create comments
-
-
+summary: Needs ability to create comments
diff --git a/.be/bugs/c894f10f-197d-4b22-9c5b-19f394df40d4/values b/.be/bugs/c894f10f-197d-4b22-9c5b-19f394df40d4/values
index 84a0a11..947a596 100644
--- a/.be/bugs/c894f10f-197d-4b22-9c5b-19f394df40d4/values
+++ b/.be/bugs/c894f10f-197d-4b22-9c5b-19f394df40d4/values
@@ -1,35 +1,14 @@
+creator: W. Trevor King <wking@drexel.edu>
+severity: minor
-creator=W. Trevor King <wking@drexel.edu>
+status: closed
+summary: Allow user id to be cached in settings for duplicate bugdirs
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Allow user id to be cached in settings for duplicate bugdirs
-
-
-
-
-
-
-time=Sat, 22 Nov 2008 21:36:06 +0000
-
-
+time: Sat, 22 Nov 2008 21:36:06 +0000
diff --git a/.be/bugs/cb56c990-a757-4aef-9888-a30918a7b3d7/values b/.be/bugs/cb56c990-a757-4aef-9888-a30918a7b3d7/values
index 790c8c6..804f631 100644
--- a/.be/bugs/cb56c990-a757-4aef-9888-a30918a7b3d7/values
+++ b/.be/bugs/cb56c990-a757-4aef-9888-a30918a7b3d7/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: 'Beweb: Stripey tables'
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Beweb: Stripey tables
-
-
-
-
-
-
-time=Wed, 04 Jan 2006 21:06:10 +0000
-
-
+time: Wed, 04 Jan 2006 21:06:10 +0000
diff --git a/.be/bugs/cf77c72d-b099-413a-802e-a8892ac8c26b/values b/.be/bugs/cf77c72d-b099-413a-802e-a8892ac8c26b/values
index 39b0fd7..4e6607c 100644
--- a/.be/bugs/cf77c72d-b099-413a-802e-a8892ac8c26b/values
+++ b/.be/bugs/cf77c72d-b099-413a-802e-a8892ac8c26b/values
@@ -1,35 +1,14 @@
+assigned: abentley
+creator: abentley
-assigned=abentley
+severity: minor
+status: fixed
-
-creator=abentley
-
-
-
-
-
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=date-stamp bugs
-
-
+summary: date-stamp bugs
diff --git a/.be/bugs/dac91856-cb6a-4f69-8c03-38ff0b29aab2/values b/.be/bugs/dac91856-cb6a-4f69-8c03-38ff0b29aab2/values
index c36e743..17288dc 100644
--- a/.be/bugs/dac91856-cb6a-4f69-8c03-38ff0b29aab2/values
+++ b/.be/bugs/dac91856-cb6a-4f69-8c03-38ff0b29aab2/values
@@ -1,35 +1,14 @@
+creator: wking
+severity: serious
-creator=wking
+status: fixed
+summary: BE not notifying git of some changed files
-
-severity=serious
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=BE not notifying git of some changed files
-
-
-
-
-
-
-time=Mon, 17 Nov 2008 15:02:15 +0000
-
-
+time: Mon, 17 Nov 2008 15:02:15 +0000
diff --git a/.be/bugs/dba25cfd-aa15-457c-903a-b53ecb5a3b2c/values b/.be/bugs/dba25cfd-aa15-457c-903a-b53ecb5a3b2c/values
index 06b20b7..9271b50 100644
--- a/.be/bugs/dba25cfd-aa15-457c-903a-b53ecb5a3b2c/values
+++ b/.be/bugs/dba25cfd-aa15-457c-903a-b53ecb5a3b2c/values
@@ -1,35 +1,15 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: there's a tyop in the wx example gui (in the line that appends ../../ to
+ sys.path)
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=there's a tyop in the wx example gui (in the line that appends ../../ to sys.path)
-
-
-
-
-
-
-time=Tue, 27 Dec 2005 16:59:49 +0000
-
-
+time: Tue, 27 Dec 2005 16:59:49 +0000
diff --git a/.be/bugs/e0155831-499f-421a-ad02-cd15fc3fecf1/values b/.be/bugs/e0155831-499f-421a-ad02-cd15fc3fecf1/values
index 6233efd..bffaec4 100644
--- a/.be/bugs/e0155831-499f-421a-ad02-cd15fc3fecf1/values
+++ b/.be/bugs/e0155831-499f-421a-ad02-cd15fc3fecf1/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=No way to commit/update from beweb
-
-
+summary: No way to commit/update from beweb
diff --git a/.be/bugs/e2f6514c-5f9f-4734-a537-daf3fbe7e9a0/values b/.be/bugs/e2f6514c-5f9f-4734-a537-daf3fbe7e9a0/values
index 608b460..7b5e6e6 100644
--- a/.be/bugs/e2f6514c-5f9f-4734-a537-daf3fbe7e9a0/values
+++ b/.be/bugs/e2f6514c-5f9f-4734-a537-daf3fbe7e9a0/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: Add a reporter field
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Add a reporter field
-
-
-
-
-
-
-time=Thu, 14 Sep 2006 16:47:57 +0000
-
-
+time: Thu, 14 Sep 2006 16:47:57 +0000
diff --git a/.be/bugs/ecc91b94-7f3f-44a7-af58-03191d327a7f/values b/.be/bugs/ecc91b94-7f3f-44a7-af58-03191d327a7f/values
index 555375b..df99653 100644
--- a/.be/bugs/ecc91b94-7f3f-44a7-af58-03191d327a7f/values
+++ b/.be/bugs/ecc91b94-7f3f-44a7-af58-03191d327a7f/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: no tests for missing $EDITOR
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=no tests for missing $EDITOR
-
-
-
-
-
-
-time=Tue, 17 May 2005 13:27:33 +0000
-
-
+time: Tue, 17 May 2005 13:27:33 +0000
diff --git a/.be/bugs/ee681951-f254-43d3-a53a-1b36ae415d5c/values b/.be/bugs/ee681951-f254-43d3-a53a-1b36ae415d5c/values
index 2e595f9..01b1768 100644
--- a/.be/bugs/ee681951-f254-43d3-a53a-1b36ae415d5c/values
+++ b/.be/bugs/ee681951-f254-43d3-a53a-1b36ae415d5c/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
+summary: Support rcs configuration
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=Support rcs configuration
-
-
-
-
-
-
-target=patch-52
-
-
+target: patch-52
diff --git a/.be/bugs/f51dc5a7-37b7-4ce1-859a-b7cb58be6494/values b/.be/bugs/f51dc5a7-37b7-4ce1-859a-b7cb58be6494/values
index ef82d6f..4e5613f 100644
--- a/.be/bugs/f51dc5a7-37b7-4ce1-859a-b7cb58be6494/values
+++ b/.be/bugs/f51dc5a7-37b7-4ce1-859a-b7cb58be6494/values
@@ -1,28 +1,11 @@
+severity: fatal
+status: fixed
-severity=fatal
+summary: Can't create bugs
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Can't create bugs
-
-
-
-
-
-
-target=0.1
-
-
+target: '0.1'
diff --git a/.be/bugs/f5c06914-dc64-4658-8ec7-32a026a53f55/values b/.be/bugs/f5c06914-dc64-4658-8ec7-32a026a53f55/values
index bcf47f4..cf35f07 100644
--- a/.be/bugs/f5c06914-dc64-4658-8ec7-32a026a53f55/values
+++ b/.be/bugs/f5c06914-dc64-4658-8ec7-32a026a53f55/values
@@ -1,35 +1,14 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: fixed
+summary: Implement bug tree diff
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=Implement bug tree diff
-
-
-
-
-
-
-target=0.2
-
-
+target: '0.2'
diff --git a/.be/bugs/f65b680b-4309-43a2-ae2d-e65811c9d107/values b/.be/bugs/f65b680b-4309-43a2-ae2d-e65811c9d107/values
index e73c0b8..a2b042c 100644
--- a/.be/bugs/f65b680b-4309-43a2-ae2d-e65811c9d107/values
+++ b/.be/bugs/f65b680b-4309-43a2-ae2d-e65811c9d107/values
@@ -1,28 +1,11 @@
+creator: abentley
+severity: minor
-creator=abentley
+status: closed
-
-
-
-severity=minor
-
-
-
-
-
-
-status=closed
-
-
-
-
-
-
-summary=friendly name is created, but not used
-
-
+summary: friendly name is created, but not used
diff --git a/.be/bugs/f7ccd916-b5c7-4890-a2e3-8c8ace17ae3a/values b/.be/bugs/f7ccd916-b5c7-4890-a2e3-8c8ace17ae3a/values
index e710d29..93ad759 100644
--- a/.be/bugs/f7ccd916-b5c7-4890-a2e3-8c8ace17ae3a/values
+++ b/.be/bugs/f7ccd916-b5c7-4890-a2e3-8c8ace17ae3a/values
@@ -1,35 +1,14 @@
+creator: W. Trevor King <wking@drexel.edu>
+severity: minor
-creator=W. Trevor King <wking@drexel.edu>
+status: fixed
+summary: UTF-8 encoding trouble with pipes in becommands/show
-
-severity=minor
-
-
-
-
-
-
-status=fixed
-
-
-
-
-
-
-summary=UTF-8 encoding trouble with pipes in becommands/show
-
-
-
-
-
-
-time=Tue, 25 Nov 2008 02:30:35 +0000
-
-
+time: Tue, 25 Nov 2008 02:30:35 +0000
diff --git a/becommands/depend.py b/becommands/depend.py
new file mode 100644
index 0000000..8dbb2eb
--- /dev/null
+++ b/becommands/depend.py
@@ -0,0 +1,83 @@
+# Copyright (C) 2009 W. Trevor King <wking@drexel.edu>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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."""
+from libbe import cmdutil, bugdir
+import os, copy
+__desc__ = __doc__
+
+def execute(args, test=False):
+ """
+ >>> from libbe import utility
+ >>> bd = bugdir.simple_bug_dir()
+ >>> bd.save()
+ >>> os.chdir(bd.root)
+ >>> execute(["a", "b"], test=True)
+ Blocks on a:
+ b
+ >>> execute(["a"], test=True)
+ Blocks on a:
+ b
+ >>> execute(["-r", "a", "b"], test=True)
+ """
+ parser = get_parser()
+ options, args = parser.parse_args(args)
+ cmdutil.default_complete(options, args, parser,
+ bugid_args={0: lambda bug : bug.active==True,
+ 1: lambda bug : bug.active==True})
+
+ if len(args) < 1:
+ raise cmdutil.UsageError("Please a bug id.")
+ if len(args) > 2:
+ help()
+ raise cmdutil.UsageError("Too many arguments.")
+
+ bd = bugdir.BugDir(from_disk=True, manipulate_encodings=not test)
+ bugA = bd.bug_from_shortname(args[0])
+ if len(args) == 2:
+ bugB = bd.bug_from_shortname(args[1])
+ estrs = bugA.extra_strings
+ depend_string = "BLOCKED-BY:%s" % bugB.uuid
+ if options.remove == True:
+ estrs.remove(depend_string)
+ else: # add the dependency
+ estrs.append(depend_string)
+ bugA.extra_strings = estrs # reassign to notice change
+ bugA.save()
+
+ depends = []
+ for estr in bugA.extra_strings:
+ if estr.startswith("BLOCKED-BY:"):
+ depends.append(estr[11:])
+ if len(depends) > 0:
+ print "Blocks on %s:" % bugA.uuid
+ print '\n'.join(depends)
+
+def get_parser():
+ parser = cmdutil.CmdOptionParser("be depend BUG-ID [BUG-ID]")
+ parser.add_option("-r", "--remove", action="store_true", dest="remove",
+ help="Remove dependency (instead of adding it)")
+ return parser
+
+longhelp="""
+Set a dependency with the second bug (B) blocking the first bug (A).
+If bug B is not specified, just print a list of bugs blocking (A).
+
+To search for bugs blocked by a particular bug, try
+ $ be list --extra-strings BLOCKED-BY:<your-bug-uuid>
+"""
+
+def help():
+ return get_parser().help_str() + longhelp
diff --git a/becommands/list.py b/becommands/list.py
index 1f06569..fa2f592 100644
--- a/becommands/list.py
+++ b/becommands/list.py
@@ -109,6 +109,8 @@ def execute(args, test=False):
target.append(bd.target)
if target == []: # set the default value
target = "all"
+ if options.extra_strings != None:
+ required_extra_strings = options.extra_strings.split(',')
def filter(bug):
if status != "all" and not bug.status in status:
@@ -119,6 +121,10 @@ def execute(args, test=False):
return False
if target != "all" and not bug.target in target:
return False
+ if options.extra_strings != None:
+ for string in bug.extra_strings:
+ if string not in required_extra_strings:
+ return False
return True
bugs = [b for b in bd if filter(b) ]
@@ -152,13 +158,15 @@ def execute(args, test=False):
def get_parser():
parser = cmdutil.CmdOptionParser("be list [options]")
parser.add_option("-s", "--status", metavar="STATUS", dest="status",
- help="List options matching STATUS", default=None)
+ help="List bugs matching STATUS", default=None)
parser.add_option("-v", "--severity", metavar="SEVERITY", dest="severity",
- help="List options matching SEVERITY", default=None)
+ help="List bugs matching SEVERITY", default=None)
parser.add_option("-a", "--assigned", metavar="ASSIGNED", dest="assigned",
- help="List options matching ASSIGNED", default=None)
+ help="List bugs matching ASSIGNED", default=None)
parser.add_option("-t", "--target", metavar="TARGET", dest="target",
- help="List options matching TARGET", default=None)
+ help="List bugs matching TARGET", default=None)
+ parser.add_option("-e", "--extra-strings", metavar="STRINGS", dest="extra_strings",
+ help="List bugs matching _all_ extra strings in comma-seperated list STRINGS. e.g. --extra-strings TAG:working,TAG:xml", default=None)
parser.add_option("-S", "--sort", metavar="SORT-BY", dest="sort_by",
help="Adjust bug-sort criteria with comma-separated list SORT-BY. e.g. \"--sort creator,time\". Available criteria: %s" % ','.join(AVAILABLE_CMPS), default=None)
# boolean options. All but uuids and xml are special cases of long forms
diff --git a/becommands/tag.py b/becommands/tag.py
new file mode 100644
index 0000000..2394284
--- /dev/null
+++ b/becommands/tag.py
@@ -0,0 +1,132 @@
+# Copyright (C) 2009 W. Trevor King <wking@drexel.edu>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# 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."""
+from libbe import cmdutil, bugdir
+import os, copy
+__desc__ = __doc__
+
+def execute(args, test=False):
+ """
+ >>> from libbe import utility
+ >>> bd = bugdir.simple_bug_dir()
+ >>> os.chdir(bd.root)
+ >>> a = bd.bug_from_shortname("a")
+ >>> print a.extra_strings
+ []
+ >>> execute(["a", "GUI"], test=True)
+ Tags for a:
+ GUI
+ >>> bd._clear_bugs() # resync our copy of bug
+ >>> a = bd.bug_from_shortname("a")
+ >>> print a.extra_strings
+ ['TAG:GUI']
+ >>> execute(["a", "later"], test=True)
+ Tags for a:
+ GUI
+ later
+ >>> execute(["a"], test=True)
+ Tags for a:
+ GUI
+ later
+ >>> execute(["--list"], test=True)
+ GUI
+ later
+ >>> execute(["a", "Alphabetically first"], test=True)
+ Tags for a:
+ Alphabetically first
+ GUI
+ later
+ >>> bd._clear_bugs() # resync our copy of bug
+ >>> a = bd.bug_from_shortname("a")
+ >>> print a.extra_strings
+ ['TAG:Alphabetically first', 'TAG:GUI', 'TAG:later']
+ >>> a.extra_strings = []
+ >>> print a.extra_strings
+ []
+ >>> a.save()
+ >>> execute(["a"], test=True)
+ >>> bd._clear_bugs() # resync our copy of bug
+ >>> a = bd.bug_from_shortname("a")
+ >>> print a.extra_strings
+ []
+ >>> execute(["a", "Alphabetically first"], test=True)
+ Tags for a:
+ Alphabetically first
+ >>> execute(["--remove", "a", "Alphabetically first"], test=True)
+ """
+ parser = get_parser()
+ options, args = parser.parse_args(args)
+ cmdutil.default_complete(options, args, parser,
+ bugid_args={0: lambda bug : bug.active==True})
+
+ if len(args) == 0 and options.list == False:
+ raise cmdutil.UsageError("Please specify a bug id.")
+ elif len(args) > 2 or (len(args) > 0 and options.list == True):
+ help()
+ raise cmdutil.UsageError("Too many arguments.")
+
+ bd = bugdir.BugDir(from_disk=True, manipulate_encodings=not test)
+ if options.list:
+ bd.load_all_bugs()
+ tags = []
+ for bug in bd:
+ for estr in bug.extra_strings:
+ if estr.startswith("TAG:"):
+ tag = estr[4:]
+ if tag not in tags:
+ tags.append(tag)
+ tags.sort()
+ print '\n'.join(tags)
+ return
+ bug = bd.bug_from_shortname(args[0])
+ if len(args) == 2:
+ given_tag = args[1]
+ estrs = bug.extra_strings
+ tag_string = "TAG:%s" % given_tag
+ if options.remove == True:
+ estrs.remove(tag_string)
+ else: # add the tag
+ estrs.append(tag_string)
+ bug.extra_strings = estrs # reassign to notice change
+ bug.save()
+
+ tags = []
+ for estr in bug.extra_strings:
+ if estr.startswith("TAG:"):
+ tags.append(estr[4:])
+
+ if len(tags) > 0:
+ print "Tags for %s:" % bug.uuid
+ print '\n'.join(tags)
+
+def get_parser():
+ parser = cmdutil.CmdOptionParser("be tag BUG-ID [TAG]\nor: be tag --list")
+ parser.add_option("-r", "--remove", action="store_true", dest="remove",
+ help="Remove TAG (instead of adding it)")
+ parser.add_option("-l", "--list", action="store_true", dest="list",
+ help="List all available tags and exit")
+ return parser
+
+longhelp="""
+If TAG is given, add TAG to BUG-ID. If it is not specified, just
+print the tags for BUG-ID.
+
+To search for bugs with a particular tag, try
+ $ be list --extra-strings TAG:<your-tag>
+"""
+
+def help():
+ return get_parser().help_str() + longhelp
diff --git a/libbe/bug.py b/libbe/bug.py
index 43974dd..7418933 100644
--- a/libbe/bug.py
+++ b/libbe/bug.py
@@ -18,6 +18,7 @@ import os
import os.path
import errno
import time
+import types
import xml.sax.saxutils
import doctest
@@ -184,6 +185,27 @@ class Bug(settings_object.SavedSettingsObject):
fset=_set_time,
doc="An integer version of .time_string")
+ def _extra_strings_check_fn(value):
+ "Require an iterable full of strings"
+ if value == settings_object.EMPTY:
+ return True
+ elif not hasattr(value, "__iter__"):
+ return False
+ for x in value:
+ if type(x) not in types.StringTypes:
+ return False
+ return True
+ def _extra_strings_change_hook(self, old, new):
+ self.extra_strings.sort() # to make merging easier
+ self._prop_save_settings(old, new)
+ @_versioned_property(name="extra_strings",
+ doc="Space for an array of extra strings. Useful for storing state for functionality implemented purely in becommands/<some_function>.py.",
+ default=[],
+ check_fn=_extra_strings_check_fn,
+ change_hook=_extra_strings_change_hook,
+ mutable=True)
+ def extra_strings(): return {}
+
@_versioned_property(name="summary",
doc="A one-line bug description")
def summary(): return {}
diff --git a/libbe/bugdir.py b/libbe/bugdir.py
index a9ec42e..3c2c247 100644
--- a/libbe/bugdir.py
+++ b/libbe/bugdir.py
@@ -54,9 +54,9 @@ class AlreadyInitialized(Exception):
class MultipleBugMatches(ValueError):
def __init__(self, shortname, matches):
msg = ("More than one bug matches %s. "
- "Please be more specific.\n%s" % shortname, matches)
+ "Please be more specific.\n%s" % (shortname, matches))
ValueError.__init__(self, msg)
- self.shortname = shortnamename
+ self.shortname = shortname
self.matches = matches
diff --git a/libbe/comment.py b/libbe/comment.py
index 80b97a1..df5a63f 100644
--- a/libbe/comment.py
+++ b/libbe/comment.py
@@ -151,10 +151,10 @@ class Comment(Tree, settings_object.SavedSettingsObject):
if self.rcs != None and self.sync_with_disk == True:
import rcs
return self.rcs.get_file_contents(self.get_path("body"))
- def _set_comment_body(self, value, force=False):
+ 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 value != None, "Can't save empty comment"
- self.rcs.set_file_contents(self.get_path("body"), value)
+ assert new != None, "Can't save empty comment"
+ self.rcs.set_file_contents(self.get_path("body"), new)
@Property
@change_hook_property(hook=_set_comment_body)
@@ -323,7 +323,7 @@ class Comment(Tree, settings_object.SavedSettingsObject):
# raise Exception, str(self)+'\n'+str(self.settings)+'\n'+str(self._settings_loaded)
#assert self.in_reply_to != None, "Comment must be a reply to something"
self.save_settings()
- self._set_comment_body(self.body, force=True)
+ self._set_comment_body(new=self.body, force=True)
def remove(self):
for comment in self.traverse():
diff --git a/libbe/mapfile.py b/libbe/mapfile.py
index c36d454..0272890 100644
--- a/libbe/mapfile.py
+++ b/libbe/mapfile.py
@@ -113,7 +113,7 @@ def parse(contents):
else:
newlines.append(line)
contents = '\n'.join(newlines)
- return yaml.load(contents)
+ return yaml.load(contents) or {}
def map_save(rcs, path, map, allow_no_rcs=False):
"""Save the map as a mapfile to the specified path"""
diff --git a/libbe/properties.py b/libbe/properties.py
index a8e89fb..956ecc3 100644
--- a/libbe/properties.py
+++ b/libbe/properties.py
@@ -26,12 +26,17 @@ and
for more information on decorators.
"""
+import copy
+import types
import unittest
class ValueCheckError (ValueError):
def __init__(self, name, value, allowed):
- msg = "%s not in %s for %s" % (value, allowed, name)
+ action = "in" # some list of allowed values
+ if type(allowed) == types.FunctionType:
+ action = "allowed by" # some allowed-value check function
+ msg = "%s not %s %s for %s" % (value, action, allowed, name)
ValueError.__init__(self, msg)
self.name = name
self.value = value
@@ -66,7 +71,7 @@ def doc_property(doc=None):
return funcs
return decorator
-def local_property(name, null=None):
+def local_property(name, null=None, mutable_null=False):
"""
Define get/set access to per-parent-instance local storage. Uses
._<name>_value to store the value for a particular owner instance.
@@ -80,7 +85,11 @@ def local_property(name, null=None):
def _fget(self):
if fget is not None:
fget(self)
- value = getattr(self, "_%s_value" % name, null)
+ if mutable_null == True:
+ ret_null = copy.deepcopy(null)
+ else:
+ ret_null = null
+ value = getattr(self, "_%s_value" % name, ret_null)
return value
def _fset(self, value):
setattr(self, "_%s_value" % name, value)
@@ -118,7 +127,46 @@ def settings_property(name, null=None):
return funcs
return decorator
-def defaulting_property(default=None, null=None):
+
+# Allow comparison and caching with _original_ values for mutables,
+# since
+#
+# >>> a = []
+# >>> b = a
+# >>> b.append(1)
+# >>> a
+# [1]
+# >>> a==b
+# True
+def _hash_mutable_value(value):
+ return repr(value)
+def _init_mutable_property_cache(self):
+ if not hasattr(self, "_mutable_property_cache_hash"):
+ # first call to _fget for any mutable property
+ self._mutable_property_cache_hash = {}
+ self._mutable_property_cache_copy = {}
+def _set_cached_mutable_property(self, cacher_name, property_name, value):
+ _init_mutable_property_cache(self)
+ self._mutable_property_cache_hash[(cacher_name, property_name)] = \
+ _hash_mutable_value(value)
+ self._mutable_property_cache_copy[(cacher_name, property_name)] = \
+ copy.deepcopy(value)
+def _get_cached_mutable_property(self, cacher_name, property_name, default=None):
+ _init_mutable_property_cache(self)
+ if (cacher_name, property_name) not in self._mutable_property_cache_copy:
+ return default
+ return self._mutable_property_cache_copy[(cacher_name, property_name)]
+def _cmp_cached_mutable_property(self, cacher_name, property_name, value):
+ _init_mutable_property_cache(self)
+ if (cacher_name, property_name) not in self._mutable_property_cache_hash:
+ return 1 # any value > non-existant old hash
+ old_hash = self._mutable_property_cache_hash[(cacher_name, property_name)]
+ return cmp(_hash_mutable_value(value), old_hash)
+
+
+def defaulting_property(default=None, null=None,
+ default_mutable=False,
+ null_mutable=False):
"""
Define a default value for get access to a property.
If the stored value is null, then default is returned.
@@ -127,12 +175,25 @@ def defaulting_property(default=None, null=None):
if hasattr(funcs, "__call__"):
funcs = funcs()
fget = funcs.get("fget")
+ fset = funcs.get("fset")
+ name = funcs.get("name", "<unknown>")
def _fget(self):
value = fget(self)
if value == null:
- return default
+ if default_mutable == True:
+ return copy.deepcopy(default)
+ else:
+ return default
return value
+ def _fset(self, value):
+ if value == default:
+ if null_mutable == True:
+ value = copy.deepcopy(null)
+ else:
+ value = null
+ fset(self, value)
funcs["fget"] = _fget
+ funcs["fset"] = _fset
return funcs
return decorator
@@ -184,7 +245,7 @@ def checked_property(allowed=[]):
return funcs
return decorator
-def cached_property(generator, initVal=None):
+def cached_property(generator, initVal=None, mutable=False):
"""
Allow caching of values generated by generator(instance), where
instance is the instance to which this property belongs. Uses
@@ -193,7 +254,7 @@ def cached_property(generator, initVal=None):
When the cache flag is True or missing and the stored value is
initVal, the first fget call triggers the generator function,
- whiose output is stored in _<name>_cached_value. That and
+ whose output is stored in _<name>_cached_value. That and
subsequent calls to fget will return this cached value.
If the input value is no longer initVal (e.g. a value has been
@@ -205,25 +266,27 @@ def cached_property(generator, initVal=None):
The cache flag is missing on initialization. Particular instances
may override by setting their own flag.
+
+ In the case that mutable == True, all caching is disabled and the
+ generator is called whenever the cached value would otherwise be
+ used. This avoids uncertainties in the value of stored mutables.
"""
def decorator(funcs):
if hasattr(funcs, "__call__"):
funcs = funcs()
fget = funcs.get("fget")
- fset = funcs.get("fset")
name = funcs.get("name", "<unknown>")
def _fget(self):
cache = getattr(self, "_%s_cache" % name, True)
value = fget(self)
- if cache == True:
- if value == initVal:
+ if value == initVal:
+ if cache == True and mutable == False:
if hasattr(self, "_%s_cached_value" % name):
value = getattr(self, "_%s_cached_value" % name)
else:
value = generator(self)
setattr(self, "_%s_cached_value" % name, value)
- else:
- if value == initVal:
+ else:
value = generator(self)
return value
funcs["fget"] = _fget
@@ -258,12 +321,15 @@ def primed_property(primer, initVal=None):
return funcs
return decorator
-def change_hook_property(hook):
+def change_hook_property(hook, mutable=False):
"""
Call the function hook(instance, old_value, new_value) whenever a
value different from the current value is set (instance is a a
reference to the class instance to which this property belongs).
- This is useful for saving changes to disk, etc.
+ This is useful for saving changes to disk, etc. This function is
+ called _after_ the new value has been stored, allowing you to
+ change the stored value if you want.
+
"""
def decorator(funcs):
if hasattr(funcs, "__call__"):
@@ -271,15 +337,31 @@ def change_hook_property(hook):
fget = funcs.get("fget")
fset = funcs.get("fset")
name = funcs.get("name", "<unknown>")
+ def _fget(self, new_value=None, from_fset=False): # only used if mutable == True
+ value = fget(self)
+ if _cmp_cached_mutable_property(self, "change hook property", name, value) != 0:
+ # there has been a change, cache new value
+ old_value = _get_cached_mutable_property(self, "change hook property", name)
+ _set_cached_mutable_property(self, "change hook property", name, value)
+ if from_fset == True: # return previously cached value
+ value = old_value
+ else: # the value changed while we weren't looking
+ hook(self, old_value, value)
+ return value
def _fset(self, value):
- old_value = fget(self)
+ if mutable == True: # get cached previous value
+ old_value = _fget(self, new_value=value, from_fset=True)
+ else:
+ old_value = fget(self)
+ fset(self, value)
if value != old_value:
hook(self, old_value, value)
- fset(self, value)
+ if mutable == True:
+ funcs["fget"] = _fget
funcs["fset"] = _fset
return funcs
return decorator
-
+
class DecoratorTests(unittest.TestCase):
def testLocalDoc(self):
@@ -320,16 +402,18 @@ class DecoratorTests(unittest.TestCase):
class Test(object):
@Property
@defaulting_property(default='y', null='x')
- @local_property(name="DEFAULT")
+ @local_property(name="DEFAULT", null=5)
def x(): return {}
t = Test()
- self.failUnless(t.x == None, str(t.x))
+ self.failUnless(t.x == 5, str(t.x))
t.x = 'x'
self.failUnless(t.x == 'y', str(t.x))
t.x = 'y'
self.failUnless(t.x == 'y', str(t.x))
t.x = 'z'
self.failUnless(t.x == 'z', str(t.x))
+ t.x = 5
+ self.failUnless(t.x == 5, str(t.x))
def testCheckedLocalProperty(self):
class Test(object):
@Property
@@ -474,6 +558,57 @@ class DecoratorTests(unittest.TestCase):
t.x = 2
self.failUnless(t.old == 1, t.old)
self.failUnless(t.new == 2, t.new)
+ def testChangeHookMutableProperty(self):
+ class Test(object):
+ def _hook(self, old, new):
+ self.old = old
+ self.new = new
+ self.hook_calls += 1
+
+ @Property
+ @change_hook_property(_hook, mutable=True)
+ @local_property(name="HOOKED")
+ def x(): return {}
+ t = Test()
+ t.hook_calls = 0
+ t.x = []
+ self.failUnless(t.old == None, t.old)
+ self.failUnless(t.new == [], t.new)
+ a = t.x
+ a.append(5)
+ t.x = a
+ self.failUnless(t.old == [], t.old)
+ self.failUnless(t.new == [5], t.new)
+ t.x = []
+ self.failUnless(t.old == [5], t.old)
+ self.failUnless(t.new == [], t.new)
+ # now append without reassigning. this doesn't trigger the
+ # change, since we don't ever set t.x, only get it and mess
+ # with it. It does, however, update our t.new, since t.new =
+ # t.x and is not a static copy.
+ t.x.append(5)
+ self.failUnless(t.old == [5], t.old)
+ self.failUnless(t.new == [5], t.new)
+ # however, the next t.x get _will_ notice the change...
+ a = t.x
+ self.failUnless(t.old == [], t.old)
+ self.failUnless(t.new == [5], t.new)
+ self.failUnless(t.hook_calls == 6, t.hook_calls)
+ t.x.append(6) # this append(6) is not noticed yet
+ self.failUnless(t.old == [], t.old)
+ self.failUnless(t.new == [5,6], t.new)
+ self.failUnless(t.hook_calls == 6, t.hook_calls)
+ # this append(7) is not noticed, but the t.x get causes the
+ # append(6) to be noticed
+ t.x.append(7)
+ self.failUnless(t.old == [5], t.old)
+ self.failUnless(t.new == [5,6,7], t.new)
+ self.failUnless(t.hook_calls == 7, t.hook_calls)
+ a = t.x # now the append(7) is noticed
+ self.failUnless(t.old == [5,6], t.old)
+ self.failUnless(t.new == [5,6,7], t.new)
+ self.failUnless(t.hook_calls == 8, t.hook_calls)
+
suite = unittest.TestLoader().loadTestsFromTestCase(DecoratorTests)
diff --git a/libbe/settings_object.py b/libbe/settings_object.py
index 1df3e6b..60fddb9 100644
--- a/libbe/settings_object.py
+++ b/libbe/settings_object.py
@@ -87,6 +87,7 @@ def attr_name_to_setting_name(self, name):
def versioned_property(name, doc,
default=None, generator=None,
change_hook=prop_save_settings,
+ mutable=False,
primer=prop_load_settings,
allowed=None, check_fn=None,
settings_properties=[],
@@ -125,10 +126,12 @@ def versioned_property(name, doc,
def decorator(funcs):
fulldoc = doc
if default != None:
- defaulting = defaulting_property(default=default, null=EMPTY)
+ defaulting = defaulting_property(default=default, null=EMPTY,
+ default_mutable=mutable)
fulldoc += "\n\nThis property defaults to %s" % default
if generator != None:
- cached = cached_property(generator=generator, initVal=EMPTY)
+ cached = cached_property(generator=generator, initVal=EMPTY,
+ mutable=mutable)
fulldoc += "\n\nThis property is generated with %s" % generator
if check_fn != None:
fn_checked = fn_checked_property(value_allowed_fn=check_fn)
@@ -137,7 +140,7 @@ def versioned_property(name, doc,
checked = checked_property(allowed=allowed)
fulldoc += "\n\nThe allowed values for this property are: %s." \
% (', '.join(allowed))
- hooked = change_hook_property(hook=change_hook)
+ hooked = change_hook_property(hook=change_hook, mutable=mutable)
primed = primed_property(primer=primer, initVal=UNPRIMED)
settings = settings_property(name=name, null=UNPRIMED)
docp = doc_property(doc=fulldoc)
@@ -146,12 +149,10 @@ def versioned_property(name, doc,
deco = defaulting(deco)
if generator != None:
deco = cached(deco)
- if default != None:
- deco = defaulting(deco)
- if allowed != None:
- deco = checked(deco)
if check_fn != None:
deco = fn_checked(deco)
+ if allowed != None:
+ deco = checked(deco)
return Property(deco)
return decorator
@@ -219,6 +220,7 @@ class SavedSettingsObject(object):
class SavedSettingsObjectTests(unittest.TestCase):
def testSimpleProperty(self):
+ """Testing a minimal versioned property"""
class Test(SavedSettingsObject):
settings_properties = []
required_saved_properties = []
@@ -276,6 +278,7 @@ class SavedSettingsObjectTests(unittest.TestCase):
self.failUnless(t.settings["Content-type"] == EMPTY,
t.settings["Content-type"])
def testDefaultingProperty(self):
+ """Testing a defaulting versioned property"""
class Test(SavedSettingsObject):
settings_properties = []
required_saved_properties = []
@@ -305,6 +308,7 @@ class SavedSettingsObjectTests(unittest.TestCase):
self.failUnless(t._get_saved_settings()=={"Content-type":"text/html"},
t._get_saved_settings())
def testRequiredDefaultingProperty(self):
+ """Testing a required defaulting versioned property"""
class Test(SavedSettingsObject):
settings_properties = []
required_saved_properties = []
@@ -324,6 +328,7 @@ class SavedSettingsObjectTests(unittest.TestCase):
self.failUnless(t._get_saved_settings()=={"Content-type":"text/html"},
t._get_saved_settings())
def testClassVersionedPropertyDefinition(self):
+ """Testing a class-specific _versioned property decorator"""
class Test(SavedSettingsObject):
settings_properties = []
required_saved_properties = []
@@ -348,6 +353,59 @@ class SavedSettingsObjectTests(unittest.TestCase):
t.content_type = "text/html"
self.failUnless(t._get_saved_settings()=={"Content-type":"text/html"},
t._get_saved_settings())
+ def testMutableChangeHookedProperty(self):
+ """Testing a mutable change-hooked property"""
+ SAVES = []
+ def prop_log_save_settings(self, old, new, saves=SAVES):
+ saves.append("'%s' -> '%s'" % (str(old), str(new)))
+ prop_save_settings(self, old, new)
+ class Test(SavedSettingsObject):
+ settings_properties = []
+ required_saved_properties = []
+ @versioned_property(name="List-type",
+ doc="A test property",
+ mutable=True,
+ change_hook=prop_log_save_settings,
+ settings_properties=settings_properties,
+ required_saved_properties=required_saved_properties)
+ def list_type(): return {}
+ def __init__(self):
+ SavedSettingsObject.__init__(self)
+ t = Test()
+ self.failUnless(t._settings_loaded == False, t._settings_loaded)
+ t.load_settings()
+ self.failUnless(SAVES == [], SAVES)
+ self.failUnless(t._settings_loaded == True, t._settings_loaded)
+ self.failUnless(t.list_type == EMPTY, t.list_type)
+ self.failUnless(SAVES == [
+ "'None' -> '<class 'libbe.settings_object.EMPTY'>'"
+ ], SAVES)
+ self.failUnless(t.settings["List-type"]==EMPTY,t.settings["List-type"])
+ t.list_type = []
+ self.failUnless(t.settings["List-type"] == [], t.settings["List-type"])
+ self.failUnless(SAVES == [
+ "'None' -> '<class 'libbe.settings_object.EMPTY'>'",
+ "'<class 'libbe.settings_object.EMPTY'>' -> '[]'"
+ ], SAVES)
+ t.list_type.append(5)
+ self.failUnless(SAVES == [
+ "'None' -> '<class 'libbe.settings_object.EMPTY'>'",
+ "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+ "'<class 'libbe.settings_object.EMPTY'>' -> '[]'" # <- TODO. Where did this come from?
+ ], SAVES)
+ self.failUnless(t.settings["List-type"] == [5],t.settings["List-type"])
+ self.failUnless(SAVES == [ # the append(5) has not yet been saved
+ "'None' -> '<class 'libbe.settings_object.EMPTY'>'",
+ "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+ "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+ ], SAVES)
+ self.failUnless(t.list_type == [5], t.list_type) # <-get triggers saved
+ self.failUnless(SAVES == [ # now the append(5) has been saved.
+ "'None' -> '<class 'libbe.settings_object.EMPTY'>'",
+ "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+ "'<class 'libbe.settings_object.EMPTY'>' -> '[]'",
+ "'[]' -> '[5]'"
+ ], SAVES)
unitsuite=unittest.TestLoader().loadTestsFromTestCase(SavedSettingsObjectTests)
suite = unittest.TestSuite([unitsuite, doctest.DocTestSuite()])