summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/cli.rst23
-rw-r--r--gitlab/cli.py20
-rw-r--r--gitlab/v4/cli.py59
3 files changed, 76 insertions, 26 deletions
diff --git a/docs/cli.rst b/docs/cli.rst
index 8d0550b..349ee02 100644
--- a/docs/cli.rst
+++ b/docs/cli.rst
@@ -80,10 +80,11 @@ section.
* - ``url``
- URL for the GitLab server
* - ``private_token``
- - Your user token. Login/password is not supported.
- Refer `the official documentation`__ to learn how to obtain a token.
+ - Your user token. Login/password is not supported. Refer to `the official
+ documentation`__ to learn how to obtain a token.
* - ``api_version``
- - API version to use (``3`` or ``4``), defaults to ``3``
+ - GitLab API version to use (``3`` or ``4``). Defaults to ``3`` for now,
+ but will switch to ``4`` eventually.
* - ``http_username``
- Username for optional HTTP authentication
* - ``http_password``
@@ -126,7 +127,8 @@ Use the following optional arguments to change the behavior of ``gitlab``.
These options must be defined before the mandatory arguments.
``--verbose``, ``-v``
- Outputs detail about retrieved objects.
+ Outputs detail about retrieved objects. Available for legacy (default)
+ output only.
``--config-file``, ``-c``
Path to a configuration file.
@@ -134,11 +136,18 @@ These options must be defined before the mandatory arguments.
``--gitlab``, ``-g``
ID of a GitLab server defined in the configuration file.
+``--output``, ``-o``
+ Output format. Defaults to a custom format. Can also be ``yaml`` or ``json``.
+
+``--fields``, ``-f``
+ Comma-separated list of fields to display (``yaml`` and ``json`` formats
+ only). If not used, all the object fields are displayed.
+
Example:
.. code-block:: console
- $ gitlab -v -g elsewhere -c /tmp/gl.cfg project list
+ $ gitlab -o yaml -f id,permissions -g elsewhere -c /tmp/gl.cfg project list
Examples
@@ -168,12 +177,11 @@ Get a specific project (id 2):
$ gitlab project get --id 2
-Get a specific user by id or by username:
+Get a specific user by id:
.. code-block:: console
$ gitlab user get --id 3
- $ gitlab user get-by-username --query jdoe
Get a list of snippets for this project:
@@ -200,7 +208,6 @@ Create a snippet:
$ gitlab project-snippet create --project-id 2
Impossible to create object (Missing attribute(s): title, file-name, code)
-
$ # oops, let's add the attributes:
$ gitlab project-snippet create --project-id 2 --title "the title" \
--file-name "the name" --code "the code"
diff --git a/gitlab/cli.py b/gitlab/cli.py
index d803eb5..f6b357b 100644
--- a/gitlab/cli.py
+++ b/gitlab/cli.py
@@ -51,7 +51,6 @@ def register_custom_action(cls_name, mandatory=tuple(), optional=tuple()):
custom_actions[final_name] = {}
action = f.__name__
-
custom_actions[final_name][action] = (mandatory, optional, in_obj)
return wrapped_f
@@ -79,7 +78,7 @@ def _get_base_parser():
parser.add_argument("--version", help="Display the version.",
action="store_true")
parser.add_argument("-v", "--verbose", "--fancy",
- help="Verbose mode",
+ help="Verbose mode (legacy format only)",
action="store_true")
parser.add_argument("-d", "--debug",
help="Debug mode (display HTTP requests",
@@ -92,6 +91,15 @@ def _get_base_parser():
"be used. If not defined, the default selection "
"will be used."),
required=False)
+ parser.add_argument("-o", "--output",
+ help=("Output format (v4 only): json|legacy|yaml"),
+ required=False,
+ choices=['json', 'legacy', 'yaml'],
+ default="legacy")
+ parser.add_argument("-f", "--fields",
+ help=("Fields to display in the output (comma "
+ "separated). Not used with legacy output"),
+ required=False)
return parser
@@ -117,6 +125,10 @@ def main():
config_files = args.config_file
gitlab_id = args.gitlab
verbose = args.verbose
+ output = args.output
+ fields = []
+ if args.fields:
+ fields = [x.strip() for x in args.fields.split(',')]
debug = args.debug
action = args.action
what = args.what
@@ -124,7 +136,7 @@ def main():
args = args.__dict__
# Remove CLI behavior-related args
for item in ('gitlab', 'config_file', 'verbose', 'debug', 'what', 'action',
- 'version'):
+ 'version', 'output'):
args.pop(item)
args = {k: v for k, v in args.items() if v is not None}
@@ -137,6 +149,6 @@ def main():
if debug:
gl.enable_debug()
- cli_module.run(gl, what, action, args, verbose)
+ cli_module.run(gl, what, action, args, verbose, output, fields)
sys.exit(0)
diff --git a/gitlab/v4/cli.py b/gitlab/v4/cli.py
index 821a27d..ca5c6b1 100644
--- a/gitlab/v4/cli.py
+++ b/gitlab/v4/cli.py
@@ -245,30 +245,47 @@ def extend_parser(parser):
return parser
+class JSONPrinter(object):
+ def display(self, d, **kwargs):
+ import json # noqa
+
+ print(json.dumps(d))
+
+
+class YAMLPrinter(object):
+ def display(self, d, **kwargs):
+ import yaml # noqa
+
+ print(yaml.safe_dump(d, default_flow_style=False))
+
+
class LegacyPrinter(object):
- def display(self, obj, verbose=False, padding=0):
- def display_dict(d):
+ def display(self, d, **kwargs):
+ verbose = kwargs.get('verbose', False)
+ padding = kwargs.get('padding', 0)
+ obj = kwargs.get('obj')
+
+ def display_dict(d, padding):
for k in sorted(d.keys()):
v = d[k]
if isinstance(v, dict):
print('%s%s:' % (' ' * padding, k))
new_padding = padding + 2
- self.display(v, True, new_padding)
+ self.display(v, verbose=True, padding=new_padding, obj=v)
continue
print('%s%s: %s' % (' ' * padding, k, v))
if verbose:
if isinstance(obj, dict):
- display_dict(obj)
+ display_dict(obj, padding)
return
# not a dict, we assume it's a RESTObject
- id = getattr(obj, obj._id_attr)
+ id = getattr(obj, obj._id_attr, None)
print('%s: %s' % (obj._id_attr, id))
attrs = obj.attributes
attrs.pop(obj._id_attr)
- display_dict(attrs)
- print('')
+ display_dict(attrs, padding)
else:
id = getattr(obj, obj._id_attr)
@@ -278,19 +295,33 @@ class LegacyPrinter(object):
print('%s: %s' % (obj._short_print_attr, value))
-def run(gl, what, action, args, verbose):
+PRINTERS = {
+ 'json': JSONPrinter,
+ 'legacy': LegacyPrinter,
+ 'yaml': YAMLPrinter,
+}
+
+
+def run(gl, what, action, args, verbose, output, fields):
g_cli = GitlabCLI(gl, what, action, args)
ret_val = g_cli()
- printer = LegacyPrinter()
+ printer = PRINTERS[output]()
+
+ def get_dict(obj):
+ if fields:
+ return {k: v for k, v in obj.attributes.items()
+ if k in fields}
+ return obj.attributes
if isinstance(ret_val, list):
- for o in ret_val:
- if isinstance(o, gitlab.base.RESTObject):
- printer.display(o, verbose)
+ for obj in ret_val:
+ if isinstance(obj, gitlab.base.RESTObject):
+ printer.display(get_dict(obj), verbose=verbose, obj=obj)
else:
- print(o)
+ print(obj)
+ print('')
elif isinstance(ret_val, gitlab.base.RESTObject):
- printer.display(ret_val, verbose)
+ printer.display(get_dict(ret_val), verbose=verbose, obj=ret_val)
elif isinstance(ret_val, six.string_types):
print(ret_val)