1. Steve Losh
  2. hg-review

Commits

Steve Losh  committed d0665ea Merge

Merge documentation.

  • Participants
  • Parent commits cde269f, 466feb8
  • Branches default
  • Tags semver, v0.9.0

Comments (0)

Files changed (19)

File LICENSE

View file
+            GNU GENERAL PUBLIC LICENSE
+               Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+            GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+             END OF TERMS AND CONDITIONS
+
+        How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+

File docs/Makefile

View file
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html      to make standalone HTML files"
+	@echo "  dirhtml   to make HTML files named index.html in directories"
+	@echo "  pickle    to make pickle files"
+	@echo "  json      to make JSON files"
+	@echo "  htmlhelp  to make HTML files and a HTML help project"
+	@echo "  qthelp    to make HTML files and a qthelp project"
+	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  changes   to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck to check all external links for integrity"
+	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/hg-review.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/hg-review.qhc"
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
+	      "run these through (pdf)latex."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."

File docs/api.rst

View file
+API
+===
+
+hg-review takes Mercurial's approach to API stability:
+
+* The command line interface is fairly stable and will not break often.
+* File formats will not change often.
+* The internal implementation may change frequently -- there are no guarantees
+  of stability.
+
+Providing a stable CLI means that (possibly non-GPL) programs can interact with
+hg-review easily without fear of constant breaking.
+
+Stable file formats mean that older versions of hg-review will be able to work
+with review data from newer versions (albeit with reduced functionality).
+
+*Not* providing a stable internal implementation allows hg-review's code to be
+kept clean and elegant. It means that Python programs will needs to use
+subprocesses to avoid breaking, but this is a tradeoff that the author feels is
+worth making.
+
+Data Repository Layout
+----------------------
+
+The structure of hg-review's data repository looks like this::
+
+    your-project/
+    |
+    +-- .hg/
+    |   |
+    |   +-- review
+    |   |   |
+    |   |   +-- {{ changeset hash }}
+    |   |   |   |
+    |   |   |   +-- .exists
+    |   |   |   |
+    |   |   |   +-- comments
+    |   |   |   |   |
+    |   |   |   |   +-- {{ comment hash }}
+    |   |   |   |   |
+    |   |   |   |   `-- other comments...
+    |   |   |   |
+    |   |   |   +-- signoffs
+    |   |   |       |
+    |   |   |       +-- {{ signoff hash }}
+    |   |   |       |
+    |   |   |       `-- other signoffs ...
+    |   |   |
+    |   |   `-- other changesets ...
+    |   |
+    |   `-- other files ...
+    |
+    `-- other files ...
+
+All review data for a changeset is stored in::
+
+    .hg/review/{{ changeset hash }}/
+
+A ``.exists`` file is included in that directory when code review for
+that changeset is initialized. This allows us to check if a given changeset has
+been initialized for code review very quickly.
+
+Comments for a changeset are stored in::
+
+    .hg/review/{{ changeset hash }}/comments/{{ comment hash }}
+
+Signoffs for a changeset are stored in::
+
+    .hg/review/{{ changeset hash }}/signoffs/{{ signoff hash }}
+
+File Formats
+------------
+
+hg-review's file format is (fairly) stable and is designed to be easily parsed
+to enable export to other code review systems.
+
+Comment and signoff files are stored as JSON. The files are indented four
+spaces per level to make them more human-readable.
+
+``.exists`` Files
+'''''''''''''''''
+
+The ``.exists`` file is always empty. It simply exists to make looking up
+whether a given changeset has been initialized faster. It may go away in the
+future -- do not depend on it.
+
+Comment Files
+'''''''''''''
+
+Here is a sample comment file::
+
+    {
+        "author": "Steve Losh <steve@stevelosh.com>", 
+        "file": [
+            "reykjavi\u0301k.txt", 
+            "cmV5YWphdmnMgWsudHh0"
+        ], 
+        "hgdate": "Mon Jul 12 23:55:51 2010 -0400", 
+        "lines": [
+            0
+        ], 
+        "message": "Sample.", 
+        "node": "0e987f91e9b6628b26a30c5d00668a15fae8f22f", 
+        "style": "markdown"
+    }
+
+Comment files have some or all of the following fields:
+
+``author``
+    The Mercurial username of the person that added this comment.
+
+``file``
+    A list of two strings. The first string is a (JSON-encoded) representation
+    of the UTF-8 filename. The second string is a base64 encoded version of the
+    actual bytes of the filename (which is what Mercurial gives and expects to
+    receive internally). If this is a review-level comment both strings will be
+    blank.
+
+``hgdate``
+    The date and time the comment was added (or last edited).
+
+``lines``
+    A list of integers representing the lines of the file that this comment
+    applies to. If this is a file-level or review-level comment the list will
+    be empty.
+
+``message``
+    A string representing the raw comment message.
+
+``node``
+    A string representing the hash of the changset this comment belongs to, for
+    easy lookup later.
+
+``style``
+    A string representing the style of this comment -- this will be
+    ``markdown`` for Markdown comments and blank for plain-text comments. More
+    styles may be added in the future.
+
+Signoff Files
+'''''''''''''
+
+Here is a sample signoff file::
+
+    {
+        "author": "Steve Losh <steve@stevelosh.com>", 
+        "hgdate": "Tue Jul 13 00:16:00 2010 -0400", 
+        "message": "Sample.", 
+        "node": "0e987f91e9b6628b26a30c5d00668a15fae8f22f", 
+        "opinion": "yes", 
+        "style": "markdown"
+    }
+
+Signoff files have some or all of the following fields:
+
+``author``
+    The Mercurial username of the person that added this comment.
+
+``hgdate``
+    The date and time the comment was added (or last edited).
+
+``message``
+    A string representing the raw comment message.
+
+``node``
+    A string representing the hash of the changset this comment belongs to, for
+    easy lookup later.
+
+``opinion``
+    A string representing the signoff opinion. This will be ``yes``, ``no``, or
+    a blank string (for a neutral signoff).
+
+``style``
+    A string representing the style of this comment -- this will be
+    ``markdown`` for Markdown comments and blank for plain-text comments. More
+    styles may be added in the future.
+
+Command Line Interface
+----------------------
+
+hg-review's command line interface is (fairly) stable. If you want to interact
+with review data for a repository this is the safest method to use.
+
+See the :doc:`command line interface documentation </cli>` for more details.
+
+Internal Python API
+-------------------
+
+hg-review's internal Python implementation is *not* stable. It may change at
+any time. Relying on it virtually guarantees your application will break at
+some point.
+
+For a more stable API you should use the command line interface.
+
+The Python API will be documented later, but is not a high priority at the
+moment because of its volatility.

File docs/cli.rst

View file
+Command Line Interface
+======================
+
+hg-review provides a command line interface. Except for initializing the review
+data, starting the web ui, and possibly some scripting, you'll probably want to
+use the :doc:`web interface </webui>` for most tasks.
+
+When you enable the hg-review extension Mercurial will gain a new command:
+``review``. This command on its own will display review data for a changeset,
+but it also has several subcommands detailed below.
+
+You can always get help on a given topic right from the command line with
+``hg help review`` or ``hg help review-topic``.
+
+.. _c-review:
+
+``review``
+----------
+
+View code review data for a changeset. Usage::
+
+    hg review [-r REV] [-U CONTEXT] [--quiet] [FILE]
+
+Diffs of all changed files will be shown with comments inline.
+
+The line numbers printed are the ones that should be used to add line-level
+comments.
+
+Options:
+
+``--unified VALUE``
+    The number of lines of context to show for diffs in this changeset
+    (default: ``5``).
+
+``--rev VALUE``
+    The revision to show (default: ``.``).
+
+``--quiet``
+    Do not show diffs -- only show review-level comments and signoffs (default:
+    ``false``).
+
+``--verbose``
+    Show the short identifier of each comment and signoff, mainly for use with
+    the :ref:`edit <c-edit>` subcommand (default: ``false``).
+
+``--debug``
+    Show the full identifier of each comment and signoff, mainly for use with
+    the :ref:`edit <c-edit>` subcommand (default: ``false``).
+
+.. _c-init:
+
+``--init``
+----------
+
+Initialize code review for a repository. Usage::
+
+    hg review --init --remote-path PATH
+
+When run for the first time in a project, it will do two things:
+
+* Create a new repository to hold the review data at ``.hg/review/``.
+
+* Create and ``hg add`` a ``.hgreview`` file in the current repository. You
+  will need to commit this file yourself with: ``hg commmit .hgreview -m
+  'initialize code review data'``
+
+The ``--remote-path`` option is required and specifies the path where the
+canonical code review data for this project will live.  This is the path that
+will be cloned when someone else runs ``hg review --init`` on the project.
+
+Options:
+
+``--remote-path VALUE``
+    The URL to the public code review data repository.
+
+
+.. _c-comment:
+
+``--comment``
+-------------
+
+Add a code review comment for a changeset. Usage::
+
+    hg review --comment [-m MESSAGE] [--mdown] [-r REV] [-l LINES] [FILE]
+
+If no files are given the comment will be attached to the changeset as a whole.
+
+If one or more files are given but no lines are given, the comment will be
+attached to each file as a whole.
+
+If a file is given and lines are given the comment will be attached to those
+specific lines. Lines should be specified as a comma-separated list of line
+numbers (as numbered in the output of "hg review"), such as ``3`` or ``2,3``.
+
+Options:
+
+``--rev VALUE``
+    The revision to add a comment to (default: ``.``).
+
+``--lines VALUE``
+    Comment on the given lines (specified as a comma-separated list of line
+    numbers) of the file (default: ``None``).
+
+``--message VALUE``
+    Use ``VALUE`` as the comment instead of opening an editor (default:
+    ``None`` (i.e. "open an editor")).
+
+``--mdown``
+    Use Markdown to format the comment (default: ``False``).
+
+
+.. _c-signoff:
+
+``--signoff``
+-------------
+
+Add a code review signoff for a changeset. Usage::
+
+    hg review --signoff [-m MESSAGE] [--mdown] [--yes | --no] [-r REV]
+
+The ``--yes`` and ``--no`` options can be used to indicate whether you think the
+changeset is "good" or "bad".
+
+It's up to the collaborators of each individual project to decide exactly what
+that means.  If neither option is given the signoff will be marked as
+"neutral".
+
+Options:
+
+``--rev VALUE``
+    The revision to sign off on (default: ``.``).
+
+``--yes``
+    Sign off as "yes" for the changeset (default: ``False`` (i.e. "neutral")).
+
+``--no``
+    Sign off as "no" for the changeset (default: ``False`` (i.e. "neutral")).
+
+``--message VALUE``
+    Use ``VALUE`` as the signoff message instead of opening an editor (default:
+    ``None`` (i.e. "open an editor")).
+
+``--mdown``
+    Use Markdown to format the signoff message (default: ``False``).
+
+
+.. _c-edit:
+
+``--edit``
+----------
+
+Edit a comment or signoff. Usage::
+
+    hg review --edit IDENTIFIER [--yes | --no] [-m MESSAGE] [-l LINES] [--mdown] [FILE]
+
+Edit the comment or changeset with the given identifier.
+
+You can find the identifier of the item you would like to edit by running ``hg
+review --verbose`` to display identifiers.
+
+Any other options given (such as ``--message``, ``--yes`` or filenames) will
+replace the content of the item you edit.
+
+``--message VALUE``
+    Replace the comment or signoff message with VALUE (default: ``None`` (i.e.
+    "open an editor")).
+
+``--mdown``
+    Use Markdown to format the comment or signoff message (default: ``False``
+    (i.e. "Use the same formatting the item already has)).
+
+``--lines``
+    The line(s) of the file to comment on (default: ``None`` (i.e. "use the
+    same line the comment already has)). Returns an error if you're editing
+    a signoff or a review-level comment.
+
+``--yes``
+    Change the signoff to state the the changeset is "good" (default:
+    ``False``). Returns an error if you are not editing a signoff.
+
+``--no``
+    Change the signoff to state the the changeset is "bad" (default:
+    ``False``). Returns an error if you are not editing a signoff.
+
+
+.. _c-check:
+
+``--check``
+-----------
+
+Check the review status of a changeset. Usage::
+
+    hg review --check [-r REV] [--no-nos] [--yeses NUM] [--seen]
+
+Check that the given changeset "passes" the given tests of review status. If no
+tests are given an error is returned.
+
+Tests are checked in the following order:
+
+- ``--no-nos``
+- ``--yeses``
+- ``--seen``
+
+If any tests fail the command returns a status of 1 with a message describing
+the failure on stderr, otherwise it returns 0 and prints nothing.
+
+``--rev VALUE``
+    The revision to check (default: ``.``).
+
+``--no-nos``
+    Ensure this revision does *not* have any signoffs of "no" (default:
+    ``False`` (i.e. "Don't perform this check")).
+
+``--yeses VALUE``
+    Ensure this revision has at least ``VALUE`` signoffs of "yes" (default:
+    ``None`` (i.e. "Don't perform this check").
+
+``--seen``
+    Ensure this revision has at least one comment or signoff (default:
+    ``False`` (i.e. "Don't perform this check")).
+
+
+.. _c-web:
+
+``--web``
+---------
+
+Start the web interface. Usage::
+
+    hg review --web [--read-only] [--allow-anon] [--address ADDRESS] [--port PORT]
+
+Visit http://localhost:8080/ (replace the port number if you specified
+a different port) in a modern browser of your choice to use the web interface.
+
+Use ``Ctrl+C`` to stop the interface.
+
+Options:
+
+``--read-only``
+    Make the web interface read-only; disallowing comments, signoffs, pushes
+    and pulls (default: ``False``).
+
+``--allow-anon``
+    Allow anonymous comments on the web interface and set the username for
+    comments to an anonymous username (default: ``False`` (i.e. allow comments
+    and use your Mercurial username)).
+
+``--address VALUE``
+    Run the web interface on the specified address (default: ``127.0.0.1``).
+
+``--port VALUE``
+    Run the web interface on the specified port (default: ``8080``).
+

File docs/concepts.rst

View file
+Concepts
+========
+
+You're not perfect.
+
+Your code is not perfect.
+
+If you're the only person that's reading your code, it's wrong.
+
+As developers we need to review each other's code. This helps us catch errors
+before they find our users. It also makes us take greater care when writing
+code because we know someone will be looking at it.
+
+Code Review Basics
+------------------
+
+The simplest form of code review is asking a friend to look at the code you
+just wrote. Often a second set of eyes can find problems you might not have
+seen, especially if that person has more experience than you.
+
+Unfortunately this isn't always practical. You might work remotely with people
+thousands of miles away and not have a chance to simply turn around and say:
+"Hey, could you look at this?"
+
+Code review tools (like hg-review) exist to make reviewing other people's code
+easier.
+
+Their goal is to make it as easy as possible to tell another developer: "No,
+you did *this* wrong.  Fix it."
+
+Other Code Review Tools
+-----------------------
+
+There are a lot of "code review tools" out there. 
+
+The primary author of hg-review has a lot of experience with `Atlassian
+Crucible <http://www.atlassian.com/software/crucible/>`_, but some other
+popular tools include:
+
+* `Rietveld <http://codereview.appspot.com/>`_
+* `Reviewboard <http://www.reviewboard.org/>`_
+* `Gerrit <http://code.google.com/p/gerrit/>`_
+* `Code Collaborator <http://smartbear.com/codecollab.php>`_
+
+All of these tools try to accomplish the same goal: making it easy for
+developers to tell each other how to write better code.
+
+hg-review has the same goal, but it goes about it a little differently.
+
+Distributed Code Review
+-----------------------
+
+Let's back up for just a second and talk about version control. Some of the
+most popular version control systems a few years ago were *centralized* systems
+like `Subversion <http://subversion.apache.org/>`_ and
+`CVS <http://www.nongnu.org/cvs/>`_.
+
+With these systems you had a central server that contained all the history of
+your project. You would push changes to this central server and it would store
+them.
+
+In the past half-decade or so there has been a move toward *decentralized* or
+*distributed* version control systems. With these systems you commit to your
+local machine and then *push* and *pull* your commits to other people.
+
+Code review tools, however, seem to have remained rooted in the "centralized
+server" approach.  Even the tools that support decentralized version control
+systems like `git <http://git-scm.com>`_ and `Mercurial <http://hg-scm.org>`_
+rely on a central server to store the code review data.
+
+hg-review does away with the "centralized data store" model and embraces
+Mercurial's distributed nature. Code review data is held in a normal Mercurial
+repository and can be pushed and pulled like any other type of data.
+
+This has several advantages, the biggest one being that you can review code
+while offline without sacrificing any functionality.
+
+It also means that the full power of Mercurial (such as tracking history and
+signing changesets with GPG) can be used on the review data.
+
+Review Data
+-----------
+
+hg-review tracks two kinds of code review data: comments and signoffs.
+
+Comments are simple comments that people make about changesets. People can
+comment on:
+
+* A changeset as a whole.
+* A specific file within a changeset.
+* One or more lines of a specific file within a changeset.
+
+Signoffs, on the other hand, *always* apply to a changeset as a whole. Each
+person can have one signoff for any particular changeset (though they can edit
+their signoff later).
+
+Signoffs can be used for whatever purpose your project might find useful, but
+the author of hg-review recommends that signoffs of "yes" mean:
+
+    I approve of this changeset and think it should make its way to production.
+
+And signoffs of "No" mean:
+
+    I do not approve of this changeset and do not think it should make its way to
+    production without another changeset on top of it that fixes the problems
+    I have listed.
+
+Signoffs of "neutral" might mean:
+
+    This changeset doesn't really impact me, so I don't care.
+
+Or perhaps:
+
+    I've looked at this code but don't have the expertise to provide a useful
+    opinion.
+
+
+Repository Structure
+--------------------
+
+While it's not necessary to know exactly how the guts of hg-review work, it
+*is* helpful to understand the basic idea behind it.
+
+Let's say you have a project with a Mercurial repository in
+``~/src/yourproject/`` and you'd like to start using hg-review with it.
+
+The first thing to understand is that Mercurial stores data about this local
+repository in ``~/src/yourproject/.hg/``, and that data is local to your
+machine. It is never committed or tracked by Mercurial, but is instead used by
+the Mercurial program itself to work with your repository.
+
+hg-review creates a *separate* Mercurial repository to keep track of its data.
+It stores this repository in ``~/src/yourproject/.hg/review/``.
+
+Because this is inside of Mercurial's internal ``.hg`` directory of your
+project changes to the review data (like comments and signoffs) won't be
+tracked in your project's repository.
+
+hg-review manages its own data in its own repository to avoid cluttering up
+your project's log with useless "added a comment"-type commits.
+
+This structure means that you can ``cd`` into the review data repository itself
+and interact with it just as you would a normal Mercurial repository. You can
+``push`` and ``pull`` to and from other people, backout changesets and do
+anything else you could with a normal Mercurial repository.

