Commit Graph

33 Commits

Author SHA1 Message Date
Jun Wu
e8c21b7691 template: add a way to support command-level template cleanly
Summary:
There mercurial template language is a powerful language. But it has some
limitations right now:

- It's focused on "commit". If there is no commit, things become harder.
- The related formatter concept is coupled with "a list of things". If there
  is no list, things become impossible.
- Some commands use formatter/template partially, and that does not play
  very well with `ui.write`, and is difficult to document.

This patch starts to solve all the issues, by introducing command-level
template state, and with the vision:

- Anything could be used as an "environment" passed to the template
  language, a commit, a file, a line, a "command" with customized
  properties, etc.
  - If a template keyword function is incompatible with the environment, it
    should fail gracefully.
- The template language is a super set of other things. `-Tjson` should not
  be magical, but an alias of `{some complex expression | json}`.
  - Discourage the use of formatter.
- Template keywords can be registered and documented.

This would remove the limitations of the template language and unleash its
full potential.

Note there are still some cases where the formatter is desirable. For example,
`hg log` with a large revset should be able to stream its output. The command
template feature added right now only renders things at the end of a command,
and is not (and requires significant effort to be) streaming-friendly.

Reviewed By: mitrandir77

Differential Revision: D8221078

fbshipit-source-id: 26fed50025c4676af277686382ce2d36f1faed97
2018-06-06 15:43:25 -07:00
Lukasz Langa
dfda82e492 Upgrade to 18.5b1
Summary: Mostly empty lines removed and added.  A few bugfixes on excessive line splitting.

Reviewed By: quark-zju

Differential Revision: D8199128

fbshipit-source-id: 90c1616061bfd7cfbba0b75f03f89683340374d5
2018-05-30 02:23:58 -07:00
Jun Wu
584656dff3 codemod: join the auto-formatter party
Summary:
Turned on the auto formatter. Ran `arc lint --apply-patches --take BLACK **/*.py`.
Then run `arc lint` again so some other autofixers like spellchecker etc. looked
at the code base. Manually accept the changes whenever they make sense, or use
a workaround (ex. changing "dict()" to "dict constructor") where autofix is false
positive. Disabled linters on files that are hard (i18n/polib.py) to fix, or less
interesting to fix (hgsubversion tests), or cannot be fixed without breaking
OSS build (FBPYTHON4).

Conflicted linters (test-check-module-imports.t, part of test-check-code.t,
test-check-pyflakes.t) are removed or disabled.

Duplicated linters (test-check-pyflakes.t, test-check-pylint.t) are removed.

An issue of the auto-formatter is lines are no longer guarnateed to be <= 80
chars. But that seems less important comparing with the benefit auto-formatter
provides.

As we're here, also remove test-check-py3-compat.t, as it is currently broken
if `PYTHON3=/bin/python3` is set.

Reviewed By: wez, phillco, simpkins, pkaush, singhsrb

Differential Revision: D8173629

fbshipit-source-id: 90e248ae0c5e6eaadbe25520a6ee42d32005621b
2018-05-25 22:17:29 -07:00
Mark Thomas
0aab0bd5dd commands: allow commands to have subcommands
Summary:
Add generalised support for subcommands.  This is similar to the monkey-patched
version in `fbsparse`, but fully supported by the command infrastructure.

Subcommands are the same structure as normal commands, but are attached to a
table in the `subcommands` attribute of the main command.  Normally, if no
subcommand is provided, the normal command function is called.  This can be
made into an error by setting `subonly` on the top-level command.

In order to make `fbsparse` continue to work, I've temporarily hacked how it
handles help text.  This will be fixed in a later diff that switches fbsparse
to use this infrastructure.

Reviewed By: mjpieters

Differential Revision: D7849476

