Skip to content

Commit

Permalink
feat: add model for tracking codebase git mirror
Browse files Browse the repository at this point in the history
* fix release ordering to sort by semantic version number rather than by
  string
  • Loading branch information
sgfost committed Jul 30, 2024
1 parent bc520b6 commit 161a2fa
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@
</tr>
</thead>
<tbody>
{% for related_release in codebase.ordered_releases(has_change_perm) %}
{% for related_release in codebase.ordered_releases(has_change_perm, asc=False) %}
<tr>
<td><a href='{{ related_release.get_absolute_url() }}'>{{ related_release.version_number }}</a></td>
<td>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Generated by Django 4.2.11 on 2024-05-07 22:25

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
("library", "0026_alter_codebasereleaseplatformtag_tag_and_more"),
]

operations = [
migrations.CreateModel(
name="CodebaseGitMirror",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("repository_name", models.CharField(max_length=100, unique=True)),
(
"remote_url",
models.URLField(
blank=True, help_text="URL of mirrored remote repository"
),
),
("last_local_update", models.DateTimeField(blank=True, null=True)),
("last_remote_update", models.DateTimeField(blank=True, null=True)),
(
"local_releases",
models.ManyToManyField(
related_name="+", to="library.codebaserelease"
),
),
(
"remote_releases",
models.ManyToManyField(
related_name="+", to="library.codebaserelease"
),
),
],
),
migrations.AddField(
model_name="codebase",
name="git_mirror",
field=models.OneToOneField(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="codebase",
to="library.codebasegitmirror",
),
),
]
70 changes: 63 additions & 7 deletions django/library/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import uuid
from collections import OrderedDict
from datetime import timedelta
from packaging.version import Version

import semver
from django.conf import settings
Expand Down Expand Up @@ -535,6 +536,38 @@ def get_all_release_programming_languages(self, codebase):
).values_list("programming_languages__name", flat=True)


class CodebaseGitMirror(models.Model):
"""
model to keep track of the state of a git mirror for a codebase
"""

repository_name = models.CharField(max_length=100, unique=True)
remote_url = models.URLField(
blank=True,
help_text=_("URL of mirrored remote repository"),
)
# keep track of timestamp and releases that have been mirrored locally
last_local_update = models.DateTimeField(null=True, blank=True)
local_releases = models.ManyToManyField("CodebaseRelease", related_name="+")
# keep track of timestamp and releases that have been synced to the remote
last_remote_update = models.DateTimeField(null=True, blank=True)
remote_releases = models.ManyToManyField("CodebaseRelease", related_name="+")

@property
def latest_local_release(self):
return max(self.local_releases.all(), key=lambda r: Version(r.version_number))

@property
def latest_remote_release(self):
return max(self.remote_releases.all(), key=lambda r: Version(r.version_number))

@property
def unmirrored_local_releases(self):
return self.codebase.ordered_releases().exclude(
id__in=self.local_releases.values_list("id", flat=True)
)


@add_to_comses_permission_whitelist
class Codebase(index.Indexed, ModeratedContent, ClusterableModel):
"""
Expand Down Expand Up @@ -570,6 +603,13 @@ class Codebase(index.Indexed, ModeratedContent, ClusterableModel):
on_delete=models.SET_NULL,
)

git_mirror = models.OneToOneField(
"CodebaseGitMirror",
null=True,
related_name="codebase",
on_delete=models.SET_NULL,
)

repository_url = models.URLField(
blank=True,
help_text=_(
Expand Down Expand Up @@ -718,6 +758,16 @@ def base_library_dir(self):
def base_git_dir(self):
return pathlib.Path(settings.REPOSITORY_ROOT, str(self.uuid))

def create_git_mirror(self, repository_name, **kwargs):
if not self.git_mirror:
git_mirror = CodebaseGitMirror.objects.create(
repository_name=repository_name,
**kwargs,
)
self.git_mirror = git_mirror
self.save()
return self.git_mirror

@property
def codebase_contributors_redis_key(self):
return f"codebase:contributors:{self.identifier}"
Expand Down Expand Up @@ -807,13 +857,19 @@ def download_count(self):
release__codebase__id=self.id
).count()

def ordered_releases(self, has_change_perm=False, **kwargs):
releases = self.releases.order_by("-version_number").filter(**kwargs)
return (
releases
if has_change_perm
else releases.filter(status=CodebaseRelease.Status.PUBLISHED)
)
def ordered_releases(self, has_change_perm=False, asc=True, **kwargs):
"""
list public releases (or all release if has_change_perm is True) in ascending (default) or descending order
"""
if has_change_perm:
releases = self.releases.filter(**kwargs)
else:
releases = self.releases.filter(
status=CodebaseRelease.Status.PUBLISHED, **kwargs
)
releases_list = list(releases)
releases_list.sort(key=lambda r: Version(r.version_number), reverse=not asc)
return releases_list

@classmethod
def get_list_url(cls):
Expand Down

0 comments on commit 161a2fa

Please sign in to comment.