pyenv-virtualenv for Windows 1.2
A 'pyenv' plugin to manage Python virtual environments, depending on different Python versions, for various Python projects.
Loading...
Searching...
No Matches
pyenv-virtualenv-delete.py
Go to the documentation of this file.
1##
2# @package pyenv-virtualenv-delete
3# @file pyenv-virtualenv-delete.py
4# @author Michael Paul Korthals
5# @date 2025-07-10
6# @version 1.0.0
7# @copyright © 2025 Michael Paul Korthals. All rights reserved.
8# See License details in the documentation.
9#
10# Utility application to delete a virtual environment from the
11# related Python version.
12#
13
14# --- IMPORTS ----------------------------------------------------------
15
16# Python
17import argparse
18import os
19import shutil
20import sys
21
22# Avoid colored output problems
23os.system('')
24
25# Community
26try:
27 import virtualenv
28except ImportError():
29 print(
30 '\x1b[101mCRITICAL %s\x1b[0m'
31 %
32 'Cannot find package "%s".'
33 %
34 'virtualenv'
35 )
36 print(
37 '\x1b[37mINFO %s\x1b[0m'
38 %
39 'Install it using "pip". Then try again.')
40 import virtualenv
41
42# My
43import lib.log as log
44import lib.hlp as hlp
45import lib.tbl as tbl
46
47# --- RUN ---------------------------------------------------------------
48
49## Sub routine to run the application.
50#
51# @param args Parsed command line arguments of this application.
52# @return RC = 0 or other values in case of error.
53def run(args: argparse.Namespace) -> int:
54 rc: int = 0
55 cwd = os.getcwd()
56 # noinspection PyBroadException
57 try:
58 while True:
59 # Optimize arguments
60 version: str = args.version.strip()
61 name: str = args.name.strip()
62 # Filter version (by wildcard in name)
64 version,
65 venv_capable=True,
66 as_paths=True
67 )
68 envs = []
69 for ver in vers:
70 ver_envs = hlp.getEnvs(
71 ver,
72 name=name,
73 as_paths=True
74 )
75 for env in ver_envs:
76 envs.append(env)
77 # End for
78 if len(envs) == 0:
79 log.warning('"Python {}" virtual environments "{}" not found.'.format(version, name))
80 log.info('Call "pyenv virtualenvs". Then try "pyenv virtualenvs-delete" again, giving correct arguments.')
81 rc = 0
82 break
83 # Load data for table
84 data = [
85 [tbl.HEADER, 'Item', 'Version', 'Name', 'Path'],
86 [tbl.SEPARATOR]
87 ]
88 for i in range(len(envs)):
89 env = envs[i]
90 version1, name1, path1 = hlp.parseEnvDir(env)
91 data.append(
92 [
93 tbl.DATA,
94 i + 1,
95 '\x1b[92m{}\x1b[0m'.format(version1),
96 '\x1b[91m{}\x1b[0m'.format(name1),
97 path1
98 ]
99 )
100 data.append([tbl.SEPARATOR])
101 # Ensure correct grammar in all dynamic strings
102 plural=''
103 plural1 = 'this'
104 plural2 = 'has'
105 if len(envs) != 1:
106 plural = 's'
107 plural1 = 'these'
108 plural2 = 'have'
109 # Output actual arguments
110 print('')
111 log.notice('Deleting {} Python virtual environment{} from "pyenv":'.format(len(envs), plural))
112 log.notice(' * Version: \x1b[0m"\x1b[92m{}\x1b[0m"'.format(version))
113 log.notice(' * Name: \x1b[0m"\x1b[91m{}\x1b[0m"'.format(name))
114 # Display list of virtual environments to be deleted
116 data=data,
117 headline='\x1b[91mSELECTED PYTHON VIRTUAL ENVIRONMENT{} TO DELETE:\x1b[0m'.format(plural.upper())
118 )
119 table.run()
120 # Let the user decide what to do
121 # noinspection SpellCheckingInspection
122 s = input('\x1b[94mDo you really want to delete {} item{}?\x1b[0m [\x1b[91myes\x1b[0m/\x1b[92mNo\x1b[0m]: '.format(plural1, plural)).strip().lower()
123 if (s == '') or (not s.startswith('y')):
124 rc = 130
125 log.verbose('Cancelled (RC = {}).'.format(rc))
126 sys.exit(rc)
127 # Delete the selected virtual environments
128 for env in envs:
129 # Remove junctions to this "env"
130 junctions = hlp.getEnvJunctions(env)
131 for junction in junctions:
132 os.remove(junction)
133 # Recursive remove this "env"
134 shutil.rmtree(env)
135 # Log success message
137 'Matching "{}", {} virtual environment{} and its junction{} {} been deleted from "pyenv".'.format(
138 name,
139 len(envs),
140 plural,
141 plural,
142 plural2
143 )
144 )
145 # Go on
146 break
147 # End while
148 except SystemExit:
149 pass
150 except:
151 log.error(sys.exc_info())
152 rc = 1
153 finally:
154 os.chdir(cwd)
155 return rc
156
157
158# --- MAIN --------------------------------------------------------------
159
160## Parse CLI arguments for this application.<br>
161# <br>
162# Implement this as required, but don't touch the interface definition
163# for input and output.
164#
165# @return A tuple of:
166# * Namespace to read arguments in "dot" notation or None
167# in case of help or error.
168# * RC = 0 or another value in case of error.
169def parseCliArguments() -> tuple[(argparse.Namespace, None), int]:
170 rc: int = 0
171 # noinspection PyBroadException
172 try:
173 parser = argparse.ArgumentParser(
174# --- BEGIN CHANGE -----------------------------------------------------
175 prog='pyenv virtualenv-delete',
176 description='Delete existing virtual environment in "pyenv". Wildcards are allowed.'
177 )
178 # Add positional str argument
179 parser.add_argument(
180 'version',
181 help='Python version, which contains the virtual environment you want to delete.'
182 )
183 # Add positional str argument
184 parser.add_argument(
185 'name',
186 help='Short name of the Python virtual environment, which you want to delete.'
187 )
188# --- END CHANGE -------------------------------------------------------
189 return parser.parse_args(), rc
190 except SystemExit:
191 return None, 0
192 except:
193 log.error(sys.exc_info())
194 return None, 1
195
196## Main routine of the application.
197#
198# @return RC = 0 or other values in case of error.
199def main() -> int:
200 # noinspection PyBroadException
201 try:
202 while True:
203 # Audit the operating system platform
204 rc = hlp.auditPlatform('Windows')
205 if rc != 0:
206 # Deviation: Reject unsupported platform
207 break
208 # Audit the global Python version number
210 if rc != 0:
211 # Deviation: Reject unsupported Python version
212 break
213 # Initialize the colored logging to console
215 # Audit the "pyenv" version number
216 rc = hlp.auditPyEnv('3')
217 if rc != 0:
218 # Deviation: Reject unsupported "pyenv" version
219 break
220 # Parse arguments
221 log.verbose('Parsing arguments ...')
222 args, rc = parseCliArguments()
223 if rc != 0:
224 break
225 if args is None: # -h, --help
226 break
227 # Run this application
228 log.verbose('Running application ...')
229 rc = run(args)
230 if rc != 0:
231 break
232 # Go on
233 break
234 # End while
235 except Exception as exc:
237 log.error(sys.exc_info())
238 else:
239 print(
240 '\x1b[91mERROR: Unexpected error "%s".\x1b[0m'
241 %
242 str(exc)
243 )
244 rc = 1
245 return rc
246
247
248if __name__ == "__main__":
249 sys.exit(main())
250
251# --- END OF CODE ------------------------------------------------------
252
int auditPyEnv(str min_ver)
Check if "pyenv" version is greater or equal the given minimal version.
Definition hlp.py:213
int auditGlobalPythonVersion(str min_ver)
Check if Python version is greater or equal the given minimal version.
Definition hlp.py:148
int auditPlatform(str name)
Check if the program in running on the required platform.
Definition hlp.py:85
tuple[str, str, str] parseEnvDir(str env_dir)
Parse virtual environment directory path.
Definition hlp.py:819
list[str] getEnvs(str ver, str name=' *', bool as_paths=False)
Get list of installed virtual environments for a specific Python version in "pyenv".
Definition hlp.py:718
list[str] getEnvJunctions(str path)
Scan the Pythons versions in "pyenv" for junctions, which points to a specific virtual environment di...
Definition hlp.py:561
list[str] getPythonVersions(str version=' *', bool venv_capable=False, bool as_paths=False)
Get list of installed Python version directories in "pyenv".
Definition hlp.py:500
warning((str, tuple) msg)
Log warning message colored to console only.
Definition log.py:191
notice((str, tuple) msg)
Log notice message colored to console only.
Definition log.py:197
verbose((str, tuple) msg)
Log verbose message colored to console only.
Definition log.py:209
initLogging()
Initialize the logging.
Definition log.py:71
success((str, tuple) msg)
Log success message colored to console only.
Definition log.py:185
bool isInitialized()
Definition log.py:90
info((str, tuple) msg)
Log info message colored to console only.
Definition log.py:203
error((str, tuple) msg)
Log error message colored to console only.
Definition log.py:179
int main()
Main routine of the application.
int run(argparse.Namespace args)
Sub routine to run the application.
tuple[(argparse.Namespace, None), int] parseCliArguments()
Parse CLI arguments for this application.