Skip to content

Commit 273776c

Browse files
authored
Merge pull request #4929 from stsewd/remove-repeated-code
Remove repeated and dead code
2 parents 4ba947a + 54b5372 commit 273776c

File tree

2 files changed

+72
-115
lines changed

2 files changed

+72
-115
lines changed

readthedocs/core/symlink.py

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,27 @@
5252
fabric -> rtd-builds/fabric/en/latest/ # single version
5353
"""
5454

55-
from __future__ import absolute_import, unicode_literals
56-
from builtins import object
55+
from __future__ import (
56+
absolute_import,
57+
division,
58+
print_function,
59+
unicode_literals,
60+
)
61+
62+
import logging
5763
import os
5864
import shutil
59-
import logging
6065
from collections import OrderedDict
6166

67+
from builtins import object
6268
from django.conf import settings
6369

6470
from readthedocs.builds.models import Version
65-
from readthedocs.core.utils.extend import SettingsOverrideObject
6671
from readthedocs.core.utils import safe_makedirs, safe_unlink
72+
from readthedocs.core.utils.extend import SettingsOverrideObject
73+
from readthedocs.doc_builder.environments import LocalEnvironment
6774
from readthedocs.projects import constants
6875
from readthedocs.projects.models import Domain
69-
from readthedocs.projects.utils import run
7076

7177
log = logging.getLogger(__name__)
7278

@@ -83,6 +89,7 @@ def __init__(self, project):
8389
self.subproject_root = os.path.join(
8490
self.project_root, 'projects'
8591
)
92+
self.environment = LocalEnvironment(project)
8693
self.sanity_check()
8794

8895
def sanity_check(self):
@@ -146,17 +153,27 @@ def symlink_cnames(self, domain=None):
146153
else:
147154
domains = Domain.objects.filter(project=self.project)
148155
for dom in domains:
149-
log_msg = 'Symlinking CNAME: {0} -> {1}'.format(dom.domain, self.project.slug)
150-
log.info(constants.LOG_TEMPLATE.format(project=self.project.slug,
151-
version='', msg=log_msg))
156+
log_msg = 'Symlinking CNAME: {} -> {}'.format(
157+
dom.domain, self.project.slug
158+
)
159+
log.info(
160+
constants.LOG_TEMPLATE.format(
161+
project=self.project.slug,
162+
version='', msg=log_msg
163+
)
164+
)
152165

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

157170
# Project symlink
158-
project_cname_symlink = os.path.join(self.PROJECT_CNAME_ROOT, dom.domain)
159-
run(['ln', '-nsf', self.project.doc_path, project_cname_symlink])
171+
project_cname_symlink = os.path.join(
172+
self.PROJECT_CNAME_ROOT, dom.domain
173+
)
174+
self.environment.run(
175+
'ln', '-nsf', self.project.doc_path, project_cname_symlink
176+
)
160177

161178
def remove_symlink_cname(self, domain):
162179
"""Remove CNAME symlink."""
@@ -201,10 +218,12 @@ def symlink_subprojects(self):
201218
# TODO this should use os.symlink, not a call to shell. For now,
202219
# this passes command as a list to be explicit about escaping
203220
# characters like spaces.
204-
status, _, stderr = run(['ln', '-nsf', docs_dir, symlink])
205-
if status > 0:
206-
log.error('Could not symlink path: status=%d error=%s',
207-
status, stderr)
221+
result = self.environment.run('ln', '-nsf', docs_dir, symlink)
222+
if result.exit_code > 0:
223+
log.error(
224+
'Could not symlink path: status=%d error=%s',
225+
result.exit_code, result.error
226+
)
208227

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

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

236-
log_msg = 'Symlinking translation: {0}->{1}'.format(language, slug)
237-
log.info(constants.LOG_TEMPLATE.format(project=self.project.slug,
238-
version='', msg=log_msg))
255+
log_msg = 'Symlinking translation: {}->{}'.format(language, slug)
256+
log.info(
257+
constants.LOG_TEMPLATE.format(
258+
project=self.project.slug,
259+
version='', msg=log_msg
260+
)
261+
)
239262
symlink = os.path.join(self.project_root, language)
240263
docs_dir = os.path.join(self.WEB_ROOT, slug, language)
241-
run(['ln', '-nsf', docs_dir, symlink])
264+
self.environment.run('ln', '-nsf', docs_dir, symlink)
242265

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

269292
# Create symlink
270293
if version is not None:
271-
docs_dir = os.path.join(settings.DOCROOT, self.project.slug,
272-
'rtd-builds', version.slug)
273-
run(['ln', '-nsf', docs_dir, symlink])
294+
docs_dir = os.path.join(
295+
settings.DOCROOT,
296+
self.project.slug,
297+
'rtd-builds',
298+
version.slug
299+
)
300+
self.environment.run('ln', '-nsf', docs_dir, symlink)
274301

275302
def symlink_versions(self):
276303
"""
@@ -280,7 +307,9 @@ def symlink_versions(self):
280307
HOME/user_builds/<project>/rtd-builds/<version>
281308
"""
282309
versions = set()
283-
version_dir = os.path.join(self.WEB_ROOT, self.project.slug, self.project.language)
310+
version_dir = os.path.join(
311+
self.WEB_ROOT, self.project.slug, self.project.language
312+
)
284313
# Include active public versions,
285314
# as well as public versions that are built but not active, for archived versions
286315
version_queryset = self.get_version_queryset()
@@ -289,11 +318,21 @@ def symlink_versions(self):
289318
safe_makedirs(version_dir)
290319
for version in version_queryset:
291320
log_msg = 'Symlinking Version: {}'.format(version)
292-
log.info(constants.LOG_TEMPLATE.format(project=self.project.slug,
293-
version='', msg=log_msg))
321+
log.info(
322+
constants.LOG_TEMPLATE.format(
323+
project=self.project.slug,
324+
version='',
325+
msg=log_msg
326+
)
327+
)
294328
symlink = os.path.join(version_dir, version.slug)
295-
docs_dir = os.path.join(settings.DOCROOT, self.project.slug, 'rtd-builds', version.slug)
296-
run(['ln', '-nsf', docs_dir, symlink])
329+
docs_dir = os.path.join(
330+
settings.DOCROOT,
331+
self.project.slug,
332+
'rtd-builds',
333+
version.slug
334+
)
335+
self.environment.run('ln', '-nsf', docs_dir, symlink)
297336
versions.add(version.slug)
298337

299338
# Remove old symlinks

readthedocs/projects/utils.py

Lines changed: 6 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
"""Utility functions used by projects."""
33

44
from __future__ import (
5-
absolute_import, division, print_function, unicode_literals)
5+
absolute_import,
6+
division,
7+
print_function,
8+
unicode_literals,
9+
)
610

7-
import fnmatch
811
import logging
912
import os
10-
import subprocess
11-
import traceback
1213

13-
import six
14-
from builtins import object, open
14+
from builtins import open
1515
from django.conf import settings
1616

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

3434

35-
def find_file(filename):
36-
"""
37-
Recursively find matching file from the current working path.
38-
39-
:param file: Filename to match
40-
:returns: A list of matching filenames.
41-
"""
42-
matches = []
43-
for root, __, filenames in os.walk('.'):
44-
for match in fnmatch.filter(filenames, filename):
45-
matches.append(os.path.join(root, match))
46-
return matches
47-
48-
49-
def run(*commands):
50-
"""
51-
Run one or more commands.
52-
53-
Each argument in `commands` can be passed as a string or as a list. Passing
54-
as a list is the preferred method, as space escaping is more explicit and it
55-
avoids the need for executing anything in a shell.
56-
57-
If more than one command is given, then this is equivalent to
58-
chaining them together with ``&&``; if all commands succeed, then
59-
``(status, out, err)`` will represent the last successful command.
60-
If one command failed, then ``(status, out, err)`` will represent
61-
the failed command.
62-
63-
:returns: ``(status, out, err)``
64-
"""
65-
environment = os.environ.copy()
66-
environment['READTHEDOCS'] = 'True'
67-
if 'DJANGO_SETTINGS_MODULE' in environment:
68-
del environment['DJANGO_SETTINGS_MODULE']
69-
if 'PYTHONPATH' in environment:
70-
del environment['PYTHONPATH']
71-
# Remove PYTHONHOME env variable if set, otherwise pip install of requirements
72-
# into virtualenv will install incorrectly
73-
if 'PYTHONHOME' in environment:
74-
del environment['PYTHONHOME']
75-
cwd = os.getcwd()
76-
if not commands:
77-
raise ValueError('run() requires one or more command-line strings')
78-
79-
for command in commands:
80-
# If command is a string, split it up by spaces to pass into Popen.
81-
# Otherwise treat the command as an iterable.
82-
if isinstance(command, six.string_types):
83-
run_command = command.split()
84-
else:
85-
try:
86-
run_command = list(command)
87-
command = ' '.join(command)
88-
except TypeError:
89-
run_command = command
90-
log.debug('Running command: cwd=%s command=%s', cwd, command)
91-
try:
92-
p = subprocess.Popen(
93-
run_command,
94-
cwd=cwd,
95-
stdout=subprocess.PIPE,
96-
stderr=subprocess.PIPE,
97-
env=environment,
98-
)
99-
100-
out, err = p.communicate()
101-
ret = p.returncode
102-
except OSError:
103-
out = ''
104-
err = traceback.format_exc()
105-
ret = -1
106-
log.exception('Command failed')
107-
108-
return (ret, out, err)
109-
110-
11135
def safe_write(filename, contents):
11236
"""
11337
Normalize and write to filename.
@@ -126,9 +50,3 @@ def safe_write(filename, contents):
12650
with open(filename, 'w', encoding='utf-8', errors='ignore') as fh:
12751
fh.write(contents)
12852
fh.close()
129-
130-
131-
class DictObj(object):
132-
133-
def __getattr__(self, attr):
134-
return self.__dict__.get(attr)

0 commit comments

Comments
 (0)