Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1940fee

Browse files
author
Gauvain Pocentek
committed
Implement attribute types to handle special cases
Some attributes need to be parsed/modified to work with the API (forinstance lists). This patch provides two attribute types that willsimplify parts of the code, and fix some CLI bugs.Fixes#443
1 parent455a8fc commit1940fee

File tree

6 files changed

+169
-20
lines changed

6 files changed

+169
-20
lines changed

‎docs/cli.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ Use sudo to act as another user (admin only):
235235
236236
$ gitlab project create --name user_project1 --sudo username
237237
238+
List values are comma-separated:
239+
240+
..code-block::console
241+
242+
$ gitlab issue list --labels foo,bar
243+
238244
Reading values from files
239245
-------------------------
240246

‎gitlab/mixins.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,21 @@ def list(self, **kwargs):
108108
GitlabListError: If the server cannot perform the request
109109
"""
110110

111+
# Duplicate data to avoid messing with what the user sent us
112+
data=kwargs.copy()
113+
114+
# We get the attributes that need some special transformation
115+
types=getattr(self,'_types', {})
116+
iftypes:
117+
forattr_name,type_clsintypes.items():
118+
ifattr_nameindata.keys():
119+
type_obj=type_cls(data[attr_name])
120+
data[attr_name]=type_obj.get_for_api()
121+
111122
# Allow to overwrite the path, handy for custom listings
112-
path=kwargs.pop('path',self.path)
113-
obj=self.gitlab.http_list(path,**kwargs)
123+
path=data.pop('path',self.path)
124+
125+
obj=self.gitlab.http_list(path,**data)
114126
ifisinstance(obj,list):
115127
return [self._obj_cls(self,item)foriteminobj]
116128
else:
@@ -187,8 +199,22 @@ def create(self, data, **kwargs):
187199
GitlabCreateError: If the server cannot perform the request
188200
"""
189201
self._check_missing_create_attrs(data)
202+
203+
# special handling of the object if needed
190204
ifhasattr(self,'_sanitize_data'):
191205
data=self._sanitize_data(data,'create')
206+
207+
# We get the attributes that need some special transformation
208+
types=getattr(self,'_types', {})
209+
210+
iftypes:
211+
# Duplicate data to avoid messing with what the user sent us
212+
data=data.copy()
213+
forattr_name,type_clsintypes.items():
214+
ifattr_nameindata.keys():
215+
type_obj=type_cls(data[attr_name])
216+
data[attr_name]=type_obj.get_for_api()
217+
192218
# Handle specific URL for creation
193219
path=kwargs.pop('path',self.path)
194220
server_data=self.gitlab.http_post(path,post_data=data,**kwargs)
@@ -238,11 +264,20 @@ def update(self, id=None, new_data={}, **kwargs):
238264
path='%s/%s'% (self.path,id)
239265

240266
self._check_missing_update_attrs(new_data)
267+
268+
# special handling of the object if needed
241269
ifhasattr(self,'_sanitize_data'):
242270
data=self._sanitize_data(new_data,'update')
243271
else:
244272
data=new_data
245273

274+
# We get the attributes that need some special transformation
275+
types=getattr(self,'_types', {})
276+
forattr_name,type_clsintypes.items():
277+
ifattr_nameindata.keys():
278+
type_obj=type_cls(data[attr_name])
279+
data[attr_name]=type_obj.get_for_api()
280+
246281
returnself.gitlab.http_put(path,post_data=data,**kwargs)
247282

248283

‎gitlab/tests/test_types.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (C) 2018 Gauvain Pocentek <gauvain@pocentek.net>
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU Lesser General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU Lesser General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Lesser General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
try:
19+
importunittest
20+
exceptImportError:
21+
importunittest2asunittest
22+
23+
fromgitlabimporttypes
24+
25+
26+
classTestGitlabAttribute(unittest.TestCase):
27+
deftest_all(self):
28+
o=types.GitlabAttribute('whatever')
29+
self.assertEqual('whatever',o.get())
30+
31+
o.set_from_cli('whatever2')
32+
self.assertEqual('whatever2',o.get())
33+
34+
self.assertEqual('whatever2',o.get_for_api())
35+
36+
o=types.GitlabAttribute()
37+
self.assertEqual(None,o._value)
38+
39+
40+
classTestListAttribute(unittest.TestCase):
41+
deftest_list_input(self):
42+
o=types.ListAttribute()
43+
o.set_from_cli('foo,bar,baz')
44+
self.assertEqual(['foo','bar','baz'],o.get())
45+
46+
o.set_from_cli('foo')
47+
self.assertEqual(['foo'],o.get())
48+
49+
deftest_empty_input(self):
50+
o=types.ListAttribute()
51+
o.set_from_cli('')
52+
self.assertEqual([],o.get())
53+
54+
o.set_from_cli(' ')
55+
self.assertEqual([],o.get())
56+
57+
deftest_get_for_api(self):
58+
o=types.ListAttribute()
59+
o.set_from_cli('foo,bar,baz')
60+
self.assertEqual('foo,bar,baz',o.get_for_api())
61+
62+
63+
classTestLowercaseStringAttribute(unittest.TestCase):
64+
deftest_get_for_api(self):
65+
o=types.LowercaseStringAttribute('FOO')
66+
self.assertEqual('foo',o.get_for_api())