fbshipit-source-id: b988edabb17da77bf91a278e0faa2feecd0c1db9
2018-05-03 04:35:46 -07:00
Jun Wu
14783221f6 hint: add a simple framework for registering hint messages
Summary:
This allows us to have a unified way to print hint messages at the end of a
command. It would be helpful for feature discovery in general.

Reviewed By: mjpieters

Differential Revision: D7392132

fbshipit-source-id: 8b4e94cc2176266652459ecca3428bd86d95bfe2
2018-04-13 21:51:48 -07:00
rlevasseur@google.com
f0bc85352f docs: add args/returns docs for some cmdutil, context, and registrar functions
When writing my first extension, I found it hard to figure out these functions.
I figured documenting their inputs/outputs would help future authors who
are new to the codebase.

Differential Revision: https://phab.mercurial-scm.org/D1440
2017-11-16 15:01:21 -08:00
Martin von Zweigbergk
745cf248e6 registrar: don't i18n ProgrammingError message
Differential Revision: https://phab.mercurial-scm.org/D1188
2017-10-18 22:10:08 -07:00
Martin von Zweigbergk
0975261d97 registrar: move "constant" possiblecmdtypes to class level
While at it, switch to set literal syntax.

Differential Revision: https://phab.mercurial-scm.org/D1187
2017-10-18 22:07:53 -07:00
Pulkit Goyal
aaa435b086 registrar: add support for storing the type of command in func object
This patch adds support for storing the type of command which is going to run in
the func object. For this it does the following:

1) Add three possible values as attributes to the registrar.command class
2) Add a new argument to registrar.command._doregister function
3) Add a new attribute cmdtype to the func object

The type of command will be helpful in deciding what level of access on hidden
commits it can has.

Differential Revision: https://phab.mercurial-scm.org/D736
2017-09-20 04:47:43 +05:30
Saurabh Singh
786710798c registrar: fixing typo in comment
I was just going through the module and noticed the typo. This commit
fixes 'onfalure' -> 'onfailure'.

Differential Revision: https://phab.mercurial-scm.org/D906
2017-10-02 19:17:04 +01:00
Augie Fackler
c01b8ec959 registrar: remove superfluous pass statements 2017-09-30 07:45:41 -04:00
Jun Wu
a29ad18d8b revset: move weight information to predicate
Previously revset weight is hardcoded and cannot be modified. This patch
moves it to predicate so newly registered revsets could define their weight
to properly give static optimization some hint.

Differential Revision: https://phab.mercurial-scm.org/D657
2017-09-01 19:42:09 -07:00
FUJIWARA Katsunori
0c86ac795a filemerge: move decorator definition for internal merge tools to registrar
This patch also adds extra loading entry for internal merge tools to
extensions.py, for similarity to other decorators defined in
registrar.py.

This patch uses "internalmerge" for decorator class name, instead of
original "internaltool", because the latter is too generic.

BTW, after this patch, 4-spaces indentation is added to the 1st line
of internal merge tool description docstring, and this may make
already translated entries in *.po fuzzy.

Even though this indentation is required for "definition list" in reST
syntax, absence of it has been overlooked, because help.makeitemsdoc()
forcibly inserts it at generation of online help.

But this forcible insertion causes formatting issue (I'll send another
patch series for this). Therefore, this additional indentation should
be reasonable.
2017-08-06 01:13:57 +09:00
Pierre-Yves David
1dab0bbe74 configitems: add an official API for extensions to register config item
Extensions can have a 'configtable' mapping and use
'registrar.configitem(table)' to retrieve the registration function.

