Skip to content

[Integration][Gitlab-v2] Added support for file kind #1482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 239 commits into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from 203 commits
Commits
Show all changes
239 commits
Select commit Hold shift + click to select a range
241bcd0
Initialise Integration
shariff-6 Feb 20, 2025
60d7cc1
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Feb 20, 2025
bceae7d
Install dependancies
shariff-6 Feb 20, 2025
18d6284
Implement main entry point and event handlers for GitLab integration
shariff-6 Feb 21, 2025
f639890
Implement GraphQL client for GitLab API
shariff-6 Feb 21, 2025
5c0823f
Add base GitLab client with GraphQL and REST support
shariff-6 Feb 21, 2025
93e6985
Define GraphQL fragments and queries for GitLab projects
shariff-6 Feb 21, 2025
be056ce
Implement REST client for GitLab API
shariff-6 Feb 21, 2025
37b4f6a
Implement AuthClient for handling authentication headers
shariff-6 Feb 21, 2025
f5c0600
Export AuthClient, GraphQLClient, and RestClient
shariff-6 Feb 21, 2025
c326328
Export ProjectQueries
shariff-6 Feb 21, 2025
ae5fdad
Update GitLab integration to sync projects and configure settings
shariff-6 Feb 21, 2025
8f6b48c
Removes deprecated appHost
shariff-6 Feb 21, 2025
8b97c1d
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Feb 24, 2025
0bd4782
Adds makefile
shariff-6 Feb 24, 2025
2ee66f4
Updates ocean version
shariff-6 Feb 24, 2025
a6bea07
feat: add Groups, Issues, and MRs to GitLab integration
shariff-6 Feb 26, 2025
e99eb0b
feat: implement methods for fetching GitLab entities
shariff-6 Feb 26, 2025
e92cbb4
Adds group query
shariff-6 Feb 26, 2025
a09aee6
feat: enhance GitLab integration to process issues and merge requests…
shariff-6 Feb 27, 2025
9c0e4d0
Copyrefactor: improve GitLabClient group handling and resource fetching
shariff-6 Feb 27, 2025
bdfccd0
refactor: improve GitLab client REST API implementation
shariff-6 Feb 27, 2025
bb09d9e
Adds group to project response
shariff-6 Feb 27, 2025
abdaa2c
Adds groups, issues and merge-request to kind
shariff-6 Feb 27, 2025
dc76acd
Group, Issue, Project, MR kind and blueprint config
shariff-6 Feb 27, 2025
a6b2d8d
Fixes lint, upgrades ocean version
shariff-6 Feb 27, 2025
cd7ba20
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Feb 27, 2025
1fa4886
chore: Release GitLab v2 integration version 0.1.0
shariff-6 Feb 27, 2025
f3f2b19
refactor: simplify GitLab client resource fetching methods
shariff-6 Feb 27, 2025
af7d31c
refactor: optimize GitLab client authentication and code structure
shariff-6 Feb 27, 2025
675cb05
docs: Add docstring for get_projects method in GitLab base client
shariff-6 Feb 27, 2025
f89ab8e
Fixes lint
shariff-6 Feb 27, 2025
754cac5
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Feb 27, 2025
25167e6
fix: Update Makefile to correctly include infrastructure Makefile
shariff-6 Mar 3, 2025
261b556
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 3, 2025
b251549
Update ocean version
shariff-6 Mar 3, 2025
6fbcf1a
Fixes lint
shariff-6 Mar 3, 2025
1ab8781
Fixes lint
shariff-6 Mar 3, 2025
066b178
Merge branch 'main' into PORT-13110-Initialise-New-Gitlab-Integration
mk-armah Mar 4, 2025
a76b987
Merge branch 'main' into PORT-13110-Initialise-New-Gitlab-Integration
mk-armah Mar 5, 2025
82f69e4
Introduces label kind
shariff-6 Mar 5, 2025
9892a08
Sets onboarding defaults to service
shariff-6 Mar 5, 2025
3e21427
Test for auth and base client
shariff-6 Mar 5, 2025
59fe569
Fixes lint
shariff-6 Mar 5, 2025
be6e173
Init file
shariff-6 Mar 5, 2025
5480c0b
Fixes lint
shariff-6 Mar 5, 2025
e918ac8
Adds language support
shariff-6 Mar 5, 2025
84706ac
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 5, 2025
9248890
Corrects .env example remove mapping
shariff-6 Mar 5, 2025
51005f4
Fixes type hinting and mocks
shariff-6 Mar 5, 2025
3478ac3
Fixes type hints and lints.
shariff-6 Mar 5, 2025
1abe7c3
Fixes lint
shariff-6 Mar 5, 2025
a669791
Removes, namespace, and default path from default blueprint
shariff-6 Mar 6, 2025
78d7621
Remove inline comment
shariff-6 Mar 7, 2025
b58da27
Updating Changelog
shariff-6 Mar 7, 2025
64083ba
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 11, 2025
8ef99c5
Update ocean version
shariff-6 Mar 11, 2025
de74b2c
Update lock file
shariff-6 Mar 11, 2025
8243aed
Enhance GitLab REST and GraphQL clients with params and file content
shariff-6 Mar 11, 2025
bd160ed
Add file search and content parsing to GitLab client
shariff-6 Mar 11, 2025
2ffeba8
Add utility functions for GitLab file handling
shariff-6 Mar 11, 2025
3fa5d62
Add GitLab file entity processor and path utilities
shariff-6 Mar 11, 2025
d459d50
Extend GitLab integration with file resource support
shariff-6 Mar 11, 2025
08ca505
Update GraphQL projects query to include file blobs
shariff-6 Mar 11, 2025
a21258f
Fixes lint adds tests
shariff-6 Mar 11, 2025
465e9b9
Fixes lint
shariff-6 Mar 11, 2025
10c67bb
Adds pyyaml to dependancies
shariff-6 Mar 11, 2025
f694c69
parses files async
shariff-6 Mar 11, 2025
2c595ee
Add Typing stubs for PyYAM
shariff-6 Mar 11, 2025
e6143ec
Updates version and changelog
shariff-6 Mar 11, 2025
55ac4ff
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 11, 2025
fa70401
Updates changelog and version
shariff-6 Mar 11, 2025
754a68c
- Added process_file method to handle parsing logic.
shariff-6 Mar 12, 2025
9bb73ec
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 12, 2025
17f1e98
Bump ocean version
shariff-6 Mar 12, 2025
ba3dcd4
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 12, 2025
9292c41
Bump Ocean Version
shariff-6 Mar 12, 2025
edeaaaa
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 12, 2025
2bd60ea
Fix poetry mismatch
shariff-6 Mar 12, 2025
bbf4b55
Enhance logging in GitLabClient for repository and group searches
shariff-6 Mar 12, 2025
795ca83
Update integrations/gitlab-v2/main.py
shariff-6 Mar 13, 2025
eca0db3
Refactor GitLab client and add concurrent resource fetching
shariff-6 Mar 13, 2025
dd3b160
Revert response type for 404 errors to an empty dict in HTTPBaseClien…
shariff-6 Mar 13, 2025
0c6f6ed
Refactor GitLab client to improve group resource fetching and paginat…
shariff-6 Mar 13, 2025
80a0ad2
Bumps ocean version
shariff-6 Mar 13, 2025
9e28701
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 13, 2025
65ca286
Remove docstring
shariff-6 Mar 13, 2025
d2d27a5
Remove unused imports
shariff-6 Mar 13, 2025
e923b85
Fixes lint
shariff-6 Mar 13, 2025
2a3b32f
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 13, 2025
5bd1876
commit: Enable incremental streaming of nested fields in GitLabClient…
shariff-6 Mar 14, 2025
5525f89
Fixes type hints
shariff-6 Mar 14, 2025
03bd8c7
Enhance GraphQLClient pagination and nested field processing
shariff-6 Mar 15, 2025
a46b380
Fix type hints
shariff-6 Mar 15, 2025
fa2f6ae
Confidently gets resource type
shariff-6 Mar 15, 2025
5b12ffd
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 17, 2025
4514852
Ensure __labels and are always arrays in project data
shariff-6 Mar 17, 2025
f73660a
Fixes lint
shariff-6 Mar 17, 2025
6b3c0de
Configure Ruff to target Python 3.12
shariff-6 Mar 17, 2025
130f9d4
Removes unused imports
shariff-6 Mar 17, 2025
94143b1
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 17, 2025
0bcaaf7
Moves pagination logic to client
shariff-6 Mar 18, 2025
260cb84
- Added class-level BoundedSemaphore(10) in __init__ to cap concurren…
shariff-6 Mar 18, 2025
46b9b60
Adds type hints
shariff-6 Mar 18, 2025
0f2739f
Updates test case input with the given value.
shariff-6 Mar 18, 2025
2afca36
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 18, 2025
a970fd5
Removes unused imports
shariff-6 Mar 18, 2025
1c9f71a
Fixes lint
shariff-6 Mar 18, 2025
d52b1f1
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 18, 2025
3032080
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 18, 2025
ae60b5c
- Introduced `BATCH_SIZE = 100` and `SUB_BATCH_SIZE = 50` for better …
shariff-6 Mar 18, 2025
44dc123
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 18, 2025
7f514b0
Refactor GraphQLClient to streamline project processing and remove su…
shariff-6 Mar 19, 2025
79325db
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 19, 2025
18f06de
**Refactor GraphQL client and introduce project labels query**
shariff-6 Mar 19, 2025
e63439f
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 19, 2025
dea6712
- Renamed `project_labels` to `labels` in `RESOURCE_QUERIES`
shariff-6 Mar 19, 2025
93443b0
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 19, 2025
4ff1235
Removes interpolation from labels query
shariff-6 Mar 19, 2025
d3dd6bb
- Added `tenacity` for automatic retries in `_execute_query`, replaci…
shariff-6 Mar 19, 2025
762fa8f
Fixes lint
shariff-6 Mar 19, 2025
dc7b3b9
Enhance project fetching by adding support for conditional label incl…
shariff-6 Mar 20, 2025
d6702e9
Add optional parameters to get_projects
shariff-6 Mar 20, 2025
70cc277
Fixes lint
shariff-6 Mar 20, 2025
dc7cf12
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 20, 2025
da7f9e2
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 20, 2025
b3e7916
This commit extends the GitLabClient class to enable searching for fi…
shariff-6 Mar 20, 2025
58bb510
This commit updates the RestClient class to support fetching file con…
shariff-6 Mar 20, 2025
3811892
This commit refines the GitLab integration by optimizing file search …
shariff-6 Mar 20, 2025
37638d3
Fix mypy errors
shariff-6 Mar 20, 2025
b523b9a
Enhance GitLabClient tests to include project_id and validate file co…
shariff-6 Mar 20, 2025
79742d4
Fixes lint, and adds File Kind to ObjectKind
shariff-6 Mar 20, 2025
a32a747
Removes unised imports
shariff-6 Mar 20, 2025
f1c6daa
### Refactor GitLabClient to Use Concurrent Processing with Semaphore
shariff-6 Mar 21, 2025
92fcb6b
Merge branch 'main' into PORT-13110-Initialise-New-Gitlab-Integration
mk-armah Mar 21, 2025
6ecd307
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 21, 2025
8ae027f
- Replaced `asyncio.as_completed` with `stream_async_iterators_tasks`…
shariff-6 Mar 21, 2025
4766481
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 21, 2025
fb8c637
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 21, 2025
7692e77
Adds Graphql Error Handler
shariff-6 Mar 21, 2025
ba9a390
Update integrations/gitlab-v2/clients/exceptions.py
shariff-6 Mar 21, 2025
c530633
Organise files and folders
shariff-6 Mar 21, 2025
ba213c4
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 21, 2025
35a1b13
Fix cursor parameter naming and clean up unused code in GraphQLClient
shariff-6 Mar 21, 2025
6a05c01
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 23, 2025
2b90624
Process search in groups concurrently
shariff-6 Mar 23, 2025
e46d41d
Removes redundant garabage collector
shariff-6 Mar 23, 2025
26f57dc
- Reformatted `search_files` method for better readability and indent…
shariff-6 Mar 23, 2025
b9cffad
Remove redundant garbage collector
shariff-6 Mar 23, 2025
11b4a1b
Remove unused imports
shariff-6 Mar 23, 2025
82610dc
Rename get_group_resource to get_groups_resource for consistency
shariff-6 Mar 23, 2025
91a6541
Refactor GitLab integration to use consistent naming for group resour…
shariff-6 Mar 23, 2025
4b47185
- Added `include_languages` field to `ProjectSelector` to allow fetch…
shariff-6 Mar 24, 2025
39e3131
- Updated `identifier` mapping in `port-app-config.yml` to use `path_…
shariff-6 Mar 24, 2025
52208e9
Fixes type hints and lint
shariff-6 Mar 24, 2025
6050297
Fixes lint
shariff-6 Mar 24, 2025
bc87d0a
Bumps ocean version
shariff-6 Mar 24, 2025
447d622
Fix lint
shariff-6 Mar 24, 2025
7cd41cb
Remove graphql client
shariff-6 Mar 24, 2025
f154b8d
Removes labels from changelog
shariff-6 Mar 24, 2025
8944789
Removes graphql
shariff-6 Mar 24, 2025
eeecf99
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 24, 2025
3898118
Removes labels kind
shariff-6 Mar 24, 2025
c36ea78
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 24, 2025
7024140
Renames method to desrcitpive paginated convention
shariff-6 Mar 24, 2025
cfa09ed
Decouples client initialisation
shariff-6 Mar 24, 2025
4aafba5
Initialise utils folder
shariff-6 Mar 24, 2025
f2877c3
Fixes imports
shariff-6 Mar 24, 2025
6eb8991
Remove unused imports
shariff-6 Mar 24, 2025
192a21a
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 24, 2025
3d50ca0
Removes langauges and labels from default properties
shariff-6 Mar 24, 2025
e1aad8c
Merge branch 'main' into PORT-13110-Initialise-New-Gitlab-Integration
mk-armah Mar 24, 2025
dbbb687
Rename utils folder to helpers, rename objeckt kinds to utils
shariff-6 Mar 24, 2025
7a96b4b
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 24, 2025
857629e
Fixes imports
shariff-6 Mar 24, 2025
21ea559
Fixes lint
shariff-6 Mar 24, 2025
d51bec5
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 25, 2025
b0a5a2d
- Removed `get_project_resource` from `GitLabClient` and `RestClient`…
shariff-6 Mar 25, 2025
1d3560e
Remove unused imports.
shariff-6 Mar 25, 2025
8a4f839
Fix imports
shariff-6 Mar 25, 2025
432e4c0
Update integrations/gitlab-v2/clients/base_client.py
shariff-6 Mar 25, 2025
1022e80
Update integrations/gitlab-v2/main.py
shariff-6 Mar 25, 2025
2080a36
Update integrations/gitlab-v2/clients/rest_client.py
shariff-6 Mar 25, 2025
29a5786
- Raised `DEFAULT_MIN_ACCESS_LEVEL` from 10 (Guest) to 30 (Developer)…
shariff-6 Mar 25, 2025
22b4dc2
Fixes type hints in make_paginated_request
shariff-6 Mar 25, 2025
4e07a7b
Fixes lint
shariff-6 Mar 25, 2025
8d0a958
Updates min access level to 30
shariff-6 Mar 25, 2025
80ae65c
Remove enrichment of labels
shariff-6 Mar 25, 2025
2b19438
Fixes lint
shariff-6 Mar 25, 2025
2fa3eed
Removes labels
shariff-6 Mar 25, 2025
b45f5d1
Remove unused imports
shariff-6 Mar 25, 2025
85337ad
Merge branch 'PORT-13110-Initialise-New-Gitlab-Integration' of https:…
shariff-6 Mar 25, 2025
65b9ea2
Fixes imports
shariff-6 Mar 25, 2025
0ec6fd4
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Mar 25, 2025
f91d65c
Adds feature to process search:// prefix patterns
shariff-6 Mar 26, 2025
c2f5682
Fixes lint
shariff-6 Mar 26, 2025
214a7a2
Updates Lock File
shariff-6 Mar 26, 2025
0ba5b16
- Grouped GitLabClient methods into public (project, group, file) and…
shariff-6 Mar 27, 2025
b3683cb
Moves process file to helper
shariff-6 Mar 27, 2025
8c9c14e
feat: Refactor search_files to use scope and query with _search_in_re…
shariff-6 Mar 27, 2025
8e79012
Renames _search_in_group_with_query with _search_in_group
shariff-6 Mar 27, 2025
ae30e7a
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Apr 2, 2025
9b00038
Remove redundant content checks in get_file_content
shariff-6 Apr 2, 2025
0099f84
- Removed `file_entity_processor.py` from `gitops` and moved `GitLabF…
shariff-6 Apr 2, 2025
804f6c8
Remove unused imports
shariff-6 Apr 2, 2025
177e311
Removes relatives imports, and list appending in preciing of search b…
shariff-6 Apr 2, 2025
96c876f
- Moved PARSEABLE_EXTENSIONS to a global variable in gitlab_client.py
shariff-6 Apr 2, 2025
d36a31a
- Switch GitLabClient._process_batch to asyncio.gather for full batch…
shariff-6 Apr 2, 2025
0913167
Fixes lint
shariff-6 Apr 2, 2025
6468038
Reslves dependancies
shariff-6 Apr 2, 2025
7d4126d
Removes references to glob patterns
shariff-6 Apr 2, 2025
407f9a0
Removes groups search
shariff-6 Apr 3, 2025
ad1ba12
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Apr 3, 2025
edc7060
Bump ocean version
shariff-6 Apr 3, 2025
6fdd64a
Ensure that file resync is skipped with a warning when no repositories
shariff-6 Apr 3, 2025
4d3c5e7
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Apr 3, 2025
df58ae2
Updates imprts to use gitlab folder
shariff-6 Apr 3, 2025
0496c3a
Fixes lint
shariff-6 Apr 3, 2025
44f1edd
Removes duplicate methods
shariff-6 Apr 3, 2025
8c62866
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Apr 4, 2025
a7e5f82
- **Enrichment**: Replaced `AsyncIterator`-based `_enrich_batch` with an
shariff-6 Apr 7, 2025
1ca9dcf
Update integrations/gitlab-v2/gitlab/clients/utils.py
shariff-6 Apr 7, 2025
160dd84
Fixes lint
shariff-6 Apr 7, 2025
5a6e2f2
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Apr 7, 2025
43b6dba
Merge branch 'PORT-13460-Add-Support-for-file-kind-Gitlab' of https:/…
shariff-6 Apr 7, 2025
52357b2
- Renamed `query` to `path` in `search_files` and made `repositories`…
shariff-6 Apr 8, 2025
ca855ca
Bump ocean version
shariff-6 Apr 8, 2025
1ca60ec
Merge branch 'main' of https://github.com/port-labs/ocean into PORT-1…
shariff-6 Apr 8, 2025
d227d90
Rename `_process_batch` to `_process_file_batch` for clarity in GitLa…
shariff-6 Apr 8, 2025
c813977
Update integrations/gitlab-v2/gitlab/clients/gitlab_client.py
shariff-6 Apr 8, 2025
aeb3b05
Update integrations/gitlab-v2/gitlab/clients/gitlab_client.py
shariff-6 Apr 8, 2025
877548d
Rename search methods in GitLabClient to be specific i.e search_files
shariff-6 Apr 8, 2025
e3fd210
Refactor GitLab integration to use dedicated entity processors for fi…
shariff-6 Apr 8, 2025
bbb72b5
Move parse_file_content function to helpers
shariff-6 Apr 8, 2025
ba9a111
Fixes lint
shariff-6 Apr 8, 2025
77a6ba4
Removes rate limit on non file or search operations
shariff-6 Apr 8, 2025
57d15af
Fixes lint
shariff-6 Apr 8, 2025
da24a5e
Refactor GitLab client to remove default ref parameter and clean up F…
shariff-6 Apr 8, 2025
d3f48e3
Bups integration version, updates changelog
shariff-6 Apr 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions integrations/gitlab-v2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- towncrier release notes start -->