‎gitlab/types.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (C) 2018 Gauvain Pocentek <gauvain@pocentek.net>
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU Lesser General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU Lesser General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Lesser General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
19+
classGitlabAttribute(object):
20+
def__init__(self,value=None):
21+
self._value=value
22+
23+
defget(self):
24+
returnself._value
25+
26+
defset_from_cli(self,cli_value):
27+
self._value=cli_value
28+
29+
defget_for_api(self):
30+
returnself._value
31+
32+
33+
classListAttribute(GitlabAttribute):
34+
defset_from_cli(self,cli_value):
35+
ifnotcli_value.strip():
36+
self._value= []
37+
else:
38+
self._value= [item.strip()foritemincli_value.split(',')]
39+
40+
defget_for_api(self):
41+
return",".join(self._value)
42+
43+
44+
classLowercaseStringAttribute(GitlabAttribute):
45+
defget_for_api(self):
46+
returnstr(self._value).lower()

‎gitlab/v4/cli.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ def __init__(self, gl, what, action, args):
4545
self.mgr_cls._path=self.mgr_cls._path%self.args
4646
self.mgr=self.mgr_cls(gl)
4747

48+
types=getattr(self.mgr_cls,'_types', {})
49+
iftypes:
50+
forattr_name,type_clsintypes.items():
51+
ifattr_nameinself.args.keys():
52+
obj=type_cls()
53+
obj.set_from_cli(self.args[attr_name])
54+
self.args[attr_name]=obj.get()
55+
4856
def__call__(self):
4957
method='do_%s'%self.action
5058
ifhasattr(self,method):

‎gitlab/v4/objects.py

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
fromgitlabimportcli
2424
fromgitlab.exceptionsimport*# noqa
2525
fromgitlab.mixinsimport*# noqa
26+
fromgitlabimporttypes
2627
fromgitlabimportutils
2728

2829
VISIBILITY_PRIVATE='private'
@@ -315,12 +316,7 @@ class UserManager(CRUDMixin, RESTManager):
315316
'website_url','skip_confirmation','external','organization',
316317
'location')
317318
)
318-
319-
def_sanitize_data(self,data,action):
320-
new_data=data.copy()
321-
if'confirm'indata:
322-
new_data['confirm']=str(new_data['confirm']).lower()
323-
returnnew_data
319+
_types= {'confirm':types.LowercaseStringAttribute}
324320

325321

326322
classCurrentUserEmail(ObjectDeleteMixin,RESTObject):
@@ -528,6 +524,7 @@ class GroupIssueManager(GetFromListMixin, RESTManager):
528524
_obj_cls=GroupIssue
529525
_from_parent_attrs= {'group_id':'id'}
530526
_list_filters= ('state','labels','milestone','order_by','sort')
527+
_types= {'labels':types.ListAttribute}
531528

532529

533530
classGroupMember(SaveMixin,ObjectDeleteMixin,RESTObject):
@@ -736,6 +733,7 @@ class IssueManager(GetFromListMixin, RESTManager):
736733
_path='/issues'
737734
_obj_cls=Issue
738735
_list_filters= ('state','labels','order_by','sort')
736+
_types= {'labels':types.ListAttribute}
739737

740738

741739
classLicense(RESTObject):
@@ -1346,12 +1344,7 @@ class ProjectIssueManager(CRUDMixin, RESTManager):
13461344
_update_attrs= (tuple(), ('title','description','assignee_id',
13471345
'milestone_id','labels','created_at',
13481346
'updated_at','state_event','due_date'))
1349-
1350-
def_sanitize_data(self,data,action):
1351-
new_data=data.copy()
1352-
if'labels'indata:
1353-
new_data['labels']=','.join(data['labels'])
1354-
returnnew_data
1347+
_types= {'labels':types.ListAttribute}
13551348

13561349

13571350
classProjectMember(SaveMixin,ObjectDeleteMixin,RESTObject):
@@ -1669,12 +1662,7 @@ class ProjectMergeRequestManager(CRUDMixin, RESTManager):
16691662
'description','state_event','labels',
16701663
'milestone_id'))
16711664
_list_filters= ('iids','state','order_by','sort')
1672-
1673-
def_sanitize_data(self,data,action):
1674-
new_data=data.copy()
1675-
if'labels'indata:
1676-
new_data['labels']=','.join(data['labels'])
1677-
returnnew_data
1665+
_types= {'labels':types.ListAttribute}
16781666

16791667

16801668
classProjectMilestone(SaveMixin,ObjectDeleteMixin,RESTObject):

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp