Skip to content

Version handling improvements #1354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions readthedocs/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from tastypie.http import HttpCreated, HttpApplicationError
from tastypie.utils import dict_strip_unicode_keys, trailing_slash

from builds.constants import LATEST
from builds.models import Build, Version
from core.utils import trigger_build
from projects.models import Project, ImportedFile
Expand Down Expand Up @@ -150,7 +151,7 @@ def version_compare(self, request, **kwargs):
if highest[0]:
ret_val['url'] = highest[0].get_absolute_url()
ret_val['slug'] = highest[0].slug,
if base and base != 'latest':
if base and base != LATEST:
try:
ver_obj = project.versions.get(slug=base)
base_ver = mkversion(ver_obj)
Expand All @@ -167,7 +168,7 @@ def version_compare(self, request, **kwargs):

def build_version(self, request, **kwargs):
project = get_object_or_404(Project, slug=kwargs['project_slug'])
version = kwargs.get('version_slug', 'latest')
version = kwargs.get('version_slug', LATEST)
version_obj = project.versions.get(slug=version)
trigger_build(project=project, version=version_obj)
return self.create_response(request, {'building': True})
Expand Down
18 changes: 15 additions & 3 deletions readthedocs/betterversion/better.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
from distlib.version import AdaptiveVersion
from collections import defaultdict

class BetterVersion(AdaptiveVersion):

class VersionIdentifier(AdaptiveVersion):
"""
An extended variant of ``distlib.version.AdaptiveVersion``. The constructor
takes a version string like ``0.7.3`` and the class then provides a nice
interface to access the different major/minor version numbers etc.
"""

@property
def major_version(self):
return self._parts[0][0]
Expand All @@ -14,8 +21,8 @@ def minor_version(self):
except IndexError, e:
return 0

class VersionManager(object):

class VersionManager(object):
def __init__(self):
self._state = defaultdict(lambda: defaultdict(list))

Expand Down Expand Up @@ -50,13 +57,18 @@ def prune_point(self, num_latest):
# Raise these for now.
raise


def version_windows(versions, major=1, minor=1, point=1, flat=False):
# TODO: This needs some documentation on how VersionManager etc works and
# some examples what the expected outcome is.

major_version_window = major
minor_version_window = minor
point_version_window = point

manager = VersionManager()
[ manager.add(v) for v in versions]
for v in versions:
manager.add(v)
manager.prune_major(major_version_window)
manager.prune_minor(minor_version_window)
manager.prune_point(point_version_window)
Expand Down
6 changes: 6 additions & 0 deletions readthedocs/builds/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@
('tag', _('Tag')),
('unknown', _('Unknown')),
)

LATEST = 'latest'
LATEST_VERBOSE_NAME = 'latest'

STABLE = 'stable'
STABLE_VERBOSE_NAME = 'stable'
3 changes: 2 additions & 1 deletion readthedocs/builds/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from guardian.shortcuts import assign
from taggit.managers import TaggableManager

from builds.constants import LATEST
from privacy.loader import VersionManager, RelatedProjectManager
from projects.models import Project
from projects import constants
Expand Down Expand Up @@ -79,7 +80,7 @@ def save(self, *args, **kwargs):

@property
def remote_slug(self):
if self.slug == 'latest':
if self.slug == LATEST:
if self.project.default_branch:
return self.project.default_branch
else:
Expand Down
5 changes: 4 additions & 1 deletion readthedocs/builds/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import logging
from shutil import rmtree

from builds.constants import LATEST


log = logging.getLogger(__name__)


Expand Down Expand Up @@ -42,7 +45,7 @@ def get_bitbucket_username_repo(version, repo_url=None):

def get_vcs_version_slug(version):
slug = None
if version.slug == 'latest':
if version.slug == LATEST:
if version.project.default_branch:
slug = version.project.default_branch
else:
Expand Down
4 changes: 3 additions & 1 deletion readthedocs/core/djangome_urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from django.conf.urls import patterns, url
from builds.constants import LATEST


urlpatterns = patterns(
'', # base view, flake8 complains if it is on the previous line.
url('^$',
'djangome.views.redirect_home',
{'version': 'latest'}),
{'version': LATEST}),
)
3 changes: 2 additions & 1 deletion readthedocs/core/management/commands/build_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.conf import settings

from projects import tasks
from builds.constants import LATEST
from builds.models import Version

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -35,7 +36,7 @@ def handle(self, *args, **options):
queryset = Version.objects.public(project__slug=project)
log.info("Building all versions for %s" % project)
elif getattr(settings, 'INDEX_ONLY_LATEST', True):
queryset = Version.objects.filter(slug='latest')
queryset = Version.objects.filter(slug=LATEST)
else:
queryset = Version.objects.public()
for v in queryset:
Expand Down
3 changes: 2 additions & 1 deletion readthedocs/core/management/commands/import_intersphinx.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from django.core.management.base import BaseCommand

from builds.constants import LATEST
from builds.models import Version
from projects.tasks import update_intersphinx


class Command(BaseCommand):
def handle(self, *args, **options):
for version in Version.objects.filter(slug="latest"):
for version in Version.objects.filter(slug=LATEST):
update_intersphinx(version.pk)
3 changes: 2 additions & 1 deletion readthedocs/core/management/commands/pull.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.core.management.base import BaseCommand
from django.conf import settings

