Skip to content

Commit 72c723f

Browse files
authored
Merge pull request #576 from linode/dev
Release v5.48.2
2 parents ede396a + 17fcb03 commit 72c723f

34 files changed

+269
-121
lines changed

.github/labels.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
- name: new-feature
2+
description: for new features in the changelog.
3+
color: 225fee
4+
- name: improvement
5+
description: for improvements in existing functionality in the changelog.
6+
color: 22ee47
7+
- name: repo-ci-improvement
8+
description: for improvements in the repository or CI workflow in the changelog.
9+
color: c922ee
10+
- name: bugfix
11+
description: for any bug fixes in the changelog.
12+
color: ed8e21
13+
- name: documentation
14+
description: for updates to the documentation in the changelog.
15+
color: d3e1e6
16+
- name: testing
17+
description: for updates to the testing suite in the changelog.
18+
color: 933ac9
19+
- name: breaking-change
20+
description: for breaking changes in the changelog.
21+
color: ff0000
22+
- name: ignore-for-release
23+
description: PRs you do not want to render in the changelog
24+
color: 7b8eac

.github/release-drafter.yml

Lines changed: 0 additions & 21 deletions
This file was deleted.

.github/release.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
changelog:
2+
exclude:
3+
labels:
4+
- ignore-for-release
5+
categories:
6+
- title: ⚠️ Breaking Change
7+
labels:
8+
- breaking-change
9+
- title: 🐛 Bug Fixes
10+
labels:
11+
- bugfix
12+
- title: 🚀 New Features
13+
labels:
14+
- new-feature
15+
- title: 💡 Improvements
16+
labels:
17+
- improvement
18+
- title: 🧪 Testing Improvements
19+
labels:
20+
- testing
21+
- title: ⚙️ Repo/CI Improvements
22+
labels:
23+
- repo-ci-improvement
24+
- title: 📖 Documentation
25+
labels:
26+
- documentation
27+
- title: 📦 Dependency Updates
28+
labels:
29+
- dependencies
30+
- title: Other Changes
31+
labels:
32+
- "*"

