gitlabber 1.2.7__tar.gz → 2.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.
- {gitlabber-1.2.7/gitlabber.egg-info → gitlabber-2.0.0}/PKG-INFO +127 -41
- {gitlabber-1.2.7 → gitlabber-2.0.0}/README.rst +120 -35
- gitlabber-2.0.0/gitlabber/__init__.py +8 -0
- gitlabber-2.0.0/gitlabber/__main__.py +8 -0
- gitlabber-2.0.0/gitlabber/archive.py +40 -0
- gitlabber-2.0.0/gitlabber/auth.py +62 -0
- gitlabber-2.0.0/gitlabber/cli.py +492 -0
- gitlabber-2.0.0/gitlabber/config.py +98 -0
- gitlabber-2.0.0/gitlabber/exceptions.py +137 -0
- gitlabber-2.0.0/gitlabber/format.py +20 -0
- gitlabber-2.0.0/gitlabber/git.py +412 -0
- gitlabber-2.0.0/gitlabber/gitlab_tree.py +327 -0
- gitlabber-2.0.0/gitlabber/method.py +18 -0
- gitlabber-2.0.0/gitlabber/naming.py +18 -0
- gitlabber-2.0.0/gitlabber/progress.py +192 -0
- gitlabber-2.0.0/gitlabber/rate_limiter.py +93 -0
- gitlabber-2.0.0/gitlabber/tree_builder.py +565 -0
- gitlabber-2.0.0/gitlabber/url_builder.py +78 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0/gitlabber.egg-info}/PKG-INFO +127 -41
- gitlabber-2.0.0/gitlabber.egg-info/SOURCES.txt +118 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/gitlabber.egg-info/requires.txt +4 -2
- {gitlabber-1.2.7 → gitlabber-2.0.0}/pyproject.toml +49 -7
- gitlabber-2.0.0/setup.cfg +10 -0
- gitlabber-2.0.0/setup.py +3 -0
- gitlabber-2.0.0/tests/__pycache__/__init__.cpython-312.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/__init__.cpython-313.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/conftest.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/gitlab_test_utils.cpython-312.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/gitlab_test_utils.cpython-313.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/io_test_util.cpython-312.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/io_test_util.cpython-313.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_archive.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_archive.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_archive.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_archive.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_auth.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_cli.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_cli.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_cli.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_cli.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_config.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_e2e.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_e2e.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_e2e.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_e2e.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_e2e.cpython-313.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_format.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_format.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_format.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_format.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_git.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_git.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_git.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_git.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_gitlab_tree.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_gitlab_tree.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_gitlab_tree.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_gitlab_tree.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_helpers.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_integration.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_integration.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_integration.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_integration.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_main.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_method.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_method.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_method.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_method.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_naming.cpython-312-pytest-8.3.3.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_naming.cpython-312-pytest-8.3.4.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_naming.cpython-312-pytest-8.3.5.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_naming.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_performance.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_performance.cpython-313.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_progress.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_rate_limiter.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/__pycache__/test_url_builder.cpython-313-pytest-9.0.1.pyc +0 -0
- gitlabber-2.0.0/tests/conftest.py +92 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/gitlab_test_utils.py +69 -25
- gitlabber-2.0.0/tests/io_test_util.py +53 -0
- gitlabber-2.0.0/tests/test_archive.py +27 -0
- gitlabber-2.0.0/tests/test_auth.py +51 -0
- gitlabber-2.0.0/tests/test_cli.py +114 -0
- gitlabber-2.0.0/tests/test_config.py +93 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/test_e2e.py +74 -13
- gitlabber-2.0.0/tests/test_format.py +23 -0
- gitlabber-2.0.0/tests/test_git.py +219 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/test_gitlab_tree.py +128 -2
- gitlabber-2.0.0/tests/test_helpers.py +391 -0
- gitlabber-2.0.0/tests/test_integration.py +86 -0
- gitlabber-2.0.0/tests/test_main.py +16 -0
- gitlabber-2.0.0/tests/test_method.py +20 -0
- gitlabber-2.0.0/tests/test_naming.py +20 -0
- gitlabber-2.0.0/tests/test_performance.py +236 -0
- gitlabber-2.0.0/tests/test_progress.py +99 -0
- gitlabber-2.0.0/tests/test_rate_limiter.py +218 -0
- gitlabber-2.0.0/tests/test_url_builder.py +95 -0
- gitlabber-1.2.7/gitlabber/__init__.py +0 -2
- gitlabber-1.2.7/gitlabber/__main__.py +0 -2
- gitlabber-1.2.7/gitlabber/archive.py +0 -23
- gitlabber-1.2.7/gitlabber/cli.py +0 -242
- gitlabber-1.2.7/gitlabber/format.py +0 -19
- gitlabber-1.2.7/gitlabber/git.py +0 -100
- gitlabber-1.2.7/gitlabber/gitlab_tree.py +0 -225
- gitlabber-1.2.7/gitlabber/method.py +0 -19
- gitlabber-1.2.7/gitlabber/naming.py +0 -18
- gitlabber-1.2.7/gitlabber/progress.py +0 -34
- gitlabber-1.2.7/gitlabber.egg-info/SOURCES.txt +0 -50
- gitlabber-1.2.7/setup.cfg +0 -24
- gitlabber-1.2.7/setup.py +0 -90
- gitlabber-1.2.7/tests/io_test_util.py +0 -25
- gitlabber-1.2.7/tests/test_archive.py +0 -22
- gitlabber-1.2.7/tests/test_cli.py +0 -139
- gitlabber-1.2.7/tests/test_format.py +0 -17
- gitlabber-1.2.7/tests/test_git.py +0 -184
- gitlabber-1.2.7/tests/test_integration.py +0 -28
- gitlabber-1.2.7/tests/test_method.py +0 -18
- gitlabber-1.2.7/tests/test_naming.py +0 -17
- {gitlabber-1.2.7 → gitlabber-2.0.0}/LICENSE.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/MANIFEST.in +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/gitlabber.egg-info/dependency_links.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/gitlabber.egg-info/entry_points.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/gitlabber.egg-info/top_level.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__init__.py +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/__init__.cpython-311.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/gitlab_test_utils.cpython-311.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/io_test_util.cpython-311.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_archive.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_cli.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_e2e.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_format.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_git.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_gitlab_tree.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_integration.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_method.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/__pycache__/test_naming.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/test-input.yaml +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/test-output.json +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/test-output.tree +0 -0
- {gitlabber-1.2.7 → gitlabber-2.0.0}/tests/test-output.yaml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: gitlabber
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: A Gitlab clone/pull utility for backing up or cloning Gitlab groups
|
|
5
5
|
Author-email: Erez Mazor <erezmazor@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -14,19 +14,19 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
14
14
|
Classifier: Natural Language :: English
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
-
Requires-Python: >=3
|
|
20
|
+
Requires-Python: >=3.11
|
|
23
21
|
Description-Content-Type: text/x-rst
|
|
24
22
|
License-File: LICENSE.txt
|
|
25
|
-
Requires-Dist: docopt
|
|
26
23
|
Requires-Dist: anytree
|
|
27
24
|
Requires-Dist: globre
|
|
28
25
|
Requires-Dist: pyyaml
|
|
29
|
-
Requires-Dist:
|
|
26
|
+
Requires-Dist: pydantic>=2.7
|
|
27
|
+
Requires-Dist: pydantic-settings>=2.7
|
|
28
|
+
Requires-Dist: typer>=0.12
|
|
29
|
+
Requires-Dist: rich
|
|
30
30
|
Requires-Dist: GitPython
|
|
31
31
|
Requires-Dist: python-gitlab
|
|
32
32
|
Provides-Extra: test
|
|
@@ -34,6 +34,7 @@ Requires-Dist: coverage; extra == "test"
|
|
|
34
34
|
Requires-Dist: pytest; extra == "test"
|
|
35
35
|
Requires-Dist: pytest-cov; extra == "test"
|
|
36
36
|
Requires-Dist: pytest-integration; extra == "test"
|
|
37
|
+
Dynamic: license-file
|
|
37
38
|
|
|
38
39
|
.. image:: https://github.com/ezbz/gitlabber/actions/workflows/python-app.yml/badge.svg?branch=master
|
|
39
40
|
:target: https://github.com/ezbz/gitlabber/actions/workflows/python-app.yml
|
|
@@ -51,7 +52,7 @@ Requires-Dist: pytest-integration; extra == "test"
|
|
|
51
52
|
:target: https://pypi.python.org/pypi/gitlabber/
|
|
52
53
|
|
|
53
54
|
.. image:: https://readthedocs.org/projects/gitlabber/badge/?version=latest&style=plastic
|
|
54
|
-
:target: https://
|
|
55
|
+
:target: https://app.readthedocs.org/projects/gitlabber/
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
Gitlabber
|
|
@@ -69,54 +70,84 @@ Gitlabber clones or pulls all projects under a subset of groups / subgroups by b
|
|
|
69
70
|
Installation
|
|
70
71
|
------------
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
System Requirements
|
|
74
|
+
-------------------
|
|
75
|
+
* Python 3.11 or higher
|
|
76
|
+
* Git 2.0 or higher
|
|
77
|
+
* Network access to GitLab instance
|
|
73
78
|
|
|
74
|
-
|
|
79
|
+
Installation Methods
|
|
80
|
+
~~~~~~~~~~~~~~~~~~~~
|
|
81
|
+
* PyPI (recommended):
|
|
75
82
|
|
|
76
|
-
|
|
83
|
+
.. code-block:: bash
|
|
84
|
+
|
|
85
|
+
pip install gitlabber
|
|
86
|
+
|
|
87
|
+
* From source:
|
|
88
|
+
|
|
89
|
+
.. code-block:: bash
|
|
90
|
+
|
|
91
|
+
git clone https://github.com/ezbz/gitlabber.git
|
|
92
|
+
cd gitlabber
|
|
93
|
+
pip install -e .
|
|
77
94
|
|
|
78
95
|
* You'll need to create an `access token <https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html>`_ from GitLab with API scopes `read_repository`
|
|
79
96
|
and ``read_api`` (or ``api``, for GitLab versions <12.0)
|
|
80
97
|
|
|
98
|
+
Quick Start
|
|
99
|
+
-----------
|
|
100
|
+
|
|
101
|
+
.. code-block:: bash
|
|
102
|
+
|
|
103
|
+
# Install gitlabber
|
|
104
|
+
pip install gitlabber
|
|
105
|
+
|
|
106
|
+
# Clone all your GitLab projects
|
|
107
|
+
gitlabber -t <your-token> -u <gitlab-url> .
|
|
108
|
+
|
|
81
109
|
Usage
|
|
82
110
|
-----
|
|
83
111
|
|
|
84
112
|
* Arguments can be provided via the CLI arguments directly or via environment variables:
|
|
85
113
|
|
|
86
|
-
|
|
87
|
-
| Argument
|
|
88
|
-
|
|
89
|
-
| token
|
|
90
|
-
|
|
91
|
-
| url
|
|
92
|
-
|
|
93
|
-
| method
|
|
94
|
-
|
|
95
|
-
| naming
|
|
96
|
-
|
|
97
|
-
| include
|
|
98
|
-
|
|
99
|
-
| exclude
|
|
100
|
-
|
|
114
|
+
+------------------+------------------+---------------------------+
|
|
115
|
+
| Argument | Flag | Environment Variable |
|
|
116
|
+
+==================+==================+===========================+
|
|
117
|
+
| token | -t | `GITLAB_TOKEN` |
|
|
118
|
+
+------------------+------------------+---------------------------+
|
|
119
|
+
| url | -u | `GITLAB_URL` |
|
|
120
|
+
+------------------+------------------+---------------------------+
|
|
121
|
+
| method | -m | `GITLABBER_CLONE_METHOD` |
|
|
122
|
+
+------------------+------------------+---------------------------+
|
|
123
|
+
| naming | -n | `GITLABBER_FOLDER_NAMING` |
|
|
124
|
+
+------------------+------------------+---------------------------+
|
|
125
|
+
| include | -i | `GITLABBER_INCLUDE` |
|
|
126
|
+
+------------------+------------------+---------------------------+
|
|
127
|
+
| exclude | -x | `GITLABBER_EXCLUDE` |
|
|
128
|
+
+------------------+------------------+---------------------------+
|
|
101
129
|
|
|
102
130
|
* To view the tree run the command with your includes/excludes and the ``-p`` flag. It will print your tree like so:
|
|
103
131
|
|
|
104
|
-
.. code-block:: bash
|
|
132
|
+
.. code-block:: bash
|
|
133
|
+
|
|
134
|
+
root [http://gitlab.my.com]
|
|
135
|
+
├── group1 [/group1]
|
|
136
|
+
│ └── subgroup1 [/group1/subgroup1]
|
|
137
|
+
│ └── project1 [/group1/subgroup1/project1]
|
|
138
|
+
└── group2 [/group2]
|
|
139
|
+
├── subgroup1 [/group2/subgroup1]
|
|
140
|
+
│ └── project2 [/group2/subgroup1/project2]
|
|
141
|
+
├── subgroup2 [/group2/subgroup2]
|
|
142
|
+
└── subgroup3 [/group2/subgroup3]
|
|
105
143
|
|
|
106
|
-
root [http://gitlab.my.com]
|
|
107
|
-
├── group1 [/group1]
|
|
108
|
-
│ └── subgroup1 [/group1/subgroup1]
|
|
109
|
-
│ └── project1 [/group1/subgroup1/project1]
|
|
110
|
-
└── group2 [/group2]
|
|
111
|
-
├── subgroup1 [/group2/subgroup1]
|
|
112
|
-
│ └── project2 [/group2/subgroup1/project2]
|
|
113
|
-
├── subgroup2 [/group2/subgroup2]
|
|
114
|
-
└── subgroup3 [/group2/subgroup3]
|
|
115
144
|
|
|
116
145
|
* To see how to use glob patterns and regex to filter tree nodes, see the `globre project page <https://pypi.org/project/globre/#details>`_.
|
|
117
146
|
|
|
118
147
|
* Include/Exclude patterns do not work at the API level but work on the results returned from the API, for large Gitlab installations this can take a lot of time, if you need to reduce the amound of API calls for such projects use the ``--group-search`` parameter to search only for the top level groups the interest you using the `Gitlab Group Search API <https://docs.gitlab.com/ee/api/groups.html#search-for-group>`_ which allows you to do a partial like query for a Group's path or name
|
|
119
148
|
|
|
149
|
+
* **Performance optimization**: For large GitLab instances with many groups and projects, use the ``--api-concurrency`` option to dramatically speed up tree building. This enables parallel API calls (default: 5 concurrent requests) which can provide **4-6x speedup** in real-world scenarios. For example, building a tree with 21 subgroups and 21 projects can be reduced from ~96 seconds (sequential) to ~16-21 seconds (with ``--api-concurrency 5-10``). The ``-c/--concurrency`` option controls parallel git operations (cloning/pulling), while ``--api-concurrency`` controls parallel API calls (fetching groups/projects). Both can be tuned independently based on your needs.
|
|
150
|
+
|
|
120
151
|
* Cloning vs Pulling: when running Gitlabber consecutively with the same parameters, it will scan the local tree structure; if the project directory exists and is a valid git repository (has .git folder in it) Gitlabber will perform a git pull in the directory, otherwise the project directory will be created and the GitLab project will be cloned into it.
|
|
121
152
|
|
|
122
153
|
* Cloning submodules: use the ``-r`` flag to recurse git submodules, uses the ``--recursive`` for cloning and utilizes `GitPython's smart update method <https://github.com/gitpython-developers/GitPython/blob/20f4a9d49b466a18f1af1fdfb480bc4520a4cdc2/git/objects/submodule/root.py#L67>`_ for updating cloned repositories
|
|
@@ -126,7 +157,7 @@ Usage
|
|
|
126
157
|
.. code-block:: bash
|
|
127
158
|
|
|
128
159
|
usage: gitlabber [-h] [-t token] [-T] [-u url] [--verbose] [-p] [--print-format {json,yaml,tree}] [-n {name,path}] [-m {ssh,http}]
|
|
129
|
-
[-a {include,exclude,only}] [-i csv] [-x csv] [-r] [-F] [-d] [-s] [-g term] [-U] [-o options] [--version]
|
|
160
|
+
[-a {include,exclude,only}] [-i csv] [-x csv] [-c N] [--api-concurrency N] [-r] [-F] [-d] [-s] [-g term] [-U] [-o options] [--version]
|
|
130
161
|
[dest]
|
|
131
162
|
|
|
132
163
|
Gitlabber - clones or pulls entire groups/projects tree from gitlab
|
|
@@ -148,15 +179,18 @@ Usage
|
|
|
148
179
|
the folder naming strategy for projects from the gitlab API attributes (default: "name")
|
|
149
180
|
-m {ssh,http}, --method {ssh,http}
|
|
150
181
|
the git transport method to use for cloning (default: "ssh")
|
|
182
|
+
--fail-fast exit immediately when encountering discovery errors
|
|
151
183
|
-a {include,exclude,only}, --archived {include,exclude,only}
|
|
152
184
|
include archived projects and groups in the results (default: "include")
|
|
153
185
|
-i csv, --include csv
|
|
154
186
|
comma delimited list of glob patterns of paths to projects or groups to clone/pull
|
|
155
187
|
-x csv, --exclude csv
|
|
156
188
|
comma delimited list of glob patterns of paths to projects or groups to exclude from clone/pull
|
|
189
|
+
-c N, --concurrency N
|
|
190
|
+
number of concurrent git operations (default: 1)
|
|
191
|
+
--api-concurrency N number of concurrent API calls for tree building (default: 5)
|
|
157
192
|
-r, --recursive clone/pull git submodules recursively
|
|
158
193
|
-F, --use-fetch clone/fetch git repository (mirrored repositories)
|
|
159
|
-
-d, --dont-checkout don't checkout pulled git repository
|
|
160
194
|
-s, --include-shared include shared projects in the results
|
|
161
195
|
-g term, --group-search term
|
|
162
196
|
only include groups matching the search term, filtering done at the API level (useful for large projects, see: https://docs.gitlab.com/ee/api/groups.html#search-for-group works with partial names of path or name)
|
|
@@ -185,22 +219,54 @@ Usage
|
|
|
185
219
|
clone projects that start with a case insensitive 'w' using a regular expression:
|
|
186
220
|
gitlabber -i '/{[w].*}' .
|
|
187
221
|
|
|
188
|
-
clone
|
|
222
|
+
clone the personal projects to username-personal-projects
|
|
189
223
|
gitlabber -U .
|
|
190
224
|
|
|
191
225
|
perform a shallow clone of the git repositories
|
|
192
226
|
gitlabber -o "\-\-depth=1," .
|
|
193
227
|
|
|
228
|
+
speed up tree building for large GitLab instances with parallel API calls (4-6x faster)
|
|
229
|
+
# Real-world example: 96s → 16-21s for instances with many subgroups/projects
|
|
230
|
+
gitlabber --api-concurrency 10 -t <token> -u <url> .
|
|
231
|
+
|
|
232
|
+
use both API and git concurrency for maximum performance
|
|
233
|
+
# API concurrency speeds up tree discovery, git concurrency speeds up cloning
|
|
234
|
+
gitlabber --api-concurrency 5 -c 10 -t <token> -u <url> .
|
|
235
|
+
|
|
236
|
+
**Performance Results:**
|
|
237
|
+
* Sequential (``--api-concurrency 1``): ~96 seconds
|
|
238
|
+
* With ``--api-concurrency 5``: ~21 seconds (**4.6x speedup**)
|
|
239
|
+
* With ``--api-concurrency 10``: ~16 seconds (**6x speedup**)
|
|
194
240
|
|
|
241
|
+
*Note: Actual speedup depends on your GitLab instance structure (number of groups, subgroups, and projects). Instances with many nested subgroups benefit most from higher concurrency values.*
|
|
242
|
+
|
|
243
|
+
Common Use Cases
|
|
244
|
+
----------------
|
|
245
|
+
|
|
246
|
+
Clone Specific Groups
|
|
247
|
+
---------------------
|
|
248
|
+
|
|
249
|
+
.. code-block:: bash
|
|
250
|
+
|
|
251
|
+
# Clone only projects from a specific group
|
|
252
|
+
gitlabber -i '/MyGroup/**' .
|
|
253
|
+
|
|
254
|
+
Exclude Archived Projects
|
|
255
|
+
-------------------------
|
|
256
|
+
|
|
257
|
+
.. code-block:: bash
|
|
258
|
+
|
|
259
|
+
# Clone all non-archived projects
|
|
260
|
+
gitlabber -a exclude .
|
|
195
261
|
|
|
196
262
|
Debugging
|
|
197
263
|
---------
|
|
198
264
|
* You can use the ``--verbose`` flag to print Gitlabber debug messages
|
|
199
265
|
* For more verbose GitLab messages, you can get the `GitPython <https://gitpython.readthedocs.io/en/stable>`_ module to print more debug messages by setting the environment variable:
|
|
200
266
|
|
|
201
|
-
.. code-block:: bash
|
|
267
|
+
.. code-block:: bash
|
|
202
268
|
|
|
203
|
-
|
|
269
|
+
export GIT_PYTHON_TRACE='full'
|
|
204
270
|
|
|
205
271
|
Troubleshooting
|
|
206
272
|
---------------
|
|
@@ -213,6 +279,26 @@ Known Limitations
|
|
|
213
279
|
* Folder naming strategy: Consecutively running Gitlabber with different values for the ``-n`` parameter will produce undesirable results. Use the same value as previous runs, or simply don't change it from the default (project name).
|
|
214
280
|
* If you're going to clone a large number of projects, observe rate limits `for gitlab.com <https://docs.gitlab.com/ee/user/gitlab_com/index.html#gitlabcom-specific-rate-limits/>`_, and `for on-premise installations <https://docs.gitlab.com/ee/security/rate_limits.html>`_.
|
|
215
281
|
|
|
282
|
+
Branch Synchronization Issues
|
|
283
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
284
|
+
|
|
285
|
+
Gitlabber's default pull behavior (``git pull -v -- origin``) may fail when you have a local branch checked out that no longer exists on the remote repository. This commonly occurs after:
|
|
286
|
+
|
|
287
|
+
- Merging a merge request where the remote branch is automatically deleted
|
|
288
|
+
- Manual deletion of remote branches
|
|
289
|
+
|
|
290
|
+
**Error Example:**
|
|
291
|
+
|
|
292
|
+
.. code-block:: text
|
|
293
|
+
|
|
294
|
+
git.exc.GitCommandError: Cmd('git') failed due to: exit code(1)
|
|
295
|
+
cmdline: git pull -v -- origin
|
|
296
|
+
|
|
297
|
+
**Workaround:** Use the ``--use-fetch`` flag instead of the default pull behavior:
|
|
298
|
+
|
|
299
|
+
.. code-block:: bash
|
|
300
|
+
|
|
301
|
+
gitlabber --use-fetch -t <your-token> -u <gitlab-url> .
|
|
216
302
|
|
|
217
303
|
Links
|
|
218
304
|
-----
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
:target: https://pypi.python.org/pypi/gitlabber/
|
|
15
15
|
|
|
16
16
|
.. image:: https://readthedocs.org/projects/gitlabber/badge/?version=latest&style=plastic
|
|
17
|
-
:target: https://
|
|
17
|
+
:target: https://app.readthedocs.org/projects/gitlabber/
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
Gitlabber
|
|
@@ -32,54 +32,84 @@ Gitlabber clones or pulls all projects under a subset of groups / subgroups by b
|
|
|
32
32
|
Installation
|
|
33
33
|
------------
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
System Requirements
|
|
36
|
+
-------------------
|
|
37
|
+
* Python 3.11 or higher
|
|
38
|
+
* Git 2.0 or higher
|
|
39
|
+
* Network access to GitLab instance
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
Installation Methods
|
|
42
|
+
~~~~~~~~~~~~~~~~~~~~
|
|
43
|
+
* PyPI (recommended):
|
|
38
44
|
|
|
39
|
-
|
|
45
|
+
.. code-block:: bash
|
|
46
|
+
|
|
47
|
+
pip install gitlabber
|
|
48
|
+
|
|
49
|
+
* From source:
|
|
50
|
+
|
|
51
|
+
.. code-block:: bash
|
|
52
|
+
|
|
53
|
+
git clone https://github.com/ezbz/gitlabber.git
|
|
54
|
+
cd gitlabber
|
|
55
|
+
pip install -e .
|
|
40
56
|
|
|
41
57
|
* You'll need to create an `access token <https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html>`_ from GitLab with API scopes `read_repository`
|
|
42
58
|
and ``read_api`` (or ``api``, for GitLab versions <12.0)
|
|
43
59
|
|
|
60
|
+
Quick Start
|
|
61
|
+
-----------
|
|
62
|
+
|
|
63
|
+
.. code-block:: bash
|
|
64
|
+
|
|
65
|
+
# Install gitlabber
|
|
66
|
+
pip install gitlabber
|
|
67
|
+
|
|
68
|
+
# Clone all your GitLab projects
|
|
69
|
+
gitlabber -t <your-token> -u <gitlab-url> .
|
|
70
|
+
|
|
44
71
|
Usage
|
|
45
72
|
-----
|
|
46
73
|
|
|
47
74
|
* Arguments can be provided via the CLI arguments directly or via environment variables:
|
|
48
75
|
|
|
49
|
-
|
|
50
|
-
| Argument
|
|
51
|
-
|
|
52
|
-
| token
|
|
53
|
-
|
|
54
|
-
| url
|
|
55
|
-
|
|
56
|
-
| method
|
|
57
|
-
|
|
58
|
-
| naming
|
|
59
|
-
|
|
60
|
-
| include
|
|
61
|
-
|
|
62
|
-
| exclude
|
|
63
|
-
|
|
76
|
+
+------------------+------------------+---------------------------+
|
|
77
|
+
| Argument | Flag | Environment Variable |
|
|
78
|
+
+==================+==================+===========================+
|
|
79
|
+
| token | -t | `GITLAB_TOKEN` |
|
|
80
|
+
+------------------+------------------+---------------------------+
|
|
81
|
+
| url | -u | `GITLAB_URL` |
|
|
82
|
+
+------------------+------------------+---------------------------+
|
|
83
|
+
| method | -m | `GITLABBER_CLONE_METHOD` |
|
|
84
|
+
+------------------+------------------+---------------------------+
|
|
85
|
+
| naming | -n | `GITLABBER_FOLDER_NAMING` |
|
|
86
|
+
+------------------+------------------+---------------------------+
|
|
87
|
+
| include | -i | `GITLABBER_INCLUDE` |
|
|
88
|
+
+------------------+------------------+---------------------------+
|
|
89
|
+
| exclude | -x | `GITLABBER_EXCLUDE` |
|
|
90
|
+
+------------------+------------------+---------------------------+
|
|
64
91
|
|
|
65
92
|
* To view the tree run the command with your includes/excludes and the ``-p`` flag. It will print your tree like so:
|
|
66
93
|
|
|
67
|
-
.. code-block:: bash
|
|
94
|
+
.. code-block:: bash
|
|
95
|
+
|
|
96
|
+
root [http://gitlab.my.com]
|
|
97
|
+
├── group1 [/group1]
|
|
98
|
+
│ └── subgroup1 [/group1/subgroup1]
|
|
99
|
+
│ └── project1 [/group1/subgroup1/project1]
|
|
100
|
+
└── group2 [/group2]
|
|
101
|
+
├── subgroup1 [/group2/subgroup1]
|
|
102
|
+
│ └── project2 [/group2/subgroup1/project2]
|
|
103
|
+
├── subgroup2 [/group2/subgroup2]
|
|
104
|
+
└── subgroup3 [/group2/subgroup3]
|
|
68
105
|
|
|
69
|
-
root [http://gitlab.my.com]
|
|
70
|
-
├── group1 [/group1]
|
|
71
|
-
│ └── subgroup1 [/group1/subgroup1]
|
|
72
|
-
│ └── project1 [/group1/subgroup1/project1]
|
|
73
|
-
└── group2 [/group2]
|
|
74
|
-
├── subgroup1 [/group2/subgroup1]
|
|
75
|
-
│ └── project2 [/group2/subgroup1/project2]
|
|
76
|
-
├── subgroup2 [/group2/subgroup2]
|
|
77
|
-
└── subgroup3 [/group2/subgroup3]
|
|
78
106
|
|
|
79
107
|
* To see how to use glob patterns and regex to filter tree nodes, see the `globre project page <https://pypi.org/project/globre/#details>`_.
|
|
80
108
|
|
|
81
109
|
* Include/Exclude patterns do not work at the API level but work on the results returned from the API, for large Gitlab installations this can take a lot of time, if you need to reduce the amound of API calls for such projects use the ``--group-search`` parameter to search only for the top level groups the interest you using the `Gitlab Group Search API <https://docs.gitlab.com/ee/api/groups.html#search-for-group>`_ which allows you to do a partial like query for a Group's path or name
|
|
82
110
|
|
|
111
|
+
* **Performance optimization**: For large GitLab instances with many groups and projects, use the ``--api-concurrency`` option to dramatically speed up tree building. This enables parallel API calls (default: 5 concurrent requests) which can provide **4-6x speedup** in real-world scenarios. For example, building a tree with 21 subgroups and 21 projects can be reduced from ~96 seconds (sequential) to ~16-21 seconds (with ``--api-concurrency 5-10``). The ``-c/--concurrency`` option controls parallel git operations (cloning/pulling), while ``--api-concurrency`` controls parallel API calls (fetching groups/projects). Both can be tuned independently based on your needs.
|
|
112
|
+
|
|
83
113
|
* Cloning vs Pulling: when running Gitlabber consecutively with the same parameters, it will scan the local tree structure; if the project directory exists and is a valid git repository (has .git folder in it) Gitlabber will perform a git pull in the directory, otherwise the project directory will be created and the GitLab project will be cloned into it.
|
|
84
114
|
|
|
85
115
|
* Cloning submodules: use the ``-r`` flag to recurse git submodules, uses the ``--recursive`` for cloning and utilizes `GitPython's smart update method <https://github.com/gitpython-developers/GitPython/blob/20f4a9d49b466a18f1af1fdfb480bc4520a4cdc2/git/objects/submodule/root.py#L67>`_ for updating cloned repositories
|
|
@@ -89,7 +119,7 @@ Usage
|
|
|
89
119
|
.. code-block:: bash
|
|
90
120
|
|
|
91
121
|
usage: gitlabber [-h] [-t token] [-T] [-u url] [--verbose] [-p] [--print-format {json,yaml,tree}] [-n {name,path}] [-m {ssh,http}]
|
|
92
|
-
[-a {include,exclude,only}] [-i csv] [-x csv] [-r] [-F] [-d] [-s] [-g term] [-U] [-o options] [--version]
|
|
122
|
+
[-a {include,exclude,only}] [-i csv] [-x csv] [-c N] [--api-concurrency N] [-r] [-F] [-d] [-s] [-g term] [-U] [-o options] [--version]
|
|
93
123
|
[dest]
|
|
94
124
|
|
|
95
125
|
Gitlabber - clones or pulls entire groups/projects tree from gitlab
|
|
@@ -111,15 +141,18 @@ Usage
|
|
|
111
141
|
the folder naming strategy for projects from the gitlab API attributes (default: "name")
|
|
112
142
|
-m {ssh,http}, --method {ssh,http}
|
|
113
143
|
the git transport method to use for cloning (default: "ssh")
|
|
144
|
+
--fail-fast exit immediately when encountering discovery errors
|
|
114
145
|
-a {include,exclude,only}, --archived {include,exclude,only}
|
|
115
146
|
include archived projects and groups in the results (default: "include")
|
|
116
147
|
-i csv, --include csv
|
|
117
148
|
comma delimited list of glob patterns of paths to projects or groups to clone/pull
|
|
118
149
|
-x csv, --exclude csv
|
|
119
150
|
comma delimited list of glob patterns of paths to projects or groups to exclude from clone/pull
|
|
151
|
+
-c N, --concurrency N
|
|
152
|
+
number of concurrent git operations (default: 1)
|
|
153
|
+
--api-concurrency N number of concurrent API calls for tree building (default: 5)
|
|
120
154
|
-r, --recursive clone/pull git submodules recursively
|
|
121
155
|
-F, --use-fetch clone/fetch git repository (mirrored repositories)
|
|
122
|
-
-d, --dont-checkout don't checkout pulled git repository
|
|
123
156
|
-s, --include-shared include shared projects in the results
|
|
124
157
|
-g term, --group-search term
|
|
125
158
|
only include groups matching the search term, filtering done at the API level (useful for large projects, see: https://docs.gitlab.com/ee/api/groups.html#search-for-group works with partial names of path or name)
|
|
@@ -148,22 +181,54 @@ Usage
|
|
|
148
181
|
clone projects that start with a case insensitive 'w' using a regular expression:
|
|
149
182
|
gitlabber -i '/{[w].*}' .
|
|
150
183
|
|
|
151
|
-
clone
|
|
184
|
+
clone the personal projects to username-personal-projects
|
|
152
185
|
gitlabber -U .
|
|
153
186
|
|
|
154
187
|
perform a shallow clone of the git repositories
|
|
155
188
|
gitlabber -o "\-\-depth=1," .
|
|
156
189
|
|
|
190
|
+
speed up tree building for large GitLab instances with parallel API calls (4-6x faster)
|
|
191
|
+
# Real-world example: 96s → 16-21s for instances with many subgroups/projects
|
|
192
|
+
gitlabber --api-concurrency 10 -t <token> -u <url> .
|
|
193
|
+
|
|
194
|
+
use both API and git concurrency for maximum performance
|
|
195
|
+
# API concurrency speeds up tree discovery, git concurrency speeds up cloning
|
|
196
|
+
gitlabber --api-concurrency 5 -c 10 -t <token> -u <url> .
|
|
197
|
+
|
|
198
|
+
**Performance Results:**
|
|
199
|
+
* Sequential (``--api-concurrency 1``): ~96 seconds
|
|
200
|
+
* With ``--api-concurrency 5``: ~21 seconds (**4.6x speedup**)
|
|
201
|
+
* With ``--api-concurrency 10``: ~16 seconds (**6x speedup**)
|
|
157
202
|
|
|
203
|
+
*Note: Actual speedup depends on your GitLab instance structure (number of groups, subgroups, and projects). Instances with many nested subgroups benefit most from higher concurrency values.*
|
|
204
|
+
|
|
205
|
+
Common Use Cases
|
|
206
|
+
----------------
|
|
207
|
+
|
|
208
|
+
Clone Specific Groups
|
|
209
|
+
---------------------
|
|
210
|
+
|
|
211
|
+
.. code-block:: bash
|
|
212
|
+
|
|
213
|
+
# Clone only projects from a specific group
|
|
214
|
+
gitlabber -i '/MyGroup/**' .
|
|
215
|
+
|
|
216
|
+
Exclude Archived Projects
|
|
217
|
+
-------------------------
|
|
218
|
+
|
|
219
|
+
.. code-block:: bash
|
|
220
|
+
|
|
221
|
+
# Clone all non-archived projects
|
|
222
|
+
gitlabber -a exclude .
|
|
158
223
|
|
|
159
224
|
Debugging
|
|
160
225
|
---------
|
|
161
226
|
* You can use the ``--verbose`` flag to print Gitlabber debug messages
|
|
162
227
|
* For more verbose GitLab messages, you can get the `GitPython <https://gitpython.readthedocs.io/en/stable>`_ module to print more debug messages by setting the environment variable:
|
|
163
228
|
|
|
164
|
-
.. code-block:: bash
|
|
229
|
+
.. code-block:: bash
|
|
165
230
|
|
|
166
|
-
|
|
231
|
+
export GIT_PYTHON_TRACE='full'
|
|
167
232
|
|
|
168
233
|
Troubleshooting
|
|
169
234
|
---------------
|
|
@@ -176,7 +241,27 @@ Known Limitations
|
|
|
176
241
|
* Folder naming strategy: Consecutively running Gitlabber with different values for the ``-n`` parameter will produce undesirable results. Use the same value as previous runs, or simply don't change it from the default (project name).
|
|
177
242
|
* If you're going to clone a large number of projects, observe rate limits `for gitlab.com <https://docs.gitlab.com/ee/user/gitlab_com/index.html#gitlabcom-specific-rate-limits/>`_, and `for on-premise installations <https://docs.gitlab.com/ee/security/rate_limits.html>`_.
|
|
178
243
|
|
|
244
|
+
Branch Synchronization Issues
|
|
245
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
246
|
+
|
|
247
|
+
Gitlabber's default pull behavior (``git pull -v -- origin``) may fail when you have a local branch checked out that no longer exists on the remote repository. This commonly occurs after:
|
|
248
|
+
|
|
249
|
+
- Merging a merge request where the remote branch is automatically deleted
|
|
250
|
+
- Manual deletion of remote branches
|
|
251
|
+
|
|
252
|
+
**Error Example:**
|
|
253
|
+
|
|
254
|
+
.. code-block:: text
|
|
255
|
+
|
|
256
|
+
git.exc.GitCommandError: Cmd('git') failed due to: exit code(1)
|
|
257
|
+
cmdline: git pull -v -- origin
|
|
258
|
+
|
|
259
|
+
**Workaround:** Use the ``--use-fetch`` flag instead of the default pull behavior:
|
|
260
|
+
|
|
261
|
+
.. code-block:: bash
|
|
262
|
+
|
|
263
|
+
gitlabber --use-fetch -t <your-token> -u <gitlab-url> .
|
|
179
264
|
|
|
180
265
|
Links
|
|
181
266
|
-----
|
|
182
|
-
* Gitlabber `tutorial <https://medium.com/@natskvi/clone-all-your-gitlab-groups-repos-before-starting-to-code-dd559ec5c8d6>`_ by nsk
|
|
267
|
+
* Gitlabber `tutorial <https://medium.com/@natskvi/clone-all-your-gitlab-groups-repos-before-starting-to-code-dd559ec5c8d6>`_ by nsk
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Gitlabber - A tool for cloning GitLab project hierarchies.
|
|
2
|
+
|
|
3
|
+
Gitlabber allows you to clone entire GitLab group/subgroup hierarchies
|
|
4
|
+
while maintaining the directory structure. It supports filtering, progress
|
|
5
|
+
tracking, and various configuration options.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = '2.0.0'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Enumeration for handling archived GitLab projects and groups.
|
|
2
|
+
|
|
3
|
+
This module provides the ArchivedResults enum which controls how archived
|
|
4
|
+
projects and groups are handled during tree building and filtering.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional
|
|
8
|
+
import enum
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ArchivedResults(enum.Enum):
|
|
12
|
+
"""Enumeration for handling archived results in GitLab projects.
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
INCLUDE: Include both archived and non-archived projects
|
|
16
|
+
EXCLUDE: Exclude archived projects
|
|
17
|
+
ONLY: Only include archived projects
|
|
18
|
+
"""
|
|
19
|
+
INCLUDE = (1, None)
|
|
20
|
+
EXCLUDE = (2, False)
|
|
21
|
+
ONLY = (3, True)
|
|
22
|
+
|
|
23
|
+
def __init__(self, int_value: int, api_value: Optional[bool]) -> None:
|
|
24
|
+
"""Initialize the enum value.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
int_value: Integer value for internal use
|
|
28
|
+
api_value: Boolean value for GitLab API, None for INCLUDE
|
|
29
|
+
"""
|
|
30
|
+
self.int_value = int_value
|
|
31
|
+
self.api_value = api_value
|
|
32
|
+
|
|
33
|
+
def __str__(self) -> str:
|
|
34
|
+
"""Return the lowercase name of the enum value."""
|
|
35
|
+
return self.name.lower()
|
|
36
|
+
|
|
37
|
+
def __repr__(self) -> str:
|
|
38
|
+
"""Return the string representation of the enum value."""
|
|
39
|
+
return str(self)
|
|
40
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Authentication providers for GitLab API access.
|
|
2
|
+
|
|
3
|
+
This module defines the authentication interface and implementations
|
|
4
|
+
for authenticating with GitLab instances. It supports token-based
|
|
5
|
+
authentication and provides a no-op provider for testing.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from typing import Optional
|
|
10
|
+
from gitlab import Gitlab
|
|
11
|
+
from gitlab.exceptions import GitlabAuthenticationError
|
|
12
|
+
|
|
13
|
+
class AuthProvider(ABC):
|
|
14
|
+
"""Interface for GitLab authentication providers."""
|
|
15
|
+
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def authenticate(self, gitlab_client: Gitlab) -> None:
|
|
18
|
+
"""Authenticate the GitLab client.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
gitlab_client: The GitLab client to authenticate
|
|
22
|
+
|
|
23
|
+
Raises:
|
|
24
|
+
GitlabAuthenticationError: If authentication fails
|
|
25
|
+
"""
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
class TokenAuthProvider(AuthProvider):
|
|
29
|
+
"""Authentication provider using a personal access token."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, token: str) -> None:
|
|
32
|
+
"""Initialize with a personal access token.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
token: GitLab personal access token
|
|
36
|
+
"""
|
|
37
|
+
self.token = token
|
|
38
|
+
|
|
39
|
+
def authenticate(self, gitlab_client: Gitlab) -> None:
|
|
40
|
+
"""Authenticate using the personal access token.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
gitlab_client: The GitLab client to authenticate
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
GitlabAuthenticationError: If authentication fails
|
|
47
|
+
"""
|
|
48
|
+
gitlab_client.auth()
|
|
49
|
+
|
|
50
|
+
class NoAuthProvider(AuthProvider):
|
|
51
|
+
"""Authentication provider that performs no authentication.
|
|
52
|
+
|
|
53
|
+
This is useful for testing or when authentication is handled externally.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def authenticate(self, gitlab_client: Gitlab) -> None:
|
|
57
|
+
"""Perform no authentication.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
gitlab_client: The GitLab client (not used)
|
|
61
|
+
"""
|
|
62
|
+
pass
|