[PATCH STABLE] help: machines help topic

Gregory Szorc gregory.szorc at gmail.com
Sun Jul 19 00:12:54 UTC 2015


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1437264628 25200
#      Sat Jul 18 17:10:28 2015 -0700
# Node ID 28b1e76a85fb542e0fdfb1f383733192c83f14ca
# Parent  eabba9c75061254ff62827f92df0f32491c74b3d
help: machines help topic

There are a lot of non-human consumers of Mercurial. And the challenges
and considerations for machines consuming Mercurial is significantly
different from what humans face.

I think there are enough special considerations around how machines
consume Mercurial that a dedicated help topic is warranted. I concede
the audience for this topic is probably small compared to the general
audience. However, lots of normal Mercurial users do things like create
one-off shell scripts for common workflows that I think this is useful
enough to be in the install (as opposed to, say, a wiki page - which
most users will likely never find).

This text is by no means perfect. But you have to start somewhere. I
think I did cover the important parts, though.

diff --git a/mercurial/help.py b/mercurial/help.py
--- a/mercurial/help.py
+++ b/mercurial/help.py
@@ -165,8 +165,9 @@ helptable = sorted([
     (["glossary"], _("Glossary"), loaddoc('glossary')),
     (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),
      loaddoc('hgignore')),
     (["phases"], _("Working with Phases"), loaddoc('phases')),
+    (['machines'], _('Mercurial for Machines'), loaddoc('machines')),
 ])
 
 # Map topics to lists of callable taking the current topic help and
 # returning the updated version
diff --git a/mercurial/help/machines.txt b/mercurial/help/machines.txt
new file mode 100644
--- /dev/null
+++ b/mercurial/help/machines.txt
@@ -0,0 +1,131 @@
+It is common for machines (as opposed to humans) to consume Mercurial.
+This help topic describes some of the considerations for interfacing
+machines with Mercurial.
+
+Choosing an Interface
+=====================
+
+Machines have a choice of several methods to interface with Mercurial.
+These include:
+
+- Executing the ``hg`` process
+- Querying a HTTP server
+- Calling out to a command server
+- Custom extensions
+
+Executing ``hg`` processes is very similar to how humans interact with
+Mercurial in the shell. It should already be familar to you.
+
+:hg:`serve` can be used to start a server. By default, this will start
+a "hgweb" HTTP server. This HTTP server has support for machine-readable
+output, such as JSON. For more, see :hg:`help hgweb`.
+
+:hg:`serve` can also start a "command server." Clients can connect
+to this server and issue Mercurial commands over a special protocol.
+For more details on the command server, including links to client
+libraries, see https://mercurial.selenic.com/wiki/CommandServer.
+
+For advanced use cases, you can also implement custom extensions and
+have machines interface with those. Extensions can implement custom
+commands, revsets, templates, etc. They can also change behavior of
+existing Mercurial commands. Implementing extensions is beyond the
+scope of this help topic.
+
+:hg:`serve` based interfaces (the hgweb and command servers) have the
+advantage over simple ``hg`` process invocations in that they are
+likely more efficient. This is because there is significant overhead
+to spawn new Python processes.
+
+.. tip::
+
+   If you need to invoke several ``hg`` processes in short order and/or
+   performance is important to you, use of a server-based interface
+   is highly recommended.
+
+Environment Variables
+=====================
+
+As documented in :hg:`help environment`, various environment variables
+influence the operation of Mercurial. The following are particularly
+relevant for machines consuming Mercurial:
+
+HGPLAIN
+    If not set, Mercurial's output could be influenced by configuration
+    settings that impact its encoding, verbose mode, localization, etc.
+
+    It is highly recommended for machines to set this variable when
+    invoking ``hg`` processes.
+
+HGRCPATH
+    If not set, Mercurial will inherit config options from config files
+    using the process described in :hg:`help config`. This includes
+    inheriting user or system-wide config files.
+
+    Because config files can alter the behavior of Mercurial, not
+    setting HGRCPATH to a file with a known acceptable configuration
+    could lead to unwanted or inconsistent operation.
+
+    The value of HGRCPATH can be set to an empty file or the null device
+    (often ``/dev/null``) to bypass loading of the user and system
+    config files.
+
+HGENCODING
+   If not set, the locale used by Mercurial will be detected from the
+   environment.
+
+   Explcitly setting this environment variable (commonly to "utf-8")
+   is a good practice to guarantee consistent results.
+
+Consuming Command Output
+========================
+
+It is common for machines to need to parse the output of Mercurial
+commands for relevant data.
+
+If you need to parse Mercurial command output, the recommended solution
+to this problem is to avoid it if possible. Existing libraries for the
+Mercurial command server have already solved large parts of this
+problem. These libraries will enable you to call a function and receive
+a rich data structure with the results: no parsing necessary.
+
+If you still need to parse command output, the recommended method
+to do that is to specify the ``-T/--template`` argument to the command
+and ask Mercurial to emit output in a machine readable format, such as
+JSON or XML. e.g. ``hg log -T json`` or ``hg log -T xml``. You should
+be able to convert Mercurial's stdout into a data structure from your
+program without writing any custom parsing code.
+
+If for whatever reason the default output of these pre-defined machine
+readable templates is not sufficient, try explicitly defining a
+template to tailor output to your needs. See :hg:`help templates`.
+
+If templates still don't work for you, only then should you consider
+parsing the command's default output. This is the least desirable
+because not only does it mean you need to write code to parse output,
+but also command output does not have as strong guarantees around
+backwards compatibility: upgrading Mercurial could change command
+output and break your machine consumer.
+
+.. note::
+
+   Not all commands support templatized output. It is, however, a goal
+   of Mercurial that all commands eventually support templatized output.
+
+.. note::
+
+   Commands often have varying output verbosity, even when machine
+   readable styles are being used. Adding ``-v/--verbose`` and
+   ``--debug`` to the command arguments can increase the amount of
+   data exposed by Mercurial.
+
+Benefits of "share" Extension
+=============================
+
+Machines often need to manage clones and working copies of
+repositories. The "share" extension provides functionality for sharing
+repository data across several working copies. It can even "pool"
+storage for logically related repositories.
+
+Configuring the "share" extension can lead to significant performance
+wins, particularly around disk space utilization. This is especially
+true for continuous integration (CI) environments.
diff --git a/tests/test-globalopts.t b/tests/test-globalopts.t
--- a/tests/test-globalopts.t
+++ b/tests/test-globalopts.t
@@ -348,8 +348,9 @@ Testing -h/--help:
    filesets      Specifying File Sets
    glossary      Glossary
    hgignore      Syntax for Mercurial Ignore Files
    hgweb         Configuring hgweb
+   machines      Mercurial for Machines
    merge-tools   Merge Tools
    multirevs     Specifying Multiple Revisions
    patterns      File Name Patterns
    phases        Working with Phases
@@ -429,8 +430,9 @@ Testing -h/--help:
    filesets      Specifying File Sets
    glossary      Glossary
    hgignore      Syntax for Mercurial Ignore Files
    hgweb         Configuring hgweb
+   machines      Mercurial for Machines
    merge-tools   Merge Tools
    multirevs     Specifying Multiple Revisions
    patterns      File Name Patterns
    phases        Working with Phases
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -110,8 +110,9 @@ Short help:
    filesets      Specifying File Sets
    glossary      Glossary
    hgignore      Syntax for Mercurial Ignore Files
    hgweb         Configuring hgweb
+   machines      Mercurial for Machines
    merge-tools   Merge Tools
    multirevs     Specifying Multiple Revisions
    patterns      File Name Patterns
    phases        Working with Phases
@@ -185,8 +186,9 @@ Short help:
    filesets      Specifying File Sets
    glossary      Glossary
    hgignore      Syntax for Mercurial Ignore Files
    hgweb         Configuring hgweb
+   machines      Mercurial for Machines
    merge-tools   Merge Tools
    multirevs     Specifying Multiple Revisions
    patterns      File Name Patterns
    phases        Working with Phases
@@ -733,8 +735,9 @@ Test that default list of commands omits
    filesets      Specifying File Sets
    glossary      Glossary
    hgignore      Syntax for Mercurial Ignore Files
    hgweb         Configuring hgweb
+   machines      Mercurial for Machines
    merge-tools   Merge Tools
    multirevs     Specifying Multiple Revisions
    patterns      File Name Patterns
    phases        Working with Phases
@@ -957,8 +960,9 @@ Test keyword search help
   
    config     Configuration Files
    extensions Using Additional Features
    glossary   Glossary
+   machines   Mercurial for Machines
    phases     Working with Phases
    subrepos   Subrepositories
    urls       URL Paths
   
@@ -1363,8 +1367,15 @@ Dish up an empty repo; serve it cold.
   </td><td>
   Configuring hgweb
   </td></tr>
   <tr><td>
+  <a href="/help/machines">
+  machines
+  </a>
+  </td><td>
+  Mercurial for Machines
+  </td></tr>
+  <tr><td>
   <a href="/help/merge-tools">
   merge-tools
   </a>
   </td><td>
diff --git a/tests/test-hgweb-json.t b/tests/test-hgweb-json.t
--- a/tests/test-hgweb-json.t
+++ b/tests/test-hgweb-json.t
@@ -1061,8 +1061,12 @@ help/ shows help topics
         "summary": "Configuring hgweb",
         "topic": "hgweb"
       },
       {
+        "summary": "Mercurial for Machines",
+        "topic": "machines"
+      },
+      {
         "summary": "Merge Tools",
         "topic": "merge-tools"
       },
       {


More information about the Mercurial-devel mailing list