Mini Shell
"""
Support for the Mercurial SCM
"""
import logging
import salt.utils.data
import salt.utils.path
from salt.exceptions import CommandExecutionError
log = logging.getLogger(__name__)
def __virtual__():
"""
Only load if hg is installed
"""
if salt.utils.path.which("hg") is None:
return (False, "The hg execution module cannot be loaded: hg unavailable.")
else:
return True
def _ssh_flag(identity_path):
return ["--ssh", f"ssh -i {identity_path}"]
def revision(cwd, rev="tip", short=False, user=None):
"""
Returns the long hash of a given identifier (hash, branch, tag, HEAD, etc)
cwd
The path to the Mercurial repository
rev: tip
The revision
short: False
Return an abbreviated commit hash
user : None
Run hg as a user other than what the minion runs as
CLI Example:
.. code-block:: bash
salt '*' hg.revision /path/to/repo mybranch
"""
cmd = ["hg", "id", "-i", "--debug" if not short else "", "-r", f"{rev}"]
result = __salt__["cmd.run_all"](cmd, cwd=cwd, runas=user, python_shell=False)
if result["retcode"] == 0:
return result["stdout"]
else:
return ""
def describe(cwd, rev="tip", user=None):
"""
Mimic git describe and return an identifier for the given revision
cwd
The path to the Mercurial repository
rev: tip
The path to the archive tarball
user : None
Run hg as a user other than what the minion runs as
CLI Example:
.. code-block:: bash
salt '*' hg.describe /path/to/repo
"""
cmd = [
"hg",
"log",
"-r",
f"{rev}",
"--template",
"'{{latesttag}}-{{latesttagdistance}}-{{node|short}}'",
]
desc = __salt__["cmd.run_stdout"](cmd, cwd=cwd, runas=user, python_shell=False)
return desc or revision(cwd, rev, short=True)
def archive(cwd, output, rev="tip", fmt=None, prefix=None, user=None):
"""
Export a tarball from the repository
cwd
The path to the Mercurial repository
output
The path to the archive tarball
rev: tip
The revision to create an archive from
fmt: None
Format of the resulting archive. Mercurial supports: tar,
tbz2, tgz, zip, uzip, and files formats.
prefix : None
Prepend <prefix>/ to every filename in the archive
user : None
Run hg as a user other than what the minion runs as
If ``prefix`` is not specified it defaults to the basename of the repo
directory.
CLI Example:
.. code-block:: bash
salt '*' hg.archive /path/to/repo output=/tmp/archive.tgz fmt=tgz
"""
cmd = [
"hg",
"archive",
f"{output}",
"--rev",
f"{rev}",
]
if fmt:
cmd.append("--type")
cmd.append(f"{fmt}")
if prefix:
cmd.append("--prefix")
cmd.append(f'"{prefix}"')
return __salt__["cmd.run"](cmd, cwd=cwd, runas=user, python_shell=False)
def pull(cwd, opts=None, user=None, identity=None, repository=None):
"""
Perform a pull on the given repository
cwd
The path to the Mercurial repository
repository : None
Perform pull from the repository different from .hg/hgrc:[paths]:default
opts : None
Any additional options to add to the command line
user : None
Run hg as a user other than what the minion runs as
identity : None
Private SSH key on the minion server for authentication (ssh://)
.. versionadded:: 2015.5.0
CLI Example:
.. code-block:: bash
salt '*' hg.pull /path/to/repo opts=-u
"""
cmd = ["hg", "pull"]
if identity:
cmd.extend(_ssh_flag(identity))
if opts:
for opt in opts.split():
cmd.append(opt)
if repository is not None:
cmd.append(repository)
ret = __salt__["cmd.run_all"](cmd, cwd=cwd, runas=user, python_shell=False)
if ret["retcode"] != 0:
raise CommandExecutionError(
"Hg command failed: {}".format(ret.get("stderr", ret["stdout"]))
)
return ret["stdout"]
def update(cwd, rev, force=False, user=None):
"""
Update to a given revision
cwd
The path to the Mercurial repository
rev
The revision to update to
force : False
Force an update
user : None
Run hg as a user other than what the minion runs as
CLI Example:
.. code-block:: bash
salt devserver1 hg.update /path/to/repo somebranch
"""
cmd = ["hg", "update", f"{rev}"]
if force:
cmd.append("-C")
ret = __salt__["cmd.run_all"](cmd, cwd=cwd, runas=user, python_shell=False)
if ret["retcode"] != 0:
raise CommandExecutionError(
"Hg command failed: {}".format(ret.get("stderr", ret["stdout"]))
)
return ret["stdout"]
def clone(cwd, repository, opts=None, user=None, identity=None):
"""
Clone a new repository
cwd
The path to the Mercurial repository
repository
The hg URI of the repository
opts : None
Any additional options to add to the command line
user : None
Run hg as a user other than what the minion runs as
identity : None
Private SSH key on the minion server for authentication (ssh://)
.. versionadded:: 2015.5.0
CLI Example:
.. code-block:: bash
salt '*' hg.clone /path/to/repo https://bitbucket.org/birkenfeld/sphinx
"""
cmd = ["hg", "clone", f"{repository}", f"{cwd}"]
if opts:
for opt in opts.split():
cmd.append(f"{opt}")
if identity:
cmd.extend(_ssh_flag(identity))
ret = __salt__["cmd.run_all"](cmd, runas=user, python_shell=False)
if ret["retcode"] != 0:
raise CommandExecutionError(
"Hg command failed: {}".format(ret.get("stderr", ret["stdout"]))
)
return ret["stdout"]
def status(cwd, opts=None, user=None):
"""
Show changed files of the given repository
cwd
The path to the Mercurial repository
opts : None
Any additional options to add to the command line
user : None
Run hg as a user other than what the minion runs as
CLI Example:
.. code-block:: bash
salt '*' hg.status /path/to/repo
"""
def _status(cwd):
cmd = ["hg", "status"]
if opts:
for opt in opts.split():
cmd.append(f"{opt}")
out = __salt__["cmd.run_stdout"](cmd, cwd=cwd, runas=user, python_shell=False)
types = {
"M": "modified",
"A": "added",
"R": "removed",
"C": "clean",
"!": "missing",
"?": "not tracked",
"I": "ignored",
" ": "origin of the previous file",
}
ret = {}
for line in out.splitlines():
t, f = types[line[0]], line[2:]
if t not in ret:
ret[t] = []
ret[t].append(f)
return ret
if salt.utils.data.is_iter(cwd):
return {cwd: _status(cwd) for cwd in cwd}
else:
return _status(cwd)
Zerion Mini Shell 1.0