File docs/conf.py

View file
+# -*- coding: utf-8 -*-
+#
+# hg-review documentation build configuration file, created by
+# sphinx-quickstart on Mon Jun 14 20:39:45 2010.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'hg-review'
+copyright = u'2010, Steve Losh and contributors'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = 'pre-alpha'
+# The full version, including alpha/beta/rc tags.
+release = 'pre-alpha'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme_path = ['.']
+html_theme = 'hgreview'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'hg-reviewdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'hg-review.tex', u'hg-review Documentation',
+   u'Steve Losh', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True

File docs/hacking.rst

View file
+Hacking hg-review
+=================
+
+Want to improve hg-review? Great!
+
+The easiest way is to make some changes, push them somewhere public and send
+a pull request on Bitbucket (or `email Steve <mailto:steve@stevelosh.com>`_).
+
+Rough Guidelines
+----------------
+
+Here's a few tips that will make hg-review's maintainer happier.
+
+Basic Coding Style
+''''''''''''''''''
+
+Keep lines of code under 85 characters, unless it makes things *really* ugly.
+
+Indentation is four spaces. Tabs are evil.
+
+Commit Messages
+'''''''''''''''
+
+Commit messages should start with a line like::
+
+    api: add feature X
+
+The first part is the component the change affects, like ``api``, ``cli``,
+``web``, ``docs/api``, or ``guts``.
+
+``guts`` is a catchall for changesets that affect everything at once -- using
+it means that the changeset could probably be split up into separate smallet
+changesets.
+
+The rest of the commit message should describe the change.
+
+Tests
+'''''
+
+Update the tests *in the same changeset as your change*.  This makes bisection
+by running the test suite easier.
+
+If your changeset changes the CLI output, make sure you've read the next
+section and then add a test for it *in the same changeset*.
+
+If your changeset adds a new feature, add a test for it *in the same
+changeset*.
+
+If your changeset fixes a bug, add a test that would reproduce the bug *in the
+same changeset*.
+
+Backwards Compatibility
+'''''''''''''''''''''''
+
+hg-review's internal implementation is not stable. Feel free to modify it
+however you like. Patches that clean up the code and/or enhance performance
+will be gladly accepted.
+
+hg-review's file format is stable, but new fields may be added at any time.
+Removing a field or changing its format is not allowed without a very good
+reason. Adding an entirely new file format may be acceptable if there is
+a compelling reason.
+
+hg-review's command line interface is stable. Adding new commands or adding new
+options to existing commands is fine if they prove useful. Removing commands or
+radically changing the default output of existing commands is not acceptable
+except in extreme cases.
+
+hg-review is currently compatible with Python 2.5+ and Mercurial 1.6+. Patches
+that break this compatibility will be met with a large dose of skepticism.
+
+Layout
+------
+
+hg-review's basic structure looks like this::
+
+    hg-review/
+    |
+    +-- bundled/
+    |   |
+    |   `-- ... bundled third-party modules ...
+    |
+    +-- contrib/
+    |   |
+    |   `-- ... useful items not critical to hg-review's core ...
+    |
+    +-- docs/
+    |   |
+    |   `-- ... the documentation (and theme) ...
+    |
+    +-- review/
+    |   |
+    |   +-- static/
+    |   |   |
+    |   |   `-- ... static media for the web ui ...
+    |   |
+    |   +-- templates/
+    |   |   |
+    |   |   `-- ... jinja2 templates for the web ui ...
+    |   |
+    |   +-- tests/
+    |   |   |
+    |   |   ` ... unit test files and accompanying utilities ...
+    |   |
+    |   +-- api.py          # the core hg-review backend
+    |   |
+    |   +-- cli.py          # the hg-review Mercurial extension CLI
+    |   |
+    |   +-- messages.py     # messages used by the CLI
+    |   |
+    |   +-- helps.py        # help text for the CLI commands
+    |   |
+    |   +-- rutil.py        # useful utilities
+    |   |
+    |   `-- web.py          # the web interface
+    |
+    +-- README.markdown
+    |
+    +-- LICENSE
+    |
+    +-- fabfile.py
+    |
+    `-- kick.py
+
+Testing
+-------
+
+hg-review contains a test suite for the command line interface (and therefore
+the backend API as well).
+
+The tests can be run easily with nose. If you don't have node, you'll need to
+install it first::
+
+    pip install nose
+
+Once you've got it you can run the suite by cd'ing to the hg-review directory
+and running ``nosetests``.
+
+Before submitting a changeset please make sure it doesn't break any tests.
+
+If your changeset adds a new feature, add a test for it *in the same
+changeset*.
+
+If your changeset fixes a bug, add a test that would reproduce the bug *in the
+same changeset*.
+
+Documentation
+-------------
+
+If you want to submit a patch, please update the documentation to reflect your
+change (if necessary) *in the same changeset*.
+
+The documentation is formatted as restructured text and built with Sphinx
+(version 0.6.7).
+
+The CSS for the documentation is written with LessCSS.  If you want to update
+the style you should update the ``docs/hgreview/static/review.less`` file and
+render it to CSS. Include the changes to the ``.less`` file *and* the ``.css``
+file in your changeset.

File docs/hgreview/static/aal.css

View file
+/* 
+  aardvark.legs by Anatoli Papirovski - http://fecklessmind.com/
+  Licensed under the MIT license. http://www.opensource.org/licenses/mit-license.php
+*/
+
+/* 
+  Reset first. Modified version of Eric Meyer and Paul Chaplin reset 
+  from http://meyerweb.com/eric/tools/css/reset/ 
+*/
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+header, nav, section, article, aside, footer
+{border: 0; margin: 0; outline: 0; padding: 0; background: transparent; vertical-align: baseline;}
+
+blockquote, q {quotes: none;}
+blockquote:before,blockquote:after,q:before,q:after {content: ''; content: none;}
+
+header, nav, section, article, aside, footer {display: block;}
+
+/* Basic styles */
+body {background: #fff; color: #111; font: 1em/1.5em "Helvetica Neue", Helvetica, Arial, "Liberation Sans", "Bitstream Vera Sans", sans-serif;}
+html>body {font-size: 16px;}
+
+img {display: inline-block; vertical-align: bottom;}
+
+h1,h2,h3,h4,h5,h6,strong,b,dt,th {font-weight: 700;}
+address,cite,em,i,caption,dfn,var {font-style: italic;}
+
+h1 {margin: 0 0 0.75em; font-size: 2em;}
+h2 {margin: 0 0 1em; font-size: 1.5em;}
+h3 {margin: 0 0 1.286em; font-size: 1.167em;}
+h4 {margin: 0 0 1.5em; font-size: 1em;}
+h5 {margin: 0 0 1.8em; font-size: .834em;}
+h6 {margin: 0 0 2em; font-size: .75em;}
+
+p,ul,ol,dl,blockquote,pre {margin: 0 0 1.5em;}
+
+li ul,li ol {margin: 0;}
+ul {list-style: outside disc;}
+ol {list-style: outside decimal;}
+li {margin: 0 0 0 2em;}
+dd {padding-left: 1.5em;}
+blockquote {padding: 0 1.5em;}
+
+a {text-decoration: underline;}
+a:hover {text-decoration: none;}
+abbr,acronym {border-bottom: 1px dotted; cursor: help;}
+del {text-decoration: line-through;}
+ins {text-decoration: overline;}
+sub {font-size: .834em; line-height: 1em; vertical-align: sub;}
+sup {font-size: .834em; line-height: 1em; vertical-align: super;}
+
+tt,code,kbd,samp,pre {font-size: 1em; font-family: Consolas, Monaco, "Courier New", Courier, monospace;}
+
+/* Table styles */
+table {border-collapse: collapse; border-spacing: 0; margin: 0 0 1.5em;}
+caption {text-align: left;}
+th, td {padding: .25em .5em;}
+tbody td, tbody th {border: 1px solid #000;}
+tfoot {font-style: italic;}
+
+/* Form styles */
+fieldset {clear: both;}
+legend {padding: 0 0 1.286em; font-size: 1.167em; font-weight: 700;}
+fieldset fieldset legend {padding: 0 0 1.5em; font-size: 1em;}
+* html legend {margin-left: -7px;}
+*+html legend {margin-left: -7px;}
+
+form .field, form .buttons {clear: both; margin: 0 0 1.5em;}
+form .field label {display: block;}
+form ul.fields li {list-style-type: none; margin: 0;}
+form ul.inline li, form ul.inline label {display: inline;}
+form ul.inline li {padding: 0 .75em 0 0;}
+
+input.radio, input.checkbox {vertical-align: top;}
+label, button, input.submit, input.image {cursor: pointer;}
+* html input.radio, * html input.checkbox {vertical-align: middle;}
+*+html input.radio, *+html input.checkbox {vertical-align: middle;}
+
+textarea {overflow: auto;}
+input.text, input.password, textarea, select {margin: 0; font: 1em/1.3 Helvetica, Arial, "Liberation Sans", "Bitstream Vera Sans", sans-serif; vertical-align: baseline;}
+input.text, input.password, textarea {border: 1px solid #444; border-bottom-color: #666; border-right-color: #666; padding: 2px;}
+
+* html button {margin: 0 .34em 0 0;}
+*+html button {margin: 0 .34em 0 0;}
+
+form.horizontal .field {padding-left: 150px;}
+form.horizontal .field label {display: inline; float: left; width: 140px; margin-left: -150px;}
+
+/* Useful classes */
+img.left {display: inline; float: left; margin: 0 1.5em .75em 0;}
+img.right {display: inline; float: right; margin: 0 0 .75em .75em;}

File docs/hgreview/static/review.css

View file
+@import url("aal.css");
+body, html {
+  background-color: #f8f7e8;
+  font-family: Georgia, serif;
+  color: #222;
+}
+body a, html a {
+  color: #b6410c;
+  text-decoration: none;
+}
+body a:hover, html a:hover {
+  text-decoration: underline;
+}
+body a.headerlink, html a.headerlink {
+  display: none;
+}
+body h1,
+html h1,
+body h2,
+html h2,
+body h3,
+html h3,
+body h4,
+html h4,
+body h5,
+html h5,
+body h6,
+html h6 {
+  font-weight: normal;
+}
+body h1, html h1 {
+  letter-spacing: 1px;
+}
+body ul, html ul {
+  list-style-type: none;
+}
+body ul li, html ul li {
+  margin-left: 0;
+}
+body ul li li, html ul li li {
+  margin-left: 1em;
+}
+.related {
+  display: none;
+}
+.document {
+  -webkit-border-radius: 8px;
+  -moz-border-radius: 8px;
+  border-radius: 8px;
+  border: 1px solid #edecc7;
+  margin: 25px auto 0px;
+  padding: 0px 00px;
+  width: 840px;
+}
+.document .documentwrapper {
+  -webkit-border-radius: 8px;
+  -moz-border-radius: 8px;
+  border-radius: 8px;
+  background-color: #fbfbf3;
+  float: left;
+  width: 100%;
+}
+.document .documentwrapper .bodywrapper {
+  -webkit-border-radius: 8px;
+  -moz-border-radius: 8px;
+  border-radius: 8px;
+  background-color: #fefefe;
+  margin-left: 230px;
+  border-left: 1px solid #edecc7;
+  padding: 20px 30px;
+  min-height: 700px;
+}
+.document .documentwrapper .bodywrapper div pre {
+  border: 1px solid #edecc7;
+  border-right: none;
+  background-color: #fbfbf3;
+  background-color: #f8f7e8;
+  font-size: 13px;
+  font-family: Monaco, Consolas, "Courier New", monospace;
+  line-height: 16px;
+  margin-bottom: 32px;
+  margin-top: -8px;
+  margin-left: 25px;
+  padding: 6px 8px;
+  width: 538px;
+  overflow-x: auto;
+}
+.document .documentwrapper .bodywrapper span.pre {
+  background-color: #fafaef;
+  border: 1px solid #edecc7;
+  padding: 0px 6px;
+  font-size: 13px;
+  font-family: Monaco, Consolas, "Courier New", monospace;
+  line-height: 24px;
+  white-space: pre;
+}
+.document .documentwrapper .bodywrapper ul {
+  list-style-type: disc;
+}
+.document .documentwrapper .bodywrapper ul li {
+  margin-left: 44px;
+}
+.document .documentwrapper .bodywrapper ul span.pre {
+  background-color: inherit;
+  border: none;
+  padding: 0;
+}
+.document .documentwrapper .bodywrapper ul li.toctree-l1 {
+  list-style-type: none;
+  margin-left: 0;
+}
+.document .documentwrapper .bodywrapper ul li.toctree-l2, .document .documentwrapper .bodywrapper ul li.toctree-l3 {
+  list-style-type: none;
+  margin-left: 30px;
+}
+.document .documentwrapper .bodywrapper a em {
+  font-style: normal;
+}
+.document .documentwrapper .bodywrapper tt.docutils.literal {
+  background-color: #fafaef;
+  border: 1px solid #edecc7;
+  padding: 0px 6px;
+  font-size: 13px;
+  font-family: Monaco, Consolas, "Courier New", monospace;
+  line-height: 24px;
+  white-space: pre;
+}
+.document .documentwrapper .bodywrapper tt.docutils.literal span.pre {
+  border: 0;
+  padding: 0;
+}
+.document .documentwrapper .bodywrapper .clear-code-effects {
+  border: none;
+  background: none;
+  padding: 0;
+  line-height: 1;
+}
+.document .documentwrapper .bodywrapper h1 tt.docutils.literal span.pre {
+  margin: 0 0 0.75em;
+  font-size: 2em;
+}
+.document .documentwrapper .bodywrapper h2 tt.docutils.literal span.pre {
+  margin: 0 0 1em;
+  font-size: 1.5em;
+}
+.document .documentwrapper .bodywrapper h3 tt.docutils.literal span.pre {
+  margin: 0 0 1.286em;
+  font-size: 1.167em;
+}
+.document .documentwrapper .bodywrapper h4 tt.docutils.literal span.pre {
+  margin: 0 0 1.5em;
+  font-size: 1em;
+}
+.document .documentwrapper .bodywrapper h5 tt.docutils.literal span.pre {
+  margin: 0 0 1.8em;
+  font-size: .834em;
+}
+.document .documentwrapper .bodywrapper h6 tt.docutils.literal span.pre {
+  margin: 0 0 2em;
+  font-size: .75em;
+}
+.document .documentwrapper .bodywrapper h1 tt.docutils.literal,
+.document .documentwrapper .bodywrapper h2 tt.docutils.literal,
+.document .documentwrapper .bodywrapper h3 tt.docutils.literal,
+.document .documentwrapper .bodywrapper h4 tt.docutils.literal,
+.document .documentwrapper .bodywrapper h5 tt.docutils.literal,
+.document .documentwrapper .bodywrapper h6 tt.docutils.literal {
+  border: none;
+  background: none;
+  padding: 0;
+  line-height: 1;
+}
+.document .documentwrapper .bodywrapper h1 tt.docutils.literal span.pre,
+.document .documentwrapper .bodywrapper h2 tt.docutils.literal span.pre,
+.document .documentwrapper .bodywrapper h3 tt.docutils.literal span.pre,
+.document .documentwrapper .bodywrapper h4 tt.docutils.literal span.pre,
+.document .documentwrapper .bodywrapper h5 tt.docutils.literal span.pre,
+.document .documentwrapper .bodywrapper h6 tt.docutils.literal span.pre {
+  font-weight: bold;
+  border: none;
+  background: none;
+  padding: 0;
+  line-height: 1;
+}
+.document .sphinxsidebar {
+  float: left;
+  margin-left: -100%;
+  width: 210px;
+  padding: 20px 20px;
+}
+.document .sphinxsidebar #searchbox h3 {
+  margin-bottom: 8px;
+}
+.document .sphinxsidebar #searchbox form input:nth-child(1) {
+  border: 1px solid #999;
+  font-size: 16px;
+}
+.document .sphinxsidebar #searchbox form input:nth-child(2) {
+  display: block;
+  margin-top: 6px;
+  width: 60px;
+}
+.document .sphinxsidebar #searchbox .searchtip {
+  display: none;
+}
+.document .sphinxsidebar .sphinxsidebarwrapper h4 {
+  margin-bottom: 0;
+}
+.document .sphinxsidebar .sphinxsidebarwrapper h3:nth-of-type(2) {
+  display: none;
+}
+.document .sphinxsidebar .sphinxsidebarwrapper ul.this-page-menu {
+  display: none;
+}
+.document .sphinxsidebar .sphinxsidebarwrapper ul li a span.pre {
+  font-size: 14px;
+  line-height: 24px;
+}
+.clearer {
+  clear: both;
+}
+.footer {
+  width: 840px;
+  margin: 8px auto 40px;
+  padding-right: 10px;
+  text-align: right;
+  font-style: italic;
+}

File docs/hgreview/static/review.less

View file
+@import url("aal.css");
+
+@c-cream: #edecc7;
+@c-soft-cream: lighten(@c-cream, 10%);
+
+@font-normal: Georgia, serif;
+@font-mono: Monaco, Consolas, "Courier New", monospace;
+@content-width: 840px;
+
+.border-radius(@radius) {
+    -webkit-border-radius: @radius;
+    -moz-border-radius: @radius;
+    border-radius: @radius;
+}
+
+body, html {
+    background-color: @c-soft-cream;
+    font-family: Georgia, serif;
+    color: #222;
+
+    a {
+        color: #b6410c;
+        text-decoration: none;
+
+        &:hover {
+            text-decoration: underline;
+        }
+        &.headerlink {
+            display: none;
+        }
+    }
+    h1, h2, h3, h4, h5, h6 {
+        font-weight: normal;
+    }
+    h1 {
+        letter-spacing: 1px;
+    }
+    ul {
+        list-style-type: none;
+        
+        li {
+            margin-left: 0;
+
+            li {
+                margin-left: 1em;
+            }
+        }
+    }
+}
+.related {
+    display: none;
+}
+.document {
+    .border-radius(8px);
+    border: 1px solid @c-cream;
+    margin: 25px auto 0px;
+    padding: 0px 00px;
+    width: @content-width;
+
+    .documentwrapper {
+        .border-radius(8px);
+        background-color: lighten(@c-soft-cream, 3%);
+        float: left;
+        width: 100%;
+
+        .bodywrapper {
+            .border-radius(8px);
+            background-color: #fefefe;
+            margin-left: 230px;
+            border-left: 1px solid @c-cream;
+            padding: 20px 30px;
+            min-height: 700px;
+
+            div pre {
+                border: 1px solid @c-cream;
+                border-right: none;
+                background-color: lighten(@c-soft-cream, 3%);
+                background-color: @c-soft-cream;
+                font-size: 13px;
+                font-family: @font-mono;
+                line-height: 16px;
+                margin-bottom: 32px;
+                margin-top: -8px;
+                margin-left: 25px;
+                padding: 6px 8px;
+                width: @content-width - 302px;
+                overflow-x: auto;
+            }
+            span.pre {
+                background-color: lighten(@c-soft-cream, 2%);
+                border: 1px solid @c-cream;
+                padding: 0px 6px;
+                font-size: 13px;
+                font-family: @font-mono;
+                line-height: 24px;
+                white-space: pre;
+            }
+            ul {
+                list-style-type: disc;
+
+                li {
+                    margin-left: 44px;
+                }
+                span.pre {
+                    background-color: inherit;
+                    border: none;
+                    padding: 0;
+                }
+                li.toctree-l1 {
+                    list-style-type: none;
+                    margin-left: 0;
+                }
+                li.toctree-l2, li.toctree-l3 {
+                    list-style-type: none;
+                    margin-left: 30px;
+                }
+            }
+            a em {
+                font-style: normal;
+            }
+            tt.docutils.literal {
+                background-color: lighten(@c-soft-cream, 2%);
+                border: 1px solid @c-cream;
+                padding: 0px 6px;
+                font-size: 13px;
+                font-family: @font-mono;
+                line-height: 24px;
+                white-space: pre;
+
+                span.pre {
+                    border: 0;
+                    padding: 0;
+                }
+            }
+            .clear-code-effects {
+                border: none;
+                background: none;
+                padding: 0;
+                line-height: 1;
+            }
+            h1 tt.docutils.literal span.pre { margin: 0 0 0.75em; font-size: 2em; }
+            h2 tt.docutils.literal span.pre { margin: 0 0 1em; font-size: 1.5em; }
+            h3 tt.docutils.literal span.pre { margin: 0 0 1.286em; font-size: 1.167em; }
+            h4 tt.docutils.literal span.pre { margin: 0 0 1.5em; font-size: 1em; }
+            h5 tt.docutils.literal span.pre { margin: 0 0 1.8em; font-size: .834em; }
+            h6 tt.docutils.literal span.pre { margin: 0 0 2em; font-size: .75em; }
+            h1, h2, h3, h4, h5, h6 {
+                tt.docutils.literal {
+                    .clear-code-effects;
+
+                    span.pre {
+                        font-weight: bold;
+                        .clear-code-effects;
+                    }
+                }
+            }
+        }
+    }
+    .sphinxsidebar {
+        float: left;
+        margin-left: -100%;
+        width: 210px;
+        padding: 20px 20px;
+
+        #searchbox {
+            h3 {
+                margin-bottom: 8px;
+            }
+            form {
+                input:nth-child(1) {
+                    border: 1px solid #999;
+                    font-size: 16px;
+                }
+                input:nth-child(2) {
+                    display: block;
+                    margin-top: 6px;
+                    width: 60px;
+                }
+            }
+            .searchtip {
+                display: none;
+            }
+        }
+        .sphinxsidebarwrapper {
+            h4 {
+                margin-bottom: 0;
+            }
+            h3:nth-of-type(2) {
+                display: none;
+            }
+            ul.this-page-menu {
+                display: none;
+            }
+            ul li a span.pre {
+                font-size: 14px;
+                line-height: 24px;
+            }
+        }
+    }
+}
+.clearer {
+    clear: both;
+}
+.footer {
+    width: @content-width;
+    margin: 8px auto 40px;
+    padding-right: 10px;
+    text-align: right;
+    font-style: italic;
+}

File docs/hgreview/theme.conf

View file
+[theme]
+inherit = basic
+stylesheet = review.css
+pygments_style = none
+

File docs/index.rst

View file
+.. hg-review documentation master file, created by
+   sphinx-quickstart on Mon Jun 14 20:39:45 2010.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+hg-review documentation
+=======================
+
+hg-review is a `Mercurial <http://hg-scm.org>`_ extension for performing
+distributed `code review <http://en.wikipedia.org/wiki/Code_review>`_.
+
+Quickstart
+----------
+
+If you're impatient and want to play with hg-review right away, here's what you
+need to do.
+
+First, clone the extension somewhere::
+
+    hg clone http://bitbucket.org/sjl/hg-review/
+
+Then add it to your ``~/.hgrc`` file::
+
+    [extensions]
+    review = [path to]/hg-review/review/
+
+Now you need a repository that has code review enabled.  Luckily, you've
+already got one -- hg-review uses itself for code review. 
+
+``cd`` into the directory you cloned hg-review to and initialize the review
+data, then start the web interface::
+
+    cd hg-review
+    hg review --init
+    hg review --web
+
+Open http://localhost:8080/ in your browser of choice and poke around. Check
+out the :doc:`Overview </overview>` when you're ready to learn more.
+
+User's Guide
+------------
+
+If you want to use hg-review for anything more than some simple poking around,
+this is the place to start.
+
+.. toctree::
+   :maxdepth: 2
+
+   overview
+   concepts
+   webui
+   cli
+
+Developer's Guide
+-----------------
+
+If you want to integrate hg-review with your own application or Mercurial
+extension, or hack on hg-review itself, this is what you need to know.
+
+.. toctree::
+   :maxdepth: 2
+
+   api
+   hacking
+   licensing
+

File docs/kick

View file
+#!/usr/bin/env bash
+
+kicker -qs -l 0.1 -e reload_safari \
+_build/**/*

File docs/kick-content

View file
+#!/usr/bin/env bash
+
+kicker -qs -l 0.1 -e 'make html; reload_safari' \
+*.rst

File docs/licensing.rst

View file
+Licensing
+=========
+
+hg-review is distributed under the same license as Mercurial itself: `GPL
+version 2 or any later version
+<http://bitbucket.org/sjl/hg-review/src/tip/LICENSE>`_.
+
+If you want to create a program that works with hg-review you should look at
+`Mercurial's License FAQ page <http://mercurial.selenic.com/wiki/License>`_ to
+learn about how this might affect you.
+
+The basic idea is:
+
+* If you review code with hg-review, you are not affected by the license.
+* If you bundle hg-review with another application and don't change anything,
+  you are not affected by the license.
+* If you create an application that interacts with hg-review solely through its
+  command line interface or web interface, you are not affected by the license.
+* If you create an application that interactes with hg-review by calling its
+  internal Python API, you *are* affected by the license and will need to
+  license your application's code as GPL version 2 or later.
+
+Note that the last item (using hg-review's internal Python API) is probably the
+one you *won't* want to do anyway, since the Python API is *not* stable.
+
+If you have any questions please `email Steve <mailto:steve@stevelosh.com>`_,
+but remember that he's not a lawyer and might not have a fast answer for tricky
+questions.

File docs/overview.rst

View file
+Overview
+========
+
+Let's get started using hg-review.  No matter how you want to use it, you need
+to install it first. 
+
+Installation
+------------
+
+hg-review requires `Python <http://python.org>`_ 2.5 or later and `Mercurial
+<http://hg-scm.org>`_ 1.6 or later.
+
+You probably have both of these requirements already, but if you encounter
+problems you might want to check these first with ``python --version`` and
+``hg --version``.
+
+hg-review also depends on a couple of other things like `Flask
+<http://flask.pocoo.org>`_ and `Jinja2 <http://jinja.pocoo.org/2/>`_, but it
+bundles these requirements so you don't need to worry about them.
+
+To install hg-review, first clone the extension somewhere::
+
+    hg clone http://bitbucket.org/sjl/hg-review/
+
+Then add it to your ``~/.hgrc`` file::
+
+    [extensions]
+    review = [path to]/hg-review/review/
+
+Usage
+-----
+
+The easiest way to work with hg-review is with the :doc:`web interface
+</webui>`.  There's also a :doc:`command-line interface </cli>`, but it's
+easiest to work with the web interface.
+
+Projects with Existing Code Reviews
+'''''''''''''''''''''''''''''''''''
+
+If you want to work with a repository that already has code review set up all
+you need to do is cd into that repository, pull down the review data, and fire
+up the web ui::
+
+    cd ~/src/someproject
+    hg review --init
+    hg review --web
+
+Once that's done you can visit http://localhost:8080/ in your browser to start
+reviewing.
+
+You should read over the :doc:`concepts </concepts>` documentation to make sure
+you know how hg-review works and the :doc:`web interface </webui>`
+documentation for a quick tour of how to use the web UI.
+
+Projects without Existing Code Reviews
+''''''''''''''''''''''''''''''''''''''
+
+If you want to *start* using hg-review with a repository, you need to do a few
+things to get it ready.
+
+First, create a repository to hold the code review data. This repository should
+be in a location that's accessible by anyone that needs to see the review data.
+
+For example, if you're working on an open-source project that's hosted at
+http://bitbucket.org/you/project/ you should create a new repository for
+the review data at http://bitbucket.org/you/project-review/
+
+Next you'll need to initialize the review data in your project. ``cd`` into you
+project's directory and run:: 
+
+    hg review --init --remote-path URL
+
+The ``URL`` should be the *public* URL of the review repo you just created.
+
+This will create a local review data repo for you, as well as an ``.hgreview``
+file in your project. You need to commit this ``.hgreview`` file to your
+project with the command that hg-review suggested.
+
+Don't worry, this is the only time hg-review will make you commit something to
+your project's repository and clutter up its changelog.
+
+Now you can get to work reviewing changesets with the web interface by
+running ``hg review --web`` in your project.
+
+You should read over the :doc:`concepts </concepts>` documentation to make sure
+you know how hg-review works, and the :doc:`web interface </webui>`
+documentation for a quick tour of how to use the web UI.
+
+Reporting Bugs
+--------------
+
+If you encounter any errors while using hg-review please `post a bug
+<http://bitbucket.org/sjl/hg-review/issues/>`_.

File docs/publish.sh

View file
+#!/usr/bin/env bash
+
+make html
+rsync --delete -az _build/html/ ~/src/sjl.bitbucket.org/hg-review
+hg -R ~/src/sjl.bitbucket.org commit -Am 'hg-review: Update documentation.'
+hg -R ~/src/sjl.bitbucket.org push

File docs/webui.rst

View file
+Web Interface
+=============
+
+The web interface of hg-review is probably what you're going to use the most.
+
+Running Locally