Skip to content

Commit

Permalink
Merge pull request #4929 from stsewd/remove-repeated-code
Browse files Browse the repository at this point in the history
Remove repeated and dead code
  • Loading branch information
humitos committed Dec 3, 2018
2 parents 4ba947a + 54b5372 commit 273776c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 115 deletions.
93 changes: 66 additions & 27 deletions readthedocs/core/symlink.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,27 @@
fabric -> rtd-builds/fabric/en/latest/ # single version
"""

from __future__ import absolute_import, unicode_literals
from builtins import object
from __future__ import (
absolute_import,
division,
print_function,
unicode_literals,
)

import logging
import os
import shutil
import logging
from collections import OrderedDict

from builtins import object
from django.conf import settings

from readthedocs.builds.models import Version
from readthedocs.core.utils.extend import SettingsOverrideObject
from readthedocs.core.utils import safe_makedirs, safe_unlink
from readthedocs.core.utils.extend import SettingsOverrideObject
from readthedocs.doc_builder.environments import LocalEnvironment
from readthedocs.projects import constants
from readthedocs.projects.models import Domain
from readthedocs.projects.utils import run

log = logging.getLogger(__name__)

Expand All @@ -83,6 +89,7 @@ def __init__(self, project):
self.subproject_root = os.path.join(
self.project_root, 'projects'
)
self.environment = LocalEnvironment(project)
self.sanity_check()

def sanity_check(self):
Expand Down Expand Up @@ -146,17 +153,27 @@ def symlink_cnames(self, domain=None):
else:
domains = Domain.objects.filter(project=self.project)
for dom in domains:
log_msg = 'Symlinking CNAME: {0} -> {1}'.format(dom.domain, self.project.slug)
log.info(constants.LOG_TEMPLATE.format(project=self.project.slug,
version='', msg=log_msg))
log_msg = 'Symlinking CNAME: {} -> {}'.format(
dom.domain, self.project.slug
)
log.info(
constants.LOG_TEMPLATE.format(
project=self.project.slug,
version='', msg=log_msg
)
)

# CNAME to doc root
symlink = os.path.join(self.CNAME_ROOT, dom.domain)
run(['ln', '-nsf', self.project_root, symlink])
self.environment.run('ln', '-nsf', self.project_root, symlink)

# Project symlink
project_cname_symlink = os.path.join(self.PROJECT_CNAME_ROOT, dom.domain)
run(['ln', '-nsf', self.project.doc_path, project_cname_symlink])
project_cname_symlink = os.path.join(
self.PROJECT_CNAME_ROOT, dom.domain
)
self.environment.run(
'ln', '-nsf', self.project.doc_path, project_cname_symlink
)

def remove_symlink_cname(self, domain):
"""Remove CNAME symlink."""
Expand Down Expand Up @@ -201,10 +218,12 @@ def symlink_subprojects(self):
# TODO this should use os.symlink, not a call to shell. For now,
# this passes command as a list to be explicit about escaping
# characters like spaces.
status, _, stderr = run(['ln', '-nsf', docs_dir, symlink])
if status > 0:
log.error('Could not symlink path: status=%d error=%s',
status, stderr)
result = self.environment.run('ln', '-nsf', docs_dir, symlink)
if result.exit_code > 0:
log.error(
'Could not symlink path: status=%d error=%s',
result.exit_code, result.error
)

# Remove old symlinks
if os.path.exists(self.subproject_root):
Expand Down Expand Up @@ -233,12 +252,16 @@ def symlink_translations(self):

for (language, slug) in list(translations.items()):

log_msg = 'Symlinking translation: {0}->{1}'.format(language, slug)
log.info(constants.LOG_TEMPLATE.format(project=self.project.slug,
version='', msg=log_msg))
log_msg = 'Symlinking translation: {}->{}'.format(language, slug)
log.info(
constants.LOG_TEMPLATE.format(
project=self.project.slug,
version='', msg=log_msg
)
)
symlink = os.path.join(self.project_root, language)
docs_dir = os.path.join(self.WEB_ROOT, slug, language)
run(['ln', '-nsf', docs_dir, symlink])
self.environment.run('ln', '-nsf', docs_dir, symlink)

# Remove old symlinks
for lang in os.listdir(self.project_root):
Expand Down Expand Up @@ -268,9 +291,13 @@ def symlink_single_version(self):

# Create symlink
if version is not None:
docs_dir = os.path.join(settings.DOCROOT, self.project.slug,
'rtd-builds', version.slug)
run(['ln', '-nsf', docs_dir, symlink])
docs_dir = os.path.join(
settings.DOCROOT,
self.project.slug,
'rtd-builds',
version.slug
)
self.environment.run('ln', '-nsf', docs_dir, symlink)

def symlink_versions(self):
"""
Expand All @@ -280,7 +307,9 @@ def symlink_versions(self):
HOME/user_builds/<project>/rtd-builds/<version>
"""
versions = set()
version_dir = os.path.join(self.WEB_ROOT, self.project.slug, self.project.language)
version_dir = os.path.join(
self.WEB_ROOT, self.project.slug, self.project.language
)
# Include active public versions,
# as well as public versions that are built but not active, for archived versions
version_queryset = self.get_version_queryset()
Expand All @@ -289,11 +318,21 @@ def symlink_versions(self):
safe_makedirs(version_dir)
for version in version_queryset:
log_msg = 'Symlinking Version: {}'.format(version)
log.info(constants.LOG_TEMPLATE.format(project=self.project.slug,
version='', msg=log_msg))
log.info(
constants.LOG_TEMPLATE.format(
project=self.project.slug,
version='',
msg=log_msg
)
)
symlink = os.path.join(version_dir, version.slug)
docs_dir = os.path.join(settings.DOCROOT, self.project.slug, 'rtd-builds', version.slug)
run(['ln', '-nsf', docs_dir, symlink])
docs_dir = os.path.join(
settings.DOCROOT,
self.project.slug,
'rtd-builds',
version.slug
)
self.environment.run('ln', '-nsf', docs_dir, symlink)
versions.add(version.slug)

# Remove old symlinks
Expand Down
94 changes: 6 additions & 88 deletions readthedocs/projects/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
"""Utility functions used by projects."""

from __future__ import (
absolute_import, division, print_function, unicode_literals)
absolute_import,
division,
print_function,
unicode_literals,
)

import fnmatch
import logging
import os
import subprocess
import traceback

import six
from builtins import object, open
from builtins import open
from django.conf import settings

log = logging.getLogger(__name__)
Expand All @@ -32,82 +32,6 @@ def version_from_slug(slug, version):
return v


def find_file(filename):
"""
Recursively find matching file from the current working path.
:param file: Filename to match
:returns: A list of matching filenames.
"""
matches = []
for root, __, filenames in os.walk('.'):
for match in fnmatch.filter(filenames, filename):
matches.append(os.path.join(root, match))
return matches


def run(*commands):
"""
Run one or more commands.
Each argument in `commands` can be passed as a string or as a list. Passing
as a list is the preferred method, as space escaping is more explicit and it
avoids the need for executing anything in a shell.
If more than one command is given, then this is equivalent to
chaining them together with ``&&``; if all commands succeed, then
``(status, out, err)`` will represent the last successful command.
If one command failed, then ``(status, out, err)`` will represent
the failed command.
:returns: ``(status, out, err)``
"""
environment = os.environ.copy()
environment['READTHEDOCS'] = 'True'
if 'DJANGO_SETTINGS_MODULE' in environment:
del environment['DJANGO_SETTINGS_MODULE']
if 'PYTHONPATH' in environment:
del environment['PYTHONPATH']
# Remove PYTHONHOME env variable if set, otherwise pip install of requirements
# into virtualenv will install incorrectly
if 'PYTHONHOME' in environment:
del environment['PYTHONHOME']
cwd = os.getcwd()
if not commands:
raise ValueError('run() requires one or more command-line strings')

for command in commands:
# If command is a string, split it up by spaces to pass into Popen.
# Otherwise treat the command as an iterable.
if isinstance(command, six.string_types):
run_command = command.split()
else:
try:
run_command = list(command)
command = ' '.join(command)
except TypeError:
run_command = command
log.debug('Running command: cwd=%s command=%s', cwd, command)
try:
p = subprocess.Popen(
run_command,
cwd=cwd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=environment,
)

out, err = p.communicate()
ret = p.returncode
except OSError:
out = ''
err = traceback.format_exc()
ret = -1
log.exception('Command failed')

return (ret, out, err)


def safe_write(filename, contents):
"""
Normalize and write to filename.
Expand All @@ -126,9 +50,3 @@ def safe_write(filename, contents):
with open(filename, 'w', encoding='utf-8', errors='ignore') as fh:
fh.write(contents)
fh.close()


class DictObj(object):

def __getattr__(self, attr):
return self.__dict__.get(attr)

0 comments on commit 273776c

Please sign in to comment.