Bug#756741: tracker.debian.org: Dead package warning
Control: tag-1 + patch
Here are 2 patches to fix this
--
Sophie Brun
>From 70612cefe4521658c352a1fc1ad037df2c6c0839 Mon Sep 17 00:00:00 2001
From: Sophie Brun <sophie@freexian.com>
Date: Fri, 12 Sep 2014 14:17:21 +0200
Subject: [PATCH 1/2] core/models: add Repository.is_development_repository()
Identifying development repositories is important to know when a package
is going away (because it's no longer in any development repository).
---
distro_tracker/core/models.py | 21 +++++++++++++++++++++
distro_tracker/core/tests/tests_models.py | 22 ++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/distro_tracker/core/models.py b/distro_tracker/core/models.py
index eb43765..4ab27dd 100644
--- a/distro_tracker/core/models.py
+++ b/distro_tracker/core/models.py
@@ -952,6 +952,27 @@ class Repository(models.Model):
raise ValidationError(
"Only one repository can be set as the default")
+ def is_development_repository(self):
+ """Returns a boolean indicating whether the repository is used for
+ development.
+
+ A developement repository is a repository where new
+ versions of packages tend to be uploaded. The list of development
+ repositories can be provided in the list
+ DISTRO_TRACKER_DEVEL_REPOSITORIES (it should contain codenames and/or
+ suite names). If that setting does not exist, then the default
+ repository is assumed to be the only development repository.
+
+ :rtype: bool
+ """
+ if hasattr(settings, 'DISTRO_TRACKER_DEVEL_REPOSITORIES'):
+ for repo in settings.DISTRO_TRACKER_DEVEL_REPOSITORIES:
+ if self.codename == repo or self.suite == repo:
+ return True
+ else:
+ return self.default
+ return False
+
@python_2_unicode_compatible
class ContributorName(models.Model):
diff --git a/distro_tracker/core/tests/tests_models.py b/distro_tracker/core/tests/tests_models.py
index ca4a7f7..ef64ab4 100644
--- a/distro_tracker/core/tests/tests_models.py
+++ b/distro_tracker/core/tests/tests_models.py
@@ -620,6 +620,12 @@ class RepositoryTests(TestCase):
binary_package_name=self.bin_pkg_name,
version='1.0.0',
source_package=self.source_package)
+ self.repo1 = Repository.objects.create(
+ name='repo1', shorthand='repo1', codename='codename1',
+ suite='suite1')
+ self.repo2 = Repository.objects.create(
+ name='repo2', shorthand='repo2', codename='codename2',
+ suite='suite2')
def test_add_source_entry_to_repository(self):
"""
@@ -783,6 +789,22 @@ class RepositoryTests(TestCase):
self.source_package.source_package_name.name),
expected_entry)
+ def test_is_development_repository_default_case(self):
+ """We have not provided any explicit list of development repositories.
+ The default repository is the only development repository."""
+ self.assertTrue(self.repository.is_development_repository())
+ self.assertFalse(self.repo1.is_development_repository())
+ self.assertFalse(self.repo2.is_development_repository())
+
+ @override_settings(
+ DISTRO_TRACKER_DEVEL_REPOSITORIES=['suite1', 'codename2'])
+ def test_is_development_repository_explicit_list(self):
+ """We have provided an explicit list of development repositories. It
+ should be the reference."""
+ self.assertFalse(self.repository.is_development_repository())
+ self.assertTrue(self.repo1.is_development_repository())
+ self.assertTrue(self.repo2.is_development_repository())
+
class SourcePackageTests(TestCase):
fixtures = ['repository-test-fixture.json']
--
2.1.0
>From 3be7f31236e1a6023dfd1e97c52746c3e15c097b Mon Sep 17 00:00:00 2001
From: Sophie Brun <sophie@freexian.com>
Date: Fri, 12 Sep 2014 15:54:37 +0200
Subject: [PATCH 2/2] core: add a panel displaying a warning when the package
is gone
Closes: #756741
---
distro_tracker/core/panels.py | 37 ++++++++++++
.../templates/core/panels/package-is-gone.html | 23 ++++++++
distro_tracker/core/tests/tests_panels.py | 66 +++++++++++++++++++++-
distro_tracker/project/settings/debian.py | 6 ++
4 files changed, 129 insertions(+), 3 deletions(-)
create mode 100644 distro_tracker/core/templates/core/panels/package-is-gone.html
diff --git a/distro_tracker/core/panels.py b/distro_tracker/core/panels.py
index efd0878..057c19d 100644
--- a/distro_tracker/core/panels.py
+++ b/distro_tracker/core/panels.py
@@ -19,6 +19,7 @@ from distro_tracker.core.utils import get_vcs_name
from distro_tracker.core.utils import get_or_none
from distro_tracker import vendor
from distro_tracker.core.models import SourcePackageName
+from distro_tracker.core.models import PseudoPackageName
from distro_tracker.core.models import ActionItem
from distro_tracker.core.models import PackageExtractedInfo
from distro_tracker.core.models import MailingList
@@ -930,3 +931,39 @@ class ActionNeededPanel(BasePanel):
@property
def has_content(self):
return bool(self.context['items'])
+
+
+class DeadPackageWarningPanel(BasePanel):
+ """
+ The panel displays a warning when the package has been dropped
+ from development repositories, and another one when the package no longer
+ exists in any repository.
+ """
+ title = 'package is gone'
+ template_name = 'core/panels/package-is-gone.html'
+ panel_importance = 9
+ position = 'center'
+
+ @property
+ def has_content(self):
+ if isinstance(self.package, SourcePackageName):
+ for repo in self.package.repositories:
+ if repo.is_development_repository():
+ return False
+ return True
+ elif isinstance(self.package, PseudoPackageName):
+ return False
+ else:
+ return True
+
+ @cached_property
+ def context(self):
+ if isinstance(self.package, SourcePackageName):
+ disappeared = len(self.package.repositories) == 0
+ else:
+ disappeared = True
+ return {
+ 'disappeared': disappeared,
+ 'removals_url': getattr(settings, 'DISTRO_TRACKER_REMOVALS_URL',
+ ''),
+ }
diff --git a/distro_tracker/core/templates/core/panels/package-is-gone.html b/distro_tracker/core/templates/core/panels/package-is-gone.html
new file mode 100644
index 0000000..8938db1
--- /dev/null
+++ b/distro_tracker/core/templates/core/panels/package-is-gone.html
@@ -0,0 +1,23 @@
+{% extends 'core/panels/panel.html' %}
+
+{% block panel-body %}
+{% if panel.context.disappeared %}
+This package is not part of any {{ DISTRO_TRACKER_VENDOR_NAME }}
+distribution. Thus you won't find much information here. The package is
+either very new and hasn't appeared on mirrors yet, or it's an old package
+that eventually got removed. The old news are kept for historic purpose
+only.
+{% else %}
+This package is not in any development repository. This probably
+means that the package
+{% if panel.context.removals_url %}
+<a href="{{ panel.context.removals_url }}">has been removed</a>
+{% else %}
+has been removed
+{% endif %}
+(or has been renamed). Thus the information here is of little interest ...
+the package is going to disappear unless someone takes it over and
+reintroduces it.
+{% endif %}
+{% endblock %}
+
diff --git a/distro_tracker/core/tests/tests_panels.py b/distro_tracker/core/tests/tests_panels.py
index f02fa93..b56b3ff 100644
--- a/distro_tracker/core/tests/tests_panels.py
+++ b/distro_tracker/core/tests/tests_panels.py
@@ -14,12 +14,16 @@
Tests for the Distro Tracker core panels.
"""
from __future__ import unicode_literals
-from distro_tracker.test import TestCase
from django.core.urlresolvers import reverse
+from bs4 import BeautifulSoup as soup
+
+from distro_tracker.test import TestCase
from distro_tracker.core.models import SourcePackageName
+from distro_tracker.core.models import PseudoPackageName
+from distro_tracker.core.models import PackageName
from distro_tracker.core.models import SourcePackage
-from distro_tracker.core.panels import VersionedLinks
-from bs4 import BeautifulSoup as soup
+from distro_tracker.core.models import Repository, SourcePackageRepositoryEntry
+from distro_tracker.core.panels import VersionedLinks, DeadPackageWarningPanel
class VersionedLinksPanelTests(TestCase):
@@ -124,3 +128,59 @@ class GeneralInfoLinkPanelItemsTests(TestCase):
response = self.get_package_page_response()
self.assertTrue(self.get_general_info_link_panel(response))
self.assertTrue(self.homepage_is_in_linkspanel(response))
+
+
+class DeadPackageWarningPanelTests(TestCase):
+ def setUp(self):
+ self.pkgname = SourcePackageName.objects.create(name='dummy-package')
+ self.srcpkg = SourcePackage.objects.create(
+ source_package_name=self.pkgname, version='1.0.0')
+ self.default_repo = \
+ Repository.objects.create(name='default', shorthand='default',
+ default=True)
+ self.repo1 = Repository.objects.create(name='repo1', shorthand='repo1')
+ self.panel = DeadPackageWarningPanel(self.pkgname, None)
+
+ def test_has_content_pkg_in_no_repository(self):
+ """The package is not in any repository. We should display the
+ warning."""
+ self.assertTrue(self.panel.has_content)
+
+ def test_has_content_pkg_not_in_devel_repos(self):
+ """The package is not in a development repository. We should display
+ the warning."""
+ SourcePackageRepositoryEntry.objects.create(
+ source_package=self.srcpkg, repository=self.repo1)
+ self.assertTrue(self.panel.has_content)
+
+ def test_has_content_pkg_in_devel_repos(self):
+ """The package is in at least one of the development repositories.
+ We should not display the warning."""
+ SourcePackageRepositoryEntry.objects.create(
+ source_package=self.srcpkg, repository=self.default_repo)
+ self.assertFalse(self.panel.has_content)
+
+ def test_has_content_for_pseudo_package(self):
+ """A pseudo-package is never obsolete. No warning displayed."""
+ pkgname = PseudoPackageName.objects.create(name='pseudo')
+ panel = DeadPackageWarningPanel(pkgname, None)
+
+ self.assertFalse(panel.has_content)
+
+ def test_has_content_for_old_packages(self):
+ """Old package only exists as PackageName. We should display the
+ warning in this case."""
+ pkgname = PackageName.objects.create(name='oldpkg')
+ panel = DeadPackageWarningPanel(pkgname, None)
+
+ self.assertTrue(panel.has_content)
+
+ def test_context_pkg_disappeared_completely(self):
+ """The package is not in any repository. The context exports this."""
+ self.assertTrue(self.panel.context['disappeared'])
+
+ def test_context_pkg_disappeared_from_devel_repository(self):
+ """The package is in a few repositories. The context exports this."""
+ SourcePackageRepositoryEntry.objects.create(
+ source_package=self.srcpkg, repository=self.repo1)
+ self.assertFalse(self.panel.context['disappeared'])
diff --git a/distro_tracker/project/settings/debian.py b/distro_tracker/project/settings/debian.py
index e80b5b7..2c36283 100644
--- a/distro_tracker/project/settings/debian.py
+++ b/distro_tracker/project/settings/debian.py
@@ -34,6 +34,12 @@ DISTRO_TRACKER_DEBIAN_PIUPARTS_SUITES = (
'sid',
)
+#: The page documenting package removals
+DISTRO_TRACKER_REMOVALS_URL = "https://ftp-master.debian.org/removals.txt"
+
+#: A list of the repositories where new versions are uploaded
+DISTRO_TRACKER_DEVEL_REPOSITORIES = ['unstable', 'experimental']
+
# Various settings for sso.debian.org support
_index_auth = MIDDLEWARE_CLASSES.index(
'django.contrib.auth.middleware.AuthenticationMiddleware') + 1
--
2.1.0
Reply to: