aptivate/dye — pull request #31 by qris (2014-03-22 15:56:43+00:00)
Title: Import only specific values from project_settings into env.

Prevents project_settings from accidentally stomping all over env, for
example overwriting env.path with garbage.

On this Mac, the first remotely executed `sudo` command fails:

[server.compume.qwirx.com:48001] sudo: mkdir -p /var/django/boxcastle
[server.compume.qwirx.com:48001] out: sudo password:
[server.compume.qwirx.com:48001] out: /bin/bash: module: No such file or directory
[server.compume.qwirx.com:48001] out:

Fatal error: sudo() received nonzero return code 1 while executing!

Requested: mkdir -p /var/django/boxcastle
Executed: sudo -S -p 'sudo password:' /bin/bash -l -c "export PATH=\"\$PATH:\"\"\" && mkdir -p /var/django/boxcastle"

Aborting.

The PATH statement added to the environment is clearly absurd (some Python internals instead of a list of directories).

Tracing through, I find that env.path is set wrongly here:

> /Users/chriswilson/projects/boxcastle/django/website/.ve/src/dye/dye/fablib.py(17)_setup_paths()
-> for setting in user_settings:
(Pdb) p user_settings
['repo_type', 'host_list', 'requirements_per_env', 'local_vcs_root', 'project_type', 'relative_ve_dir', 'local_requirements_file', 'project_name', 'server_project_home', 'repository', 'default_branch', 'test_cmd', 'webserver', 'user', 'path', 'local_deploy_dir', 'socket', 'use_virtualenv', 'server_home', 'relative_django_dir', 'django_apps', 'relative_django_settings_dir', 'os']
(Pdb) l
12
13
14	def _setup_paths(project_settings):
15	# first merge in variables from project_settings - but ignore __doc__ etc
16	user_settings = [x for x in vars(project_settings).keys() if not x.startswith('__')]
17 ->	for setting in user_settings:
18	env[setting] = vars(project_settings)[setting]
19
20	# allow for project_settings having set up some of these differently
21	env.setdefault('verbose', False)
22	env.setdefault('use_sudo', True)
(Pdb) p vars(project_settings)['path']

(Pdb) p vars

(Pdb) p project_settings

(Pdb) p project_settings.path

It seems that `fablib.py(17)_setup_paths()` tries to import every single variable defined in `project_settings.py` directly into `env`. And `project_settings.py` does this:

from os import path

which means that `project_settings.path` is defined (it points to the `posixpath` module that we just imported), and it gets stuffed into `env.path`.

We could work around this by undefining `path` at the end of `project_settings.py`. But I think it makes more sense not to wholesale blat the `env` with whatever random crap happens to be in the `project_settings` module.

Either we should be explicit about what we export from it, or simply place a *reference* to `project_settings` in `env`, so that we can access variables from it when needed, without having to constantly be wary of overwriting `env` with anything we do in `project_settings`.

This patch imports only certain specific settings from `project_settings` into `env`. The rest are accessible via `env.project` in custom tasks. Lightly tested.