mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge 22ac5c0563
into c459ddabbd
This commit is contained in:
commit
6dc80e6984
4 changed files with 1027 additions and 25 deletions
1
debian/install
vendored
1
debian/install
vendored
|
@ -6,5 +6,6 @@ conf/* /usr/share/yunohost/conf/
|
|||
locales/* /usr/share/yunohost/locales/
|
||||
doc/yunohost.8.gz /usr/share/man/man8/
|
||||
doc/bash_completion.d/* /etc/bash_completion.d/
|
||||
doc/yunohost_zsh_completion /usr/share/zsh/vendor-completions/_yunohost
|
||||
conf/metronome/modules/* /usr/lib/metronome/modules/
|
||||
src/* /usr/lib/python3/dist-packages/yunohost/
|
||||
|
|
1
debian/rules
vendored
1
debian/rules
vendored
|
@ -7,4 +7,5 @@
|
|||
override_dh_auto_build:
|
||||
# Generate bash completion file
|
||||
python3 doc/generate_bash_completion.py
|
||||
python3 doc/generate_zsh_completion.py
|
||||
python3 doc/generate_manpages.py --gzip --output doc/yunohost.8.gz
|
||||
|
|
730
doc/generate_zsh_completion.py
Normal file
730
doc/generate_zsh_completion.py
Normal file
|
@ -0,0 +1,730 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
"""
|
||||
INSTALL:
|
||||
This script creates a `yunohost_zsh_completion` file in the same folder as this script.
|
||||
To install, copy (and rename) the created file to:
|
||||
- (Debian) `/usr/share/zsh/vendor-completions/_yunohost`
|
||||
- (Fedora) `/usr/share/zsh/site-functions/_yunohost`
|
||||
- (other distribution) `/usr/local/share/zsh/site-functions/_yunohost`
|
||||
|
||||
DOCS:
|
||||
- https://github.com/zsh-users/zsh/blob/master/Etc/completion-style-guide
|
||||
- http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System
|
||||
or `man zshcompsys`
|
||||
- http://zsh.sourceforge.net/Guide/zshguide06.html
|
||||
|
||||
Misc:
|
||||
- http://zsh.sourceforge.net/Doc/Release/Parameters.html#Array-Parameters
|
||||
|
||||
TODO:
|
||||
- use the extra:required:True pattern (similar to `nargs`?)
|
||||
- Have the global options listed in a separate category
|
||||
- Allow multiple arguments per option
|
||||
(e.g.: `yunohost user info alice --fields uid cn mail`)
|
||||
- In `yunohost.yml`, consider merging:
|
||||
- metavar
|
||||
- pattern
|
||||
- autocomplete
|
||||
- Make use of `type`, maybe using `_guard`
|
||||
- Use `pattern`, maybe with `_guard`. This seems hard though, as ZSH has
|
||||
its own globbing language...
|
||||
Link about this globbing system:
|
||||
http://zsh.sourceforge.net/Doc/Release/Expansion.html#Filename-Generation
|
||||
|
||||
NOTES:
|
||||
- Command for debugging zsh: `unfunction _yunohost; autoload -U _yunohost`
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- Optimization:
|
||||
- caching mecanism: invalidate the cache afer some commands? Hard, the
|
||||
cache is local to user
|
||||
- implement a zstyle switch, to change the cache validity period?
|
||||
|
||||
AUTHORS:
|
||||
- buzuck (Fol)
|
||||
- kayou
|
||||
- getzze
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import yaml
|
||||
|
||||
|
||||
THIS_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
ACTIONSMAP_FILE = THIS_SCRIPT_DIR + "/../share/actionsmap.yml"
|
||||
ZSH_COMPLETION_FILE = THIS_SCRIPT_DIR + "/yunohost_zsh_completion"
|
||||
|
||||
# This dict will contain the completion function data
|
||||
COMPLETION_FUNCTIONS = {}
|
||||
|
||||
|
||||
def main():
|
||||
yunohost_map = yaml.safe_load(open(ACTIONSMAP_FILE, "r"))
|
||||
output = CONST_HEADER
|
||||
#
|
||||
# Creation of the entry function of the completion script
|
||||
output += entry_point(yunohost_map)
|
||||
|
||||
#
|
||||
# The main loop, going through all (sub)commands
|
||||
for key, value in yunohost_map.items():
|
||||
output += make_category(key, value)
|
||||
|
||||
#
|
||||
# Building the auxilliary completion functions, they have been added
|
||||
# to this dict during the main loop
|
||||
output += build_completion_functions(COMPLETION_FUNCTIONS)
|
||||
output += CONST_END_OF_FILE
|
||||
|
||||
with open(ZSH_COMPLETION_FILE, "w") as _yunohost:
|
||||
_yunohost.write(output)
|
||||
|
||||
|
||||
def entry_point(yunohost_map: dict) -> str:
|
||||
"""
|
||||
Provides the entry point of the completion script: a function called _yunohost, along with the routing function.
|
||||
:param dict yunohost_map: The while YAML
|
||||
:return str: The resulting string
|
||||
"""
|
||||
categories = ""
|
||||
|
||||
# Remember the amount of spaces to get a human readable completion file
|
||||
spaces = re.search(r"\n(\s*)YNH_GLOBAL_OPTIONS", ENTRY_POINT).group(1)
|
||||
if "_global" in yunohost_map and "arguments" in yunohost_map["_global"]:
|
||||
global_arguments = make_argument_list(yunohost_map["_global"], spaces)
|
||||
else:
|
||||
global_arguments = "\n".join(
|
||||
"{}{}".format(spaces, global_arg) for global_arg in GLOBAL_ARGUMENTS
|
||||
)
|
||||
# Remove spaces and newlines before and after
|
||||
global_arguments = global_arguments.strip()
|
||||
|
||||
# Remember the amount of spaces to get a human readable completion file
|
||||
spaces = re.search(r"\n(\s*)YNH_COMMANDS_DESCRIPTION", ENTRY_POINT).group(1)
|
||||
#
|
||||
# Going through the main ynh commands
|
||||
for category, content in yunohost_map.items():
|
||||
# We only consider a command an item that has a "category_help" field
|
||||
if "category_help" not in content:
|
||||
continue
|
||||
|
||||
# Creation of the category line, with the right amount of spaces
|
||||
categories += "{}'{}:{}'\n".format(
|
||||
spaces, category, _escape(content["category_help"])
|
||||
)
|
||||
# Remove spaces and newlines before and after
|
||||
categories = categories.strip()
|
||||
|
||||
return ENTRY_POINT.replace("YNH_GLOBAL_OPTIONS", global_arguments).replace(
|
||||
"YNH_COMMANDS_DESCRIPTION", categories
|
||||
)
|
||||
|
||||
|
||||
def make_category(category_name: str, category_map: dict) -> str:
|
||||
"""
|
||||
Generates the main function of a given category.
|
||||
Reminder:
|
||||
yunohost monitor info --cpu --ram
|
||||
^ ^ ^ ^
|
||||
(script) | category | action | parameters
|
||||
:param str category_name: The name of the category
|
||||
:param dict category_map: The mapping associated to the category
|
||||
:return str: The entry point of the given category
|
||||
"""
|
||||
# No need to go further if a category does not have an `action` field
|
||||
if "actions" not in category_map:
|
||||
return ""
|
||||
|
||||
output = TEMPLATES["command"]
|
||||
subcategories = ""
|
||||
|
||||
# Memorizing the spaces, to get a human readable file
|
||||
spaces = re.search(r"\n(\s*)YNH_ACTIONS_DESCRIPTION", output).group(1)
|
||||
|
||||
# First, complete the main action map
|
||||
for action, action_details in category_map["actions"].items():
|
||||
# Empty element failsafe
|
||||
if action_details.get("hide_in_help", False) or (
|
||||
"action_help" not in action_details and "arguments" not in action_details
|
||||
):
|
||||
continue
|
||||
|
||||
# Adding the new action to the map of the category
|
||||
new_action = "'{}:{}'".format(action, _escape(action_details["action_help"]))
|
||||
output = output.replace(
|
||||
"YNH_ACTIONS_DESCRIPTION",
|
||||
"{} \\\n{}YNH_ACTIONS_DESCRIPTION".format(new_action, spaces),
|
||||
)
|
||||
# Generation of this action completion function
|
||||
output += make_action(action, action_details).replace("COMMAND", category_name)
|
||||
|
||||
# Removing the remaining tag, uneeded now
|
||||
output = re.sub(r"\n(\s*)YNH_ACTIONS_DESCRIPTION", "", output)
|
||||
|
||||
#
|
||||
# Going through the subcategories if any
|
||||
#
|
||||
if "subcategories" in category_map:
|
||||
# Getting the template, and saving the spaces
|
||||
subcategories = TEMPLATES["subcategory"]
|
||||
spaces = re.search(
|
||||
r"\n(\s*)YNH_SUBCACTEGORIES_DESCRIPTION", subcategories
|
||||
).group(1)
|
||||
|
||||
# Looping through the subcategories
|
||||
for subcategory, subcategory_details in category_map["subcategories"].items():
|
||||
# Append new subcategory
|
||||
new_subcategory = "'{}:{}'".format(
|
||||
subcategory, _escape(subcategory_details["subcategory_help"])
|
||||
)
|
||||
subcategories = subcategories.replace(
|
||||
"YNH_SUBCACTEGORIES_DESCRIPTION",
|
||||
"{}\\\n{}YNH_SUBCACTEGORIES_DESCRIPTION".format(
|
||||
new_subcategory, spaces
|
||||
),
|
||||
)
|
||||
# Creation of the subcategory
|
||||
output += make_category(
|
||||
category_name + "_" + subcategory, subcategory_details
|
||||
)
|
||||
|
||||
# Removing the remaining tag, uneeded now
|
||||
subcategories = re.sub(
|
||||
r"\n(\s*)YNH_SUBCACTEGORIES_DESCRIPTION", "", subcategories
|
||||
)
|
||||
|
||||
# Adding the subcategories to the final output. `subcategories` may be
|
||||
# empty, if no subcategory exists for the current command.
|
||||
return output.replace("YNH_SUBCATEGORY", subcategories).replace(
|
||||
"COMMAND", category_name
|
||||
)
|
||||
|
||||
|
||||
def make_action(action_name: str, action_map: dict) -> str:
|
||||
"""
|
||||
Generates the completion function for a given action
|
||||
Reminder:
|
||||
yunohost monitor info --cpu --ram
|
||||
^ ^ ^ ^
|
||||
(script) | category | action | parameters
|
||||
:param str action_name: The name of the action
|
||||
:param dict action_map: The mapping associated to the action
|
||||
:return str: The entry point of the given category
|
||||
"""
|
||||
# Return immediately if no argument is expected for this action
|
||||
if "arguments" not in action_map:
|
||||
return TEMPLATES["action_without_arguments"].replace("ACTION", action_name)
|
||||
|
||||
action = TEMPLATES["action"]
|
||||
# Memorizing the spaces, to get a human readable file
|
||||
spaces = re.search(r"\n(\s*)YNH_ACTION", action).group(1)
|
||||
|
||||
# Creation of the arguments list
|
||||
args = make_argument_list(action_map, spaces)
|
||||
|
||||
# Insertion of the action's name
|
||||
return action.replace("YNH_ACTION", args).replace("ACTION", action_name)
|
||||
|
||||
|
||||
def make_argument_list(action_map: dict, spaces: str = 4 * " ") -> str:
|
||||
"""
|
||||
Builds the actions list.
|
||||
:param dict action_map: The list of possible arguments
|
||||
:param str spaces: [optional] The amount of spaces used for the indentation
|
||||
:return str: The arguments list, ready to use
|
||||
"""
|
||||
action_list = "YNH_ACTION"
|
||||
# This is a counter, in case of position dependent paremeters (the ones not
|
||||
# beginning with a `-`)
|
||||
position = 0
|
||||
|
||||
# Early return if no arguments key found
|
||||
if "arguments" not in action_map:
|
||||
return ""
|
||||
|
||||
for argument_name, argument_details in action_map["arguments"].items():
|
||||
#
|
||||
# Initializing the argument dict to make sure all fields are defined
|
||||
# - id: identifier (`-n` or `--name`). If none (e.g. `ynh app install
|
||||
# APP_NAME`), this field is the arguments position or cardinality (from
|
||||
# `nargs`)
|
||||
# - excludes: usually the argument itself. Only used for optional args
|
||||
# - desc: the argument description
|
||||
# - completion: the completion function name
|
||||
#
|
||||
arg = {"excludes": "", "spec": "", "desc": "", "mess": "", "action": ""}
|
||||
|
||||
#
|
||||
# Forcing to str, as the yaml parser inteprets numbers as integers
|
||||
# (eg.: `firewall allow... -4`)
|
||||
argument_name = str(argument_name)
|
||||
|
||||
#
|
||||
# Check if the argument should be hidden (API only)
|
||||
#
|
||||
if (
|
||||
argument_details.get("extra", {})
|
||||
.get("autocomplete", {})
|
||||
.get("hide_in_help", False)
|
||||
):
|
||||
continue
|
||||
|
||||
#
|
||||
# Generation of the completion hints
|
||||
#
|
||||
arg["action"] = make_argument_completion(argument_details)
|
||||
|
||||
#
|
||||
# A parameter not beginning with `-` is considered mandatory.
|
||||
if argument_name[0] != "-":
|
||||
position += 1
|
||||
# This parameter may be used more than once, else we use the position counter
|
||||
if argument_details.get("nargs", "") in ["+", "*"]:
|
||||
if argument_details["nargs"] == "+":
|
||||
arg["spec"] = "'{{{},*}}'".format(str(position))
|
||||
else: # argument_details["nargs"] == "*":
|
||||
arg["spec"] = "*"
|
||||
else:
|
||||
arg["spec"] = str(position)
|
||||
arg["mess"] = argument_details.get("help", argument_name)
|
||||
|
||||
#
|
||||
# If defined, add the default value as a hint
|
||||
if "default" in argument_details:
|
||||
arg["mess"] += " (default: {})".format(argument_details["default"])
|
||||
# Escape special character in the description
|
||||
arg["mess"] = _escape(arg["mess"])
|
||||
|
||||
# ----
|
||||
# NOTE: a double colon marks for an optional argument:
|
||||
# '::Username to update:__ynh_user_list'
|
||||
# ----
|
||||
placeholder = "'{}{}{}:{}:{}'"
|
||||
|
||||
#
|
||||
# This is an optional parameter, beginning with a `-`
|
||||
else:
|
||||
# `full` is the extended form of the argument (e.g.: -n is short for --number)
|
||||
if "full" in argument_details:
|
||||
full_name = argument_details["full"]
|
||||
arg["mess"] = str(full_name).lstrip("--")
|
||||
arg["spec"] = "'{{{},{}}}'".format(argument_name, full_name)
|
||||
arg["excludes"] = "({} {})".format(argument_name, full_name)
|
||||
else:
|
||||
arg["mess"] = str(argument_name).lstrip("--")
|
||||
arg["spec"] = argument_name
|
||||
# Escape special character in the description
|
||||
arg["mess"] = _escape(arg["mess"])
|
||||
|
||||
# The description of the parameter
|
||||
# Getting the `help` field if any, else simply by using it's name
|
||||
arg["desc"] = "[{}]".format(argument_details.get("help", arg["mess"]))
|
||||
|
||||
has_action = True
|
||||
# Add a pattern field to match multiple arguments
|
||||
if argument_details.get("nargs", "") in ["+", "*"]:
|
||||
if arg["excludes"]:
|
||||
# suppose that `arg["excludes"] = (-f --foo)`
|
||||
arg["excludes"] = "(* " + arg["excludes"][1:]
|
||||
else:
|
||||
arg["excludes"] = "(*)"
|
||||
arg["mess"] = "*:" + arg["mess"]
|
||||
has_action = True
|
||||
|
||||
# Options without arguments should skip the message and action fields
|
||||
elif argument_details.get("action", "").startswith("store_"):
|
||||
has_action = False
|
||||
|
||||
# Place holder for the parameters
|
||||
if has_action:
|
||||
placeholder = "'{}{}{}:{}:{}'"
|
||||
else:
|
||||
placeholder = "'{}{}{}'"
|
||||
|
||||
#
|
||||
# Putting it all together
|
||||
# Escape special character in the description
|
||||
arg["desc"] = _escape(arg["desc"])
|
||||
action_list = action_list.replace(
|
||||
"YNH_ACTION",
|
||||
"{} \\\n{}YNH_ACTION".format(placeholder, spaces).format(
|
||||
arg["excludes"], arg["spec"], arg["desc"], arg["mess"], arg["action"]
|
||||
),
|
||||
)
|
||||
# Removing the extra tag and backslash,
|
||||
return re.sub(r"\s*\\\n(\s*)YNH_ACTION", "", action_list)
|
||||
|
||||
|
||||
def make_argument_completion(argument_details: dict) -> str:
|
||||
"""
|
||||
Finds the completion function for the given argument, if defined.
|
||||
:param dict argument_details: The mapping of the argument
|
||||
:return str: The name of the completion function, or an empty string
|
||||
"""
|
||||
# `COMPLETION_FUNCTIONS` hold the elements needed to generate it. The
|
||||
# actual creation of this function will be done by build_completion_functions(),
|
||||
# called near the end of this script.
|
||||
# `choices` and `autocomplete` should not be present at the same time (`choices` takes precedence)
|
||||
|
||||
#
|
||||
# A list of choices is defined
|
||||
if "choices" in argument_details:
|
||||
return "({})".format(" ".join(argument_details["choices"]))
|
||||
|
||||
#
|
||||
# An autocompletion function is defined
|
||||
if "extra" in argument_details and "autocomplete" in argument_details["extra"]:
|
||||
autocomplete = argument_details["extra"]["autocomplete"]
|
||||
|
||||
#
|
||||
# This is a combinaision of YunoHost and jq commands
|
||||
#
|
||||
if "ynh_selector" in autocomplete and "jq_selector" in autocomplete:
|
||||
# Create this function's name
|
||||
function_name = _remove_special_chars(
|
||||
"__ynh_" + _norm_name(autocomplete["ynh_selector"])
|
||||
)
|
||||
#
|
||||
# Add it to the function's dict, if it has not been created yet
|
||||
if function_name not in COMPLETION_FUNCTIONS:
|
||||
# First, build the shell command that returns the completions
|
||||
call = "sudo yunohost {} --output-as json | jq -cr '{}'".format(
|
||||
autocomplete["ynh_selector"], autocomplete["jq_selector"]
|
||||
)
|
||||
# If a cache is needed, wrap the call in the caching function
|
||||
if "use_cache" in autocomplete:
|
||||
call = "__get_ynh_cache 'YNH_{}' \"{}\"".format(
|
||||
_norm_name(autocomplete["ynh_selector"]), call
|
||||
)
|
||||
# Lastly, save the content
|
||||
COMPLETION_FUNCTIONS[function_name] = {"shell_call": call}
|
||||
return function_name
|
||||
|
||||
#
|
||||
# The autocompletion is done by a grep
|
||||
#
|
||||
elif "shell_call" in autocomplete:
|
||||
# Create this function's name
|
||||
function_name = _remove_special_chars(
|
||||
"__ynh_" + _norm_name(autocomplete["shell_call"])
|
||||
)
|
||||
#
|
||||
# Add it to the function's dict, if it has not been created yet
|
||||
if function_name not in COMPLETION_FUNCTIONS:
|
||||
# First, build the shell command that returns the completions
|
||||
call = autocomplete["shell_call"]
|
||||
|
||||
# If a cache is needed, wrap the call in the caching function
|
||||
# Note: not tested with grep, only with YunoHost's commands
|
||||
if "use_cache" in autocomplete:
|
||||
call = "__get_ynh_cache 'YNH_{}' \"{}\"".format(
|
||||
_remove_special_chars(autocomplete["shell_call"]), call
|
||||
)
|
||||
# Lastly, save the content
|
||||
COMPLETION_FUNCTIONS[function_name] = {"shell_call": call}
|
||||
return function_name
|
||||
|
||||
#
|
||||
# This is a combinaision of two other completion functions
|
||||
#
|
||||
elif "aggregate" in autocomplete:
|
||||
# Create this function's name
|
||||
function = "__ynh"
|
||||
for subcall in autocomplete["aggregate"]:
|
||||
function += "_" + _norm_name(subcall["ynh_selector"])
|
||||
|
||||
# If this function is yet undefined, create it
|
||||
if function not in COMPLETION_FUNCTIONS:
|
||||
aggregation = ""
|
||||
for subcall in autocomplete["aggregate"]:
|
||||
aggregation += "\n'{}:{}:{}' \\".format(
|
||||
subcall["name"],
|
||||
subcall["name"],
|
||||
_norm_name("__ynh_" + subcall["ynh_selector"]),
|
||||
)
|
||||
# Saving the result, and removing the extra backslash
|
||||
COMPLETION_FUNCTIONS[function] = {"aggregated": aggregation}
|
||||
return function
|
||||
|
||||
#
|
||||
# The autocompletion is done by a ZSH function
|
||||
#
|
||||
elif "zsh_completion" in autocomplete:
|
||||
return autocomplete["zsh_completion"]
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
def build_completion_functions(functions: dict) -> str:
|
||||
"""
|
||||
Generates the custom completion functions for YunoHost, from the "metavar"
|
||||
object of the YAML mapping.
|
||||
:param dict metavars: The "metavar" object from the YAML
|
||||
:return str: All custom completion functions, beginning by "__ynh_"
|
||||
"""
|
||||
output = ""
|
||||
|
||||
#
|
||||
# This basically consists in associating the type of the completion
|
||||
# function to it's template
|
||||
for function, completion in functions.items():
|
||||
if "aggregated" in completion:
|
||||
output += (
|
||||
TEMPLATES["completion_function_aggregate"]
|
||||
.replace("FUNCTION", function)
|
||||
.replace("AGGREGATED", completion["aggregated"])
|
||||
)
|
||||
else:
|
||||
output += (
|
||||
TEMPLATES["completion_shell_call"]
|
||||
.replace("FUNCTION", function)
|
||||
.replace("SHELL_CALL", completion["shell_call"])
|
||||
)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# Utility functions, mainly string manipulation
|
||||
#
|
||||
|
||||
|
||||
def _norm_name(string: str) -> str:
|
||||
"""
|
||||
Normalizies a string to make it look like a function name:
|
||||
- lowercase
|
||||
- spaces replaced by underscores
|
||||
- no dashs
|
||||
:param str string: the string to norm.
|
||||
:return str: The normed string
|
||||
"""
|
||||
return (
|
||||
string.lower()
|
||||
.replace(" ", "_")
|
||||
.replace("-", "")
|
||||
.replace("/", "_")
|
||||
.replace(".", "_")
|
||||
)
|
||||
|
||||
|
||||
def _escape(string: str) -> str:
|
||||
r"""
|
||||
Escapes any special character:
|
||||
- single quotes (') are put in a separate double quoted string ('"'"')
|
||||
- colons (:) and other characters are preceded by a backslash (\:)
|
||||
:param str string: The string to escape
|
||||
:return str: `string` escaped
|
||||
"""
|
||||
return string.replace("'", "'\"'\"'").replace(":", r"\:")
|
||||
|
||||
|
||||
def _remove_special_chars(string: str) -> str:
|
||||
"""
|
||||
Removes any character with a special meaning in ZSH, such as `$`, `{` ...
|
||||
:param str string: The string to clean
|
||||
:return str: `string` cleaned
|
||||
"""
|
||||
# NOTE: this list may not be comprehensive and should be extended if needed
|
||||
return re.sub(r'[- =\^+:\?\'"$(){}\[\]/\\\\]', "", string).replace(".", "")
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# The ZSH templates are defined below
|
||||
#
|
||||
|
||||
GLOBAL_ARGUMENTS = [
|
||||
r"""'(-h --help)'{-h,--help}'[Show help message and exit]'""",
|
||||
r"""'--output-as[Output result in another format]:output:(json plain none)'""",
|
||||
r"""'--debug[Log and print debug messages]'""",
|
||||
r"""'--quiet[Don't produce any output]'""",
|
||||
r"""'--version[Display YunoHost packages versions (alias to `yunohost tools versions`)]'""",
|
||||
r"""'--timeout[Number of seconds before this command will timeout because it can't acquire the lock (meaning that another command is currently running), by default there is no timeout and the command will wait until it can get the lock]'""",
|
||||
]
|
||||
|
||||
CONST_HEADER = r"""#compdef yunohost
|
||||
# -----------------------------------------------------------------------------
|
||||
# Description
|
||||
# -----------
|
||||
# Completion script for yunohost, automatically generated from the action map
|
||||
# decribed by `yunohost.yml`
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
local state line curcontext
|
||||
|
||||
# For debug purposes only
|
||||
__log() {
|
||||
echo $@ >> '/tmp/zsh-completion.log'
|
||||
}
|
||||
|
||||
# First argument: The name of the completion list
|
||||
# 2nd argument: The command to get it
|
||||
# (( $+functions[__get_ynh_cache] )) ||
|
||||
function __get_ynh_cache() {
|
||||
# Checking a global cache policy is defined,
|
||||
# and linkage to ynh-cache-policy
|
||||
local update_policy completion_items
|
||||
zstyle -s ":completion:${curcontext}:" cache-policy update_policy
|
||||
if [[ -z "$update_policy" ]]; then
|
||||
zstyle ":completion:${curcontext}:" cache-policy __yunohost_cache_policy
|
||||
fi
|
||||
# If the cache is invalid (too old), regenerate it
|
||||
if _cache_invalid $1 || ! _retrieve_cache $1; then
|
||||
completion_items=(`eval $2`)
|
||||
_store_cache $1 completion_items
|
||||
else
|
||||
_retrieve_cache $1
|
||||
fi
|
||||
echo $completion_items
|
||||
}
|
||||
# (( $+functions[__yunohost_cache_policy] )) ||
|
||||
__yunohost_cache_policy(){
|
||||
local cache_file="$1"
|
||||
# Rebuild if the yunohost executable is newer than cache
|
||||
[[ "${commands[yunohost]}" -nt "${cache_file}" ]] && return
|
||||
|
||||
# Rebuild if cache is more than a week old
|
||||
local -a oldp
|
||||
# oldp=( "$1"(mM+1) ) # month
|
||||
# oldp=( "$1"(Nm+7) ) # 1 week
|
||||
oldp=( "$1"(Nmd+1) ) # 1 day
|
||||
(( $#oldp )) && return
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Routing function, used to go through $words and find the correct subfunction
|
||||
# (Suggestions welcome to improve that design... =/ )
|
||||
# (( $+functions[__jump] )) ||
|
||||
function __jump() {
|
||||
local cmd
|
||||
|
||||
# Remember the subcommand name
|
||||
if (( ${#@} == 0 )); then
|
||||
local cmd=${words[2]}
|
||||
else
|
||||
cmd=$1 # < no more used?
|
||||
fi
|
||||
|
||||
# Set the context for the subcommand
|
||||
ynhcommand="${ynhcommand}_${cmd}"
|
||||
# Narrow the range of words we are looking at to exclude `yunohost`
|
||||
(( CURRENT-- ))
|
||||
shift words
|
||||
# Run the completion for the subcommand
|
||||
if ! _call_function ret ${ynhcommand#:*:}; then
|
||||
_default && ret=0
|
||||
fi
|
||||
return ret
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
# --------------- Main entry point -----------------------------------
|
||||
ENTRY_POINT = r"""
|
||||
# (( $+functions[_yunohost] )) ||
|
||||
function _yunohost() {
|
||||
local curcontext="${curcontext}" state line ret=1
|
||||
local mode
|
||||
# `ynhcommand` is where `__jump` builds the name of the completion function
|
||||
ynhcommand='_yunohost'
|
||||
|
||||
typeset -ag common_options; common_options=(
|
||||
YNH_GLOBAL_OPTIONS
|
||||
)
|
||||
|
||||
if (( CURRENT > 2 )); then
|
||||
__jump
|
||||
else
|
||||
local -a yunohost_categories; yunohost_categories=(
|
||||
YNH_COMMANDS_DESCRIPTION
|
||||
)
|
||||
_describe -V -t yunohost-commands 'yunohost category' yunohost_categories "$@"
|
||||
fi
|
||||
|
||||
_arguments -s -C $common_options
|
||||
# unset common_option
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
CONST_END_OF_FILE = r"""
|
||||
_yunohost "$@"
|
||||
"""
|
||||
|
||||
|
||||
TEMPLATES = {
|
||||
"command": r"""
|
||||
|
||||
#-----------------------------------------
|
||||
# COMMAND
|
||||
#-----------------------------------------
|
||||
|
||||
# (( $+functions[_yunohost_COMMAND] )) ||
|
||||
function _yunohost_COMMAND() {
|
||||
if (( CURRENT > 2 )); then
|
||||
__jump
|
||||
else
|
||||
local -a yunohost_COMMAND; yunohost_COMMAND=(
|
||||
YNH_ACTIONS_DESCRIPTION
|
||||
)
|
||||
_describe -V -t yunohost-COMMAND 'yunohost COMMAND category' yunohost_COMMAND "$@"
|
||||
YNH_SUBCATEGORY
|
||||
fi
|
||||
}
|
||||
""",
|
||||
# --------------------------------------------------------------------
|
||||
"subcategory": r"""
|
||||
local -a yunohost_COMMAND_subcategories; yunohost_COMMAND_subcategories=(
|
||||
YNH_SUBCACTEGORIES_DESCRIPTION
|
||||
)
|
||||
_describe -V -t yunohost-COMMAND-subcategories 'yunohost COMMAND subcategories' yunohost_COMMAND_subcategories "$@"
|
||||
""",
|
||||
# --------------------------------------------------------------------
|
||||
# Note: The common_options are not added until we find a way to have them
|
||||
# in a separate category. It is too confusing to have them mixed with
|
||||
# the command's options.
|
||||
# Memo:
|
||||
# YNH_ACTION \
|
||||
# $common_options
|
||||
#
|
||||
"action": r"""
|
||||
# (( $+functions[_yunohost_COMMAND_ACTION] )) ||
|
||||
function _yunohost_COMMAND_ACTION() {
|
||||
_arguments -s -C \
|
||||
YNH_ACTION
|
||||
}
|
||||
|
||||
""",
|
||||
# --------------------------------------------------------------------
|
||||
"action_without_arguments": r"""
|
||||
# (( $+functions[_yunohost_COMMAND_ACTION] )) ||
|
||||
function _yunohost_COMMAND_ACTION() { }
|
||||
|
||||
""",
|
||||
# --------------------------------------------------------------------
|
||||
"completion_shell_call": r"""
|
||||
# (( $+functions[FUNCTION] )) ||
|
||||
function FUNCTION() {
|
||||
compadd "$@" -- ${(@)$(SHELL_CALL)}
|
||||
}
|
||||
""",
|
||||
# --------------------------------------------------------------------
|
||||
# The newline is included in `AGGREGATED`
|
||||
"completion_function_aggregate": r"""
|
||||
# (( $+functions[FUNCTION] )) ||
|
||||
function FUNCTION() {
|
||||
_alternative \AGGREGATED
|
||||
}
|
||||
""",
|
||||
}
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -37,6 +37,32 @@ _global:
|
|||
authentication:
|
||||
api: ldap_admin
|
||||
cli: null
|
||||
arguments:
|
||||
-h:
|
||||
full: --help
|
||||
help: Show this help message and exit
|
||||
--version:
|
||||
help: Display YunoHost packages versions
|
||||
action: callback
|
||||
callback:
|
||||
method: yunohost.utils.packages.ynh_packages_version
|
||||
return: true
|
||||
--output-as:
|
||||
help: Output result in another format
|
||||
choices:
|
||||
- json
|
||||
- plain
|
||||
- none
|
||||
--debug:
|
||||
help: Log and print debug messages
|
||||
action: store_true
|
||||
--quiet:
|
||||
help: Don't produce any output
|
||||
action: store_true
|
||||
--timeout:
|
||||
help: Number of seconds before this command will timeout because it can't acquire the lock (meaning that another command is currently running), by default there is no timeout and the command will wait until it can get the lock
|
||||
type: int
|
||||
|
||||
|
||||
#############################
|
||||
# User #
|
||||
|
@ -53,6 +79,16 @@ user:
|
|||
--fields:
|
||||
help: fields to fetch (username, fullname, mail, mail-alias, mail-forward, mailbox-quota, groups, shell, home-path)
|
||||
nargs: "+"
|
||||
choices:
|
||||
- username
|
||||
- fullname
|
||||
- mail
|
||||
- mail-alias
|
||||
- mail-forward
|
||||
- mailbox-quota
|
||||
- groups
|
||||
- shell
|
||||
- home-path
|
||||
|
||||
### user_create()
|
||||
create:
|
||||
|
@ -107,6 +143,10 @@ user:
|
|||
pattern: &pattern_domain
|
||||
- !!str ^([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,})$
|
||||
- "pattern_domain"
|
||||
autocomplete: &domains_list
|
||||
ynh_selector: domain list
|
||||
jq_selector: '.domains[]'
|
||||
use_cache: false
|
||||
-q:
|
||||
full: --mailbox-quota
|
||||
help: Mailbox size quota
|
||||
|
@ -131,6 +171,10 @@ user:
|
|||
help: Username to delete
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: &users_list
|
||||
ynh_selector: user list --fields username
|
||||
jq_selector: '.users[].username'
|
||||
use_cache: false
|
||||
--purge:
|
||||
help: Purge user's home and mail directories
|
||||
action: store_true
|
||||
|
@ -142,6 +186,8 @@ user:
|
|||
arguments:
|
||||
username:
|
||||
help: Username to update
|
||||
extra:
|
||||
autocomplete: *users_list
|
||||
-F:
|
||||
full: --fullname
|
||||
help: The full name of the user. For example 'Camille Dupont'
|
||||
|
@ -212,6 +258,8 @@ user:
|
|||
arguments:
|
||||
username:
|
||||
help: Username or email to get information
|
||||
extra:
|
||||
autocomplete: *users_list
|
||||
|
||||
### user_export()
|
||||
export:
|
||||
|
@ -226,6 +274,9 @@ user:
|
|||
csvfile:
|
||||
help: "CSV file with columns username, firstname, lastname, password, mail, mailbox-quota, mail-alias, mail-forward, groups (separated by coma)"
|
||||
type: open
|
||||
extra:
|
||||
autocomplete:
|
||||
zsh_completion: _files
|
||||
-u:
|
||||
full: --update
|
||||
help: Update all existing users contained in the CSV file (by default existing users are ignored)
|
||||
|
@ -279,6 +330,10 @@ user:
|
|||
help: Name of the group to be deleted
|
||||
extra:
|
||||
pattern: *pattern_groupname
|
||||
autocomplete: &user_groups_list
|
||||
ynh_selector: user group list -s
|
||||
jq_selector: '.groups[]'
|
||||
use_cache: false
|
||||
|
||||
### user_group_info()
|
||||
info:
|
||||
|
@ -288,7 +343,8 @@ user:
|
|||
groupname:
|
||||
help: Name of the group to fetch info about
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
pattern: *pattern_groupname
|
||||
autocomplete: *user_groups_list
|
||||
|
||||
### user_group_add()
|
||||
add:
|
||||
|
@ -299,12 +355,14 @@ user:
|
|||
help: Name of the group to add user(s) to
|
||||
extra:
|
||||
pattern: *pattern_groupname
|
||||
autocomplete: *user_groups_list
|
||||
usernames:
|
||||
help: User(s) to add in the group
|
||||
nargs: "*"
|
||||
metavar: USERNAME
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: *users_list
|
||||
|
||||
### user_group_remove()
|
||||
remove:
|
||||
|
@ -315,12 +373,14 @@ user:
|
|||
help: Name of the group to remove user(s) from
|
||||
extra:
|
||||
pattern: *pattern_groupname
|
||||
autocomplete: *user_groups_list
|
||||
usernames:
|
||||
help: User(s) to remove from the group
|
||||
nargs: "*"
|
||||
metavar: USERNAME
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: *users_list
|
||||
|
||||
add-mailalias:
|
||||
action_help: Add mail aliases to group
|
||||
|
@ -330,6 +390,7 @@ user:
|
|||
help: Name of the group to add user(s) to
|
||||
extra:
|
||||
pattern: *pattern_groupname
|
||||
autocomplete: *user_groups_list
|
||||
aliases:
|
||||
help: Mail aliases to add
|
||||
nargs: "+"
|
||||
|
@ -344,13 +405,13 @@ user:
|
|||
help: Name of the group to add user(s) to
|
||||
extra:
|
||||
pattern: *pattern_groupname
|
||||
autocomplete: *user_groups_list
|
||||
aliases:
|
||||
help: Mail aliases to remove
|
||||
nargs: "+"
|
||||
metavar: MAIL
|
||||
|
||||
|
||||
|
||||
permission:
|
||||
subcategory_help: Manage permissions
|
||||
actions:
|
||||
|
@ -363,6 +424,11 @@ user:
|
|||
apps:
|
||||
help: Apps to list permission for (all by default)
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: &apps_list
|
||||
ynh_selector: app list
|
||||
jq_selector: '.apps[].id'
|
||||
use_cache: false
|
||||
-s:
|
||||
full: --short
|
||||
help: Only list permission names
|
||||
|
@ -379,6 +445,11 @@ user:
|
|||
arguments:
|
||||
permission:
|
||||
help: Name of the permission to fetch info about (use "yunohost user permission list" and "yunohost user permission -f" to see all the current permissions)
|
||||
extra:
|
||||
autocomplete: &permissions_list
|
||||
ynh_selector: user permission list
|
||||
jq_selector: '.permissions | keys[]'
|
||||
use_cache: false
|
||||
|
||||
### user_permission_update()
|
||||
update:
|
||||
|
@ -387,6 +458,8 @@ user:
|
|||
arguments:
|
||||
permission:
|
||||
help: Permission to manage (e.g. mail or nextcloud or wordpress.editors) (use "yunohost user permission list" and "yunohost user permission -f" to see all the current permissions)
|
||||
extra:
|
||||
autocomplete: *permissions_list
|
||||
-l:
|
||||
full: --label
|
||||
help: Label for this permission. This label will be shown on the SSO and in the admin
|
||||
|
@ -394,8 +467,8 @@ user:
|
|||
full: --show_tile
|
||||
help: Define if a tile will be shown in the SSO
|
||||
choices:
|
||||
- 'True'
|
||||
- 'False'
|
||||
- "True"
|
||||
- "False"
|
||||
|
||||
## user_permission_add()
|
||||
add:
|
||||
|
@ -404,12 +477,18 @@ user:
|
|||
arguments:
|
||||
permission:
|
||||
help: Permission to manage (e.g. mail or nextcloud or wordpress.editors) (use "yunohost user permission list" and "yunohost user permission -f" to see all the current permissions)
|
||||
extra:
|
||||
autocomplete: *permissions_list
|
||||
names:
|
||||
help: Group or usernames to grant this permission to
|
||||
nargs: "*"
|
||||
metavar: GROUP_OR_USER
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: &user_and_groups_list
|
||||
ynh_selector: user group list
|
||||
jq_selector: '[(.groups | keys), ([.groups[] | select(.members).members[]] | unique)] | add[]'
|
||||
use_cache: false
|
||||
|
||||
## user_permission_remove()
|
||||
remove:
|
||||
|
@ -418,12 +497,15 @@ user:
|
|||
arguments:
|
||||
permission:
|
||||
help: Permission to manage (e.g. mail or nextcloud or wordpress.editors) (use "yunohost user permission list" and "yunohost user permission -f" to see all the current permissions)
|
||||
extra:
|
||||
autocomplete: *permissions_list
|
||||
names:
|
||||
help: Group or usernames to revoke this permission to
|
||||
nargs: "*"
|
||||
metavar: GROUP_OR_USER
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: *user_and_groups_list
|
||||
|
||||
## user_permission_reset()
|
||||
reset:
|
||||
|
@ -432,6 +514,8 @@ user:
|
|||
arguments:
|
||||
permission:
|
||||
help: Permission to manage (e.g. mail or nextcloud or wordpress.editors) (use "yunohost user permission list" and "yunohost user permission -f" to see all the current permissions)
|
||||
extra:
|
||||
autocomplete: *permissions_list
|
||||
|
||||
ssh:
|
||||
subcategory_help: Manage ssh access
|
||||
|
@ -446,6 +530,7 @@ user:
|
|||
help: Username of the user
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: *users_list
|
||||
|
||||
### user_ssh_keys_add()
|
||||
add-key:
|
||||
|
@ -456,6 +541,7 @@ user:
|
|||
help: Username of the user
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: *users_list
|
||||
key:
|
||||
help: The key to be added
|
||||
-c:
|
||||
|
@ -471,6 +557,7 @@ user:
|
|||
help: Username of the user
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: *users_list
|
||||
key:
|
||||
help: The key to be removed
|
||||
|
||||
|
@ -505,6 +592,7 @@ domain:
|
|||
help: Domain to check
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
|
||||
### domain_add()
|
||||
add:
|
||||
|
@ -535,6 +623,7 @@ domain:
|
|||
help: Domain to delete
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
-r:
|
||||
full: --remove-apps
|
||||
help: Remove apps installed on the domain
|
||||
|
@ -564,6 +653,7 @@ domain:
|
|||
help: Target domain
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
|
||||
### domain_maindomain()
|
||||
main-domain:
|
||||
|
@ -577,6 +667,7 @@ domain:
|
|||
help: Change the current main domain
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
|
||||
### certificate_status()
|
||||
cert-status:
|
||||
|
@ -586,6 +677,8 @@ domain:
|
|||
domain_list:
|
||||
help: Domains to check
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
--full:
|
||||
help: Show more details
|
||||
action: store_true
|
||||
|
@ -598,6 +691,8 @@ domain:
|
|||
domain_list:
|
||||
help: Domains for which to install the certificates
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
--force:
|
||||
help: Install even if current certificate is not self-signed
|
||||
action: store_true
|
||||
|
@ -616,6 +711,8 @@ domain:
|
|||
domain_list:
|
||||
help: Domains for which to renew the certificates
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
--force:
|
||||
help: Ignore the validity threshold (15 days)
|
||||
action: store_true
|
||||
|
@ -628,7 +725,7 @@ domain:
|
|||
|
||||
### domain_url_available()
|
||||
url-available:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: Check availability of a web path
|
||||
api: GET /domain/<domain>/urlavailable
|
||||
arguments:
|
||||
|
@ -636,18 +733,21 @@ domain:
|
|||
help: The domain for the web path (e.g. your.domain.tld)
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
path:
|
||||
help: The path to check (e.g. /coffee)
|
||||
|
||||
|
||||
### domain_action_run()
|
||||
action-run:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: Run domain action
|
||||
api: PUT /domain/<domain>/actions/<action>
|
||||
arguments:
|
||||
domain:
|
||||
help: Domain name
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
action:
|
||||
help: action id
|
||||
-a:
|
||||
|
@ -666,6 +766,7 @@ domain:
|
|||
help: Domain to subscribe to the DynDNS service
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
-p:
|
||||
full: --recovery-password
|
||||
nargs: "?"
|
||||
|
@ -682,6 +783,7 @@ domain:
|
|||
help: Domain to unsubscribe from the DynDNS service
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
required: True
|
||||
-p:
|
||||
full: --recovery-password
|
||||
|
@ -699,6 +801,7 @@ domain:
|
|||
help: Domain to set recovery password for
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
required: True
|
||||
-p:
|
||||
full: --recovery-password
|
||||
|
@ -719,6 +822,8 @@ domain:
|
|||
arguments:
|
||||
domain:
|
||||
help: Domain name
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
key:
|
||||
help: A specific panel, section or a question identifier
|
||||
nargs: '?'
|
||||
|
@ -738,6 +843,8 @@ domain:
|
|||
arguments:
|
||||
domain:
|
||||
help: Domain name
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
key:
|
||||
help: The question or form key
|
||||
nargs: '?'
|
||||
|
@ -762,6 +869,7 @@ domain:
|
|||
help: Target domain
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
|
||||
### domain_dns_push()
|
||||
push:
|
||||
|
@ -772,6 +880,7 @@ domain:
|
|||
help: Domain name to push DNS conf for
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
-d:
|
||||
full: --dry-run
|
||||
help: Only display what's to be pushed
|
||||
|
@ -794,6 +903,9 @@ domain:
|
|||
domain_list:
|
||||
help: Domains to check
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
|
||||
--full:
|
||||
help: Show more details
|
||||
action: store_true
|
||||
|
@ -806,6 +918,8 @@ domain:
|
|||
domain_list:
|
||||
help: Domains for which to install the certificates
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
--force:
|
||||
help: Install even if current certificate is not self-signed
|
||||
action: store_true
|
||||
|
@ -824,6 +938,8 @@ domain:
|
|||
domain_list:
|
||||
help: Domains for which to renew the certificates
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
--force:
|
||||
help: Ignore the validity threshold (30 days)
|
||||
action: store_true
|
||||
|
@ -873,10 +989,18 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: Name, local path or git URL of the app to fetch the manifest of
|
||||
extra:
|
||||
autocomplete: &apps_catalog_list
|
||||
ynh_selector: app catalog
|
||||
jq_selector: '.apps | keys[]'
|
||||
use_cache: true
|
||||
-s:
|
||||
full: --with-screenshot
|
||||
help: Also return a base64 screenshot if any (API only)
|
||||
action: store_true
|
||||
extra:
|
||||
autocomplete:
|
||||
hide_in_help: true
|
||||
|
||||
### app_list()
|
||||
list:
|
||||
|
@ -899,6 +1023,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: Specific app ID
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
-f:
|
||||
full: --full
|
||||
help: Display all details, including the app manifest and various other infos
|
||||
|
@ -912,6 +1038,8 @@ app:
|
|||
-a:
|
||||
full: --app
|
||||
help: Specific app to map
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
-r:
|
||||
full: --raw
|
||||
help: Return complete dict
|
||||
|
@ -921,6 +1049,7 @@ app:
|
|||
help: Allowed app map for a user
|
||||
extra:
|
||||
pattern: *pattern_username
|
||||
autocomplete: *users_list
|
||||
|
||||
### app_install()
|
||||
install:
|
||||
|
@ -929,6 +1058,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: Name, local path or git URL of the app to install
|
||||
extra:
|
||||
autocomplete: *apps_catalog_list
|
||||
-l:
|
||||
full: --label
|
||||
help: Custom name for the app
|
||||
|
@ -951,6 +1082,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: App to remove
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
-p:
|
||||
full: --purge
|
||||
help: Also remove all application data
|
||||
|
@ -964,6 +1097,8 @@ app:
|
|||
app:
|
||||
help: App(s) to upgrade (default all)
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
-u:
|
||||
full: --url
|
||||
help: Git url to fetch for upgrade
|
||||
|
@ -990,6 +1125,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: Target app instance name
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
-d:
|
||||
full: --domain
|
||||
help: New app domain on which the application will be moved
|
||||
|
@ -997,6 +1134,7 @@ app:
|
|||
ask: ask_new_domain
|
||||
pattern: *pattern_domain
|
||||
required: True
|
||||
autocomplete: *domains_list
|
||||
-p:
|
||||
full: --path
|
||||
help: New path at which the application will be moved
|
||||
|
@ -1011,6 +1149,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: App ID
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
key:
|
||||
help: Key to get/set
|
||||
-v:
|
||||
|
@ -1029,31 +1169,41 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: App ID
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
|
||||
### app_register_url()
|
||||
register-url:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: Book/register a web path for a given app
|
||||
arguments:
|
||||
app:
|
||||
help: App which will use the web path
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
domain:
|
||||
help: The domain on which the app should be registered (e.g. your.domain.tld)
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
path:
|
||||
help: The path to be registered (e.g. /coffee)
|
||||
|
||||
|
||||
### app_makedefault()
|
||||
makedefault:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: Redirect domain root to an app
|
||||
api: PUT /apps/<app>/default
|
||||
arguments:
|
||||
app:
|
||||
help: App name to put on domain root
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
-d:
|
||||
full: --domain
|
||||
help: Specific domain to put app on (the app domain by default)
|
||||
extra:
|
||||
autocomplete: *domains_list
|
||||
-u:
|
||||
full: --undo
|
||||
help: Undo redirection
|
||||
|
@ -1061,14 +1211,19 @@ app:
|
|||
|
||||
### app_dismiss_notification
|
||||
dismiss-notification:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: Dismiss post_install or post_upgrade notification
|
||||
api: PUT /apps/<app>/dismiss_notification/<name>
|
||||
arguments:
|
||||
app:
|
||||
help: App ID to dismiss notification for
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
name:
|
||||
help: Notification name, either post_install or post_upgrade
|
||||
choices:
|
||||
- post_install
|
||||
- post_upgrade
|
||||
|
||||
### app_ssowatconf()
|
||||
ssowatconf:
|
||||
|
@ -1081,6 +1236,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: App ID
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
new_label:
|
||||
help: New app label
|
||||
|
||||
|
@ -1097,6 +1254,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: App name
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
|
||||
### app_action_run()
|
||||
run:
|
||||
|
@ -1105,6 +1264,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: App name
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
action:
|
||||
help: action id
|
||||
-a:
|
||||
|
@ -1124,6 +1285,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: App name
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
key:
|
||||
help: A specific panel, section or a question identifier
|
||||
nargs: '?'
|
||||
|
@ -1143,6 +1306,8 @@ app:
|
|||
arguments:
|
||||
app:
|
||||
help: App name
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
key:
|
||||
help: The question or panel key
|
||||
nargs: '?'
|
||||
|
@ -1191,6 +1356,8 @@ backup:
|
|||
--apps:
|
||||
help: List of application names to backup (or all if none given)
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
--dry-run:
|
||||
help: "'Simulate' the backup and return the size details per item to backup"
|
||||
action: store_true
|
||||
|
@ -1202,12 +1369,19 @@ backup:
|
|||
arguments:
|
||||
name:
|
||||
help: Name of the local backup archive
|
||||
extra:
|
||||
autocomplete: &backups_list
|
||||
ynh_selector: backup list
|
||||
jq_selector: '.archives[]'
|
||||
use_cache: false
|
||||
--system:
|
||||
help: List of system parts to restore (or all if none is given)
|
||||
nargs: "*"
|
||||
--apps:
|
||||
help: List of application names to restore (or all if none is given)
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
--force:
|
||||
help: Force restauration on an already installed system
|
||||
action: store_true
|
||||
|
@ -1233,6 +1407,8 @@ backup:
|
|||
arguments:
|
||||
name:
|
||||
help: Name of the local backup archive
|
||||
extra:
|
||||
autocomplete: *backups_list
|
||||
-d:
|
||||
full: --with-details
|
||||
help: Show additional backup information
|
||||
|
@ -1244,7 +1420,7 @@ backup:
|
|||
|
||||
### backup_download()
|
||||
download:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: (API only) Request to download the file
|
||||
api: GET /backups/<name>/download
|
||||
arguments:
|
||||
|
@ -1260,6 +1436,7 @@ backup:
|
|||
help: Name of the archive to delete
|
||||
extra:
|
||||
pattern: *pattern_backup_archive_name
|
||||
autocomplete: *backups_list
|
||||
|
||||
|
||||
#############################
|
||||
|
@ -1286,6 +1463,11 @@ settings:
|
|||
arguments:
|
||||
key:
|
||||
help: Settings key
|
||||
extra:
|
||||
autocomplete: &settings_list
|
||||
ynh_selector: settings list
|
||||
jq_selector: '. | keys[]'
|
||||
use_cache: false
|
||||
-f:
|
||||
full: --full
|
||||
help: Display all details (meant to be used by the API)
|
||||
|
@ -1303,6 +1485,8 @@ settings:
|
|||
key:
|
||||
help: The question or form key
|
||||
nargs: '?'
|
||||
extra:
|
||||
autocomplete: *settings_list
|
||||
-v:
|
||||
full: --value
|
||||
help: new value
|
||||
|
@ -1322,6 +1506,8 @@ settings:
|
|||
arguments:
|
||||
key:
|
||||
help: Settings key
|
||||
extra:
|
||||
autocomplete: *settings_list
|
||||
|
||||
#############################
|
||||
# Service #
|
||||
|
@ -1343,6 +1529,9 @@ service:
|
|||
full: --log
|
||||
help: Absolute path to log file to display
|
||||
nargs: "+"
|
||||
extra:
|
||||
autocomplete:
|
||||
zsh_completion: _files
|
||||
--test_status:
|
||||
help: Specify a custom bash command to check the status of the service. Note that it only makes sense to specify this if the corresponding systemd service does not return the proper information already.
|
||||
--test_conf:
|
||||
|
@ -1363,6 +1552,11 @@ service:
|
|||
arguments:
|
||||
name:
|
||||
help: Service name to remove
|
||||
extra:
|
||||
autocomplete: &services_list
|
||||
ynh_selector: service status
|
||||
jq_selector: '. | keys[]'
|
||||
use_cache: false
|
||||
|
||||
### service_start()
|
||||
start:
|
||||
|
@ -1373,6 +1567,8 @@ service:
|
|||
help: Service name to start
|
||||
nargs: "+"
|
||||
metavar: NAME
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
|
||||
### service_stop()
|
||||
stop:
|
||||
|
@ -1383,6 +1579,8 @@ service:
|
|||
help: Service name to stop
|
||||
nargs: "+"
|
||||
metavar: NAME
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
|
||||
### service_reload()
|
||||
reload:
|
||||
|
@ -1392,6 +1590,8 @@ service:
|
|||
help: Service name to reload
|
||||
nargs: "+"
|
||||
metavar: NAME
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
|
||||
### service_restart()
|
||||
restart:
|
||||
|
@ -1402,6 +1602,8 @@ service:
|
|||
help: Service name to restart
|
||||
nargs: "+"
|
||||
metavar: NAME
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
|
||||
### service_reload_or_restart()
|
||||
reload_or_restart:
|
||||
|
@ -1411,6 +1613,8 @@ service:
|
|||
help: Service name to reload or restart
|
||||
nargs: "+"
|
||||
metavar: NAME
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
|
||||
### service_enable()
|
||||
enable:
|
||||
|
@ -1421,6 +1625,8 @@ service:
|
|||
help: Service name to enable
|
||||
nargs: "+"
|
||||
metavar: NAME
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
|
||||
### service_disable()
|
||||
disable:
|
||||
|
@ -1431,6 +1637,8 @@ service:
|
|||
help: Service name to disable
|
||||
nargs: "+"
|
||||
metavar: NAME
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
|
||||
### service_status()
|
||||
status:
|
||||
|
@ -1443,6 +1651,8 @@ service:
|
|||
help: Service name to show
|
||||
nargs: "*"
|
||||
metavar: NAME
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
|
||||
### service_log()
|
||||
log:
|
||||
|
@ -1451,6 +1661,8 @@ service:
|
|||
arguments:
|
||||
name:
|
||||
help: Service name to log
|
||||
extra:
|
||||
autocomplete: *services_list
|
||||
-n:
|
||||
full: --number
|
||||
help: Number of lines to display
|
||||
|
@ -1596,6 +1808,7 @@ dyndns:
|
|||
help: Full domain to subscribe with ( deprecated, use 'yunohost domain dyndns subscribe' instead )
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
-p:
|
||||
full: --recovery-password
|
||||
nargs: "?"
|
||||
|
@ -1613,6 +1826,7 @@ dyndns:
|
|||
help: Full domain to update
|
||||
extra:
|
||||
pattern: *pattern_domain
|
||||
autocomplete: *domains_list
|
||||
-f:
|
||||
full: --force
|
||||
help: Force the update (for debugging only)
|
||||
|
@ -1668,6 +1882,7 @@ tools:
|
|||
ask: ask_main_domain
|
||||
pattern: *pattern_domain
|
||||
required: True
|
||||
autocomplete: *domains_list
|
||||
-u:
|
||||
full: --username
|
||||
help: Username for the first (admin) user. For example 'camille'
|
||||
|
@ -1675,6 +1890,7 @@ tools:
|
|||
ask: ask_admin_username
|
||||
pattern: *pattern_username
|
||||
required: True
|
||||
autocomplete: *users_list
|
||||
-F:
|
||||
full: --fullname
|
||||
help: The full name for the first (admin) user. For example 'Camille Dupont'
|
||||
|
@ -1826,6 +2042,11 @@ tools:
|
|||
targets:
|
||||
help: Migrations to run (all pendings by default)
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: &migrations_list
|
||||
ynh_selector: tools migrations list
|
||||
jq_selector: '.migrations[].id'
|
||||
use_cache: false
|
||||
--skip:
|
||||
help: Skip specified migrations (to be used only if you know what you are doing)
|
||||
action: store_true
|
||||
|
@ -1857,8 +2078,13 @@ hook:
|
|||
arguments:
|
||||
app:
|
||||
help: App to link with
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
file:
|
||||
help: Script to add
|
||||
extra:
|
||||
autocomplete:
|
||||
zsh_completion: _files
|
||||
|
||||
### hook_remove()
|
||||
remove:
|
||||
|
@ -1866,14 +2092,35 @@ hook:
|
|||
arguments:
|
||||
app:
|
||||
help: Scripts related to app will be removed
|
||||
extra:
|
||||
autocomplete: *apps_list
|
||||
|
||||
### hook_info()
|
||||
info:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: Get information about a given hook
|
||||
arguments:
|
||||
action:
|
||||
help: Action name
|
||||
choices: &hook_action_choices
|
||||
- post_user_create
|
||||
- post_user_delete
|
||||
- post_user_update
|
||||
- post_app_addaccess
|
||||
- post_app_removeaccess
|
||||
- post_domain_add
|
||||
- post_domain_remove
|
||||
- post_cert_update
|
||||
- custom_dns_rules
|
||||
- post_app_change_url
|
||||
- post_app_upgrade
|
||||
- post_app_install
|
||||
- post_app_remove
|
||||
- backup
|
||||
- restore
|
||||
- backup_method
|
||||
- post_iptable_rules
|
||||
- conf_regen
|
||||
name:
|
||||
help: Hook name
|
||||
|
||||
|
@ -1884,6 +2131,7 @@ hook:
|
|||
arguments:
|
||||
action:
|
||||
help: Action name
|
||||
choices: *hook_action_choices
|
||||
-l:
|
||||
full: --list-by
|
||||
help: Property to list hook by
|
||||
|
@ -1899,11 +2147,12 @@ hook:
|
|||
|
||||
### hook_callback()
|
||||
callback:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: Execute all scripts binded to an action
|
||||
arguments:
|
||||
action:
|
||||
help: Action name
|
||||
choices: *hook_action_choices
|
||||
-n:
|
||||
full: --hooks
|
||||
help: List of hooks names to execute
|
||||
|
@ -1922,11 +2171,15 @@ hook:
|
|||
|
||||
### hook_exec()
|
||||
exec:
|
||||
hide_in_help: True
|
||||
hide_in_help: true
|
||||
action_help: Execute hook from a file with arguments
|
||||
arguments:
|
||||
path:
|
||||
help: Path of the script to execute
|
||||
extra:
|
||||
autocomplete:
|
||||
zsh_completion: _files
|
||||
|
||||
-a:
|
||||
full: --args
|
||||
help: Ordered list of arguments to pass to the script
|
||||
|
@ -1977,6 +2230,11 @@ log:
|
|||
arguments:
|
||||
path:
|
||||
help: Log file which to display the content
|
||||
extra:
|
||||
autocomplete: &logs_list
|
||||
ynh_selector: log list
|
||||
jq_selector: '.operation[].name'
|
||||
use_cache: false
|
||||
-n:
|
||||
full: --number
|
||||
help: Number of lines to display
|
||||
|
@ -2001,6 +2259,8 @@ log:
|
|||
arguments:
|
||||
path:
|
||||
help: Log file to share
|
||||
extra:
|
||||
autocomplete: *logs_list
|
||||
|
||||
|
||||
#############################
|
||||
|
@ -2021,6 +2281,12 @@ diagnosis:
|
|||
categories:
|
||||
help: Diagnosis categories to display (all by default)
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: &diagnosis_list
|
||||
ynh_selector: diagnosis list
|
||||
jq_selector: '.categories[]'
|
||||
use_cache: false
|
||||
|
||||
--full:
|
||||
help: Display additional information
|
||||
action: store_true
|
||||
|
@ -2040,6 +2306,8 @@ diagnosis:
|
|||
arguments:
|
||||
category:
|
||||
help: Diagnosis category to fetch results from
|
||||
extra:
|
||||
autocomplete: *diagnosis_list
|
||||
item:
|
||||
help: "List of criteria describing the test. Must correspond exactly to the 'meta' infos in 'yunohost diagnosis show'"
|
||||
metavar: CRITERIA
|
||||
|
@ -2052,6 +2320,8 @@ diagnosis:
|
|||
categories:
|
||||
help: Diagnosis categories to run (all by default)
|
||||
nargs: "*"
|
||||
extra:
|
||||
autocomplete: *diagnosis_list
|
||||
--force:
|
||||
help: Ignore the cached report even if it is still 'fresh'
|
||||
action: store_true
|
||||
|
|
Loading…
Add table
Reference in a new issue