summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gitlab/cli.py145
-rw-r--r--gitlab/tests/test_cli.py95
-rw-r--r--gitlab/tests/test_gitlabobject.py4
3 files changed, 172 insertions, 72 deletions
diff --git a/gitlab/cli.py b/gitlab/cli.py
index 4c20558..fc4c029 100644
--- a/gitlab/cli.py
+++ b/gitlab/cli.py
@@ -63,69 +63,6 @@ def _cls_to_what(cls):
return camel_re.sub(r'\1-\2', cls.__name__).lower()
-def _populate_sub_parser_by_class(cls, sub_parser):
- for action_name in ['list', 'get', 'create', 'update', 'delete']:
- attr = 'can' + action_name.capitalize()
- if not getattr(cls, attr):
- continue
- sub_parser_action = sub_parser.add_parser(action_name)
- [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
- required=True)
- for x in cls.requiredUrlAttrs]
- sub_parser_action.add_argument("--sudo", required=False)
-
- if action_name == "list":
- [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
- required=True)
- for x in cls.requiredListAttrs]
- sub_parser_action.add_argument("--page", required=False)
- sub_parser_action.add_argument("--per-page", required=False)
-
- elif action_name in ["get", "delete"]:
- if cls not in [gitlab.CurrentUser]:
- if cls.getRequiresId:
- id_attr = cls.idAttr.replace('_', '-')
- sub_parser_action.add_argument("--%s" % id_attr,
- required=True)
- [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
- required=True)
- for x in cls.requiredGetAttrs if x != cls.idAttr]
-
- elif action_name == "create":
- [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
- required=True)
- for x in cls.requiredCreateAttrs]
- [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
- required=False)
- for x in cls.optionalCreateAttrs]
-
- elif action_name == "update":
- id_attr = cls.idAttr.replace('_', '-')
- sub_parser_action.add_argument("--%s" % id_attr,
- required=True)
-
- attrs = (cls.requiredUpdateAttrs
- if (cls.requiredUpdateAttrs or cls.optionalUpdateAttrs)
- else cls.requiredCreateAttrs)
- [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
- required=True)
- for x in attrs if x != cls.idAttr]
-
- attrs = (cls.optionalUpdateAttrs
- if (cls.requiredUpdateAttrs or cls.optionalUpdateAttrs)
- else cls.optionalCreateAttrs)
- [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
- required=False)
- for x in attrs]
-
- if cls in EXTRA_ACTIONS:
- for action_name in sorted(EXTRA_ACTIONS[cls]):
- sub_parser_action = sub_parser.add_parser(action_name)
- d = EXTRA_ACTIONS[cls][action_name]
- [sub_parser_action.add_argument("--%s" % arg, required=True)
- for arg in d.get('required', [])]
-
-
def do_auth(gitlab_id, config_files):
try:
gl = gitlab.Gitlab.from_config(gitlab_id, config_files)
@@ -286,11 +223,70 @@ class GitlabCLI(object):
_die("Impossible to get milestone issues (%s)" % str(e))
-def main():
- if "--version" in sys.argv:
- print(gitlab.__version__)
- exit(0)
+def _populate_sub_parser_by_class(cls, sub_parser):
+ for action_name in ['list', 'get', 'create', 'update', 'delete']:
+ attr = 'can' + action_name.capitalize()
+ if not getattr(cls, attr):
+ continue
+ sub_parser_action = sub_parser.add_parser(action_name)
+ [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
+ required=True)
+ for x in cls.requiredUrlAttrs]
+ sub_parser_action.add_argument("--sudo", required=False)
+
+ if action_name == "list":
+ [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
+ required=True)
+ for x in cls.requiredListAttrs]
+ sub_parser_action.add_argument("--page", required=False)
+ sub_parser_action.add_argument("--per-page", required=False)
+ elif action_name in ["get", "delete"]:
+ if cls not in [gitlab.CurrentUser]:
+ if cls.getRequiresId:
+ id_attr = cls.idAttr.replace('_', '-')
+ sub_parser_action.add_argument("--%s" % id_attr,
+ required=True)
+ [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
+ required=True)
+ for x in cls.requiredGetAttrs if x != cls.idAttr]
+
+ elif action_name == "create":
+ [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
+ required=True)
+ for x in cls.requiredCreateAttrs]
+ [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
+ required=False)
+ for x in cls.optionalCreateAttrs]
+
+ elif action_name == "update":
+ id_attr = cls.idAttr.replace('_', '-')
+ sub_parser_action.add_argument("--%s" % id_attr,
+ required=True)
+
+ attrs = (cls.requiredUpdateAttrs
+ if (cls.requiredUpdateAttrs or cls.optionalUpdateAttrs)
+ else cls.requiredCreateAttrs)
+ [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
+ required=True)
+ for x in attrs if x != cls.idAttr]
+
+ attrs = (cls.optionalUpdateAttrs
+ if (cls.requiredUpdateAttrs or cls.optionalUpdateAttrs)
+ else cls.optionalCreateAttrs)
+ [sub_parser_action.add_argument("--%s" % x.replace('_', '-'),
+ required=False)
+ for x in attrs]
+
+ if cls in EXTRA_ACTIONS:
+ for action_name in sorted(EXTRA_ACTIONS[cls]):
+ sub_parser_action = sub_parser.add_parser(action_name)
+ d = EXTRA_ACTIONS[cls][action_name]
+ [sub_parser_action.add_argument("--%s" % arg, required=True)
+ for arg in d.get('required', [])]
+
+
+def _build_parser(args=sys.argv[1:]):
parser = argparse.ArgumentParser(
description="GitLab API Command Line Interface")
parser.add_argument("--version", help="Display the version.",
@@ -330,7 +326,20 @@ def main():
_populate_sub_parser_by_class(cls, object_subparsers)
object_subparsers.required = True
- arg = parser.parse_args()
+ return parser
+
+
+def _parse_args(args=sys.argv[1:]):
+ parser = _build_parser()
+ return parser.parse_args(args)
+
+
+def main():
+ if "--version" in sys.argv:
+ print(gitlab.__version__)
+ exit(0)
+
+ arg = _parse_args()
args = arg.__dict__
config_files = arg.config_file
diff --git a/gitlab/tests/test_cli.py b/gitlab/tests/test_cli.py
new file mode 100644
index 0000000..c32ad50
--- /dev/null
+++ b/gitlab/tests/test_cli.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2016 Gauvain Pocentek <gauvain@pocentek.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from __future__ import print_function
+from __future__ import absolute_import
+
+import argparse
+
+import six
+try:
+ import unittest
+except ImportError:
+ import unittest2 as unittest
+
+from gitlab import cli
+
+
+class TestCLI(unittest.TestCase):
+ def test_what_to_cls(self):
+ self.assertEqual("Foo", cli._what_to_cls("foo"))
+ self.assertEqual("FooBar", cli._what_to_cls("foo-bar"))
+
+ def test_cls_to_what(self):
+ class Class(object):
+ pass
+
+ class TestClass(object):
+ pass
+
+ self.assertEqual("test-class", cli._cls_to_what(TestClass))
+ self.assertEqual("class", cli._cls_to_what(Class))
+
+ def test_die(self):
+ with self.assertRaises(SystemExit) as test:
+ cli._die("foobar")
+
+ self.assertEqual(test.exception.code, 1)
+
+ def test_extra_actions(self):
+ for cls, data in six.iteritems(cli.EXTRA_ACTIONS):
+ for key in data:
+ self.assertIsInstance(data[key], dict)
+
+ def test_parsing(self):
+ args = cli._parse_args(['-v', '-g', 'gl_id',
+ '-c', 'foo.cfg', '-c', 'bar.cfg',
+ 'project', 'list'])
+ self.assertTrue(args.verbose)
+ self.assertEqual(args.gitlab, 'gl_id')
+ self.assertEqual(args.config_file, ['foo.cfg', 'bar.cfg'])
+ self.assertEqual(args.what, 'project')
+ self.assertEqual(args.action, 'list')
+
+ def test_parser(self):
+ parser = cli._build_parser()
+ subparsers = None
+ for action in parser._actions:
+ if type(action) == argparse._SubParsersAction:
+ subparsers = action
+ break
+ self.assertIsNotNone(subparsers)
+ self.assertIn('user', subparsers.choices)
+
+ user_subparsers = None
+ for action in subparsers.choices['user']._actions:
+ if type(action) == argparse._SubParsersAction:
+ user_subparsers = action
+ break
+ self.assertIsNotNone(user_subparsers)
+ self.assertIn('list', user_subparsers.choices)
+ self.assertIn('get', user_subparsers.choices)
+ self.assertIn('delete', user_subparsers.choices)
+ self.assertIn('update', user_subparsers.choices)
+ self.assertIn('create', user_subparsers.choices)
+ self.assertIn('block', user_subparsers.choices)
+ self.assertIn('unblock', user_subparsers.choices)
+
+ actions = user_subparsers.choices['create']._option_string_actions
+ self.assertFalse(actions['--twitter'].required)
+ self.assertTrue(actions['--username'].required)
diff --git a/gitlab/tests/test_gitlabobject.py b/gitlab/tests/test_gitlabobject.py
index e001a8c..aea80ca 100644
--- a/gitlab/tests/test_gitlabobject.py
+++ b/gitlab/tests/test_gitlabobject.py
@@ -492,7 +492,3 @@ class TestProjectSnippet(unittest.TestCase):
def test_blob_fail(self):
with HTTMock(self.resp_content_fail):
self.assertRaises(GitlabGetError, self.obj.Content)
-
-
-if __name__ == "__main__":
- main()