diff --git a/docs/commands.md b/docs/commands.md index 3ccb7edd..fdf42497 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -137,7 +137,7 @@ Import `VersionFile` objects from Artifactory. **Example** ```bash -./manage.py get_library_version_documentation_urls --version=1.81.0 +./manage.py import_library_version_docs_urls --version=1.81.0 ``` **Options** diff --git a/libraries/migrations/0034_strip_boost_from_documentation_urls.py b/libraries/migrations/0034_strip_boost_from_documentation_urls.py new file mode 100644 index 00000000..8070160e --- /dev/null +++ b/libraries/migrations/0034_strip_boost_from_documentation_urls.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.24 on 2025-10-16 23:31 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("libraries", "0033_libraryversion_cpp20_module_support"), + ] + + operations = [ + migrations.RunSQL( + sql="UPDATE libraries_libraryversion SET documentation_url = REPLACE(documentation_url, '/boost_', '/') WHERE documentation_url LIKE '%/boost_%';", + reverse_sql="UPDATE libraries_libraryversion SET documentation_url = REPLACE(documentation_url, '/doc/libs/', '/doc/libs/boost_') WHERE documentation_url LIKE '/doc/libs/[0-9]%';", + ), + ] diff --git a/libraries/tasks.py b/libraries/tasks.py index 9239812b..fc921995 100644 --- a/libraries/tasks.py +++ b/libraries/tasks.py @@ -60,6 +60,7 @@ def get_and_store_library_version_documentation_urls_for_version(version_pk): return base_path = f"doc/libs/{version.boost_url_slug}/libs/" + boost_stripped_base_path = base_path.replace("doc/libs/boost_", "doc/libs/") key = f"{base_path}libraries.htm" result = get_content_from_s3(key) @@ -74,7 +75,7 @@ def get_and_store_library_version_documentation_urls_for_version(version_pk): try: # In most cases, the name matches close enough to get the correct object library_version = library_versions.get(library__name__iexact=library_name) - library_version.documentation_url = f"/{base_path}{url_path}" + library_version.documentation_url = f"/{boost_stripped_base_path}{url_path}" library_version.save() except LibraryVersion.DoesNotExist: logger.info( @@ -131,7 +132,9 @@ def get_and_store_library_version_documentation_urls_for_version(version_pk): content = get_content_from_s3(key[0]) if content: - library_version.documentation_url = documentation_url + library_version.documentation_url = documentation_url.replace( + "doc/libs/boost_", "doc/libs/" + ) library_version.save() else: logger.info(f"No valid docs in S3 for key {documentation_url}") diff --git a/libraries/templatetags/doc_url_with_latest.py b/libraries/templatetags/doc_url_with_latest.py new file mode 100644 index 00000000..58944670 --- /dev/null +++ b/libraries/templatetags/doc_url_with_latest.py @@ -0,0 +1,20 @@ +import re +from django import template + +register = template.Library() + + +@register.simple_tag +def doc_url_with_latest(documentation_url, version_str, latest_str): + """ + Replace the version segment in a documentation URL with the latest string. + Only replaces if version_str matches latest_str. + + Usage: {% doc_url_with_latest library_version.documentation_url version_str LATEST_RELEASE_URL_PATH_STR %} + Example: /doc/libs/1_89_0/libs/accumulators/index.html -> /doc/libs/latest/libs/accumulators/index.html + """ + if not documentation_url or version_str != latest_str: + return documentation_url + + # Pattern matches /doc/libs/{version}/ where version is typically digits/underscores + return re.sub(r"(doc/libs/)([^/]+)(\S+)", rf"\1{latest_str}\3", documentation_url) diff --git a/libraries/tests/test_tasks.py b/libraries/tests/test_tasks.py index f86ec70e..89e6c53f 100644 --- a/libraries/tests/test_tasks.py +++ b/libraries/tests/test_tasks.py @@ -42,9 +42,10 @@ def test_get_and_store_library_version_documentation_urls_for_version( # Refresh the library_version object from the database library_version.refresh_from_db() # Assert that the docs_path was updated as expected + slug = version.boost_url_slug.replace("boost_", "") assert ( library_version.documentation_url - == f"/doc/libs/{version.boost_url_slug}/libs/{library_name}/index.html" + == f"/doc/libs/{slug}/libs/{library_name}/index.html" ) diff --git a/libraries/tests/test_views.py b/libraries/tests/test_views.py index 4fa0e40d..050d0ade 100644 --- a/libraries/tests/test_views.py +++ b/libraries/tests/test_views.py @@ -249,7 +249,7 @@ def test_library_detail_context_get_documentation_url_no_docs_link( response = tp.get(url) tp.response_200(response) assert "documentation_url" in response.context - assert response.context["documentation_url"] == "/doc/libs/1_79_0" + assert response.context["documentation_url"] is None def test_library_detail_context_get_documentation_url_missing_docs_bool( @@ -267,7 +267,7 @@ def test_library_detail_context_get_documentation_url_missing_docs_bool( response = tp.get(url) tp.response_200(response) assert "documentation_url" in response.context - assert response.context["documentation_url"] == "/doc/libs/1_79_0" + assert response.context["documentation_url"] is None def test_library_detail_context_get_documentation_url_docs_present( diff --git a/libraries/utils.py b/libraries/utils.py index 317058e9..4d57c50c 100644 --- a/libraries/utils.py +++ b/libraries/utils.py @@ -193,6 +193,13 @@ def generate_canonical_library_uri(uri): def get_documentation_url(library_version, latest): + url = library_version.documentation_url + if url and latest: + url = library_doc_latest_transform(url) + return url + + +def get_documentation_url_redirect(library_version, latest): """Get the documentation URL for the current library.""" def find_documentation_url(library_version): diff --git a/libraries/views.py b/libraries/views.py index 8062710c..4a307894 100644 --- a/libraries/views.py +++ b/libraries/views.py @@ -32,6 +32,7 @@ from .utils import ( determine_selected_boost_version, set_selected_boost_version, get_documentation_url, + get_documentation_url_redirect, get_prioritized_version, get_version_from_cookie, ) @@ -337,7 +338,9 @@ class LibraryDetail(VersionAlertMixin, BoostVersionMixin, ContributorMixin, Deta library_slug=self.kwargs.get("library_slug"), version_slug=get_prioritized_version(request), ) - return redirect(get_documentation_url(library_version, latest=False)) + return redirect( + get_documentation_url_redirect(library_version, latest=False) + ) response = super().dispatch(request, *args, **kwargs) set_selected_boost_version( self.kwargs.get("version_slug", LATEST_RELEASE_URL_PATH_STR), response diff --git a/templates/libraries/detail.html b/templates/libraries/detail.html index 893d3bed..36800d2e 100644 --- a/templates/libraries/detail.html +++ b/templates/libraries/detail.html @@ -70,8 +70,13 @@ Documentation - {{ request.get_host }}{{ documentation_url|cut:"https://" }} + {{ request.get_host }}{{ documentation_url|cut:"https://" }} + {% else %} +
+ Documentation + No documentation for this version +
{% endif %}
diff --git a/templates/libraries/includes/_documentation_link_icon.html b/templates/libraries/includes/_documentation_link_icon.html index 1f2d7da8..02518a4d 100644 --- a/templates/libraries/includes/_documentation_link_icon.html +++ b/templates/libraries/includes/_documentation_link_icon.html @@ -1,3 +1,7 @@ - - - +{% load doc_url_with_latest %} + +{% if library_version.documentation_url %} + + + +{% endif %}