gitlabber 1.2.7__tar.gz → 1.2.8__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-1.2.8}/PKG-INFO +5 -5
- {gitlabber-1.2.7 → gitlabber-1.2.8}/README.rst +2 -3
- gitlabber-1.2.8/gitlabber/__init__.py +2 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/cli.py +1 -7
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/gitlab_tree.py +27 -16
- {gitlabber-1.2.7 → gitlabber-1.2.8/gitlabber.egg-info}/PKG-INFO +5 -5
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber.egg-info/SOURCES.txt +1 -13
- {gitlabber-1.2.7 → gitlabber-1.2.8}/pyproject.toml +24 -2
- gitlabber-1.2.8/setup.cfg +10 -0
- gitlabber-1.2.8/setup.py +3 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/gitlab_test_utils.py +16 -5
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_e2e.py +16 -6
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_gitlab_tree.py +73 -1
- gitlabber-1.2.7/gitlabber/__init__.py +0 -2
- gitlabber-1.2.7/setup.cfg +0 -24
- gitlabber-1.2.7/setup.py +0 -90
- gitlabber-1.2.7/tests/__pycache__/__init__.cpython-311.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/gitlab_test_utils.cpython-311.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/io_test_util.cpython-311.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_archive.cpython-311-pytest-8.2.2.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_cli.cpython-311-pytest-8.2.2.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_e2e.cpython-311-pytest-8.2.2.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_format.cpython-311-pytest-8.2.2.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_git.cpython-311-pytest-8.2.2.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_gitlab_tree.cpython-311-pytest-8.2.2.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_integration.cpython-311-pytest-8.2.2.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_method.cpython-311-pytest-8.2.2.pyc +0 -0
- gitlabber-1.2.7/tests/__pycache__/test_naming.cpython-311-pytest-8.2.2.pyc +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/LICENSE.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/MANIFEST.in +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/__main__.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/archive.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/format.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/git.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/method.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/naming.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber/progress.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber.egg-info/dependency_links.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber.egg-info/entry_points.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber.egg-info/requires.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/gitlabber.egg-info/top_level.txt +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/__init__.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/io_test_util.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test-input.yaml +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test-output.json +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test-output.tree +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test-output.yaml +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_archive.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_cli.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_format.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_git.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_integration.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_method.py +0 -0
- {gitlabber-1.2.7 → gitlabber-1.2.8}/tests/test_naming.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: gitlabber
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.8
|
|
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
|
|
@@ -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
|
|
@@ -156,7 +157,6 @@ Usage
|
|
|
156
157
|
comma delimited list of glob patterns of paths to projects or groups to exclude from clone/pull
|
|
157
158
|
-r, --recursive clone/pull git submodules recursively
|
|
158
159
|
-F, --use-fetch clone/fetch git repository (mirrored repositories)
|
|
159
|
-
-d, --dont-checkout don't checkout pulled git repository
|
|
160
160
|
-s, --include-shared include shared projects in the results
|
|
161
161
|
-g term, --group-search term
|
|
162
162
|
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,7 +185,7 @@ Usage
|
|
|
185
185
|
clone projects that start with a case insensitive 'w' using a regular expression:
|
|
186
186
|
gitlabber -i '/{[w].*}' .
|
|
187
187
|
|
|
188
|
-
clone
|
|
188
|
+
clone the personal projects to username-personal-projects
|
|
189
189
|
gitlabber -U .
|
|
190
190
|
|
|
191
191
|
perform a shallow clone of the git repositories
|
|
@@ -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
|
|
@@ -119,7 +119,6 @@ Usage
|
|
|
119
119
|
comma delimited list of glob patterns of paths to projects or groups to exclude from clone/pull
|
|
120
120
|
-r, --recursive clone/pull git submodules recursively
|
|
121
121
|
-F, --use-fetch clone/fetch git repository (mirrored repositories)
|
|
122
|
-
-d, --dont-checkout don't checkout pulled git repository
|
|
123
122
|
-s, --include-shared include shared projects in the results
|
|
124
123
|
-g term, --group-search term
|
|
125
124
|
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,7 +147,7 @@ Usage
|
|
|
148
147
|
clone projects that start with a case insensitive 'w' using a regular expression:
|
|
149
148
|
gitlabber -i '/{[w].*}' .
|
|
150
149
|
|
|
151
|
-
clone
|
|
150
|
+
clone the personal projects to username-personal-projects
|
|
152
151
|
gitlabber -U .
|
|
153
152
|
|
|
154
153
|
perform a shallow clone of the git repositories
|
|
@@ -92,7 +92,7 @@ def parse_args(argv=None):
|
|
|
92
92
|
clone projects that start with a case insensitive 'w' using a regular expression:
|
|
93
93
|
gitlabber -i '/{[w].*}' .
|
|
94
94
|
|
|
95
|
-
clone
|
|
95
|
+
clone the user personal projects to username-personal-projects
|
|
96
96
|
gitlabber -U .
|
|
97
97
|
|
|
98
98
|
perform a shallow clone of the git repositories
|
|
@@ -199,12 +199,6 @@ def parse_args(argv=None):
|
|
|
199
199
|
action='store_true',
|
|
200
200
|
default=False,
|
|
201
201
|
help='clone/fetch git repository (mirrored repositories)')
|
|
202
|
-
parser.add_argument(
|
|
203
|
-
'-d',
|
|
204
|
-
'--dont-checkout',
|
|
205
|
-
action='store_true',
|
|
206
|
-
default=False,
|
|
207
|
-
help="don't checkout pulled git repository")
|
|
208
202
|
parser.add_argument(
|
|
209
203
|
'-s',
|
|
210
204
|
'--include-shared',
|
|
@@ -119,26 +119,37 @@ class GitlabTree:
|
|
|
119
119
|
projects = group.projects.list(archived=self.archived, with_shared=self.include_shared, get_all=True)
|
|
120
120
|
self.progress.update_progress_length(len(projects))
|
|
121
121
|
self.add_projects(parent, projects)
|
|
122
|
+
|
|
123
|
+
if self.include_shared and hasattr(group, 'shared_projects'):
|
|
124
|
+
shared_projects = group.shared_projects.list(get_all=True)
|
|
125
|
+
self.progress.update_progress_length(len(shared_projects))
|
|
126
|
+
self.add_projects(parent, shared_projects)
|
|
122
127
|
except GitlabListError as error:
|
|
123
128
|
log.error(f"Error getting projects on {group.name} id: [{group.id}] error message: [{error.error_message}]")
|
|
124
129
|
|
|
125
130
|
def get_subgroups(self, group, parent):
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
131
|
+
try:
|
|
132
|
+
subgroups = group.subgroups.list(as_list=False, get_all=True)
|
|
133
|
+
self.progress.update_progress_length(len(subgroups))
|
|
134
|
+
for subgroup_def in subgroups:
|
|
135
|
+
try:
|
|
136
|
+
subgroup = self.gitlab.groups.get(subgroup_def.id)
|
|
137
|
+
subgroup_id = subgroup.name if self.naming == FolderNaming.NAME else subgroup.path
|
|
138
|
+
node = self.make_node("subgroup", subgroup_id, parent, url=subgroup.web_url)
|
|
139
|
+
self.progress.show_progress(node.name, 'group')
|
|
140
|
+
self.get_subgroups(subgroup, node)
|
|
141
|
+
self.get_projects(subgroup, node)
|
|
142
|
+
except GitlabGetError as error:
|
|
143
|
+
if error.response_code == 404:
|
|
144
|
+
log.error(f"{error.response_code} error while getting subgroup with name: {group.name} [id: {group.id}]. Check your permissions as you may not have access to it. Message: {error.error_message}")
|
|
145
|
+
continue
|
|
146
|
+
else:
|
|
147
|
+
raise error
|
|
148
|
+
except GitlabListError as error:
|
|
149
|
+
if error.response_code == 404:
|
|
150
|
+
log.error(f"{error.response_code} error while listing subgroup with name: {group.name} [id: {group.id}]. Check your permissions as you may not have access to it. Message: {error.error_message}")
|
|
151
|
+
else:
|
|
152
|
+
raise error
|
|
142
153
|
|
|
143
154
|
def load_gitlab_tree(self):
|
|
144
155
|
log.debug(f"Starting group search with archived: {self.archived} search term: {self.group_search}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: gitlabber
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.8
|
|
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
|
|
@@ -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
|
|
@@ -156,7 +157,6 @@ Usage
|
|
|
156
157
|
comma delimited list of glob patterns of paths to projects or groups to exclude from clone/pull
|
|
157
158
|
-r, --recursive clone/pull git submodules recursively
|
|
158
159
|
-F, --use-fetch clone/fetch git repository (mirrored repositories)
|
|
159
|
-
-d, --dont-checkout don't checkout pulled git repository
|
|
160
160
|
-s, --include-shared include shared projects in the results
|
|
161
161
|
-g term, --group-search term
|
|
162
162
|
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,7 +185,7 @@ Usage
|
|
|
185
185
|
clone projects that start with a case insensitive 'w' using a regular expression:
|
|
186
186
|
gitlabber -i '/{[w].*}' .
|
|
187
187
|
|
|
188
|
-
clone
|
|
188
|
+
clone the personal projects to username-personal-projects
|
|
189
189
|
gitlabber -U .
|
|
190
190
|
|
|
191
191
|
perform a shallow clone of the git repositories
|
|
@@ -35,16 +35,4 @@ tests/test_git.py
|
|
|
35
35
|
tests/test_gitlab_tree.py
|
|
36
36
|
tests/test_integration.py
|
|
37
37
|
tests/test_method.py
|
|
38
|
-
tests/test_naming.py
|
|
39
|
-
tests/__pycache__/__init__.cpython-311.pyc
|
|
40
|
-
tests/__pycache__/gitlab_test_utils.cpython-311.pyc
|
|
41
|
-
tests/__pycache__/io_test_util.cpython-311.pyc
|
|
42
|
-
tests/__pycache__/test_archive.cpython-311-pytest-8.2.2.pyc
|
|
43
|
-
tests/__pycache__/test_cli.cpython-311-pytest-8.2.2.pyc
|
|
44
|
-
tests/__pycache__/test_e2e.cpython-311-pytest-8.2.2.pyc
|
|
45
|
-
tests/__pycache__/test_format.cpython-311-pytest-8.2.2.pyc
|
|
46
|
-
tests/__pycache__/test_git.cpython-311-pytest-8.2.2.pyc
|
|
47
|
-
tests/__pycache__/test_gitlab_tree.cpython-311-pytest-8.2.2.pyc
|
|
48
|
-
tests/__pycache__/test_integration.cpython-311-pytest-8.2.2.pyc
|
|
49
|
-
tests/__pycache__/test_method.cpython-311-pytest-8.2.2.pyc
|
|
50
|
-
tests/__pycache__/test_naming.cpython-311-pytest-8.2.2.pyc
|
|
38
|
+
tests/test_naming.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gitlabber"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.8"
|
|
8
8
|
description = "A Gitlab clone/pull utility for backing up or cloning Gitlab groups"
|
|
9
9
|
readme = "README.rst"
|
|
10
10
|
requires-python = ">=3"
|
|
@@ -54,4 +54,26 @@ gitlabber = "gitlabber.cli:main"
|
|
|
54
54
|
|
|
55
55
|
[tool.setuptools]
|
|
56
56
|
packages = ["gitlabber"]
|
|
57
|
-
include-package-data = true
|
|
57
|
+
include-package-data = true
|
|
58
|
+
|
|
59
|
+
[tool.pytest.ini_options]
|
|
60
|
+
addopts = [
|
|
61
|
+
"-vv",
|
|
62
|
+
"--cov=gitlabber",
|
|
63
|
+
"--no-cov-on-fail",
|
|
64
|
+
"--cov-append",
|
|
65
|
+
"--cov-report=term-missing",
|
|
66
|
+
"--cov-report=xml",
|
|
67
|
+
"--verbose",
|
|
68
|
+
"--capture=sys",
|
|
69
|
+
"--without-slow-integration",
|
|
70
|
+
"--integration-cover"
|
|
71
|
+
]
|
|
72
|
+
norecursedirs = [
|
|
73
|
+
"dist",
|
|
74
|
+
"build"
|
|
75
|
+
]
|
|
76
|
+
testpaths = ["tests"]
|
|
77
|
+
|
|
78
|
+
[tool.coverage.run]
|
|
79
|
+
parallel = true
|
gitlabber-1.2.8/setup.py
ADDED
|
@@ -23,7 +23,7 @@ TREE_TEST_OUTPUT_FILE = "tests/test-output.tree"
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class MockNode:
|
|
26
|
-
def __init__(self, type, id, name, url, subgroups=mock.MagicMock(), projects=mock.MagicMock(), parent_id=None, archived=0, shared=False, group_search=None, git_options=None):
|
|
26
|
+
def __init__(self, type, id, name, url, subgroups=mock.MagicMock(), projects=mock.MagicMock(), shared_projects=mock.MagicMock(), parent_id=None, archived=0, shared=False, group_search=None, git_options=None):
|
|
27
27
|
self.type = type
|
|
28
28
|
self.id = id
|
|
29
29
|
self.name = name
|
|
@@ -34,6 +34,7 @@ class MockNode:
|
|
|
34
34
|
self.http_url_to_repo = url
|
|
35
35
|
self.subgroups = subgroups
|
|
36
36
|
self.projects = projects
|
|
37
|
+
self.shared_projects = shared_projects
|
|
37
38
|
self.parent_id = parent_id
|
|
38
39
|
self.archived = archived
|
|
39
40
|
self.shared = shared
|
|
@@ -119,9 +120,17 @@ def validate_tree(root):
|
|
|
119
120
|
validate_subgroup(root.children[0].children[0])
|
|
120
121
|
validate_project(root.children[0].children[0].children[0])
|
|
121
122
|
|
|
122
|
-
def create_test_gitlab(monkeypatch, includes=None, excludes=None, in_file=None, hide_token=True, method=CloneMethod.SSH):
|
|
123
|
+
def create_test_gitlab(monkeypatch, includes=None, excludes=None, in_file=None, hide_token=True, method=CloneMethod.SSH, token=TOKEN):
|
|
123
124
|
gl = gitlab_tree.GitlabTree(
|
|
124
|
-
URL,
|
|
125
|
+
URL,
|
|
126
|
+
token,
|
|
127
|
+
method, # Use the method parameter instead of hardcoding "ssh"
|
|
128
|
+
"name",
|
|
129
|
+
includes=includes,
|
|
130
|
+
excludes=excludes,
|
|
131
|
+
in_file=in_file,
|
|
132
|
+
hide_token=hide_token
|
|
133
|
+
)
|
|
125
134
|
projects = Listable(MockNode("project", 2, PROJECT_NAME, PROJECT_URL if hide_token else PROJECT_URL_WITH_TOKEN))
|
|
126
135
|
groups = Listable(
|
|
127
136
|
MockNode("group", 2, GROUP_NAME, GROUP_URL, subgroups=Listable(
|
|
@@ -131,7 +140,6 @@ def create_test_gitlab(monkeypatch, includes=None, excludes=None, in_file=None,
|
|
|
131
140
|
monkeypatch.setattr(gl.gitlab, "groups", Tree(groups))
|
|
132
141
|
return gl
|
|
133
142
|
|
|
134
|
-
|
|
135
143
|
def create_test_gitlab_with_toplevel_subgroups(monkeypatch):
|
|
136
144
|
gl = gitlab_tree.GitlabTree(URL, TOKEN, "ssh", "path")
|
|
137
145
|
groups = Listable(
|
|
@@ -167,9 +175,12 @@ def create_test_gitlab_with_shared(monkeypatch, includes=None, excludes=None, in
|
|
|
167
175
|
|
|
168
176
|
projects = Listable(
|
|
169
177
|
MockNode("project", 19, PROJECT_NAME, PROJECT_URL),
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
shared_projects = Listable(
|
|
170
181
|
MockNode("project", 20, "_shared_" + PROJECT_NAME, "_shared_" + PROJECT_URL, shared=True)
|
|
171
182
|
)
|
|
172
183
|
monkeypatch.setattr(gl.gitlab, "groups", Tree(Listable(
|
|
173
|
-
MockNode("group", 21, GROUP_NAME, GROUP_URL, projects=projects)
|
|
184
|
+
MockNode("group", 21, GROUP_NAME, GROUP_URL, projects=projects, shared_projects=shared_projects)
|
|
174
185
|
)))
|
|
175
186
|
return gl
|
|
@@ -11,7 +11,7 @@ coverage.process_startup()
|
|
|
11
11
|
@pytest.mark.slow_integration_test
|
|
12
12
|
def test_clone_subgroup():
|
|
13
13
|
os.environ['GITLAB_URL'] = 'https://gitlab.com/'
|
|
14
|
-
output = io_util.execute(['-p', '--print-format', 'json', '--group-search', 'Group Test'],
|
|
14
|
+
output = io_util.execute(['-p', '--print-format', 'json', '--group-search', 'Group Test'], 90)
|
|
15
15
|
obj = json.loads(output)
|
|
16
16
|
assert obj['children'][0]['name'] == 'Group Test'
|
|
17
17
|
assert obj['children'][0]['children'][0]['name'] == 'Subgroup Test'
|
|
@@ -23,7 +23,7 @@ def test_clone_subgroup():
|
|
|
23
23
|
@pytest.mark.slow_integration_test
|
|
24
24
|
def test_clone_subgroup_exclude_archived():
|
|
25
25
|
os.environ['GITLAB_URL'] = 'https://gitlab.com/'
|
|
26
|
-
output = io_util.execute(['-p', '--print-format', 'json', '--group-search', 'Group Test', '-a', 'exclude'],
|
|
26
|
+
output = io_util.execute(['-p', '--print-format', 'json', '--group-search', 'Group Test', '-a', 'exclude'], 90)
|
|
27
27
|
obj = json.loads(output)
|
|
28
28
|
assert obj['children'][0]['name'] == 'Group Test'
|
|
29
29
|
assert obj['children'][0]['children'][0]['name'] == 'Subgroup Test'
|
|
@@ -34,7 +34,7 @@ def test_clone_subgroup_exclude_archived():
|
|
|
34
34
|
@pytest.mark.slow_integration_test
|
|
35
35
|
def test_clone_subgroup_only_archived():
|
|
36
36
|
os.environ['GITLAB_URL'] = 'https://gitlab.com/'
|
|
37
|
-
output = io_util.execute(['-p', '--print-format', 'json', '--group-search', 'Group Test', '-a', 'only'],
|
|
37
|
+
output = io_util.execute(['-p', '--print-format', 'json', '--group-search', 'Group Test', '-a', 'only'], 90)
|
|
38
38
|
obj = json.loads(output)
|
|
39
39
|
assert obj['children'][0]['name'] == 'Group Test'
|
|
40
40
|
assert obj['children'][0]['children'][0]['name'] == 'Subgroup Test'
|
|
@@ -45,7 +45,7 @@ def test_clone_subgroup_only_archived():
|
|
|
45
45
|
@pytest.mark.slow_integration_test
|
|
46
46
|
def test_clone_subgroup_naming_path():
|
|
47
47
|
os.environ['GITLAB_URL'] = 'https://gitlab.com/'
|
|
48
|
-
output = io_util.execute(['-p', '--print-format', 'json', '-n', 'path', '--group-search', 'Group Test'],
|
|
48
|
+
output = io_util.execute(['-p', '--print-format', 'json', '-n', 'path', '--group-search', 'Group Test'], 90)
|
|
49
49
|
obj = json.loads(output)
|
|
50
50
|
assert obj['children'][0]['name'] == 'erez-group-test'
|
|
51
51
|
assert obj['children'][0]['children'][0]['name'] == 'subgroup-test'
|
|
@@ -58,7 +58,7 @@ def test_clone_subgroup_naming_path():
|
|
|
58
58
|
@pytest.mark.slow_integration_test
|
|
59
59
|
def test_large_groups():
|
|
60
60
|
os.environ['GITLAB_URL'] = 'https://gitlab.com/'
|
|
61
|
-
output = io_util.execute(['-p', '--print-format', 'json', '-n', 'path', '--group-search', 'large-group-test'],
|
|
61
|
+
output = io_util.execute(['-p', '--print-format', 'json', '-n', 'path', '--group-search', 'large-group-test'], 90)
|
|
62
62
|
obj = json.loads(output)
|
|
63
63
|
assert obj['children'][0]['name'] == 'large-group-test'
|
|
64
64
|
assert obj['children'][0]['children'][0]['name'] == 'many-subgroups'
|
|
@@ -70,8 +70,18 @@ def test_large_groups():
|
|
|
70
70
|
@pytest.mark.slow_integration_test
|
|
71
71
|
def test_user_personal_projects():
|
|
72
72
|
os.environ['GITLAB_URL'] = 'https://gitlab.com/'
|
|
73
|
-
output = io_util.execute(['-p', '--print-format', 'json', '-n', 'path', '--user-projects'],
|
|
73
|
+
output = io_util.execute(['-p', '--print-format', 'json', '-n', 'path', '--user-projects'], 90)
|
|
74
74
|
obj = json.loads(output)
|
|
75
75
|
assert obj['children'][0]['name'] == 'erezmazor-prsonal-projects'
|
|
76
76
|
assert obj['children'][0]['children'][0]['name'] == 'gitlabber-personal-project'
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@pytest.mark.slow_integration_test
|
|
80
|
+
def test_shared_group_and_project():
|
|
81
|
+
os.environ['GITLAB_URL'] = 'https://gitlab.com/'
|
|
82
|
+
output = io_util.execute(['-p', '--print-format', 'json', '-s', '--group-search', 'shared-group3'], 90)
|
|
83
|
+
obj = json.loads(output)
|
|
84
|
+
assert obj['children'][0]['name'] == 'Shared Group'
|
|
85
|
+
assert obj['children'][0]['children'][0]['name'] == 'Shared Project'
|
|
86
|
+
|
|
77
87
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
1
|
from gitlabber.method import CloneMethod
|
|
3
2
|
import tests.gitlab_test_utils as gitlab_util
|
|
4
3
|
import tests.io_test_util as output_util
|
|
5
4
|
from gitlabber.archive import ArchivedResults
|
|
5
|
+
import pytest
|
|
6
|
+
from unittest import mock
|
|
7
|
+
from gitlab.exceptions import GitlabGetError
|
|
6
8
|
|
|
7
9
|
def test_load_tree(monkeypatch):
|
|
8
10
|
gl = gitlab_util.create_test_gitlab(monkeypatch)
|
|
@@ -173,3 +175,73 @@ def test_hide_token_from_project_url(monkeypatch):
|
|
|
173
175
|
gl.load_tree()
|
|
174
176
|
gl.print_tree()
|
|
175
177
|
assert 'gitlab-token:xxx@' not in gl.root.children[0].children[0].children[0].url
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def test_get_subgroups_404_error(monkeypatch):
|
|
181
|
+
gl = gitlab_util.create_test_gitlab(monkeypatch)
|
|
182
|
+
|
|
183
|
+
# Create mock group and subgroup
|
|
184
|
+
mock_group = mock.Mock()
|
|
185
|
+
mock_group.name = "mock_group"
|
|
186
|
+
mock_group.id = 123
|
|
187
|
+
|
|
188
|
+
# Create a mock subgroup definition that will be returned by list()
|
|
189
|
+
mock_subgroup_def = mock.Mock()
|
|
190
|
+
mock_subgroup_def.id = 456
|
|
191
|
+
|
|
192
|
+
# Make subgroups.list return our mock subgroup definition
|
|
193
|
+
mock_group.subgroups.list.return_value = [mock_subgroup_def]
|
|
194
|
+
|
|
195
|
+
# This is the function that will raise the 404 when trying to get the subgroup
|
|
196
|
+
def mock_get_subgroup(id):
|
|
197
|
+
raise GitlabGetError(response_code=404, error_message="Not Found")
|
|
198
|
+
|
|
199
|
+
# Patch the groups.get method
|
|
200
|
+
monkeypatch.setattr(gl.gitlab.groups, "get", mock_get_subgroup)
|
|
201
|
+
|
|
202
|
+
with mock.patch("gitlabber.gitlab_tree.log.error") as mock_log_error:
|
|
203
|
+
gl.get_subgroups(mock_group, gl.root)
|
|
204
|
+
|
|
205
|
+
mock_log_error.assert_called_once_with(
|
|
206
|
+
f"404 error while getting subgroup with name: {mock_group.name} [id: {mock_group.id}]. Check your permissions as you may not have access to it. Message: Not Found"
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
def test_hide_token_in_project_url_both_cases(monkeypatch):
|
|
210
|
+
test_token = "test-token-123"
|
|
211
|
+
|
|
212
|
+
# Create two instances to test both cases
|
|
213
|
+
gl_hidden = gitlab_util.create_test_gitlab(monkeypatch,
|
|
214
|
+
hide_token=True,
|
|
215
|
+
method=CloneMethod.HTTP,
|
|
216
|
+
token=test_token)
|
|
217
|
+
|
|
218
|
+
gl_visible = gitlab_util.create_test_gitlab(monkeypatch,
|
|
219
|
+
hide_token=False,
|
|
220
|
+
method=CloneMethod.HTTP,
|
|
221
|
+
token=test_token)
|
|
222
|
+
|
|
223
|
+
# Create mock project
|
|
224
|
+
mock_project = mock.Mock()
|
|
225
|
+
mock_project.name = "test-project"
|
|
226
|
+
mock_project.path = "test-project"
|
|
227
|
+
mock_project.ssh_url_to_repo = "git@gitlab.com:group/test-project.git"
|
|
228
|
+
mock_project.http_url_to_repo = "https://gitlab.com/group/test-project.git"
|
|
229
|
+
|
|
230
|
+
# Test with hide_token=True
|
|
231
|
+
with mock.patch("gitlabber.gitlab_tree.log.debug") as mock_log_debug_hidden:
|
|
232
|
+
gl_hidden.add_projects(gl_hidden.root, [mock_project])
|
|
233
|
+
project_node_hidden = gl_hidden.root.children[0]
|
|
234
|
+
|
|
235
|
+
# Verify token is not in URL
|
|
236
|
+
assert project_node_hidden.url == "https://gitlab.com/group/test-project.git"
|
|
237
|
+
mock_log_debug_hidden.assert_any_call("Hiding token from project url: %s",
|
|
238
|
+
project_node_hidden.url)
|
|
239
|
+
|
|
240
|
+
# Test with hide_token=False
|
|
241
|
+
with mock.patch("gitlabber.gitlab_tree.log.debug") as mock_log_debug_visible:
|
|
242
|
+
gl_visible.add_projects(gl_visible.root, [mock_project])
|
|
243
|
+
project_node_visible = gl_visible.root.children[0]
|
|
244
|
+
|
|
245
|
+
expected_url = f"https://gitlab-token:{test_token}@gitlab.com/group/test-project.git"
|
|
246
|
+
assert project_node_visible.url == expected_url
|
|
247
|
+
mock_log_debug_visible.assert_any_call("Generated URL: %s", expected_url)
|
gitlabber-1.2.7/setup.cfg
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
[bdist_wheel]
|
|
2
|
-
universal = 1
|
|
3
|
-
|
|
4
|
-
[metadata]
|
|
5
|
-
description_file = README.rst
|
|
6
|
-
|
|
7
|
-
[coverage:run]
|
|
8
|
-
parallel = true
|
|
9
|
-
|
|
10
|
-
[tool:pytest]
|
|
11
|
-
addopts =
|
|
12
|
-
-vv --cov=gitlabber --no-cov-on-fail --cov-append --cov-report term-missing --cov-report xml --verbose --capture=sys --without-slow-integration --integration-cover
|
|
13
|
-
norecursedirs =
|
|
14
|
-
dist
|
|
15
|
-
build
|
|
16
|
-
|
|
17
|
-
[aliases]
|
|
18
|
-
dists = sdist bdist_wheel
|
|
19
|
-
testpaths = tests
|
|
20
|
-
|
|
21
|
-
[egg_info]
|
|
22
|
-
tag_build =
|
|
23
|
-
tag_date = 0
|
|
24
|
-
|
gitlabber-1.2.7/setup.py
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
from setuptools import setup
|
|
2
|
-
|
|
3
|
-
setup()
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# """Packaging settings."""
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
# from codecs import open
|
|
10
|
-
# from os.path import abspath, dirname, join
|
|
11
|
-
# from subprocess import call
|
|
12
|
-
|
|
13
|
-
# from setuptools import Command, find_packages, setup
|
|
14
|
-
|
|
15
|
-
# this_dir = abspath(dirname(__file__))
|
|
16
|
-
# with open(join(this_dir, 'README.rst'), encoding='utf-8') as file:
|
|
17
|
-
# long_description = file.read()
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# class RunTests(Command):
|
|
21
|
-
# """Run all tests."""
|
|
22
|
-
# description = 'run tests'
|
|
23
|
-
# user_options = []
|
|
24
|
-
|
|
25
|
-
# def initialize_options(self):
|
|
26
|
-
# pass
|
|
27
|
-
|
|
28
|
-
# def finalize_options(self):
|
|
29
|
-
# pass
|
|
30
|
-
|
|
31
|
-
# def run(self):
|
|
32
|
-
# """Run all tests!"""
|
|
33
|
-
# errno = call(['py.test'])
|
|
34
|
-
# raise SystemExit(errno)
|
|
35
|
-
# setup(
|
|
36
|
-
# python_requires='>=3',
|
|
37
|
-
# name = 'gitlabber',
|
|
38
|
-
# packages = find_packages(include=['gitlabber']),
|
|
39
|
-
# version = '1.2.7',
|
|
40
|
-
# description = 'A Gitlab clone/pull utility for backing up or cloning Gitlab groups',
|
|
41
|
-
# long_description = long_description,
|
|
42
|
-
# long_description_content_type="text/x-rst",
|
|
43
|
-
# url = 'https://github.com/ezbz/gitlabber',
|
|
44
|
-
# download_url = 'https://github.com/ezbz/gitlabber/archive/main.zip',
|
|
45
|
-
# author = 'Erez Mazor',
|
|
46
|
-
# author_email = 'erezmazor@gmail.com',
|
|
47
|
-
# license = 'MIT',
|
|
48
|
-
# keywords = ['gitlab', 'python', 'cli'],
|
|
49
|
-
# include_package_data = True,
|
|
50
|
-
|
|
51
|
-
# classifiers = [
|
|
52
|
-
# 'Development Status :: 4 - Beta',
|
|
53
|
-
# 'Intended Audience :: Developers',
|
|
54
|
-
# 'Topic :: Utilities',
|
|
55
|
-
# 'License :: OSI Approved :: MIT License',
|
|
56
|
-
# 'Natural Language :: English',
|
|
57
|
-
# 'Operating System :: OS Independent',
|
|
58
|
-
# 'Programming Language :: Python :: 3',
|
|
59
|
-
# 'Programming Language :: Python :: 3.9',
|
|
60
|
-
# 'Programming Language :: Python :: 3.10',
|
|
61
|
-
# 'Programming Language :: Python :: 3.11',
|
|
62
|
-
# 'Programming Language :: Python :: 3.12',
|
|
63
|
-
# 'Programming Language :: Python :: 3.13'
|
|
64
|
-
# ],
|
|
65
|
-
# setup_requires = [
|
|
66
|
-
# 'docopt',
|
|
67
|
-
# 'anytree',
|
|
68
|
-
# 'globre',
|
|
69
|
-
# 'pyyaml',
|
|
70
|
-
# 'tqdm',
|
|
71
|
-
# 'GitPython',
|
|
72
|
-
# 'python-gitlab'
|
|
73
|
-
# ],
|
|
74
|
-
# install_requires = [
|
|
75
|
-
# 'docopt',
|
|
76
|
-
# 'anytree',
|
|
77
|
-
# 'globre',
|
|
78
|
-
# 'pyyaml',
|
|
79
|
-
# 'tqdm',
|
|
80
|
-
# 'GitPython',
|
|
81
|
-
# 'python-gitlab'
|
|
82
|
-
# ],
|
|
83
|
-
# tests_require= ['coverage', 'pytest', 'pytest-cov', 'pytest-integration'],
|
|
84
|
-
# entry_points = {
|
|
85
|
-
# 'console_scripts': [
|
|
86
|
-
# 'gitlabber=gitlabber.cli:main',
|
|
87
|
-
# ],
|
|
88
|
-
# },
|
|
89
|
-
# cmdclass = {'test': RunTests},
|
|
90
|
-
# )
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
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
|
|
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
|