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

Commitac1c619

Browse files
fix(cli): url-encode path components of the URL
In the CLI we need to make sure the components put into the pathportion of the URL are url-encoded. Otherwise they will be interpretedas part of the path. For example can specify the project ID as a path,but in the URL it must be url-encoded or it doesn't work.Also stop adding the components of the path as query parameters in theURL.Closes:#783Closes:#1498
1 parentc9ed3dd commitac1c619

File tree

4 files changed

+67
-13
lines changed

4 files changed

+67
-13
lines changed

‎gitlab/v4/cli.py‎

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def __init__(
3939
self.action=action.lower()
4040
self.gl=gl
4141
self.args=args
42+
self.parent_args:Dict[str,Any]= {}
4243
self.mgr_cls:Union[
4344
Type[gitlab.mixins.CreateMixin],
4445
Type[gitlab.mixins.DeleteMixin],
@@ -53,7 +54,10 @@ def __init__(
5354
# the class _path attribute, and replace the value with the result.
5455
ifTYPE_CHECKING:
5556
assertself.mgr_cls._pathisnotNone
56-
self.mgr_cls._path=self.mgr_cls._path.format(**self.args)
57+
58+
self._process_from_parent_attrs()
59+
60+
self.mgr_cls._path=self.mgr_cls._path.format(**self.parent_args)
5761
self.mgr=self.mgr_cls(gl)
5862

5963
ifself.mgr_cls._types:
@@ -63,6 +67,18 @@ def __init__(
6367
obj.set_from_cli(self.args[attr_name])
6468
self.args[attr_name]=obj.get()
6569

70+
def_process_from_parent_attrs(self)->None:
71+
"""Items in the path need to be url-encoded. There is a 1:1 mapping from
72+
mgr_cls._from_parent_attrs <--> mgr_cls._path. Those values must be url-encoded
73+
as they may contain a slash '/'."""
74+
forkeyinself.mgr_cls._from_parent_attrs:
75+
ifkeynotinself.args:
76+
continue
77+
78+
self.parent_args[key]=gitlab.utils.clean_str_id(self.args[key])
79+
# If we don't delete it then it will be added to the URL as a query-string
80+
delself.args[key]
81+
6682
def__call__(self)->Any:
6783
# Check for a method that matches object + action
6884
method=f"do_{self.what}_{self.action}"
@@ -85,7 +101,7 @@ def do_custom(self) -> Any:
85101
data= {}
86102
ifself.mgr._from_parent_attrs:
87103
forkinself.mgr._from_parent_attrs:
88-
data[k]=self.args[k]
104+
data[k]=self.parent_args[k]
89105
ifnotissubclass(self.cls,gitlab.mixins.GetWithoutIdMixin):
90106
ifTYPE_CHECKING:
91107
assertisinstance(self.cls._id_attr,str)

‎tests/functional/cli/conftest.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
importpytest
2+
importresponses
3+
4+
fromgitlab.constimportDEFAULT_URL
25

36

47
@pytest.fixture
@@ -19,3 +22,14 @@ def _gitlab_cli(subcommands):
1922
returnscript_runner.run(*command)
2023

2124
return_gitlab_cli
25+
26+
27+
@pytest.fixture
28+
defresp_get_project():
29+
return {
30+
"method":responses.GET,
31+
"url":f"{DEFAULT_URL}/api/v4/projects/1",
32+
"json": {"name":"name","path":"test-path","id":1},
33+
"content_type":"application/json",
34+
"status":200,
35+
}

‎tests/functional/cli/test_cli.py‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,6 @@
1717
CI_SERVER_URL="https://gitlab.example.com"
1818

1919

20-
@pytest.fixture
21-
defresp_get_project():
22-
return {
23-
"method":responses.GET,
24-
"url":f"{DEFAULT_URL}/api/v4/projects/1",
25-
"json": {"name":"name","path":"test-path","id":1},
26-
"content_type":"application/json",
27-
"status":200,
28-
}
29-
30-
3120
deftest_main_entrypoint(script_runner,gitlab_config):
3221
ret=script_runner.run("python","-m","gitlab","--config-file",gitlab_config)
3322
assertret.returncode==2

‎tests/functional/cli/test_cli_variables.py‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
importcopy
2+
3+
importpytest
4+
importresponses
5+
6+
fromgitlabimportconfig
7+
fromgitlab.constimportDEFAULT_URL
8+
9+
110
deftest_list_instance_variables(gitlab_cli,gl):
211
cmd= ["variable","list"]
312
ret=gitlab_cli(cmd)
@@ -17,3 +26,29 @@ def test_list_project_variables(gitlab_cli, project):
1726
ret=gitlab_cli(cmd)
1827

1928
assertret.success
29+
30+
31+
deftest_list_project_variables_with_path(gitlab_cli,project):
32+
cmd= ["project-variable","list","--project-id",project.path_with_namespace]
33+
ret=gitlab_cli(cmd)
34+
35+
assertret.success
36+
37+
38+
@pytest.mark.script_launch_mode("inprocess")
39+
@responses.activate
40+
deftest_list_project_variables_with_path_url_check(
41+
monkeypatch,script_runner,resp_get_project
42+
):
43+
monkeypatch.setattr(config,"_DEFAULT_FILES", [])
44+
resp_get_project_variables=copy.deepcopy(resp_get_project)
45+
resp_get_project_variables.update(
46+
url=f"{DEFAULT_URL}/api/v4/projects/project%2Fwith%2Fa%2Fnamespace/variables"
47+
)
48+
resp_get_project_variables.update(json=[])
49+
50+
responses.add(**resp_get_project_variables)
51+
ret=script_runner.run(
52+
"gitlab","project-variable","list","--project-id","project/with/a/namespace"
53+
)
54+
assertret.success

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp