<div dir="ltr"><div>I really like this. Thanks for working on it.</div><div><br></div><div>Please do include something about HGRCPATH and explain why it shouldn't be used. I personally wasted a fair bit of time re-creating HGPLAIN by copying select parts of a users hgrc (username etc..) and setting HGRCPATH to a new temporary file... :(</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 20, 2015 at 5:52 PM, Matt Mackall <span dir="ltr"><<a href="mailto:mpm@selenic.com" target="_blank">mpm@selenic.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Sat, 2015-07-18 at 17:12 -0700, Gregory Szorc wrote:<br>
> # HG changeset patch<br>
> # User Gregory Szorc <<a href="mailto:gregory.szorc@gmail.com">gregory.szorc@gmail.com</a>><br>
> # Date 1437264628 25200<br>
> #      Sat Jul 18 17:10:28 2015 -0700<br>
> # Node ID 28b1e76a85fb542e0fdfb1f383733192c83f14ca<br>
> # Parent  eabba9c75061254ff62827f92df0f32491c74b3d<br>
> help: machines help topic<br>
><br>
> There are a lot of non-human consumers of Mercurial. And the challenges<br>
> and considerations for machines consuming Mercurial is significantly<br>
> different from what humans face.<br>
><br>
> I think there are enough special considerations around how machines<br>
> consume Mercurial that a dedicated help topic is warranted. I concede<br>
> the audience for this topic is probably small compared to the general<br>
> audience. However, lots of normal Mercurial users do things like create<br>
> one-off shell scripts for common workflows that I think this is useful<br>
> enough to be in the install (as opposed to, say, a wiki page - which<br>
> most users will likely never find).<br>
><br>
> This text is by no means perfect. But you have to start somewhere. I<br>
> think I did cover the important parts, though.<br>
><br>
> diff --git a/mercurial/help.py b/mercurial/help.py<br>
> --- a/mercurial/help.py<br>
> +++ b/mercurial/help.py<br>
> @@ -165,8 +165,9 @@ helptable = sorted([<br>
>      (["glossary"], _("Glossary"), loaddoc('glossary')),<br>
>      (["hgignore", "ignore"], _("Syntax for Mercurial Ignore Files"),<br>
>       loaddoc('hgignore')),<br>
>      (["phases"], _("Working with Phases"), loaddoc('phases')),<br>
> +    (['machines'], _('Mercurial for Machines'), loaddoc('machines')),<br>
<br>
</div></div>I like the general idea of this, but I agree this topic should be called<br>
scripting.<br>
<div><div class="h5"><br>
>  ])<br>
><br>
>  # Map topics to lists of callable taking the current topic help and<br>
>  # returning the updated version<br>
> diff --git a/mercurial/help/machines.txt b/mercurial/help/machines.txt<br>
> new file mode 100644<br>
> --- /dev/null<br>
> +++ b/mercurial/help/machines.txt<br>
> @@ -0,0 +1,131 @@<br>
> +It is common for machines (as opposed to humans) to consume Mercurial.<br>
> +This help topic describes some of the considerations for interfacing<br>
> +machines with Mercurial.<br>
> +<br>
> +Choosing an Interface<br>
> +=====================<br>
> +<br>
> +Machines have a choice of several methods to interface with Mercurial.<br>
> +These include:<br>
> +<br>
> +- Executing the ``hg`` process<br>
> +- Querying a HTTP server<br>
> +- Calling out to a command server<br>
> +- Custom extensions<br>
> +<br>
> +Executing ``hg`` processes is very similar to how humans interact with<br>
> +Mercurial in the shell. It should already be familar to you.<br>
> +<br>
> +:hg:`serve` can be used to start a server. By default, this will start<br>
> +a "hgweb" HTTP server. This HTTP server has support for machine-readable<br>
<br>
</div></div>"an"<br>
<span class=""><br>
> +output, such as JSON. For more, see :hg:`help hgweb`.<br>
> +<br>
> +:hg:`serve` can also start a "command server." Clients can connect<br>
> +to this server and issue Mercurial commands over a special protocol.<br>
> +For more details on the command server, including links to client<br>
> +libraries, see <a href="https://mercurial.selenic.com/wiki/CommandServer" rel="noreferrer" target="_blank">https://mercurial.selenic.com/wiki/CommandServer</a>.<br>
> +<br>
> +For advanced use cases, you can also implement custom extensions and<br>
> +have machines interface with those. Extensions can implement custom<br>
> +commands, revsets, templates, etc. They can also change behavior of<br>
> +existing Mercurial commands. Implementing extensions is beyond the<br>
> +scope of this help topic.<br>
<br>
</span>..and has serious licensing and stability implications! Let's not even<br>
mention this here.<br>
<div><div class="h5"><br>
> +:hg:`serve` based interfaces (the hgweb and command servers) have the<br>
> +advantage over simple ``hg`` process invocations in that they are<br>
> +likely more efficient. This is because there is significant overhead<br>
> +to spawn new Python processes.<br>
> +<br>
> +.. tip::<br>
> +<br>
> +   If you need to invoke several ``hg`` processes in short order and/or<br>
> +   performance is important to you, use of a server-based interface<br>
> +   is highly recommended.<br>
> +<br>
> +Environment Variables<br>
> +=====================<br>
> +<br>
> +As documented in :hg:`help environment`, various environment variables<br>
> +influence the operation of Mercurial. The following are particularly<br>
> +relevant for machines consuming Mercurial:<br>
> +<br>
> +HGPLAIN<br>
> +    If not set, Mercurial's output could be influenced by configuration<br>
> +    settings that impact its encoding, verbose mode, localization, etc.<br>
> +<br>
> +    It is highly recommended for machines to set this variable when<br>
> +    invoking ``hg`` processes.<br>
> +<br>
> +HGRCPATH<br>
> +    If not set, Mercurial will inherit config options from config files<br>
> +    using the process described in :hg:`help config`. This includes<br>
> +    inheriting user or system-wide config files.<br>
> +<br>
> +    Because config files can alter the behavior of Mercurial, not<br>
> +    setting HGRCPATH to a file with a known acceptable configuration<br>
> +    could lead to unwanted or inconsistent operation.<br>
> +<br>
> +    The value of HGRCPATH can be set to an empty file or the null device<br>
> +    (often ``/dev/null``) to bypass loading of the user and system<br>
> +    config files.<br>
<br>
</div></div>Scripts shouldn't be clearing this, as Augie mentioned. Not only do you<br>
lose potentially crucial extensions that the tool author hasn't<br>
considered/heard of, you also lose username, paths, auth info..<br>
<span class=""><br>
> +HGENCODING<br>
> +   If not set, the locale used by Mercurial will be detected from the<br>
> +   environment.<br>
> +<br>
> +   Explcitly setting this environment variable (commonly to "utf-8")<br>
> +   is a good practice to guarantee consistent results.<br>
> +<br>
> +Consuming Command Output<br>
> +========================<br>
> +<br>
> +It is common for machines to need to parse the output of Mercurial<br>
> +commands for relevant data.<br>
> +<br>
> +If you need to parse Mercurial command output, the recommended solution<br>
> +to this problem is to avoid it if possible.<br>
<br>
</span>Disagree. >99% of automated entities interfacing to Mercurial will be<br>
dead-simple and stupid shell scripts, aliases, or adhoc pipelines. And<br>
this is as it should be.<br>
<span class=""><br>
>  Existing libraries for the<br>
> +Mercurial command server have already solved large parts of this<br>
> +problem. These libraries will enable you to call a function and receive<br>
> +a rich data structure with the results: no parsing necessary.<br>
> +<br>
> +If you still need to parse command output, the recommended method<br>
> +to do that is to specify the ``-T/--template`` argument to the command<br>
> +and ask Mercurial to emit output in a machine readable format, such as<br>
> +JSON or XML. e.g. ``hg log -T json`` or ``hg log -T xml``. You should<br>
> +be able to convert Mercurial's stdout into a data structure from your<br>
> +program without writing any custom parsing code.<br>
<br>
</span>I can't endorse this advice either.<br>
<br>
Reminder: JSON and XML are a disaster for binary / mixed / unspecified<br>
encoding data that can be produced by<br>
manifest/cat/diff/annotate/log/everything. The traditional Unix shell<br>
tool stream-of-bytes model is way more robust here and like it or not,<br>
is what Mercurial is designed to be.<br>
<br>
Windows is not friends with UTF-8 and Mercurial is not friends with<br>
UTF-16, so this whole approach is a big problem for non-ASCII filenames<br>
on Windows.<br>
<br>
Also doing anything with JSON or XML in our aforementioned 99% case is a<br>
headache compared to, say, hg status -n.<br>
<span class=""><br>
> +If for whatever reason the default output of these pre-defined machine<br>
</span>> +readable templates is not sufficient, try explicitly definingscm: a<br>
<span class="">> +template to tailor output to your needs. See :hg:`help templates`.<br>
> +<br>
> +If templates still don't work for you, only then should you consider<br>
> +parsing the command's default output. This is the least desirable<br>
> +because not only does it mean you need to write code to parse output,<br>
> +but also command output does not have as strong guarantees around<br>
> +backwards compatibility: upgrading Mercurial could change command<br>
> +output and break your machine consumer.<br>
<br>
</span>Also not our philosophy. The things you'd actually want to parse have<br>
pretty strong guarantees, precisely to serve the aforementioned 99%<br>
case.<br>
<span class=""><br>
> +<br>
> +.. note::<br>
> +<br>
> +   Not all commands support templatized output. It is, however, a goal<br>
> +   of Mercurial that all commands eventually support templatized output.<br>
<br>
</span>In fact, very few do and mostly in an undocumented/experimental way at<br>
present. That includes hg log -T json.<br>
<span class=""><br>
> +.. note::<br>
> +<br>
> +   Commands often have varying output verbosity, even when machine<br>
> +   readable styles are being used. Adding ``-v/--verbose`` and<br>
> +   ``--debug`` to the command arguments can increase the amount of<br>
> +   data exposed by Mercurial.<br>
> +<br>
> +Benefits of "share" Extension<br>
> +=============================<br>
> +<br>
> +Machines often need to manage clones and working copies of<br>
> +repositories. The "share" extension provides functionality for sharing<br>
> +repository data across several working copies. It can even "pool"<br>
> +storage for logically related repositories.<br>
<br>
</span>I think it's preferable to have a section of 'see also's for things like<br>
environment variables, config variables, relevant extensions, revsets,<br>
filesets, templates...<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Mathematics is the supreme nostalgia of our time.<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
Mercurial-devel mailing list<br>
<a href="mailto:Mercurial-devel@selenic.com">Mercurial-devel@selenic.com</a><br>
<a href="https://selenic.com/mailman/listinfo/mercurial-devel" rel="noreferrer" target="_blank">https://selenic.com/mailman/listinfo/mercurial-devel</a><br>
</div></div></blockquote></div><br></div>