Skip to content

Commit 0901d97

Browse files
amimasJohnVillalovos
authored andcommitted
feat(cli): add support for renaming project feature flags
This adds the `--new-name` option to the `project-feature-flag update` command, allowing users to rename feature flags via the CLI. The `ProjectFeatureFlagManager.update()` method is overridden to handle the `new_name` parameter, mapping it to `name` in the API payload, while the original `name` is used as the resource ID in the URL. A functional test `test_project_feature_flag_cli_rename` is added to verify this behavior.
1 parent 9c348a3 commit 0901d97

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

gitlab/v4/objects/feature_flags.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ def _get_save_url_id(self) -> str | int | None:
3636
def save(self, **kwargs: Any) -> dict[str, Any] | None:
3737
"""Save the changes made to the object to the server.
3838
39-
The object is updated to match what the server returns.
39+
This is the standard method to use when updating a feature flag object
40+
that you have already retrieved.
4041
41-
This method overrides the default ``save()`` method to handle renaming
42-
feature flags. When the name is modified, the API requires the original
43-
name in the URL to identify the resource, while the new name is sent
44-
in the request body.
42+
It is overridden here to correctly handle renaming. When `name` is
43+
changed, the API requires the *original* name in the URL, and this
44+
method provides it.
4545
4646
Args:
4747
**kwargs: Extra options to send to the server (e.g. sudo)
@@ -71,7 +71,35 @@ class ProjectFeatureFlagManager(CRUDMixin[ProjectFeatureFlag]):
7171
required=("name",), optional=("version", "description", "active", "strategies")
7272
)
7373
_update_attrs = RequiredOptional(
74-
optional=("name", "description", "active", "strategies")
74+
# new_name is used for renaming via CLI and mapped to 'name' in update()
75+
optional=("name", "new_name", "description", "active", "strategies")
7576
)
7677
_list_filters = ("scope",)
7778
_types = {"strategies": types.JsonAttribute}
79+
80+
def update(
81+
self,
82+
id: str | int | None = None,
83+
new_data: dict[str, Any] | None = None,
84+
**kwargs: Any,
85+
) -> dict[str, Any]:
86+
"""Update a Project Feature Flag.
87+
88+
This is a lower-level method called by `ProjectFeatureFlag.save()` and
89+
is also used directly by the CLI.
90+
91+
The `new_name` parameter is a special case to support renaming via the
92+
CLI (`--new-name`). It is converted to the `name` parameter that the
93+
GitLab API expects in the request body.
94+
95+
Args:
96+
id: The current name of the feature flag.
97+
new_data: The dictionary of attributes to update.
98+
**kwargs: Extra options to send to the server (e.g. sudo)
99+
"""
100+
new_data = new_data or {}
101+
# When used via CLI, we have 'new_name' to distinguish from the ID 'name'.
102+
# When used via .save(), the object passes 'name' directly in new_data.
103+
if "new_name" in new_data:
104+
new_data["name"] = new_data.pop("new_name")
105+
return super().update(id, new_data, **kwargs)

tests/functional/cli/test_cli_project_feature_flags.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,44 @@ def test_project_feature_flag_cli_create_with_malformed_strategies(gitlab_cli, p
160160
ret = gitlab_cli(cmd)
161161
assert not ret.success
162162
assert "Could not parse JSON data" in ret.stderr
163+
164+
165+
def test_project_feature_flag_cli_rename(gitlab_cli, project, feature_flag_cli):
166+
new_name = "cli_renamed_flag"
167+
cmd = [
168+
"project-feature-flag",
169+
"update",
170+
"--project-id",
171+
str(project.id),
172+
"--name",
173+
feature_flag_cli,
174+
"--new-name",
175+
new_name,
176+
]
177+
ret = gitlab_cli(cmd)
178+
assert ret.success
179+
180+
cmd = [
181+
"-o",
182+
"json",
183+
"project-feature-flag",
184+
"get",
185+
"--project-id",
186+
str(project.id),
187+
"--name",
188+
new_name,
189+
]
190+
ret = gitlab_cli(cmd)
191+
assert ret.success
192+
data = json.loads(ret.stdout)
193+
assert data["name"] == new_name
194+
# Cleanup renamed flag
195+
cmd = [
196+
"project-feature-flag",
197+
"delete",
198+
"--project-id",
199+
str(project.id),
200+
"--name",
201+
new_name,
202+
]
203+
gitlab_cli(cmd)

0 commit comments

Comments
 (0)