|
31 | 31 | PREDEFINED_MATCH_ARGS, |
32 | 32 | PREDEFINED_MATCH_ARGS_VALUES, |
33 | 33 | STABLE, |
34 | | - TAG, |
35 | 34 | VERSION_TYPES, |
36 | 35 | ) |
37 | 36 | from readthedocs.builds.managers import ( |
@@ -330,50 +329,38 @@ def config(self): |
330 | 329 | return None |
331 | 330 |
|
332 | 331 | @property |
333 | | - def commit_name(self): |
| 332 | + def git_identifier(self): |
334 | 333 | """ |
335 | | - Return the branch name, the tag name or the revision identifier. |
| 334 | + Return the branch or tag name of the version. |
336 | 335 |
|
337 | 336 | The result could be used as ref in a git repo, e.g. for linking to |
338 | 337 | GitHub, Bitbucket or GitLab. |
| 338 | +
|
| 339 | + - If the version is latest (machine created), we resolve to the default branch of the project. |
| 340 | + - If the version is stable (machine created), we resolve to the branch that the stable version points to. |
| 341 | + - If the version is external, we return the identifier, since we don't have access to the name of the branch. |
339 | 342 | """ |
340 | | - # LATEST is special as it is usually a branch but does not contain the |
341 | | - # name in verbose_name. |
| 343 | + # Latest is special as it doesn't contain the actual name in verbose_name. |
342 | 344 | if self.slug == LATEST and self.machine: |
343 | 345 | return self.project.get_default_branch() |
344 | 346 |
|
| 347 | + # Stable is special as it doesn't contain the actual name in verbose_name. |
345 | 348 | if self.slug == STABLE and self.machine: |
346 | | - if self.type == BRANCH: |
347 | | - # Special case, as we do not store the original branch name |
348 | | - # that the stable version works on. We can only interpolate the |
349 | | - # name from the commit identifier, but it's hacky. |
350 | | - # TODO: Refactor ``Version`` to store more actual info about |
351 | | - # the underlying commits. |
352 | | - if self.identifier.startswith("origin/"): |
353 | | - return self.identifier[len("origin/") :] |
354 | | - return self.identifier |
355 | | - |
356 | | - if self.type in (BRANCH, TAG): |
357 | | - # If this version is a branch or a tag, the verbose_name will |
358 | | - # contain the actual name. We cannot use identifier as this might |
359 | | - # include the "origin/..." part in the case of a branch. A tag |
360 | | - # would contain the hash in identifier, which is not as pretty as |
361 | | - # the actual tag name. |
362 | | - return self.verbose_name |
| 349 | + original_stable = self.project.get_original_stable_version() |
| 350 | + # NOTE: we no longer save branch names with the "origin/" prefix, |
| 351 | + # but we remove it for old versions. |
| 352 | + if original_stable: |
| 353 | + return original_stable.verbose_name.removeprefix("origin/") |
| 354 | + return self.identifier.removeprefix("origin/") |
363 | 355 |
|
364 | 356 | if self.type == EXTERNAL: |
365 | 357 | # If this version is a EXTERNAL version, the identifier will |
366 | 358 | # contain the actual commit hash. which we can use to |
367 | 359 | # generate url for a given file name |
368 | 360 | return self.identifier |
369 | 361 |
|
370 | | - # If we came that far it's not a special version |
371 | | - # nor a branch, tag or EXTERNAL version. |
372 | | - # Therefore just return the identifier to make a safe guess. |
373 | | - log.debug( |
374 | | - "TODO: Raise an exception here. Testing what cases it happens", |
375 | | - ) |
376 | | - return self.identifier |
| 362 | + # For all other cases, verbose_name contains the actual name of the branch/tag. |
| 363 | + return self.verbose_name |
377 | 364 |
|
378 | 365 | def get_absolute_url(self): |
379 | 366 | """ |
@@ -561,13 +548,18 @@ class APIVersion(Version): |
561 | 548 | """ |
562 | 549 |
|
563 | 550 | project = None |
| 551 | + # This is a property in the original model, in order to |
| 552 | + # be able to assign it a value in the constructor, we need to re-declare it |
| 553 | + # as an attribute here. |
| 554 | + git_identifier = None |
564 | 555 |
|
565 | 556 | class Meta: |
566 | 557 | proxy = True |
567 | 558 |
|
568 | 559 | def __init__(self, *args, **kwargs): |
569 | 560 | self.project = APIProject(**kwargs.pop("project", {})) |
570 | 561 | self.canonical_url = kwargs.pop("canonical_url", None) |
| 562 | + self.git_identifier = kwargs.pop("git_identifier", None) |
571 | 563 | # These fields only exist on the API return, not on the model, so we'll |
572 | 564 | # remove them to avoid throwing exceptions due to unexpected fields |
573 | 565 | for key in ["resource_uri", "absolute_url", "downloads"]: |
|
0 commit comments