Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.4k
GH-83417: Allowvenv
to add a.gitignore
file to environments via a newscm_ignore_file
parameter#108125
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
GH-83417: Allowvenv
to add a.gitignore
file to environments via a newscm_ignore_file
parameter#108125
Changes from1 commit
f889dc6
1faf4b0
31d0558
41e541c
ce17684
90eb700
c3b96e0
a8528dd
ddc2225
547879d
8ba65b5
f75b26c
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
Off by default via code but on by default via the CLI, the `.gitignore` file contains `*` which causes the entire directory to be ignored.
- Loading branch information
Uh oh!
There was an error while loading.Please reload this page.
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -143,7 +143,7 @@ creation according to their needs, the :class:`EnvBuilder` class. | ||
.. class:: EnvBuilder(system_site_packages=False, clear=False, \ | ||
symlinks=False, upgrade=False, with_pip=False, \ | ||
prompt=None, upgrade_deps=False, \*, gitignore=False) | ||
brettcannon marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page.
brettcannon marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
The :class:`EnvBuilder` class accepts the following keyword arguments on | ||
instantiation: | ||
@@ -172,6 +172,10 @@ creation according to their needs, the :class:`EnvBuilder` class. | ||
* ``upgrade_deps`` -- Update the base venv modules to the latest on PyPI | ||
* ``gitignore`` -- a Boolean value which, if true, will create a | ||
brettcannon marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
``.gitignore`` file in the target directory, containing ``*`` to have the | ||
environment ignored by git. | ||
.. versionchanged:: 3.4 | ||
Added the ``with_pip`` parameter | ||
@@ -181,6 +185,9 @@ creation according to their needs, the :class:`EnvBuilder` class. | ||
.. versionadded:: 3.9 | ||
Added the ``upgrade_deps`` parameter | ||
.. versionadded:: 3.13 | ||
Added the ``gitignore`` parameter | ||
Creators of third-party virtual environment tools will be free to use the | ||
provided :class:`EnvBuilder` class as a base class. | ||
@@ -343,7 +350,7 @@ There is also a module-level convenience function: | ||
.. function:: create(env_dir, system_site_packages=False, clear=False, \ | ||
symlinks=False, with_pip=False, prompt=None, \ | ||
upgrade_deps=False, \*, gitignore=False) | ||
brettcannon marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
Create an :class:`EnvBuilder` with the given keyword arguments, and call its | ||
:meth:`~EnvBuilder.create` method with the *env_dir* argument. | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -137,7 +137,8 @@ def _check_output_of_default_create(self): | ||
self.assertIn('executable = %s' % | ||
os.path.realpath(sys.executable), data) | ||
copies = '' if os.name=='nt' else ' --copies' | ||
cmd = (f'command = {sys.executable} -m venv{copies} --without-pip ' | ||
f'--without-gitignore {self.env_dir}') | ||
self.assertIn(cmd, data) | ||
fn = self.get_env_file(self.bindir, self.exe) | ||
if not os.path.exists(fn): # diagnostics for Windows buildbot failures | ||
@@ -156,14 +157,16 @@ def test_config_file_command_key(self): | ||
('upgrade', '--upgrade'), | ||
('upgrade_deps', '--upgrade-deps'), | ||
('prompt', '--prompt'), | ||
('gitignore', '--without-gitignore'), | ||
] | ||
negated_attrs = {'with_pip', 'symlinks', 'gitignore'} | ||
for attr, opt in attrs: | ||
rmtree(self.env_dir) | ||
if not attr: | ||
b = venv.EnvBuilder() | ||
else: | ||
b = venv.EnvBuilder( | ||
**{attr: False if attr innegated_attrs else True}) | ||
brettcannon marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
b.upgrade_dependencies = Mock() # avoid pip command to upgrade deps | ||
b._setup_pip = Mock() # avoid pip setup | ||
self.run_with_capture(b.create, self.env_dir) | ||
@@ -586,6 +589,7 @@ def test_zippath_from_non_installed_posix(self): | ||
"-m", | ||
"venv", | ||
"--without-pip", | ||
"--without-gitignore", | ||
self.env_dir] | ||
# Our fake non-installed python is not fully functional because | ||
# it cannot find the extensions. Set PYTHONPATH so it can run the | ||
@@ -633,6 +637,16 @@ def test_activate_shell_script_has_no_dos_newlines(self): | ||
error_message = f"CR LF found in line {i}" | ||
self.assertFalse(line.endswith(b'\r\n'), error_message) | ||
def test_gitignore(self): | ||
""" | ||
Test that a .gitignore file is created when requested. | ||
The file should contain a `*\n` line. | ||
""" | ||
self.run_with_capture(venv.create, self.env_dir, gitignore=True) | ||
file_lines = self.get_text_file_contents('.gitignore').splitlines() | ||
self.assertIn('*', file_lines) | ||
@requireVenvCreate | ||
class EnsurePipTest(BaseTest): | ||
"""Test venv module installation of pip.""" | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -41,11 +41,13 @@ class EnvBuilder: | ||
environment | ||
:param prompt: Alternative terminal prefix for the environment. | ||
:param upgrade_deps: Update the base venv modules to the latest on PyPI | ||
:param gitignore: Create a .gitignore file in the environment directory | ||
which causes it to be ignored by git. | ||
""" | ||
def __init__(self, system_site_packages=False, clear=False, | ||
symlinks=False, upgrade=False, with_pip=False, prompt=None, | ||
upgrade_deps=False, *, gitignore=False): | ||
AA-Turner marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
self.system_site_packages = system_site_packages | ||
self.clear = clear | ||
self.symlinks = symlinks | ||
@@ -56,6 +58,7 @@ def __init__(self, system_site_packages=False, clear=False, | ||
prompt = os.path.basename(os.getcwd()) | ||
self.prompt = prompt | ||
self.upgrade_deps = upgrade_deps | ||
self.gitignore = gitignore | ||
def create(self, env_dir): | ||
""" | ||
@@ -66,6 +69,8 @@ def create(self, env_dir): | ||
""" | ||
env_dir = os.path.abspath(env_dir) | ||
context = self.ensure_directories(env_dir) | ||
if self.gitignore: | ||
self._setup_gitignore(context) | ||
# See issue 24875. We need system_site_packages to be False | ||
# until after pip is installed. | ||
true_system_site_packages = self.system_site_packages | ||
@@ -210,6 +215,8 @@ def create_configuration(self, context): | ||
args.append('--upgrade-deps') | ||
if self.orig_prompt is not None: | ||
args.append(f'--prompt="{self.orig_prompt}"') | ||
if not self.gitignore: | ||
args.append('--without-gitignore') | ||
args.append(context.env_dir) | ||
args = ' '.join(args) | ||
@@ -278,6 +285,19 @@ def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): | ||
shutil.copyfile(src, dst) | ||
def _setup_gitignore(self, context): | ||
""" | ||
Create a .gitignore file in the environment directory. | ||
The contents of the file cause the entire environment directory to be | ||
ignored by git. | ||
""" | ||
gitignore_path = os.path.join(context.env_dir, '.gitignore') | ||
with open(gitignore_path, 'w', encoding='utf-8') as file: | ||
file.write('# Created by venv; ' | ||
'see https://docs.python.org/3/library/venv.html\n') | ||
file.write('*\n') | ||
def setup_python(self, context): | ||
""" | ||
Set up a Python executable in the environment. | ||
@@ -461,11 +481,13 @@ def upgrade_dependencies(self, context): | ||
def create(env_dir, system_site_packages=False, clear=False, | ||
symlinks=False, with_pip=False, prompt=None, upgrade_deps=False, | ||
*, gitignore=False): | ||
"""Create a virtual environment in a directory.""" | ||
builder = EnvBuilder(system_site_packages=system_site_packages, | ||
clear=clear, symlinks=symlinks, with_pip=with_pip, | ||
prompt=prompt, upgrade_deps=upgrade_deps, | ||
gitignore=gitignore) | ||
builder.create(env_dir) | ||
@@ -525,6 +547,11 @@ def main(args=None): | ||
dest='upgrade_deps', | ||
help=f'Upgrade core dependencies ({", ".join(CORE_VENV_DEPS)}) ' | ||
'to the latest version in PyPI') | ||
parser.add_argument('--without-gitignore', dest='gitignore', | ||
default=True, action='store_false', | ||
help='Skips adding a .gitignore file to the ' | ||
'environment directory which causes git to ignore ' | ||
'the environment directory.') | ||
options = parser.parse_args(args) | ||
if options.upgrade and options.clear: | ||
raise ValueError('you cannot supply --upgrade and --clear together.') | ||
@@ -534,7 +561,8 @@ def main(args=None): | ||
upgrade=options.upgrade, | ||
with_pip=options.with_pip, | ||
prompt=options.prompt, | ||
upgrade_deps=options.upgrade_deps, | ||
gitignore=options.gitignore) | ||
for d in options.dirs: | ||
builder.create(d) | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -6,5 +6,5 @@ | ||
main() | ||
rc = 0 | ||
except Exception as e: | ||
print('Error:', e, file=sys.stderr) | ||
sys.exit(rc) |