fluidattacks_gitlab_sdk 3.0.2__tar.gz → 4.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/PKG-INFO +1 -1
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/__init__.py +1 -1
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/issues/_client/_updated_by.py +14 -2
- fluidattacks_gitlab_sdk-4.0.0/fluidattacks_gitlab_sdk/mr_notes/__init__.py +4 -0
- fluidattacks_gitlab_sdk-4.0.0/fluidattacks_gitlab_sdk/mr_notes/_client.py +113 -0
- fluidattacks_gitlab_sdk-4.0.0/fluidattacks_gitlab_sdk/mr_notes/_core.py +23 -0
- fluidattacks_gitlab_sdk-4.0.0/fluidattacks_gitlab_sdk/mr_notes/_decode.py +24 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/users/core.py +3 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/users/decode.py +13 -2
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/pyproject.toml +1 -1
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/arch/arch.py +6 -1
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/issues/test_decode.py +7 -1
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/merge_request/test_decode.py +4 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/mr_approvals/decoder_test.py +3 -1
- fluidattacks_gitlab_sdk-4.0.0/tests/mr_notes/data.json +62 -0
- fluidattacks_gitlab_sdk-4.0.0/tests/mr_notes/decoder_test.py +65 -0
- fluidattacks_gitlab_sdk-4.0.0/tests_fx/py.typed +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/uv.lock +22 -13
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/.envrc +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/build/default.nix +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/build/filter.nix +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/flake.lock +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/flake.nix +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_decoders.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_gql_client/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_gql_client/_client.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_gql_client/_error.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_gql_client/_handlers.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_handlers.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_http_client/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_http_client/_client_1.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_http_client/_core.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_logger.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/ids.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/issues/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/issues/_client/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/issues/_client/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/issues/_client/_get_issue.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/issues/_client/_most_recent.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/issues/core.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/jobs/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/jobs/_client.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/jobs/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/jobs/core.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/members/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/members/_client.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/members/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/members/core.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/merge_requests/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/merge_requests/_client.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/merge_requests/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/merge_requests/core.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/milestones/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/milestones/_client.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/milestones/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/milestones/core.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/mr_approvals/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/mr_approvals/_client.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/mr_approvals/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/mr_approvals/core.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/py.typed +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/users/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/mypy.ini +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/ruff.toml +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/arch/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/arch/test_arch.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/issues/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/issues/data.json +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/jobs/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/jobs/data.json +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/jobs/test_decode_job.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/members/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/members/data.json +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/members/test_decode_members.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/merge_request/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/merge_request/data.json +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/merge_request/data_mr_updates.json +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/mr_approvals/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/mr_approvals/data.json +0 -0
- {fluidattacks_gitlab_sdk-3.0.2/tests_fx → fluidattacks_gitlab_sdk-4.0.0/tests/mr_notes}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/py.typed +0 -0
- {fluidattacks_gitlab_sdk-3.0.2/tests_fx/issues → fluidattacks_gitlab_sdk-4.0.0/tests_fx}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/_utils.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2/tests_fx/jobs → fluidattacks_gitlab_sdk-4.0.0/tests_fx/issues}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/issues/test_issue_client.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2/tests_fx/members → fluidattacks_gitlab_sdk-4.0.0/tests_fx/jobs}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/jobs/client_test.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2/tests_fx/milestones → fluidattacks_gitlab_sdk-4.0.0/tests_fx/members}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/members/test_client_members.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2/tests_fx/mr_approvals → fluidattacks_gitlab_sdk-4.0.0/tests_fx/milestones}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/milestones/client_test.py +0 -0
- /fluidattacks_gitlab_sdk-3.0.2/tests_fx/py.typed → /fluidattacks_gitlab_sdk-4.0.0/tests_fx/mr_approvals/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/mr_approvals/client_test.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/test_gql_client.py +0 -0
- {fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/test_mr.py +0 -0
|
@@ -55,8 +55,19 @@ def decode_user_obj(raw: JsonObj) -> ResultE[UserObj]:
|
|
|
55
55
|
lambda user: (
|
|
56
56
|
JsonUnfolder.require(raw, "name", DecodeUtils.to_str)
|
|
57
57
|
.map(UserName)
|
|
58
|
-
.
|
|
59
|
-
lambda name:
|
|
58
|
+
.bind(
|
|
59
|
+
lambda name: JsonUnfolder.optional(
|
|
60
|
+
raw,
|
|
61
|
+
"publicEmail",
|
|
62
|
+
DecodeUtils.to_opt_str,
|
|
63
|
+
).map(
|
|
64
|
+
lambda email: UserObj(
|
|
65
|
+
user_id,
|
|
66
|
+
user,
|
|
67
|
+
name,
|
|
68
|
+
email.bind(lambda m: m),
|
|
69
|
+
),
|
|
70
|
+
),
|
|
60
71
|
)
|
|
61
72
|
),
|
|
62
73
|
)
|
|
@@ -135,6 +146,7 @@ def get_updated_by(
|
|
|
135
146
|
id
|
|
136
147
|
name
|
|
137
148
|
username
|
|
149
|
+
publicEmail
|
|
138
150
|
}
|
|
139
151
|
}
|
|
140
152
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from __future__ import (
|
|
2
|
+
annotations,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
import inspect
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
from fa_purity import (
|
|
9
|
+
Cmd,
|
|
10
|
+
FrozenList,
|
|
11
|
+
Maybe,
|
|
12
|
+
ResultE,
|
|
13
|
+
Stream,
|
|
14
|
+
cast_exception,
|
|
15
|
+
)
|
|
16
|
+
from fa_purity._core.utils import raise_exception
|
|
17
|
+
from fa_purity.json import Primitive, UnfoldedFactory
|
|
18
|
+
from fluidattacks_etl_utils.bug import Bug
|
|
19
|
+
from fluidattacks_etl_utils.decode import int_to_str
|
|
20
|
+
from fluidattacks_etl_utils.paginate import cursor_pagination
|
|
21
|
+
|
|
22
|
+
from fluidattacks_gitlab_sdk._decoders import assert_multiple
|
|
23
|
+
from fluidattacks_gitlab_sdk._http_client import (
|
|
24
|
+
ClientFactory,
|
|
25
|
+
Credentials,
|
|
26
|
+
HttpJsonClient,
|
|
27
|
+
RelativeEndpoint,
|
|
28
|
+
)
|
|
29
|
+
from fluidattacks_gitlab_sdk.ids import MrInternalId, ProjectId
|
|
30
|
+
|
|
31
|
+
from ._core import MrNote, NotesClient
|
|
32
|
+
from ._decode import decode_mr_notes
|
|
33
|
+
|
|
34
|
+
_NOTES_PER_PAGE = 100
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _get_notes_page(
|
|
38
|
+
client: HttpJsonClient,
|
|
39
|
+
project: ProjectId,
|
|
40
|
+
mr_id: MrInternalId,
|
|
41
|
+
page: int,
|
|
42
|
+
) -> Cmd[ResultE[tuple[FrozenList[MrNote], Maybe[int]]]]:
|
|
43
|
+
endpoint = RelativeEndpoint.new(
|
|
44
|
+
"projects",
|
|
45
|
+
int_to_str(project.project_id.value),
|
|
46
|
+
"merge_requests",
|
|
47
|
+
int_to_str(mr_id.internal.value),
|
|
48
|
+
"notes",
|
|
49
|
+
)
|
|
50
|
+
params: dict[str, Primitive] = {
|
|
51
|
+
"order_by": "created_at",
|
|
52
|
+
"sort": "asc",
|
|
53
|
+
"page": int_to_str(page),
|
|
54
|
+
"per_page": _NOTES_PER_PAGE,
|
|
55
|
+
}
|
|
56
|
+
return client.get(
|
|
57
|
+
endpoint,
|
|
58
|
+
UnfoldedFactory.from_dict(params),
|
|
59
|
+
).map(
|
|
60
|
+
lambda r: (
|
|
61
|
+
r.alt(
|
|
62
|
+
lambda e: cast_exception(
|
|
63
|
+
Bug.new(
|
|
64
|
+
"_get_notes_page",
|
|
65
|
+
inspect.currentframe(),
|
|
66
|
+
e,
|
|
67
|
+
(),
|
|
68
|
+
),
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
.bind(assert_multiple)
|
|
72
|
+
.bind(decode_mr_notes)
|
|
73
|
+
.map(
|
|
74
|
+
lambda notes: (
|
|
75
|
+
notes,
|
|
76
|
+
Maybe.empty() if len(notes) < _NOTES_PER_PAGE else Maybe.some(page + 1),
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _get_page(
|
|
84
|
+
client: HttpJsonClient,
|
|
85
|
+
project: ProjectId,
|
|
86
|
+
mr_id: MrInternalId,
|
|
87
|
+
maybe_page: Maybe[int],
|
|
88
|
+
) -> Cmd[tuple[FrozenList[MrNote], Maybe[int]]]:
|
|
89
|
+
page = maybe_page.value_or(1)
|
|
90
|
+
return _get_notes_page(client, project, mr_id, page).map(
|
|
91
|
+
lambda r: r.alt(raise_exception).to_union(),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _get_mr_notes(
|
|
96
|
+
client: HttpJsonClient,
|
|
97
|
+
project: ProjectId,
|
|
98
|
+
mr_id: MrInternalId,
|
|
99
|
+
) -> Stream[FrozenList[MrNote]]:
|
|
100
|
+
return cursor_pagination(
|
|
101
|
+
lambda maybe_page: _get_page(client, project, mr_id, maybe_page),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _from_client(client: HttpJsonClient) -> NotesClient:
|
|
106
|
+
return NotesClient(lambda p, i: _get_mr_notes(client, p, i))
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@dataclass(frozen=True)
|
|
110
|
+
class MrNotesFactory:
|
|
111
|
+
@staticmethod
|
|
112
|
+
def new(creds: Credentials) -> NotesClient:
|
|
113
|
+
return _from_client(ClientFactory.new(creds))
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
from fa_purity import FrozenList, Stream
|
|
7
|
+
from fa_purity.date_time import DatetimeUTC
|
|
8
|
+
|
|
9
|
+
from fluidattacks_gitlab_sdk.ids import MrInternalId, ProjectId
|
|
10
|
+
from fluidattacks_gitlab_sdk.users import UserObj
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class MrNote:
|
|
15
|
+
body: str
|
|
16
|
+
author: UserObj
|
|
17
|
+
created_at: DatetimeUTC
|
|
18
|
+
system: bool
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class NotesClient:
|
|
23
|
+
get_mr_notes: Callable[[ProjectId, MrInternalId], Stream[FrozenList[MrNote]]]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from fa_purity import FrozenList, PureIterFactory, Result, ResultE, ResultTransform
|
|
2
|
+
from fa_purity.json import JsonObj, JsonUnfolder, Unfolder
|
|
3
|
+
from fluidattacks_etl_utils import smash
|
|
4
|
+
from fluidattacks_etl_utils.decode import DecodeUtils
|
|
5
|
+
|
|
6
|
+
from fluidattacks_gitlab_sdk.mr_notes._core import MrNote
|
|
7
|
+
from fluidattacks_gitlab_sdk.users.decode import decode_user_obj
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def decode_mr_note(raw: JsonObj) -> ResultE[MrNote]:
|
|
11
|
+
return smash.smash_result_4(
|
|
12
|
+
JsonUnfolder.require(raw, "body", DecodeUtils.to_str),
|
|
13
|
+
JsonUnfolder.require(raw, "author", lambda v: Unfolder.to_json(v).bind(decode_user_obj)),
|
|
14
|
+
JsonUnfolder.require(raw, "created_at", DecodeUtils.to_date_time),
|
|
15
|
+
JsonUnfolder.require(raw, "system", DecodeUtils.to_bool),
|
|
16
|
+
).map(lambda t: MrNote(*t))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def decode_mr_notes(raw: FrozenList[JsonObj]) -> ResultE[FrozenList[MrNote]]:
|
|
20
|
+
if not raw:
|
|
21
|
+
return Result.success(FrozenList[MrNote](()), Exception)
|
|
22
|
+
return ResultTransform.all_ok(
|
|
23
|
+
PureIterFactory.from_list(raw).map(decode_mr_note).to_list(),
|
|
24
|
+
)
|
|
@@ -2,6 +2,8 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
|
+
from fa_purity import Maybe
|
|
6
|
+
|
|
5
7
|
from fluidattacks_gitlab_sdk.ids import UserId
|
|
6
8
|
|
|
7
9
|
|
|
@@ -24,3 +26,4 @@ class UserObj:
|
|
|
24
26
|
user_id: UserId
|
|
25
27
|
user: User
|
|
26
28
|
name: UserName
|
|
29
|
+
public_email: Maybe[str]
|
|
@@ -20,8 +20,19 @@ def decode_user_obj(raw: JsonObj) -> ResultE[UserObj]:
|
|
|
20
20
|
lambda user: (
|
|
21
21
|
JsonUnfolder.require(raw, "name", DecodeUtils.to_str)
|
|
22
22
|
.map(UserName)
|
|
23
|
-
.
|
|
24
|
-
lambda name:
|
|
23
|
+
.bind(
|
|
24
|
+
lambda name: JsonUnfolder.optional(
|
|
25
|
+
raw,
|
|
26
|
+
"public_email",
|
|
27
|
+
DecodeUtils.to_opt_str,
|
|
28
|
+
).map(
|
|
29
|
+
lambda email: UserObj(
|
|
30
|
+
user_id,
|
|
31
|
+
user,
|
|
32
|
+
name,
|
|
33
|
+
email.bind(lambda m: m),
|
|
34
|
+
),
|
|
35
|
+
),
|
|
25
36
|
)
|
|
26
37
|
),
|
|
27
38
|
)
|
|
@@ -34,7 +34,7 @@ dev = [
|
|
|
34
34
|
|
|
35
35
|
[tool.uv]
|
|
36
36
|
exclude-newer = "7 days"
|
|
37
|
-
exclude-newer-package = { fluidattacks-core = "2099-01-01", fluid-blends = "2099-01-01" }
|
|
37
|
+
exclude-newer-package = { fluidattacks-core = "2099-01-01", fluid-blends = "2099-01-01" , fluidattacks-utils-logger = "2099-01-01" }
|
|
38
38
|
override-dependencies = [
|
|
39
39
|
"cryptography==48.0.1"
|
|
40
40
|
]
|
|
@@ -26,7 +26,7 @@ def _module(path: str) -> FullPathModule | NoReturn:
|
|
|
26
26
|
|
|
27
27
|
_dag: Dict[str, tuple[tuple[str, ...] | str, ...]] = {
|
|
28
28
|
"fluidattacks_gitlab_sdk": (
|
|
29
|
-
("merge_requests", "members", "issues", "milestones", "mr_approvals", "jobs"),
|
|
29
|
+
("merge_requests", "members", "issues", "milestones", "mr_approvals", "mr_notes", "jobs"),
|
|
30
30
|
"users",
|
|
31
31
|
"_handlers",
|
|
32
32
|
("_http_client", "_gql_client", "_decoders"),
|
|
@@ -74,6 +74,11 @@ _dag: Dict[str, tuple[tuple[str, ...] | str, ...]] = {
|
|
|
74
74
|
"_decode",
|
|
75
75
|
"core",
|
|
76
76
|
),
|
|
77
|
+
"fluidattacks_gitlab_sdk.mr_notes": (
|
|
78
|
+
"_client",
|
|
79
|
+
"_decode",
|
|
80
|
+
"_core",
|
|
81
|
+
),
|
|
77
82
|
"fluidattacks_gitlab_sdk.jobs": ("_client", "_decode", "core"),
|
|
78
83
|
}
|
|
79
84
|
|
|
@@ -32,11 +32,17 @@ from fluidattacks_gitlab_sdk.users.core import User, UserName, UserObj
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def test_decode() -> None:
|
|
35
|
-
author = UserObj(
|
|
35
|
+
author = UserObj(
|
|
36
|
+
UserId(NaturalOperations.absolute(1)),
|
|
37
|
+
User("ghost1"),
|
|
38
|
+
UserName("Ghost User"),
|
|
39
|
+
Maybe.some(""),
|
|
40
|
+
)
|
|
36
41
|
assignee = UserObj(
|
|
37
42
|
UserId(NaturalOperations.absolute(333)),
|
|
38
43
|
User("the_user"),
|
|
39
44
|
UserName("The User"),
|
|
45
|
+
Maybe.some(""),
|
|
40
46
|
)
|
|
41
47
|
closed_by = assignee
|
|
42
48
|
issue_def = IssueDef("The title", "closed", IssueType.ISSUE, Maybe.some(""))
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/merge_request/test_decode.py
RENAMED
|
@@ -38,11 +38,13 @@ def test_decode() -> None:
|
|
|
38
38
|
UserId(NaturalOperations.absolute(987654321)),
|
|
39
39
|
User("the_author"),
|
|
40
40
|
UserName("The Author"),
|
|
41
|
+
Maybe.empty(),
|
|
41
42
|
)
|
|
42
43
|
merger = UserObj(
|
|
43
44
|
UserId(NaturalOperations.absolute(1234567)),
|
|
44
45
|
User("the_merger"),
|
|
45
46
|
UserName("The merger"),
|
|
47
|
+
Maybe.empty(),
|
|
46
48
|
)
|
|
47
49
|
project = ProjectId(NaturalOperations.absolute(123456789))
|
|
48
50
|
expected = (
|
|
@@ -115,11 +117,13 @@ def test_decode_mrs_updated() -> None:
|
|
|
115
117
|
UserId(NaturalOperations.absolute(987654321)),
|
|
116
118
|
User("the_author"),
|
|
117
119
|
UserName("The Author"),
|
|
120
|
+
Maybe.empty(),
|
|
118
121
|
)
|
|
119
122
|
merger = UserObj(
|
|
120
123
|
UserId(NaturalOperations.absolute(1234567)),
|
|
121
124
|
User("the_merger"),
|
|
122
125
|
UserName("The merger"),
|
|
126
|
+
Maybe.empty(),
|
|
123
127
|
)
|
|
124
128
|
project = ProjectId(NaturalOperations.absolute(123456789))
|
|
125
129
|
expected_mrs = (
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/mr_approvals/decoder_test.py
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
from fa_purity import FrozenList, Unsafe
|
|
3
|
+
from fa_purity import FrozenList, Maybe, Unsafe
|
|
4
4
|
from fa_purity.json import JsonValueFactory, Unfolder
|
|
5
5
|
from fluidattacks_etl_utils.natural import NaturalOperations
|
|
6
6
|
|
|
@@ -31,6 +31,7 @@ def test_decode() -> None:
|
|
|
31
31
|
UserId(NaturalOperations.absolute(26904760)),
|
|
32
32
|
User("useratfluid"),
|
|
33
33
|
UserName("User Fluid"),
|
|
34
|
+
Maybe.some(""),
|
|
34
35
|
),
|
|
35
36
|
),
|
|
36
37
|
Approver(
|
|
@@ -38,6 +39,7 @@ def test_decode() -> None:
|
|
|
38
39
|
UserId(NaturalOperations.absolute(34547217)),
|
|
39
40
|
User("project_20741933_bot_7328383692d798602683c341e690"),
|
|
40
41
|
UserName("****"),
|
|
42
|
+
Maybe.empty(),
|
|
41
43
|
),
|
|
42
44
|
),
|
|
43
45
|
)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": 2712345601,
|
|
4
|
+
"type": null,
|
|
5
|
+
"body": "required: [major-version] change the major version to publish the new indicators package",
|
|
6
|
+
"author": {
|
|
7
|
+
"id": 12345678,
|
|
8
|
+
"username": "dmurciaatfluid",
|
|
9
|
+
"public_email": "",
|
|
10
|
+
"name": "Daniel Murcia",
|
|
11
|
+
"state": "active",
|
|
12
|
+
"locked": false,
|
|
13
|
+
"avatar_url": "https://secure.gravatar.com/avatar/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?s=80&d=identicon",
|
|
14
|
+
"web_url": "https://gitlab.com/dmurciaatfluid"
|
|
15
|
+
},
|
|
16
|
+
"created_at": "2026-07-08T12:31:03.134Z",
|
|
17
|
+
"updated_at": "2026-07-08T12:31:03.134Z",
|
|
18
|
+
"system": false,
|
|
19
|
+
"noteable_id": 345678912,
|
|
20
|
+
"noteable_type": "MergeRequest"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": 2712345602,
|
|
24
|
+
"type": null,
|
|
25
|
+
"body": "<img src=\"https://res.cloudinary.com/fluid-attacks/image/upload/v1727795769/airs/logo/logo_icon.png\" width=\"24\" alt=\"Fluid Attacks\" /> **Fluid Attacks** completed security analysis\n\n**Nice job!** No vulnerabilities found",
|
|
26
|
+
"author": {
|
|
27
|
+
"id": 34547217,
|
|
28
|
+
"username": "project_20741933_bot_8385943dd3fb82db18695bfce6854920",
|
|
29
|
+
"public_email": null,
|
|
30
|
+
"name": "****",
|
|
31
|
+
"state": "active",
|
|
32
|
+
"locked": false,
|
|
33
|
+
"avatar_url": "https://secure.gravatar.com/avatar/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb?s=80&d=identicon",
|
|
34
|
+
"web_url": "https://gitlab.com/project_20741933_bot_8385943dd3fb82db18695bfce6854920"
|
|
35
|
+
},
|
|
36
|
+
"created_at": "2026-07-08T12:19:27.612Z",
|
|
37
|
+
"updated_at": "2026-07-08T12:19:27.612Z",
|
|
38
|
+
"system": false,
|
|
39
|
+
"noteable_id": 345678912,
|
|
40
|
+
"noteable_type": "MergeRequest"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": 2712345603,
|
|
44
|
+
"type": "ApprovalSystemNote",
|
|
45
|
+
"body": "approved this merge request",
|
|
46
|
+
"author": {
|
|
47
|
+
"id": 12345678,
|
|
48
|
+
"username": "dmurciaatfluid",
|
|
49
|
+
"public_email": "",
|
|
50
|
+
"name": "Daniel Murcia",
|
|
51
|
+
"state": "active",
|
|
52
|
+
"locked": false,
|
|
53
|
+
"avatar_url": "https://secure.gravatar.com/avatar/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?s=80&d=identicon",
|
|
54
|
+
"web_url": "https://gitlab.com/dmurciaatfluid"
|
|
55
|
+
},
|
|
56
|
+
"created_at": "2026-07-08T13:38:56.341Z",
|
|
57
|
+
"updated_at": "2026-07-08T13:38:56.341Z",
|
|
58
|
+
"system": true,
|
|
59
|
+
"noteable_id": 345678912,
|
|
60
|
+
"noteable_type": "MergeRequest"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from datetime import UTC, datetime
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from fa_purity import FrozenList, Maybe, Unsafe
|
|
5
|
+
from fa_purity.date_time import DatetimeUTC
|
|
6
|
+
from fa_purity.json import JsonValueFactory, Unfolder
|
|
7
|
+
from fluidattacks_etl_utils.natural import NaturalOperations
|
|
8
|
+
|
|
9
|
+
from fluidattacks_gitlab_sdk.ids import UserId
|
|
10
|
+
from fluidattacks_gitlab_sdk.mr_notes import MrNote
|
|
11
|
+
from fluidattacks_gitlab_sdk.mr_notes._decode import decode_mr_notes
|
|
12
|
+
from fluidattacks_gitlab_sdk.users.core import User, UserName, UserObj
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _assert_utc(date_time: datetime) -> DatetimeUTC:
|
|
16
|
+
return DatetimeUTC.assert_utc(date_time).alt(Unsafe.raise_exception).to_union()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_decode() -> None:
|
|
20
|
+
human_author = UserObj(
|
|
21
|
+
UserId(NaturalOperations.absolute(12345678)),
|
|
22
|
+
User("dmurciaatfluid"),
|
|
23
|
+
UserName("Daniel Murcia"),
|
|
24
|
+
Maybe.some(""),
|
|
25
|
+
)
|
|
26
|
+
bot_author = UserObj(
|
|
27
|
+
UserId(NaturalOperations.absolute(34547217)),
|
|
28
|
+
User("project_20741933_bot_8385943dd3fb82db18695bfce6854920"),
|
|
29
|
+
UserName("****"),
|
|
30
|
+
Maybe.empty(),
|
|
31
|
+
)
|
|
32
|
+
expected: FrozenList[MrNote] = (
|
|
33
|
+
MrNote(
|
|
34
|
+
"required: [major-version] change the major version to publish "
|
|
35
|
+
"the new indicators package",
|
|
36
|
+
human_author,
|
|
37
|
+
_assert_utc(datetime(2026, 7, 8, 12, 31, 3, 134000, tzinfo=UTC)),
|
|
38
|
+
system=False,
|
|
39
|
+
),
|
|
40
|
+
MrNote(
|
|
41
|
+
'<img src="https://res.cloudinary.com/fluid-attacks/image/upload/v1727795769/airs/logo'
|
|
42
|
+
'/logo_icon.png" width="24" alt="Fluid Attacks" /> **Fluid Attacks** completed securit'
|
|
43
|
+
"y analysis\n\n**Nice job!** No vulnerabilities found",
|
|
44
|
+
bot_author,
|
|
45
|
+
_assert_utc(datetime(2026, 7, 8, 12, 19, 27, 612000, tzinfo=UTC)),
|
|
46
|
+
system=False,
|
|
47
|
+
),
|
|
48
|
+
MrNote(
|
|
49
|
+
"approved this merge request",
|
|
50
|
+
human_author,
|
|
51
|
+
_assert_utc(datetime(2026, 7, 8, 13, 38, 56, 341000, tzinfo=UTC)),
|
|
52
|
+
system=True,
|
|
53
|
+
),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
raw_data_path = Path(__file__).parent / "data.json"
|
|
57
|
+
json_value = JsonValueFactory.load(raw_data_path.open(encoding="utf-8"))
|
|
58
|
+
raw_notes = (
|
|
59
|
+
json_value.bind(lambda v: Unfolder.to_list_of(v, Unfolder.to_json))
|
|
60
|
+
.alt(Unsafe.raise_exception)
|
|
61
|
+
.to_union()
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
decoded_notes = decode_mr_notes(raw_notes).alt(Unsafe.raise_exception).to_union()
|
|
65
|
+
assert decoded_notes == expected
|
|
File without changes
|
|
@@ -6,6 +6,15 @@ resolution-markers = [
|
|
|
6
6
|
"python_full_version < '3.15'",
|
|
7
7
|
]
|
|
8
8
|
|
|
9
|
+
[options]
|
|
10
|
+
exclude-newer = "2026-06-30T22:09:12.854339Z"
|
|
11
|
+
exclude-newer-span = "P7D"
|
|
12
|
+
|
|
13
|
+
[options.exclude-newer-package]
|
|
14
|
+
fluid-blends = "2099-01-02T00:00:00Z"
|
|
15
|
+
fluidattacks-utils-logger = "2099-01-02T00:00:00Z"
|
|
16
|
+
fluidattacks-core = "2099-01-02T00:00:00Z"
|
|
17
|
+
|
|
9
18
|
[manifest]
|
|
10
19
|
overrides = [{ name = "cryptography", specifier = "==48.0.1" }]
|
|
11
20
|
|
|
@@ -345,18 +354,18 @@ wheels = [
|
|
|
345
354
|
|
|
346
355
|
[[package]]
|
|
347
356
|
name = "fluidattacks-core"
|
|
348
|
-
version = "
|
|
357
|
+
version = "9.3.0"
|
|
349
358
|
source = { registry = "https://pypi.org/simple" }
|
|
350
359
|
wheels = [
|
|
351
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
352
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
353
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
354
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
355
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
356
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
357
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
358
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
359
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
360
|
+
{ url = "https://files.pythonhosted.org/packages/27/b2/d956e9939c166d4b5a8929f66cf5dc5edce877d648956ec8ad291afc42b7/fluidattacks_core-9.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1ec5dba7ef4537da0717fe14fbfff8ff161aeb8bcacb15a624894140a1c4291e", size = 6608034, upload-time = "2026-07-07T18:58:59.653Z" },
|
|
361
|
+
{ url = "https://files.pythonhosted.org/packages/2e/5c/aa071cff0e301f906604e6d8e691fd86b412c6a99ba484119e16886ebf73/fluidattacks_core-9.3.0-cp311-cp311-manylinux_2_39_aarch64.whl", hash = "sha256:b08a5318bf02e59b1f9842ac9414fbf21fb6397f0ddd108c182f9c2d2acf6368", size = 7598882, upload-time = "2026-07-07T18:59:06.246Z" },
|
|
362
|
+
{ url = "https://files.pythonhosted.org/packages/3c/60/a89b39fa1ce5aeba5171bb83dbfe026a25c3a14791818374364fd550efdc/fluidattacks_core-9.3.0-cp311-cp311-manylinux_2_39_x86_64.whl", hash = "sha256:5a04c40e2e515ab96313eb98c34c83963a5084649d423aaf07adad2d701de007", size = 7631955, upload-time = "2026-07-07T18:59:04.637Z" },
|
|
363
|
+
{ url = "https://files.pythonhosted.org/packages/90/90/99e1d19021316387edf7c536e1e8be1f89bbf48a7bcefebaea8472dfa003/fluidattacks_core-9.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4425c3ed98e0f374a5beac4a5aebbf9c308b13603305ab3bf9fa75dd8f40831c", size = 6602958, upload-time = "2026-07-07T18:59:07.945Z" },
|
|
364
|
+
{ url = "https://files.pythonhosted.org/packages/e4/26/7d5e9f29e7d9b739776b4f76c46562bbf1bdd8024c579b9d49d7f24a2fd0/fluidattacks_core-9.3.0-cp312-cp312-manylinux_2_39_aarch64.whl", hash = "sha256:b16ead5cb8af27186ed348072ba952d15e9a0209d90c7678fe4a94d11733e25e", size = 7595799, upload-time = "2026-07-07T18:59:09.597Z" },
|
|
365
|
+
{ url = "https://files.pythonhosted.org/packages/9b/37/cb1cd7b60fab669d3d9c6233ef2e7ef8030ef7ff8fb8c3d84de91c9588a7/fluidattacks_core-9.3.0-cp312-cp312-manylinux_2_39_x86_64.whl", hash = "sha256:10e2ede5108197daa7d8ac9e2e02e9b86eb3d470dab70db134681d6e845163f2", size = 7625910, upload-time = "2026-07-07T18:59:01.614Z" },
|
|
366
|
+
{ url = "https://files.pythonhosted.org/packages/e2/cb/5e610ff985b10f1beeffb2d8872903adc0e92deede845af095792b31e129/fluidattacks_core-9.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e9eb00fbbe449b43414a97a6585fb7fd72b85c3fb848cdfe9996aa20ecec53dc", size = 6602582, upload-time = "2026-07-07T18:58:58.141Z" },
|
|
367
|
+
{ url = "https://files.pythonhosted.org/packages/43/f6/2141cbce306a07bfcde9c36c70c8f38f4f8ef7a350fac9a9a48de8a8f361/fluidattacks_core-9.3.0-cp313-cp313-manylinux_2_39_aarch64.whl", hash = "sha256:018b3cf09f08b92fb6b54a74cad52f75da817ee1a38a612b5ddeb6e5da666865", size = 7595633, upload-time = "2026-07-07T18:59:03.109Z" },
|
|
368
|
+
{ url = "https://files.pythonhosted.org/packages/c7/7c/aef426597596d5e5b5cb3e7c1ea8723b3cd4010da86e0fe5926af76cddec/fluidattacks_core-9.3.0-cp313-cp313-manylinux_2_39_x86_64.whl", hash = "sha256:5865553a7c3374690a644852d70ed597ebd77b827be84fb213f19cc79c8dca9d", size = 7626399, upload-time = "2026-07-07T18:58:56.348Z" },
|
|
360
369
|
]
|
|
361
370
|
|
|
362
371
|
[[package]]
|
|
@@ -430,16 +439,16 @@ dev = [
|
|
|
430
439
|
|
|
431
440
|
[[package]]
|
|
432
441
|
name = "fluidattacks-utils-logger"
|
|
433
|
-
version = "3.0.
|
|
442
|
+
version = "3.0.3"
|
|
434
443
|
source = { registry = "https://pypi.org/simple" }
|
|
435
444
|
dependencies = [
|
|
436
445
|
{ name = "fa-purity" },
|
|
437
446
|
{ name = "fluidattacks-core" },
|
|
438
447
|
{ name = "python-json-logger" },
|
|
439
448
|
]
|
|
440
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
449
|
+
sdist = { url = "https://files.pythonhosted.org/packages/2b/3e/349b0eeda139fa281a92fdd6246f7b341ed10a0397b5680a525efaa9f7a5/fluidattacks_utils_logger-3.0.3.tar.gz", hash = "sha256:94753730cd3f7b1c4e763df562dc7acc512bc20f63e46b6935af35da152ddbd3", size = 49723, upload-time = "2026-07-03T23:08:11.876Z" }
|
|
441
450
|
wheels = [
|
|
442
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
451
|
+
{ url = "https://files.pythonhosted.org/packages/2c/33/5a75a47c6e9c9d21cb080f55ba17eca8de0a0d8aabcd303d7cfd4f3bc942/fluidattacks_utils_logger-3.0.3-py3-none-any.whl", hash = "sha256:01067b226a10761904590cdbf675c8c181f32872511cd66c184a95062f6ffbdc", size = 3825, upload-time = "2026-07-03T23:08:11.078Z" },
|
|
443
452
|
]
|
|
444
453
|
|
|
445
454
|
[[package]]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_decoders.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_handlers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/_logger.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/ids.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/jobs/core.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/fluidattacks_gitlab_sdk/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/jobs/test_decode_job.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/members/test_decode_members.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/merge_request/__init__.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/merge_request/data.json
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/mr_approvals/__init__.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests/mr_approvals/data.json
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2/tests_fx → fluidattacks_gitlab_sdk-4.0.0/tests/mr_notes}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2/tests_fx/issues → fluidattacks_gitlab_sdk-4.0.0/tests_fx}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/issues/test_issue_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/jobs/client_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/milestones/client_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-3.0.2 → fluidattacks_gitlab_sdk-4.0.0}/tests_fx/mr_approvals/client_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|