.github/workflows/publish-wiki.yml

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,18 @@
1-
name: Publish Wiki
2-
1+
name: Publish wiki
32
on:
43
push:
54
branches: [main]
6-
5+
paths:
6+
- wiki/**
7+
- .github/workflows/publish-wiki.yml
8+
concurrency:
9+
group: publish-wiki
10+
cancel-in-progress: true
11+
permissions:
12+
contents: write
713
jobs:
8-
build:
14+
publish-wiki:
915
runs-on: ubuntu-latest
1016
steps:
11-
- uses: actions/checkout@v3
12-
13-
- name: Generate App Installation Token
14-
id: generate_token
15-
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 # pin@v1
16-
with:
17-
app_id: ${{ secrets.CLI_RELEASE_APP_ID }}
18-
private_key: ${{ secrets.CLI_RELEASE_PRIVATE_KEY }}
19-
repository: linode/linode-cli
20-
21-
- name: Upload Documentation to Wiki
22-
uses: SwiftDocOrg/github-wiki-publish-action@v1
23-
with:
24-
path: "wiki"
25-
env:
26-
GH_PERSONAL_ACCESS_TOKEN: ${{ steps.generate_token.outputs.token }}
17+
- uses: actions/checkout@v4
18+
- uses: Andrew-Chen-Wang/github-wiki-action@50650fccf3a10f741995523cf9708c53cec8912a # pin@v4.4.0

.github/workflows/release-drafter.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

linodecli/__main__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Launches the CLI
33
"""
4+
45
from linodecli import main
56

67
main()

linodecli/api_request.py

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@
77
import sys
88
import time
99
from sys import version_info
10-
from typing import Iterable, List, Optional
10+
from typing import Any, Iterable, List, Optional
1111

1212
import requests
1313
from packaging import version
1414
from requests import Response
1515

1616
from linodecli.helpers import API_CA_PATH
1717

18-
from .baked.operation import ExplicitNullValue, OpenAPIOperation
18+
from .baked.operation import (
19+
ExplicitEmptyListValue,
20+
ExplicitNullValue,
21+
OpenAPIOperation,
22+
)
1923
from .helpers import handle_url_overrides
2024

2125

@@ -199,6 +203,47 @@ def _build_request_url(ctx, operation, parsed_args) -> str:
199203
return result
200204

201205

206+
def _traverse_request_body(o: Any) -> Any:
207+
"""
208+
This function traverses is intended to be called immediately before
209+
request body serialization and contains special handling for dropping
210+
keys with null values and translating ExplicitNullValue instances into
211+
serializable null values.
212+
"""
213+
if isinstance(o, dict):
214+
result = {}
215+
for k, v in o.items():
216+
# Implicit null values should be dropped from the request
217+
if v is None:
218+
continue
219+
220+
# Values that are expected to be serialized as empty lists
221+
# and explicit None values are converted here.
222+
# See: operation.py
223+
# NOTE: These aren't handled at the top-level of this function
224+
# because we don't want them filtered out in the step below.
225+
if isinstance(v, ExplicitEmptyListValue):
226+
result[k] = []
227+
continue
228+
229+
if isinstance(v, ExplicitNullValue):
230+
result[k] = None
231+
continue
232+
233+
value = _traverse_request_body(v)
234+
235+
# We should exclude implicit empty lists
236+
if not (isinstance(value, (dict, list)) and len(value) < 1):
237+
result[k] = value
238+
239+
return result
240+
241+
if isinstance(o, list):
242+
return [_traverse_request_body(v) for v in o]
243+
244+
return o
245+
246+
202247
def _build_request_body(ctx, operation, parsed_args) -> Optional[str]:
203248
if operation.method == "get":
204249
# Get operations don't have a body
@@ -208,32 +253,18 @@ def _build_request_body(ctx, operation, parsed_args) -> Optional[str]:
208253
if ctx.defaults:
209254
parsed_args = ctx.config.update(parsed_args, operation.allowed_defaults)
210255

211-
to_json = {}
212-
213-
for k, v in vars(parsed_args).items():
214-
# Skip null values
215-
if v is None:
216-
continue
217-
218-
# Explicitly include ExplicitNullValues
219-
if isinstance(v, ExplicitNullValue):
220-
to_json[k] = None
221-
continue
222-
223-
to_json[k] = v
224-
225256
expanded_json = {}
226257

227258
# expand paths
228-
for k, v in to_json.items():
259+
for k, v in vars(parsed_args).items():
229260
cur = expanded_json
230261
for part in k.split(".")[:-1]:
231262
if part not in cur:
232263
cur[part] = {}
233264
cur = cur[part]
234265
cur[k.split(".")[-1]] = v
235266

236-
return json.dumps(expanded_json)
267+
return json.dumps(_traverse_request_body(expanded_json))
237268

238269

239270
def _print_request_debug_info(method, url, headers, body):

linodecli/baked/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""
22
Collection of classes for handling the parsed OpenAPI Spec for the CLI
33
"""
4+
45
from .operation import OpenAPIOperation

linodecli/baked/colors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Applies shell color escapes for pretty printing
33
"""
4+
45
import os
56
import platform
67

linodecli/baked/operation.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
CLI Operation logic
33
"""
4+
45
import argparse
56
import glob
67
import json
@@ -60,6 +61,12 @@ class ExplicitNullValue:
6061
"""
6162

6263

64+
class ExplicitEmptyListValue:
65+
"""
66+
A special type used to explicitly pass empty lists to the API.
67+
"""
68+
69+
6370
def wrap_parse_nullable_value(arg_type):
6471
"""
6572
A helper function to parse `null` as None for nullable CLI args.
@@ -91,9 +98,16 @@ def __call__(self, parser, namespace, values, option_string=None):
9198

9299
output_list = getattr(namespace, self.dest)
93100

101+
# If a user has already specified an [] but is specifying
102+
# another value, assume "[]" was intended to be a literal.
103+
if isinstance(output_list, ExplicitEmptyListValue):
104+
setattr(namespace, self.dest, ["[]", values])
105+
return
106+
94107
# If the output list is empty and the user specifies a []
95-
# argument, keep the list empty
108+
# argument, set the list to an explicitly empty list.
96109
if values == "[]" and len(output_list) < 1:
110+
setattr(namespace, self.dest, ExplicitEmptyListValue())
97111
return
98112

99113
output_list.append(values)

0 commit comments

Comments
 (0)