## 0.1.1-dev (2025-03-12)

### Improvements

- Added Support for file kind


## 0.1.0-dev (2025-02-27)

### Features
Expand Down
185 changes: 155 additions & 30 deletions integrations/gitlab-v2/clients/gitlab_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
from functools import partial
from typing import Any, AsyncIterator, Callable, Optional

import anyio
from loguru import logger
from port_ocean.utils.async_iterators import (
semaphore_async_iterator,
stream_async_iterators_tasks,
)
from urllib.parse import quote

from .rest_client import RestClient
from .utils import parse_file_content


class GitLabClient:
Expand All @@ -21,6 +24,7 @@ class GitLabClient:
def __init__(self, base_url: str, token: str) -> None:
self.rest = RestClient(base_url, token, endpoint="api/v4")

# Public: Project Methods
async def get_projects(
self,
params: Optional[dict[str, Any]] = None,
Expand All @@ -37,39 +41,12 @@ async def get_projects(

if include_languages:
enriched_batch = await self._enrich_batch(
enriched_batch, self.enrich_project_with_languages, max_concurrent
enriched_batch, self._enrich_project_with_languages, max_concurrent
)

yield enriched_batch

async def _enrich_batch(
self,
batch: list[dict[str, Any]],
enrich_func: Callable[[dict[str, Any]], AsyncIterator[list[dict[str, Any]]]],
max_concurrent: int,
) -> list[dict[str, Any]]:

semaphore = asyncio.Semaphore(max_concurrent)
tasks = [
semaphore_async_iterator(semaphore, partial(enrich_func, project))
for project in batch
]
enriched_projects = []
async for enriched_batch in stream_async_iterators_tasks(*tasks):
enriched_projects.extend(enriched_batch)
return enriched_projects

async def enrich_project_with_languages(
self, project: dict[str, Any]
) -> AsyncIterator[list[dict[str, Any]]]:

project_path = project.get("path_with_namespace", str(project["id"]))
logger.debug(f"Enriching {project_path} with languages")
languages = await self.rest.get_project_languages(project_path)
logger.info(f"Fetched languages for {project_path}: {languages}")
project["__languages"] = languages
yield [project]

# Public: Group Methods
async def get_groups(self) -> AsyncIterator[list[dict[str, Any]]]:
"""Fetch all groups accessible to the user."""
async for batch in self.rest.get_paginated_resource(
Expand All @@ -83,7 +60,6 @@ async def get_groups_resource(
resource_type: str,
max_concurrent: int = 10,
) -> AsyncIterator[list[dict[str, Any]]]:

semaphore = asyncio.Semaphore(max_concurrent)
tasks = [
semaphore_async_iterator(
Expand All @@ -96,6 +72,79 @@ async def get_groups_resource(
if batch:
yield batch

# Public: File Methods
async def get_file_content(
self, project_id: str, file_path: str, ref: str = "main"
) -> Optional[str]:
return await self.rest.get_file_content(project_id, file_path, ref)

async def file_exists(self, project_id: str, scope: str, query: str) -> bool:
params = {"scope": scope, "search": query}
encoded_project_path = quote(project_id, safe="")
response = await self.rest.send_api_request(
"GET", f"projects/{encoded_project_path}/search", params
)
return bool(response)

async def search_files(
self,
scope: str,
query: str,
repositories: Optional[list[str]] = None,
max_concurrent: int = 10,
) -> AsyncIterator[list[dict[str, Any]]]:
"""Search for files in repositories or groups using a scope and query, returning files with content."""
logger.info(f"Searching for files with scope '{scope}' and query '{query}'")
semaphore = asyncio.Semaphore(max_concurrent)

if repositories:
logger.info(f"Searching in {len(repositories)} repositories")
for repo in repositories:
logger.debug(f"Searching repo '{repo}' for query '{query}'")
async for batch in self._search_in_repository(repo, scope, query):
yield batch
else:
logger.info("Searching across all accessible groups")
async for groups in self.get_groups():
logger.debug(f"Processing batch of {len(groups)} groups")
tasks = [
semaphore_async_iterator(
semaphore,
partial(self._search_in_group, group, scope, query),
)
for group in groups
]
async for batch in stream_async_iterators_tasks(*tasks):
yield batch

# Helpers: Enrichment
async def _enrich_batch(
self,
batch: list[dict[str, Any]],
enrich_func: Callable[[dict[str, Any]], AsyncIterator[list[dict[str, Any]]]],
max_concurrent: int,
) -> list[dict[str, Any]]:
semaphore = asyncio.Semaphore(max_concurrent)
tasks = [
semaphore_async_iterator(semaphore, partial(enrich_func, project))
for project in batch
]
enriched_projects = []
async for enriched_batch in stream_async_iterators_tasks(*tasks):
enriched_projects.extend(enriched_batch)
return enriched_projects

async def _enrich_project_with_languages(
self, project: dict[str, Any]
) -> AsyncIterator[list[dict[str, Any]]]:
project_path = project.get("path_with_namespace", str(project["id"]))
logger.debug(f"Enriching {project_path} with languages")
languages = await self.rest.get_project_languages(project_path)
logger.info(f"Fetched languages for {project_path}: {languages}")
project["__languages"] = languages
yield [project]

# Helpers: Group Processing
async def _process_single_group(
self,
group: dict[str, Any],
Expand All @@ -112,3 +161,79 @@ async def _process_single_group(
f"Fetched {len(resource_batch)} {resource_type} for group {group_id}"
)
yield resource_batch

# Helpers: File Processing and Search
async def _process_file(self, file: dict[str, Any], context: str) -> dict[str, Any]:
"""Fetch full file content and parse it."""
file_path = file["path"]
project_id = file["project_id"]
ref = file.get("ref", "main")
full_content = await self.get_file_content(project_id, file_path, ref)
if full_content is not None:
try:
file["content"] = await anyio.to_thread.run_sync(
parse_file_content, full_content, file_path, context
)
except Exception as e:
logger.error(f"Failed to parse {file_path} in {context}: {str(e)}")
file["parsed_data"] = None
else:
file["content"] = None
return file

async def _process_batch(
self, batch: list[dict[str, Any]], context: str
) -> AsyncIterator[dict[str, Any]]:
PARSEABLE_EXTENSIONS = (".json", ".yaml", ".yml")
tasks = [
(
self._process_file(file, context)
if file.get("path", "").endswith(PARSEABLE_EXTENSIONS)
else asyncio.create_task(asyncio.sleep(0, result=file))
)
for file in batch
]
for completed in asyncio.as_completed(tasks):
yield await completed

async def _search_in_repository(
self,
repo: str,
scope: str,
query: str,
) -> AsyncIterator[list[dict[str, Any]]]:
"""Search files in a repository using a scope and query."""
logger.debug(
f"Searching repo '{repo}' for query '{query}' with scope '{scope}'"
)
params = {"scope": scope, "search": query}
encoded_repo = quote(repo, safe="")
path = f"projects/{encoded_repo}/search"
async for batch in self.rest.get_paginated_resource(path, params=params):
if batch:
processed_batch = []
async for processed_file in self._process_batch(batch, repo):
processed_batch.append(processed_file)
if processed_batch:
yield processed_batch

async def _search_in_group(
self,
group: dict[str, Any],
scope: str,
query: str,
) -> AsyncIterator[list[dict[str, Any]]]:
"""Search files in a group using a scope and query."""
group_context = group.get("name", str(group["id"]))
group_id = group["id"]
params = {"scope": scope, "search": query}
logger.debug(f"Searching group '{group_context}' for query '{query}'")
async for batch in self.rest.get_paginated_group_resource(
group_id, "search", params
):
if batch:
processed_batch = []
async for processed_file in self._process_batch(batch, group_context):
processed_batch.append(processed_file)
if processed_batch:
yield processed_batch
24 changes: 16 additions & 8 deletions integrations/gitlab-v2/clients/rest_client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import base64
from typing import Any, AsyncIterator, Optional
from urllib.parse import quote

Expand All @@ -8,7 +9,7 @@

class RestClient(HTTPBaseClient):
DEFAULT_PAGE_SIZE = 100
VALID_GROUP_RESOURCES = ["issues", "merge_requests", "labels"]
VALID_GROUP_RESOURCES = ["issues", "merge_requests", "labels", "search"]

async def get_paginated_resource(
self, resource_type: str, params: Optional[dict[str, Any]] = None
Expand Down Expand Up @@ -49,6 +50,20 @@ async def get_project_languages(
path = f"projects/{encoded_project_path}/languages"
return await self.send_api_request("GET", path, params=params or {})

async def get_file_content(
self, project_id: str, file_path: str, ref: str = "main"
) -> Optional[str]:
encoded_project_id = quote(str(project_id), safe="")
encoded_file_path = quote(file_path, safe="")
path = f"projects/{encoded_project_id}/repository/files/{encoded_file_path}"
params = {"ref": ref}

response = await self.send_api_request("GET", path, params=params)
if not response:
return None

return base64.b64decode(response["content"]).decode("utf-8")

async def _make_paginated_request(
self,
path: str,
Expand All @@ -57,23 +72,16 @@ async def _make_paginated_request(
) -> AsyncIterator[list[dict[str, Any]]]:
page = 1
params_dict: dict[str, Any] = params or {}

while True:
request_params = {**params_dict, "per_page": page_size, "page": page}
logger.debug(f"Fetching page {page} from {path}")

response = await self.send_api_request("GET", path, params=request_params)

# HTTP API returns a list directly, or empty dict for 404
batch: list[dict[str, Any]] = response if isinstance(response, list) else []

if not batch:
break

yield batch

if len(batch) < page_size:
logger.debug(f"Last page reached for {path}, no more data.")
break

page += 1
47 changes: 47 additions & 0 deletions integrations/gitlab-v2/clients/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import json
from typing import Any, Union

import yaml
from braceexpand import braceexpand
from loguru import logger


def strip_recursive_prefix(pattern: str) -> str:
return pattern[3:] if pattern.startswith("**/") else pattern


def convert_glob_to_gitlab_patterns(pattern: Union[str, list[str]]) -> list[str]:
"""Converts glob patterns into GitLab-compatible patterns."""
if isinstance(pattern, list):
expanded_patterns: list[str] = []
for glob_pattern in pattern:
stripped_pattern = strip_recursive_prefix(glob_pattern)
expanded_patterns.extend(braceexpand(stripped_pattern))
return expanded_patterns

# Handle single pattern
stripped_pattern = strip_recursive_prefix(pattern)
return list(braceexpand(stripped_pattern))


def parse_file_content(
content: str, file_path: str = "unknown", context: str = "unknown"
) -> Union[str, dict[str, Any], list[Any]]:
"""Parse file content as JSON or YAML, falling back to raw string if parsing fails."""
try:
return json.loads(content)
except json.JSONDecodeError:
try:
logger.debug(f"Trying to parse file {file_path} in {context} as YAML")
documents = list(yaml.load_all(content, Loader=yaml.SafeLoader))
if not documents:
logger.debug(
f"Failed to parse {file_path} as YAML, returning raw content"
)
return content
return documents if len(documents) > 1 else documents[0]
except yaml.YAMLError:
logger.debug(
f"Failed to parse {file_path} as JSON/YAML, returning raw content"
)
return content
Empty file.
Loading