@@ -18,7 +18,9 @@ Gitlab project, and more importantly to get the commits they're pointing to.
1818
1919Internally, it reads and parses the ` .gitmodules ` file at the root of the
2020Project. To get the commit id of a submodule, it finds the last commit that
21- updated the submodule and parses its diff.
21+ updated the submodule and parses its diff (this can sometimes fail due to a
22+ [ limit of the GitLab API itself] ( https://docs.gitlab.com/ee/development/diffs.html#diff-collection-limits ) -
23+ see [ Limitations] ( #limitations ) ).
2224
2325---
2426** About the future of this package**
@@ -75,7 +77,7 @@ for subproject in subprojects:
7577 print (' - {} ({} ) -> {} ' .format(
7678 subproject.submodule.path,
7779 subproject.project.web_url,
78- subproject.commit.id))
80+ subproject.commit.id if subproject.commit else ' ? ' ))
7981```
8082Output:
8183```
@@ -95,13 +97,16 @@ for subproject in subprojects:
9597- print('- {} ({}) -> {}'.format(
9698- subproject.submodule.path,
9799- subproject.project.web_url,
98- - subproject.commit.id))
100+ - subproject.commit.id if subproject.commit else '?' ))
99101+ head_subproject_commit = subproject.project.commits.list(
100102+ ref=subproject.project.default_branch)[0]
101- + up_to_date = subproject.commit.id == head_subproject_commit.id
102- + print('- {}: {}'.format(
103- + subproject.submodule.path,
104- + 'ok' if up_to_date else '/!\\ must update'))
103+ + if subproject.commit is None: # can happen with very large commit diffs
104+ + status = 'cannot check'
105+ + elif subproject.commit.id == head_subproject_commit.id:
106+ + status = 'ok'
107+ + else:
108+ + status = '/!\\ must update'
109+ + print('- {}: {}'.format(subproject.submodule.path, status))
105110
106111```
107112Output:
@@ -125,7 +130,7 @@ iterate_subprojects(
125130 self_managed_gitlab_host: Optional[str ] = None
126131) -> Generator[Subproject, None , None ]
127132```
128- Parameters:
133+ #### Parameters:
129134- ` project ` : a ` gitlab.v4.objects.Project ` object
130135- ` gitlab ` : the ` gitlab.Gitlab ` instance that you used to authenticate, or its
131136 ` projects: gitlab.v4.objects.ProjectManager ` attribute
@@ -139,16 +144,31 @@ Parameters:
139144 self-managed GitLab instance, you should pass its url here otherwise it
140145 may be impossible to know from the URL that it's a GitLab project.
141146
142- Returns: Generator of ` Subproject ` objects
147+ #### Returns:
148+ Generator of ` Subproject ` objects
149+
150+ #### Limitations:
151+ - due to https://docs.gitlab.com/ee/development/diffs.html#diff-collection-limits ,
152+ some very large commit diffs won't be parsed entirely. This means that when
153+ inspecting the diff of the latest commit that updated ` ./<submodule_dir> ` ,
154+ in some rare cases ` ./<submodule_dir> ` might not be part of the diff
155+ object returned by the GitLab API. In that case we have no other choice than
156+ set ` Subproject.commit ` to ` None ` , that's why the two examples above
157+ check if ` subproject.commit ` is not ` None ` before using the value
158+ ` subproject.commit.id ` .
159+
160+ ---
143161
144162### ` list_subprojects(...) `
145163Same parameters as [ ` iterate_subprojects(...) ` ] ( #iterate_subprojects ) but
146164returns a ` list ` of [ ` Subproject ` ] ( #class-subproject ) objects.
147165
166+ ---
167+
148168### class ` Subproject `
149169Basic objects that contain the info about a Gitlab subproject.
150170
151- Attributes:
171+ #### Attributes:
152172- ` project: Optional[gitlab.v4.objects.Project] ` : the Gitlab project that the
153173 submodule links to (can be ` None ` if the submodule is not hosted on GitLab)
154174- ` submodule: ` [ ` Submodule ` ] ( #class-submodule ) : a basic object that contains
@@ -157,7 +177,7 @@ Attributes:
157177 the submodule points to (if the submodule is not hosted on GitLab, it will
158178 be a dummy ` Commit ` object with a single attribute ` id ` )
159179
160- Example ` str() ` output:
180+ #### Example ` str() ` output:
161181```
162182<class 'Subproject'> => {
163183 'submodule': <class 'Submodule'> => {'name': 'share/extensions', 'parent_project': <class 'gitlab.v4.objects.projects.Project'> => {'id': 3472737, 'description': 'Inkscape vector image editor', 'name': 'inkscape', 'name_with_namespace': 'Inkscape / inkscape', 'path': 'inkscape', 'path_with_namespace': 'inkscape/inkscape', 'created_at': '2017-06-09T14:16:35.615Z', 'default_branch': 'master', 'tag_list': [], 'topics': [], 'ssh_url_to_repo': 'git@gitlab.com:inkscape/inkscape.git', 'http_url_to_repo': 'https://gitlab.com/inkscape/inkscape.git', 'web_url': 'https://gitlab.com/inkscape/inkscape', 'readme_url': 'https://gitlab.com/inkscape/inkscape/-/blob/master/README.md', 'avatar_url': 'https://gitlab.com/uploads/-/system/project/avatar/3472737/inkscape.png', 'forks_count': 900, 'star_count': 2512, 'last_activity_at': '2022-01-29T23:45:49.894Z', 'namespace': {'id': 470642, 'name': 'Inkscape', 'path': 'inkscape', 'kind': 'group', 'full_path': 'inkscape', 'parent_id': None, 'avatar_url': '/uploads/-/system/group/avatar/470642/inkscape.png', 'web_url': 'https://gitlab.com/groups/inkscape'}}, 'parent_ref': 'e371b2f826adcba316f2e64bbf2f697043373d0b', 'path': 'share/extensions', 'url': 'https://gitlab.com/inkscape/extensions.git'},
@@ -166,45 +186,52 @@ Example `str()` output:
166186}
167187```
168188
189+ ---
190+
169191### ` list_submodules(...) `
170192Lists the info about the project submodules found in the ` .gitmodules ` file.
171193``` python
172194list_project_submodules(
173195 project: Project,
174196 ref: Optional[str ] = None ) -> List[Submodule]
175197```
176- Parameters:
198+ #### Parameters:
177199- ` project ` : a ` gitlab.v4.objects.Project ` object
178200- ` ref ` : (optional) a ref to a branch, commit, tag etc. Defaults to the
179201 HEAD of the project default branch.
180202
181- Returns: list of ` Submodule ` objects
203+ #### Returns:
204+ ` list ` of ` Submodule ` objects
205+
206+ ---
182207
183208### class ` Submodule `
184209Represents the ` .gitmodules ` config of a submodule + adds info about the
185210parent project
186211
187- Attributes:
212+ #### Attributes:
188213- ` parent_project: gitlab.v4.objects.Project ` : project that uses the submodule
189214- ` parent_ref: str ` : ref where the ` .gitmodules ` file was read
190215- ` name: str ` : local name used by git for the submodule
191216- ` path: str ` : local path pointing to the submodule directory in the project
192217- ` url: str ` : URL linking to the location of the repo of the submodule (not
193218 necessarily Gitlab)
194219
195- Example ` str() ` output:
220+ #### Example ` str() ` output:
196221```
197222<class 'Submodule'> => {'name': 'share/extensions', 'parent_project': <class 'gitlab.v4.objects.projects.Project'> => {'id': 3472737, 'description': 'Inkscape vector image editor', 'name': 'inkscape', 'name_with_namespace': 'Inkscape / inkscape', 'path': 'inkscape', 'path_with_namespace': 'inkscape/inkscape', 'created_at': '2017-06-09T14:16:35.615Z', 'default_branch': 'master', 'tag_list': [], 'topics': [], 'ssh_url_to_repo': 'git@gitlab.com:inkscape/inkscape.git', 'http_url_to_repo': 'https://gitlab.com/inkscape/inkscape.git', 'web_url': 'https://gitlab.com/inkscape/inkscape', 'readme_url': 'https://gitlab.com/inkscape/inkscape/-/blob/master/README.md', 'avatar_url': 'https://gitlab.com/uploads/-/system/project/avatar/3472737/inkscape.png', 'forks_count': 900, 'star_count': 2512, 'last_activity_at': '2022-01-29T23:45:49.894Z', 'namespace': {'id': 470642, 'name': 'Inkscape', 'path': 'inkscape', 'kind': 'group', 'full_path': 'inkscape', 'parent_id': None, 'avatar_url': '/uploads/-/system/group/avatar/470642/inkscape.png', 'web_url': 'https://gitlab.com/groups/inkscape'}}, 'parent_ref': 'e371b2f826adcba316f2e64bbf2f697043373d0b', 'path': 'share/extensions', 'url': 'https://gitlab.com/inkscape/extensions.git'}
198223```
199224
225+ ---
226+
200227### ` submodule_to_subproject(...) `
201228Converts a ` Submodule ` object to a [ ` Subproject ` ] ( #class-subproject ) object, assuming it's
202229hosted on Gitlab.
203230
204231Raises a ` FileNotFoundError ` if the path of the submodule actually doesn't
205232exist in the host repo or if the url of the submodule doesn't link to an
206233existing repo (both can happen if you modify the ` .gitmodules ` file without
207- using one of the ` git submodule ` commands)
234+ using one of the ` git submodule ` commands).
208235
209236``` python
210237submodule_to_subproject(
@@ -215,6 +242,7 @@ submodule_to_subproject(
215242```
216243Parameter details: See [ ` iterate_subprojects(...) ` ] ( #iterate_subprojects )
217244
245+ ---
218246
219247## Contributing
220248
0 commit comments