Skip to content
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

Update readthedocs-environment.json file when env vars are added/deleted #5540

Merged
merged 14 commits into from
Apr 22, 2019
13 changes: 13 additions & 0 deletions readthedocs/doc_builder/python_environments.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def is_obsolete(self):
* the Python version (e.g. 2.7, 3, 3.6, etc)
* the Docker image name
* the Docker image hash
* the environment variables hash

:returns: ``True`` when it's obsolete and ``False`` otherwise

Expand All @@ -174,6 +175,7 @@ def is_obsolete(self):

env_python = environment_conf.get('python', {})
env_build = environment_conf.get('build', {})
envvars_hash = environment_conf.get('envvars_hash', None)
dojutsu-user marked this conversation as resolved.
Show resolved Hide resolved

# By defaulting non-existent options to ``None`` we force a wipe since
# we don't know how the environment was created
Expand All @@ -193,12 +195,18 @@ def is_obsolete(self):
# (e.g. ``2`` or ``3``) we won't know exactly which exact version was
# used to create the venv but we can still compare it against the new
# one coming from the project version config.
print(envvars_hash, self._get_envvars_hash())
dojutsu-user marked this conversation as resolved.
Show resolved Hide resolved
return any([
env_python_version != self.config.python_full_version,
env_build_image != build_image,
env_build_hash != image_hash,
envvars_hash != self._get_envvars_hash(),
])

def _get_envvars_hash(self):
env_vars = self.version.project.environmentvariable_set.values_list('name', 'value')
dojutsu-user marked this conversation as resolved.
Show resolved Hide resolved
return hash(tuple(env_vars))

def save_environment_json(self):
"""
Save on builders disk data about the environment used to build docs.
Expand All @@ -208,6 +216,7 @@ def save_environment_json(self):
- python.version
- build.image
- build.hash
- envvars_hash
"""
data = {
'python': {
Expand All @@ -224,6 +233,10 @@ def save_environment_json(self):
},
})

data.update({
'envvars_hash': self._get_envvars_hash(),
dojutsu-user marked this conversation as resolved.
Show resolved Hide resolved
})

with open(self.environment_json_path(), 'w') as fpath:
# Compatibility for Py2 and Py3. ``io.TextIOWrapper`` expects
# unicode but ``json.dumps`` returns str in Py2.
Expand Down
9 changes: 7 additions & 2 deletions readthedocs/rtd_tests/tests/test_doc_building.py
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,9 @@ def test_save_environment_json(self, load_config):
python_env.save_environment_json()
json_data = json.load(open(python_env.environment_json_path()))

envvars = self.version.project.environmentvariable_set.values_list('name', 'value')
envvars_hash = hash(tuple(envvars))
dojutsu-user marked this conversation as resolved.
Show resolved Hide resolved

expected_data = {
'build': {
'image': 'readthedocs/build:2.0',
Expand All @@ -1484,6 +1487,7 @@ def test_save_environment_json(self, load_config):
'python': {
'version': 2.7,
},
'envvars_hash': envvars_hash
}
self.assertDictEqual(json_data, expected_data)

Expand Down Expand Up @@ -1610,9 +1614,10 @@ def test_is_obsolete_with_json_same_data_as_version(self, load_config):
build_env=self.build_env,
config=config,
)
env_json_data = '{"build": {"image": "readthedocs/build:2.0", "hash": "a1b2c3"}, "python": {"version": 3.5}}' # noqa
with patch('os.path.exists') as exists, patch('readthedocs.doc_builder.python_environments.open', mock_open(read_data=env_json_data)) as _open: # noqa
env_json_data = '{"build": {"image": "readthedocs/build:2.0", "hash": "a1b2c3"}, "python": {"version": 3.5}, "envvars_hash": 1234}' # noqa
with patch('os.path.exists') as exists, patch('readthedocs.doc_builder.python_environments.PythonEnvironment._get_envvars_hash') as get_hash, patch('readthedocs.doc_builder.python_environments.open', mock_open(read_data=env_json_data)) as _open: # noqa
dojutsu-user marked this conversation as resolved.
Show resolved Hide resolved
exists.return_value = True
get_hash.return_value = 1234
self.assertFalse(python_env.is_obsolete)

@mock.patch('readthedocs.doc_builder.config.load_config')
Expand Down