Source

VersionControl_Hg / Trunk / Documentation / Tutorials / src / en / architecture.txt

The default branch has multiple heads

Title: Architecture

---
Structure
=========
~~~
VersionControl
+--Hg.php
+--Hg
|  +  CommandProxy.php
|  +--Container
|  |  +--Repository
|  |  |  +  Branch.php
|  |  |  +  Tag.php
|  |  |  +  Exception.php
|  |  |  +  Revision.php
|  |  |  \  Diff.php
|  |  +  Abstract.php
|  |  +  Interface.php
|  |  +  Bundle.php
|  |  +--Bundle
|  |  |  \  Exception.php
|  |  +  Repository.php
|  |  +  WorkingCopy.php
|  |  \--WorkingCopy
|  |     +  Exception.php
|  |     +  File.php
|  |     \  Directory.php
|  +--Command
|  |  +  Revert.php
|  |  +  Exception.php
|  |  +  Backout.php
|  |  +  Pull.php
|  |  +  Interface.php
|  |  +  Abstract.php
|  |  +  Push.php
|  |  +--Output
|  |  |  \  Formatter.php
|  |  +  Branch.php
|  |  +  Tag.php
|  |  +  Status.php
|  |  +  Patch.php
|  |  +  Bundle.php
|  |  +  Init.php
|  |  +  Archive.php
|  |  +  Version.php
|  |  +  Add.php
|  |  +  Copy.php
|  |  +  Cat.php
|  |  +  Export.php
|  |  +  Import.php
|  |  +  Log.php
|  |  +  Commit.php
|  |  +  Forget.php
|  |  +  Remove.php
|  |  +  Clone.php
|  |  \  Diff.php
|  +  Exception.php
|  +  Executable.php
|  \--Executable
|     \  Exception.php
~~~

Hg.php contains the base object which populates two child objects:
1. Executable
2. Repository

This base class container is passed to classes which implement Mercurial commands
to make available their properties. These are primarily the path to the HG
executable and the path to the Repository we will operate on.

CommanProxy.php implements the Proxy pattern to invoke the classes which implement
Mercurial commands. These are all located in the Command sub-directory.

The Output sub-directory contains classes which can parse the raw CLI output
and reformat it into PHP Arrays, JSON, plain text and perhaps XML if there
is an agreed-upon standard for expressing VCS data in an XML language.

Containers are objects which store files and version data. A Repository is
equivalent to the '.hg' directory. A Bundle is a compressed file containing a
series of revisions in Mercurial's internal format. These can be passed around
much like patches. Only certain commands may act on a bundle: export, import,
log and several others. A 'Patches' container may be implemented in the future.

Design Patterns
===============
I decided a factory is not appropriate because the commands implement different
options as methods and thus will not have the same interface as should be the
case for factories according to Gamma, et al
(source: http://brian.deshong.net/talks/2009/atlphp/factory_method_pattern/factory_method_pattern.pdf).

I struggled with an appropriate interface, first putting the command first and
the repository as an independent object. However, I decided to use Hg.php as the
 root of all; implement modifiers and options as methods. For example, instead
 of $repo->status('modified')->excluding('**.bak') I decided to move excluding
 from Command.php to Repository.php

I also coded first with the names of the objects without Hg_Command_Status for
example, which is the preferred PEAR way.