from builds.constants import LATEST
from projects import tasks, utils

import redis
Expand All @@ -14,5 +15,5 @@ def handle(self, *args, **options):
if len(args):
for slug in args:
tasks.update_imported_docs(
utils.version_from_slug(slug, 'latest').pk
utils.version_from_slug(slug, LATEST).pk
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.core.management.base import BaseCommand
from django.conf import settings

from builds.constants import LATEST
from builds.models import Version
from search import parse_json
from restapi.utils import index_search_request
Expand All @@ -30,7 +31,7 @@ def handle(self, *args, **options):
queryset = Version.objects.public(project__slug=project)
log.info("Building all versions for %s" % project)
elif getattr(settings, 'INDEX_ONLY_LATEST', True):
queryset = Version.objects.public().filter(slug='latest')
queryset = Version.objects.public().filter(slug=LATEST)
else:
queryset = Version.objects.public()
for version in queryset:
Expand Down
8 changes: 5 additions & 3 deletions readthedocs/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from django.template.loader import get_template
from django.template import Context

from builds.constants import LATEST
from builds.constants import LATEST_VERBOSE_NAME
from builds.models import Build

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -44,10 +46,10 @@ def make_latest(project):
branch = project.default_branch or project.vcs_repo().fallback_branch
version_data, created = Version.objects.get_or_create(
project=project,
slug='latest',
slug=LATEST,
type='branch',
active=True,
verbose_name='latest',
verbose_name=LATEST_VERBOSE_NAME,
identifier=branch,
)

Expand Down Expand Up @@ -82,7 +84,7 @@ def trigger_build(project, version=None, record=True, force=False, basic=False):
return None

if not version:
version = project.versions.get(slug='latest')
version = project.versions.get(slug=LATEST)

if record:
build = Build.objects.create(
Expand Down
9 changes: 5 additions & 4 deletions readthedocs/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from core.forms import FacetedSearchForm
from core.utils import trigger_build
from donate.mixins import DonateProgressMixin
from builds.constants import LATEST
from projects import constants
from projects.models import Project, ImportedFile, ProjectRelationship
from projects.tasks import remove_dir, update_imported_docs
Expand Down Expand Up @@ -152,7 +153,7 @@ def _build_version(project, slug, already_built=()):
# short circuit versions that are default
# these will build at "latest", and thus won't be
# active
latest_version = project.versions.get(slug='latest')
latest_version = project.versions.get(slug=LATEST)
trigger_build(project=project, version=latest_version, force=True)
pc_log.info(("(Version build) Building %s:%s"
% (project.slug, latest_version.slug)))
Expand All @@ -162,7 +163,7 @@ def _build_version(project, slug, already_built=()):
trigger_build(project=project, version=slug_version, force=True)
pc_log.info(("(Version build) Building %s:%s"
% (project.slug, slug_version.slug)))
return "latest"
return LATEST
elif project.versions.exclude(active=True).filter(slug=slug).exists():
pc_log.info(("(Version build) Not Building %s" % slug))
return None
Expand Down Expand Up @@ -201,7 +202,7 @@ def _build_url(url, branches):
for project in projects:
(to_build, not_building) = _build_branches(project, branches)
if not to_build:
update_imported_docs.delay(project.versions.get(slug='latest').pk)
update_imported_docs.delay(project.versions.get(slug=LATEST).pk)
msg = '(URL Build) Syncing versions for %s' % project.slug
pc_log.info(msg)
if to_build:
Expand Down Expand Up @@ -293,7 +294,7 @@ def generic_build(request, pk=None):
_build_version(project, slug)
else:
pc_log.info(
"(Incoming Generic Build) %s [%s]" % (project.slug, 'latest'))
"(Incoming Generic Build) %s [%s]" % (project.slug, LATEST))
trigger_build(project=project, force=True)
else:
return HttpResponse("You must POST to this resource.")
Expand Down
28 changes: 28 additions & 0 deletions readthedocs/privacy/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

from guardian.shortcuts import get_objects_for_user

from builds.constants import LATEST
from builds.constants import LATEST_VERBOSE_NAME
from builds.constants import STABLE
from builds.constants import STABLE_VERBOSE_NAME
from projects import constants


Expand Down Expand Up @@ -113,6 +117,30 @@ def public(self, user=None, project=None, only_active=True, *args, **kwargs):
def api(self, user=None, *args, **kwargs):
return self.public(user, only_active=False)

def create_stable(self, **kwargs):
defaults = {
'slug': STABLE,
'verbose_name': STABLE_VERBOSE_NAME,
'machine': True,
'active': True,
'identifier': STABLE,
'type': 'branch',
}
defaults.update(kwargs)
return self.create(**defaults)

def create_latest(self, **kwargs):
defaults = {
'slug': LATEST,
'verbose_name': LATEST_VERBOSE_NAME,
'machine': True,
'active': True,
'identifier': LATEST,
'type': 'branch',
}
defaults.update(kwargs)
return self.create(**defaults)


class AdminPermission(object):

Expand Down
Loading