This behave in the same way as the other way for extensions to register new
items (commands, colors, etc).
2017-06-17 13:48:20 +02:00
Yuya Nishihara
018a4881b3 registrar: unindent superfluous "if True" block 2017-05-08 22:14:56 +09:00
Yuya Nishihara
12a6145361 registrar: switch @command decorator to class
It overrides _funcregistrarbase._doregister() since the structure of the
command table is quite different.
2017-05-08 22:08:40 +09:00
Yuya Nishihara
3e663dde68 registrar: move cmdutil.command to registrar module (API)
cmdutil.command wasn't a member of the registrar framework only for a
historical reason. Let's make that happen. This patch keeps cmdutil.command
as an alias for extension compatibility.
2016-01-09 23:07:20 +09:00
Yuya Nishihara
85fe439717 templater: add support for keyword arguments
Unlike revset, function arguments are pre-processed in templater. That's why
we need to define argspec per function. An argspec field looks somewhat
redundant in @templatefunc definition as a name field contains human-readable
list of arguments. I'll make function doc be built from argspec later.

Ported separate() function as an example.
2017-04-03 21:22:39 +09:00
Yuya Nishihara
dc941eb2d4 py3: have registrar process docstrings in bytes
Mixing bytes and unicode creates a mess. Do things in bytes as possible.

New sysbytes() helper only takes care of ASCII characters, but avoids raising
nasty unicode exception. This is the same design principle as sysstr().
2017-04-05 00:34:58 +09:00
Pierre-Yves David
9340890321 registrar: raise a programming error on duplicated registering
Previous, registering different object with the same name would silently
overwrite the first value with the second one. We now detect the situation and
raise an error. No extension in test or core had the issues.
2016-12-12 13:32:45 +01:00
Mads Kiilerich
38cb771268 spelling: fixes of non-dictionary words 2016-10-17 23:16:55 +02:00
Augie Fackler
2943f5ca36 registrar: make format strings unicodes and not bytes
Fixes issues on Python 3, wherein docstrings are unicodes. Shouldn't
break anything on Python 2.
2016-10-07 08:32:18 -04:00
Yuya Nishihara
7706430a92 revset: add 'takeorder' attribute to mark functions that need ordering flag
Since most functions shouldn't need 'order' flag, it is passed only when
explicitly required. This avoids large API breakage.
2016-08-07 17:58:50 +09:00
FUJIWARA Katsunori
7a6d96d902 registrar: add templatefunc to mark a function as template function (API)
This patch also adds loadfunction() to templater, because this
combination helps to figure out how they cooperate with each other.

Listing up loadfunction() in dispatch.extraloaders causes implicit
loading template function at loading (3rd party) extension.

This patch explicitly tests whether templatefunc decorator works as
expected, because there is no bundled extension, which defines
template function.

This change requires that "templatefunc" attribute of (3rd party)
extension is registrar.templatefunc or so.
2016-03-30 02:10:44 +09:00
FUJIWARA Katsunori
098aa2f5a6 registrar: add templatefilter to mark a function as template filter (API)
This patch also adds loadfilter() to templatefilters, because this
combination helps to figure out how they cooperate with each other.

Listing up loadfilter() in dispatch.extraloaders causes implicit
loading template filter functions at loading (3rd party) extension.

This change requires that "templatefilter" attribute of (3rd party)
extension is registrar.templatefilter or so.
2016-03-30 02:10:44 +09:00
FUJIWARA Katsunori
adbb470b46 registrar: add templatekeyword to mark a function as template keyword (API)
_templateregistrarbase is defined as a super class of templatekeyword,
for ease of adding template common features between "keyword",
"filter" and "function".

This patch also adds loadkeyword() to templatekw, because this
combination helps to figure out how they cooperate with each other.

Listing up loadkeyword() in dispatch.extraloaders causes implicit
loading template keyword functions at loading (3rd party) extension.

This change requires that "templatekeyword" attribute of (3rd party)
extension is registrar.templatekeyword or so.
2016-03-13 05:17:06 +09:00
FUJIWARA Katsunori
f997d054b1 registrar: add filesetpredicate to mark a function as fileset predicate
filesetpredicate is used to replace fileset.predicate in subsequent
patch.

This patch also adds loadpredicate() to fileset, because this
combination helps to figure out how the name of "status caller" (or
"existing caller") predicate is put into _statuscallers (or
_existingcallers).

Listing up loadpredicate() in dispatch.extraloaders causes implicit
loading fileset predicate functions at loading (3rd party) extension.
2016-03-11 04:14:54 +09:00
FUJIWARA Katsunori
e8fc6a5935 registrar: remove useless base classes (API)
Previous patches make these classes useless by removing classes
derived from them.
2016-03-11 04:14:54 +09:00
FUJIWARA Katsunori
8227e106c7 registrar: define revsetpredicate to decorate revset predicate
revsetpredicate is used to replace revset.predicate and
revset.extpredicate in subsequent patches.

This patch also adds loadpredicate() to revset, because this
combination helps to figure out how the name of safe predicate is put
into safesymbols.

This patch still uses safesymbols set to examine whether the predicate
corresponded to the 'name' is safe from DoS attack or not, because
just setting func._safe property needs changes below for such
examination.

  before:
      name in revset.safesymbols

  after:
      getattr(revset.symbols.get(name, None), '_safe', False)

"automatic registration" described in help doc of revsetpredicate
class will be achieved by the subsequent patch, which lists
loadpredicate() up in dispatch.extraloaders.
2016-03-08 23:04:53 +09:00
FUJIWARA Katsunori
e72a9be81f registrar: introduce new class for registration to replace funcregistrar
_funcregistrarbase differs from funcregistrar in points below:

  - every code paths should use same class derived from
    _funcregistrarbase to register functions in a same category

    funcregistrar expects (3rd party) extensions to use (a class
    derived from) delayregistrar.

  - actual extra setup should be executed in another function

    For example, marking revset predicate as "safe" is executed in a
    class derived from _funcregistrarbase, but putting name of "safe"
    predicate into safesymbols is executed in another function for it.

    funcregistrar expects derived classes to do so.

New class is named as module private one, because code paths, which
register functions, should use not it directly but one derived from
it.
2016-03-08 23:04:53 +09:00
FUJIWARA Katsunori
7a45cbf23f registrar: add delayregistrar class to register function in extensions
'delayregistrar' delays actual registration of function until
'setup()' invocation on it.
2015-12-29 23:58:30 +09:00
FUJIWARA Katsunori
3a36e78620 revset: use decorator to register a function as revset predicate
Using decorator can localize changes for adding (or removing) a revset
predicate function in source code.

It is also useful to pick predicates up for specific purpose. For
example, subsequent patch marks predicates as "safe" by decorator.

This patch defines 'parsefuncdecl()' in 'funcregistrar' class, because
this implementation can be uesd by other decorator class for fileset
predicate and template function.
2015-12-29 23:58:30 +09:00
FUJIWARA Katsunori
3b76ba51d4 registrar: add funcregistrar class to register function for specific purpose
This class centralizes the common logic to register function for
specific purpose like below:

    - template keyword, filter and function
    - revset predicate
    - fileset predicate
    - webcommand

'funcregistrar' also formats help document of the function with the
'decl'(aration) specified at the construction.

This can avoid (1) redundancy between 'decl' and help document, and
(2) accidental typo of help document. For example, 'foo' should appear
twice like below, if without such formatting:

    @keyword('foo')
    def foo(....):
        """:foo: Explanation of keyword foo ..."""

Almost all cases needs very simple document formatting like below:

    - "``DECL``\n    EXPLANATION"
    - ":DECL: EXPLANATION"

But webcommand needs a little complicated formatting like:

    /PATH/SPEC
    ----------

    EXPLANATION ....

To make minirst recognize the section header, hyphen line should be as
long as "/PATH/SPEC". It should be arranged by program.

Implementing 'formatdoc()' in derived class can support complicated
formatting in the latter case. But it seems redundant for simple one
in the former case.

Therefore, 'funcregistrar' does:

    - invoke 'self.formatdoc', if it is callable (for the latter case)
    - use it as the format string, otherwise (for the former case)
2015-12-29 23:58:30 +09:00