Skip to content
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
2 changes: 2 additions & 0 deletions docs/changelog/1806.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Generate ignore file for version control systems to avoid tracking virtual environments by default. Users should
remove these files if still want to track. For now we support only **git** by :user:`gaborbernat`.
4 changes: 3 additions & 1 deletion docs/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ The tool works in two phases:
- **Phase 1** discovers a python interpreter to create a virtual environment from (by default this is the same python
as the one ``virtualenv`` is running from, however we can change this via the :option:`p` option).
- **Phase 2** creates a virtual environment at the specified destination (:option:`dest`), this can be broken down into
three further sub-steps:
four further sub-steps:

- create a python that matches the target python interpreter from phase 1,
- install (bootstrap) seed packages (one or more of :pypi:`pip`, :pypi:`setuptools`, :pypi:`wheel`) in the created
virtual environment,
- install activation scripts into the binary directory of the virtual environment (these will allow end user to
*activate* the virtual environment from various shells).
- create files that mark the virtual environment as to be ignored by version control systems (currently we support
Git only, as Mercurial, Bazaar or SVN does not support ignore files in subdirectories).

The python in your new virtualenv is effectively isolated from the python that was used to create it.

Expand Down
19 changes: 19 additions & 0 deletions src/virtualenv/create/creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from argparse import ArgumentTypeError
from ast import literal_eval
from collections import OrderedDict
from textwrap import dedent

from six import add_metaclass

Expand Down Expand Up @@ -154,6 +155,7 @@ def run(self):
safe_delete(self.dest)
self.create()
self.set_pyenv_cfg()
self.setup_ignore_vcs()

def set_pyenv_cfg(self):
self.pyenv_cfg.content = OrderedDict()
Expand All @@ -162,6 +164,23 @@ def set_pyenv_cfg(self):
self.pyenv_cfg["version_info"] = ".".join(str(i) for i in self.interpreter.version_info)
self.pyenv_cfg["virtualenv"] = __version__

def setup_ignore_vcs(self):
"""Generate ignore instructions for version control systems."""
# mark this folder to be ignored by VCS, handle https://www.python.org/dev/peps/pep-0610/#registered-vcs
(self.dest / ".gitignore").write_text(
dedent(
"""
# created by virtualenv automatically
*
""",
).lstrip(),
)
# Mercurial - does not support the .hgignore file inside a subdirectory directly, but only if included via the
# subinclude directive from root, at which point on might as well ignore the directory itself, see
# https://www.selenic.com/mercurial/hgignore.5.html for more details
# Bazaar - does not support ignore files in sub-directories, only at root level via .bzrignore
# Subversion - does not support ignore files, requires direct manipulation with the svn tool

@property
def debug(self):
"""
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/create/test_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ def list_to_str(iterable):
make_file = debug["makefile_filename"]
assert os.path.exists(make_file)

git_ignore = (dest / ".gitignore").read_text()
assert git_ignore.splitlines() == ["# created by virtualenv automatically", "*"]


@pytest.mark.skipif(not CURRENT.has_venv, reason="requires interpreter with venv")
def test_venv_fails_not_inline(tmp_path, capsys, mocker):
Expand Down