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(f'"Python {version}" virtual environments "{name}" not found.')
80 log.info(f'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 [tbl.DATA, i + 1, f'\x1b[92m{version1}\x1b[0m', f'\x1b[91m{name1}\x1b[0m', path1]
93 )
94 data.append([tbl.SEPARATOR])
95 # Ensure correct grammar in all dynamic strings
96 plural=''
97 plural1 = 'this'
98 plural2 = 'has'
99 if len(envs) != 1:
100 plural = 's'
101 plural1 = 'these'
102 plural2 = 'have'
103 # Output actual arguments
104 print('')
105 log.notice(f'Deleting {len(envs)} Python virtual environment{plural} from "pyenv":')
106 log.notice(f' * Version: \x1b[0m"\x1b[92m{version}\x1b[0m"')
107 log.notice(f' * Name: \x1b[0m"\x1b[91m{name}\x1b[0m"')
108 # Display list of virtual environments to be deleted
110 data=data,
111 headline=f'\x1b[91mSELECTED PYTHON VIRTUAL ENVIRONMENT{plural.upper()} TO DELETE:\x1b[0m'
112 )
113 table.run()
114 # Let the user decide what to do
115 # noinspection SpellCheckingInspection
116 s = input(f'\x1b[94mDo you really want to delete {plural1} item{plural}?\x1b[0m [\x1b[91myes\x1b[0m/\x1b[92mNo\x1b[0m]: ').strip().lower()
117 if (s == '') or (not s.startswith('y')):
118 rc = 130
119 log.verbose(f'Cancelled (RC = {rc}).')
120 sys.exit(rc)
121 # Delete the selected virtual environments
122 for env in envs:
123 # Remove junctions to this "env"
124 junctions = hlp.getEnvJunctions(env)
125 for junction in junctions:
126 os.remove(junction)
127 # Recursive remove this "env"
128 shutil.rmtree(env)
129 # Log success message
131 f'Matching "{name}", {len(envs)} virtual environment{plural} and its junction{plural} {plural2} been deleted from "pyenv".'
132 )
133 # Go on
134 break
135 # End while
136 except SystemExit:
137 pass
138 except:
139 log.error(sys.exc_info())
140 rc = 1
141 finally:
142 os.chdir(cwd)
143 return rc
144
145
146# --- MAIN --------------------------------------------------------------
147
148## Parse CLI arguments for this application.<br>
149# <br>
150# Implement this as required, but don't touch the interface definition
151# for input and output.
152#
153# @return A tuple of:
154# * Namespace to read arguments in "dot" notation or None
155# in case of help or error.
156# * RC = 0 or another value in case of error.
157def parseCliArguments() -> tuple[(argparse.Namespace, None), int]:
158 rc: int = 0
159 # noinspection PyBroadException
160 try:
161 parser = argparse.ArgumentParser(
162# --- BEGIN CHANGE -----------------------------------------------------
163 prog='pyenv virtualenv-delete',
164 description='Delete existing virtual environment in "pyenv". Wildcards are allowed.'
165 )
166 # Add positional str argument
167 parser.add_argument(
168 'version',
169 help='Python version, which contains the virtual environment you want to delete.'
170 )
171 # Add positional str argument
172 parser.add_argument(
173 'name',
174 help='Short name of the Python virtual environment, which you want to delete.'
175 )
176# --- END CHANGE -------------------------------------------------------
177 return parser.parse_args(), rc
178 except SystemExit:
179 return None, 0
180 except:
181 log.error(sys.exc_info())
182 return None, 1
183
184## Main routine of the application.
185#
186# @return RC = 0 or other values in case of error.
187def main() -> int:
188 # noinspection PyBroadException
189 try:
190 while True:
191 # Audit the operating system platform
192 rc = hlp.auditPlatform('Windows')
193 if rc != 0:
194 # Deviation: Reject unsupported platform
195 break
196 # Audit the global Python version number
198 if rc != 0:
199 # Deviation: Reject unsupported Python version
200 break
201 # Initialize the colored logging to console
203 # Audit the "pyenv" version number
204 rc = hlp.auditPyEnv('3')
205 if rc != 0:
206 # Deviation: Reject unsupported "pyenv" version
207 break
208 # Parse arguments
209 log.verbose('Parsing arguments ...')
210 args, rc = parseCliArguments()
211 if rc != 0:
212 break
213 if args is None: # -h, --help
214 break
215 # Run this application
216 log.verbose('Running application ...')
217 rc = run(args)
218 if rc != 0:
219 break
220 # Go on
221 break
222 # End while
223 except Exception as exc:
225 log.error(sys.exc_info())
226 else:
227 print(
228 '\x1b[91mERROR: Unexpected error "%s".\x1b[0m'
229 %
230 str(exc)
231 )
232 rc = 1
233 return rc
234
235
236if __name__ == "__main__":
237 sys.exit(main())
238
239# --- END OF CODE ------------------------------------------------------
240
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.