aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/comments/4be73baf-e46b-4acb-a58e-4719e57c550b/body8
-rw-r--r--.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/comments/4be73baf-e46b-4acb-a58e-4719e57c550b/values21
-rw-r--r--.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values42
-rw-r--r--.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/comments/e757d2ae-085a-4539-99be-096386de5352/body3
-rw-r--r--.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/comments/e757d2ae-085a-4539-99be-096386de5352/values21
-rw-r--r--.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values42
-rw-r--r--.bzrignore1
-rw-r--r--Bugs-Everywhere-Web/beweb/config/app.cfg50
-rw-r--r--Bugs-Everywhere-Web/beweb/controllers.py2
-rw-r--r--Bugs-Everywhere-Web/beweb/templates/about.kid8
l---------Bugs-Everywhere-Web/libbe2
-rw-r--r--Makefile47
-rw-r--r--README2
-rw-r--r--doc/be.1.sgml247
-rw-r--r--doc/module.mk31
-rw-r--r--libbe/bugdir.py4
-rw-r--r--libbe/git.py146
-rw-r--r--libbe/rcs.py6
-rwxr-xr-x[-rw-r--r--]setup.py3
19 files changed, 677 insertions, 9 deletions
diff --git a/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/comments/4be73baf-e46b-4acb-a58e-4719e57c550b/body b/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/comments/4be73baf-e46b-4acb-a58e-4719e57c550b/body
new file mode 100644
index 0000000..ff42ab3
--- /dev/null
+++ b/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/comments/4be73baf-e46b-4acb-a58e-4719e57c550b/body
@@ -0,0 +1,8 @@
+The FSF offices are no longer at Temple Place, and there is a revised
+text of the GPLv2 giving the correct address and other textual
+clean-ups.
+
+The COPYING file should be updated to the new GPLv2 text, and the
+copyright notices throughout the working tree should be updated for
+the new boilerplate how-to-use-the-GPL text.
+
diff --git a/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/comments/4be73baf-e46b-4acb-a58e-4719e57c550b/values b/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/comments/4be73baf-e46b-4acb-a58e-4719e57c550b/values
new file mode 100644
index 0000000..a68a21d
--- /dev/null
+++ b/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/comments/4be73baf-e46b-4acb-a58e-4719e57c550b/values
@@ -0,0 +1,21 @@
+
+
+
+Content-type=text/plain
+
+
+
+
+
+
+Date=Fri, 18 Apr 2008 11:21:03 +0000
+
+
+
+
+
+
+From=benf
+
+
+
diff --git a/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values b/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values
new file mode 100644
index 0000000..05961db
--- /dev/null
+++ b/.be/bugs/00f26f04-9202-4288-8744-b29abc2342d6/values
@@ -0,0 +1,42 @@
+
+
+
+assigned=Ben Finney <ben+python@benfinney.id.au>
+
+
+
+
+
+
+creator=benf
+
+
+
+
+
+
+severity=minor
+
+
+
+
+
+
+status=closed
+
+
+
+
+
+
+summary=Address is outdated for FSF offices
+
+
+
+
+
+
+time=Fri, 18 Apr 2008 11:18:58 +0000
+
+
+
diff --git a/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/comments/e757d2ae-085a-4539-99be-096386de5352/body b/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/comments/e757d2ae-085a-4539-99be-096386de5352/body
new file mode 100644
index 0000000..0dedcdd
--- /dev/null
+++ b/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/comments/e757d2ae-085a-4539-99be-096386de5352/body
@@ -0,0 +1,3 @@
+The 'be' command should have a Unix manpage, describing it like any
+other command on the system.
+
diff --git a/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/comments/e757d2ae-085a-4539-99be-096386de5352/values b/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/comments/e757d2ae-085a-4539-99be-096386de5352/values
new file mode 100644
index 0000000..b7b289e
--- /dev/null
+++ b/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/comments/e757d2ae-085a-4539-99be-096386de5352/values
@@ -0,0 +1,21 @@
+
+
+
+Content-type=text/plain
+
+
+
+
+
+
+Date=Mon, 21 Apr 2008 03:24:11 +0000
+
+
+
+
+
+
+From=benf
+
+
+
diff --git a/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values b/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values
new file mode 100644
index 0000000..ff8a30a
--- /dev/null
+++ b/.be/bugs/b187fbce-fb10-4819-ace2-c8b0b4a45c57/values
@@ -0,0 +1,42 @@
+
+
+
+assigned=benf
+
+
+
+
+
+
+creator=benf
+
+
+
+
+
+
+severity=minor
+
+
+
+
+
+
+status=closed
+
+
+
+
+
+
+summary=Manual page for 'be' command
+
+
+
+
+
+
+time=Mon, 21 Apr 2008 03:21:35 +0000
+
+
+
diff --git a/.bzrignore b/.bzrignore
index a051550..c0fddb1 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -8,3 +8,4 @@ fte.dsk
*~
./.shelf
Bugs-Everywhere-Web/devdata.sqlite
+./doc/*.1
diff --git a/Bugs-Everywhere-Web/beweb/config/app.cfg b/Bugs-Everywhere-Web/beweb/config/app.cfg
index d37cf67..15555b7 100644
--- a/Bugs-Everywhere-Web/beweb/config/app.cfg
+++ b/Bugs-Everywhere-Web/beweb/config/app.cfg
@@ -33,6 +33,56 @@
# Set to True if the scheduler should be started
# tg.scheduler = False
+# IDENTITY
+# General configuration of the TurboGears Identity management module
+# --------
+
+# Switch to turn on or off the Identity management module
+identity.on=True
+
+# [REQUIRED] URL to which CherryPy will internally redirect when an access
+# control check fails. If Identity management is turned on, a value for this
+# option must be specified.
+identity.failure_url="/login"
+
+# identity.provider='sqlobject'
+
+# The names of the fields on the login form containing the visitor's user ID
+# and password. In addition, the submit button is specified simply so its
+# existence may be stripped out prior to passing the form data to the target
+# controller.
+# identity.form.user_name="user_name"
+# identity.form.password="password"
+# identity.form.submit="login"
+
+# What sources should the identity provider consider when determining the
+# identity associated with a request? Comma separated list of identity sources.
+# Valid sources: form, visit, http_auth
+# identity.source="form,http_auth,visit"
+
+# SqlObjectIdentityProvider
+# Configuration options for the default IdentityProvider
+# -------------------------
+
+# The classes you wish to use for your Identity model. Remember to not use reserved
+# SQL keywords for class names (at least unless you specify a different table
+# name using sqlmeta).
+identity.soprovider.model.user="stfa.model.User"
+identity.soprovider.model.group="stfa.model.Group"
+identity.soprovider.model.permission="stfa.model.Permission"
+
+# The password encryption algorithm used when comparing passwords against what's
+# stored in the database. Valid values are 'md5' or 'sha1'. If you do not
+# specify an encryption algorithm, passwords are expected to be clear text.
+# The SqlObjectProvider *will* encrypt passwords supplied as part of your login
+# form. If you set the password through the password property, like:
+# my_user.password = 'secret'
+# the password will be encrypted in the database, provided identity is up and
+# running, or you have loaded the configuration specifying what encryption to
+# use (in situations where identity may not yet be running, like tests).
+
+# identity.soprovider.encryption_algorithm=None
+
[/static]
static_filter.on = True
static_filter.dir = "%(top_level_dir)s/static"
diff --git a/Bugs-Everywhere-Web/beweb/controllers.py b/Bugs-Everywhere-Web/beweb/controllers.py
index 358e74a..8def76c 100644
--- a/Bugs-Everywhere-Web/beweb/controllers.py
+++ b/Bugs-Everywhere-Web/beweb/controllers.py
@@ -26,6 +26,7 @@ def comment_url(project, bug, comment, **kwargs):
(project, bug, comment), kwargs)
class Comment(PrestHandler):
+ @identity.require( identity.has_permission("editbugs"))
@provide_action("action", "New comment")
def new_comment(self, comment_data, comment, *args, **kwargs):
bug_tree = project_tree(comment_data['project'])
@@ -37,6 +38,7 @@ class Comment(PrestHandler):
raise cherrypy.HTTPRedirect(comment_url(comment=comment.uuid,
**comment_data))
+ @identity.require( identity.has_permission("editbugs"))
@provide_action("action", "Reply")
def reply_comment(self, comment_data, comment, *args, **kwargs):
bug_tree = project_tree(comment_data['project'])
diff --git a/Bugs-Everywhere-Web/beweb/templates/about.kid b/Bugs-Everywhere-Web/beweb/templates/about.kid
index 45d0093..fa3548a 100644
--- a/Bugs-Everywhere-Web/beweb/templates/about.kid
+++ b/Bugs-Everywhere-Web/beweb/templates/about.kid
@@ -8,15 +8,13 @@
<body>
<h1>About Bugs Everywhere</h1>
-<p>Bug Everywhere was designed by Aaron Bentley and implemented by Aaron
- Bentley and Oleg Romanyshyn.
+<p>Bugs Everywhere is a "distributed bugtracker", designed to complement distributed revision control systems.
</p>
<p>
- Development is sponsored by
- <a href="http://panoramicfeedback.com/">Panoramic Feedback</a>.
+Bugs Everywhere was conceived and written by developers at <a href="http://panoramicfeedback.com/">Panoramic Feedback</a>, primarily Aaron Bentley. <a href="http://panoramicfeedback.com/">Panoramic Feedback</a> is no longer developing BE, and the current maintainer is <a href="http://bugseverywhere.org/be/show/ChrisBall">Chris Ball</a>.
</p>
<p>
- Bugs Everywhere <a href="http://panoramicfeedback.com/opensource">web site</a>
+ Bugs Everywhere <a href="http://bugseverywhere.org/">web site</a>
</p>
<a href="/">Project List</a>
</body>
diff --git a/Bugs-Everywhere-Web/libbe b/Bugs-Everywhere-Web/libbe
index 6081eee..4e5e17e 120000
--- a/Bugs-Everywhere-Web/libbe
+++ b/Bugs-Everywhere-Web/libbe
@@ -1 +1 @@
-../libbe/ \ No newline at end of file
+../libbe \ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..47fbbfd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,47 @@
+#! /usr/bin/make -f
+# :vim: filetype=make : -*- makefile; coding: utf-8; -*-
+
+# Makefile
+# Part of Bugs Everywhere, a distributed bug tracking system.
+#
+# Copyright © 2008 Ben Finney <ben+python@benfinney.id.au>
+# This is free software; you may copy, modify and/or distribute this work
+# under the terms of the GNU General Public License, version 2 or later.
+# No warranty expressed or implied. See the file COPYING for details.
+
+# Makefile for Bugs Everywhere project
+
+SHELL = /bin/bash
+PATH = /usr/bin:/bin
+
+# Directories with semantic meaning
+DOC_DIR := doc
+
+# Variables that will be extended by module include files
+GENERATED_FILES :=
+CODE_MODULES :=
+CODE_PROGRAMS :=
+
+# List of modules (directories) that comprise our 'make' project
+MODULES += ${DOC_DIR}
+
+RM = rm
+
+
+.PHONY: all
+all: build
+
+# Include the make data for each module
+include $(patsubst %,%/module.mk,${MODULES})
+
+
+.PHONY: build
+build:
+
+.PHONY: install
+install:
+
+
+.PHONY: clean
+clean:
+ $(RM) -rf ${GENERATED_FILES}
diff --git a/README b/README
index 0cc3c70..b1ba45a 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
Bugs Everywhere
===============
This is Bugs Everywhere, a bugtracker built on distributed revision control.
-It works with Bazaar-NG and Arch at the moment, but is easily extensible. It
+It works with Bazaar and Arch at the moment, but is easily extensible. It
can also function with no RCS at all.
The idea is to package the bug information with the source code, so that
diff --git a/doc/be.1.sgml b/doc/be.1.sgml
new file mode 100644
index 0000000..5e6efc3
--- /dev/null
+++ b/doc/be.1.sgml
@@ -0,0 +1,247 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+
+<!-- Process this file with docbook-to-man to generate an nroff manual
+ page: `docbook-to-man manpage.sgml > manpage.1'. You may view
+ the manual page with: `docbook-to-man manpage.sgml | nroff -man |
+ less'. A typical entry in a Makefile or Makefile.am is:
+
+be.1: be.1.sgml
+ docbook-to-man $< > $@
+
+ The docbook-to-man binary is found in the docbook-to-man package.
+ Please remember that if you create the nroff version in one of the
+ debian/rules file targets (such as build), you will need to include
+ docbook-to-man in your Build-Depends control field.
+
+ -->
+
+ <!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>">
+ <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+ allowed: see man(7), man(1). -->
+ <!ENTITY dhsection "<manvolnum>1</manvolnum>">
+ <!ENTITY dhemail "<email>ben+debian@benfinney.id.au</email>">
+ <!ENTITY dhusername "Ben Finney">
+ <!ENTITY dhucpackage "<refentrytitle>BUGS-EVERYWHERE</refentrytitle>">
+ <!ENTITY dhpackage "bugs-everywhere">
+ <!ENTITY pkgfullname "Bugs Everywhere">
+ <!ENTITY uccmdname "<refentrytitle>BE</refentrytitle>">
+ <!ENTITY cmdname "be">
+
+ <!ENTITY debian "<productname>Debian</productname>">
+ <!ENTITY gnu "<acronym>GNU</acronym>">
+ <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+ <refentryinfo>
+ <address>
+ &dhemail;
+ </address>
+ <author>
+ &dhfirstname;
+ &dhsurname;
+ </author>
+ <copyright>
+ <year>2008</year>
+ <holder>&dhusername;</holder>
+ </copyright>
+ &dhdate;
+ </refentryinfo>
+ <refmeta>
+ &uccmdname;
+
+ &dhsection;
+ </refmeta>
+ <refnamediv>
+ <refname>&cmdname;</refname>
+
+ <refpurpose>distributed bug tracker</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&cmdname;</command>
+ <arg><replaceable>command</replaceable></arg>
+ <arg><replaceable>command_options ...</replaceable></arg>
+ <arg><replaceable>command_args ...</replaceable></arg>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>&cmdname; help</command>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>&cmdname; help</command>
+ <arg><replaceable>command</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This manual page documents briefly the
+ <command>&cmdname;</command> command, part of the
+ &pkgfullname; package.</para>
+
+ <para><command>&cmdname;</command> allows commandline interaction
+ with the &pkgfullname; database in a project tree.</para>
+
+ </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>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>AUTHOR</title>
+
+ <para>This manual page was written by &dhusername; <&dhemail;> for
+ the &debian; system (but may be used by others). Permission is
+ granted to copy, distribute and/or modify this document under
+ the terms of the &gnu; General Public License, Version 2 or any
+ later version published by the Free Software Foundation.
+ </para>
+ <para>
+ On Debian systems, the complete text of the GNU General Public
+ License can be found in /usr/share/common-licenses/GPL.
+ </para>
+
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
diff --git a/doc/module.mk b/doc/module.mk
new file mode 100644
index 0000000..1b365c8
--- /dev/null
+++ b/doc/module.mk
@@ -0,0 +1,31 @@
+# :vim: filetype=make : -*- makefile; coding: utf-8; -*-
+
+# doc/module.mk
+# Part of Bugs Everywhere, a distributed bug tracking system.
+#
+# Copyright © 2008 Ben Finney <ben+python@benfinney.id.au>
+# This is free software; you may copy, modify and/or distribute this work
+# under the terms of the GNU General Public License, version 2 or later.
+# No warranty expressed or implied. See the file COPYING for details.
+
+# Makefile module for documentation
+
+MODULE_DIR := doc
+
+MANPAGES = be.1
+manpage_files = $(patsubst %,${MODULE_DIR}/%,${MANPAGES})
+
+GENERATED_FILES += ${manpage_files}
+
+
+.PHONY: doc
+doc: man
+
+build: doc
+
+
+.PHONY: man
+man: ${manpage_files}
+
+%.1: %.1.sgml
+ docbook-to-man $< > $@
diff --git a/libbe/bugdir.py b/libbe/bugdir.py
index bfe9a27..427ed38 100644
--- a/libbe/bugdir.py
+++ b/libbe/bugdir.py
@@ -141,11 +141,11 @@ class BugDir:
except NoSuchFile:
self.settings = {"rcs_name": "None"}
- rcs_name = setting_property("rcs_name", ("None", "bzr", "Arch", "hg"))
+ rcs_name = setting_property("rcs_name", ("None", "bzr", "git", "Arch", "hg"))
_rcs = None
target = setting_property("target")
-
+
def save_settings(self):
map_save(self.rcs, os.path.join(self.dir, "settings"), self.settings)
diff --git a/libbe/git.py b/libbe/git.py
new file mode 100644
index 0000000..398585f
--- /dev/null
+++ b/libbe/git.py
@@ -0,0 +1,146 @@
+# Copyright (C) 2007 Chris Ball <chris@printf.net>
+#
+# 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
+import os
+import tempfile
+
+from rcs import invoke
+
+def strip_git(filename):
+ # Find the base path of the GIT tree, in order to strip that leading
+ # path from arguments to git -- it doesn't like absolute paths.
+ if os.path.isabs(filename):
+ filename = filename[len(git_repo_for_path('.'))+1:]
+ return filename
+
+def invoke_client(*args, **kwargs):
+ directory = kwargs['directory']
+ expect = kwargs.get('expect', (0, 1))
+ cl_args = ["git"]
+ cl_args.extend(args)
+ status,output,error = invoke(cl_args, expect, cwd=directory)
+ return status, output
+
+def add_id(filename, paranoid=False):
+ filename = strip_git(filename)
+ invoke_client("add", filename, directory=git_repo_for_path('.'))
+
+def delete_id(filename):
+ filename = strip_git(filename)
+ invoke_client("rm", filename, directory=git_repo_for_path('.'))
+
+def mkdir(path, paranoid=False):
+ os.mkdir(path)
+
+def set_file_contents(path, contents):
+ add = not os.path.exists(path)
+ file(path, "wb").write(contents)
+ if add:
+ add_id(path)
+
+def detect(path):
+ """Detect whether a directory is revision-controlled using GIT"""
+ path = os.path.realpath(path)
+ old_path = None
+ while True:
+ if os.path.exists(os.path.join(path, ".git")):
+ return True
+ if path == old_path:
+ return False
+ old_path = path
+ path = os.path.dirname(path)
+
+def precommit(directory):
+ pass
+
+def commit(directory, summary, body=None):
+ if body is not None:
+ summary += '\n' + body
+ descriptor, filename = tempfile.mkstemp()
+ try:
+ temp_file = os.fdopen(descriptor, 'wb')
+ temp_file.write(summary)
+ temp_file.close()
+ invoke_client('commit', '-a', '-F', filename, directory=directory)
+ finally:
+ os.unlink(filename)
+
+def postcommit(directory):
+ pass
+
+
+# In order to diff the bug database, you need a way to check out arbitrary
+# previous revisions and a mechanism for locating the bug_dir in the revision
+# you've checked out.
+#
+# Copying the Mercurial implementation, this feature is implemented by four
+# functions:
+#
+# git_dir_for_path : find '.git' for a git tree.
+#
+# export : check out a commit 'spec' from git-repo 'bug_dir' into a dir
+# 'revision_dir'
+#
+# find_or_make_export : check out a commit 'spec' from git repo 'directory' to
+# any location you please and return the path to the checkout
+#
+# path_in_reference : return a path to the bug_dir of the commit 'spec'
+
+def git_repo_for_path(path):
+ """Find the root of the deepest repository containing path."""
+ # Assume that nothing funny is going on; in particular, that we aren't
+ # dealing with a bare repo.
+ return os.path.dirname(git_dir_for_path(path))
+
+def git_dir_for_path(path):
+ """Find the git-dir of the deepest repo containing path."""
+ return invoke_client("rev-parse", "--git-dir", directory=path)[1].rstrip()
+
+def export(spec, bug_dir, revision_dir):
+ """Check out commit 'spec' from the git repo containing bug_dir into
+ 'revision_dir'."""
+ if not os.path.exists(revision_dir):
+ os.makedirs(revision_dir)
+ invoke_client("init", directory=revision_dir)
+ invoke_client("pull", git_dir_for_path(bug_dir), directory=revision_dir)
+ invoke_client("checkout", '-f', spec, directory=revision_dir)
+
+def find_or_make_export(spec, directory):
+ """Checkout 'spec' from the repo at 'directory' by hook or by crook and
+ return the path to the working copy."""
+ home = os.path.expanduser("~")
+ revision_root = os.path.join(home, ".be_revs")
+ if not os.path.exists(revision_root):
+ os.mkdir(revision_root)
+ revision_dir = os.path.join(revision_root, spec)
+ if not os.path.exists(revision_dir):
+ export(spec, directory, revision_dir)
+ return revision_dir
+
+def path_in_reference(bug_dir, spec):
+ """Check out 'spec' and return the path to its bug_dir."""
+ spec = spec or 'HEAD'
+ spec = invoke_client('rev-parse', spec, directory=bug_dir)[1].rstrip()
+ # This is a really hairy computation.
+ # The theory is that we can't possibly be working out of a bare repo;
+ # hence, we get the rel_bug_dir by chopping off dirname(git_dir_for_path(bug_dir))
+ # + '/'.
+ rel_bug_dir = strip_git(bug_dir)
+ export_root = find_or_make_export(spec, directory=bug_dir)
+ return os.path.join(export_root, rel_bug_dir)
+
+
+name = "git"
+
diff --git a/libbe/rcs.py b/libbe/rcs.py
index 64503db..77d6c9a 100644
--- a/libbe/rcs.py
+++ b/libbe/rcs.py
@@ -28,6 +28,9 @@ def rcs_by_name(rcs_name):
elif rcs_name == "hg":
import hg
return hg
+ elif rcs_name == "git":
+ import git
+ return git
elif rcs_name == "None":
import no_rcs
return no_rcs
@@ -37,12 +40,15 @@ def detect(dir):
import arch
import bzr
import hg
+ import git
if arch.detect(dir):
return arch
elif bzr.detect(dir):
return bzr
elif hg.detect(dir):
return hg
+ elif git.detect(dir):
+ return git
import no_rcs
return no_rcs
diff --git a/setup.py b/setup.py
index 7c4c98a..b909f3f 100644..100755
--- a/setup.py
+++ b/setup.py
@@ -9,4 +9,7 @@ setup(
url='http://panoramicfeedback.com/opensource/',
packages=['becommands', 'libbe'],
scripts=['be'],
+ data_files=[
+ ('share/man/man1', ['doc/be.1']),
+ ]
)