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-virtualenvs.py
Go to the documentation of this file.
1##
2# @package pyenv-virtualenvs
3# @file pyenv-virtualenvs.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 list the installed Python versions and
11# virtual environments. In addition the Project properties will
12# be listed and its locations will be displayed in a folder tree.
13#
14
15# --- IMPORTS ----------------------------------------------------------
16
17# Python
18import argparse
19import os
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.hlp as hlp
44import lib.log as log
45import lib.tbl as tbl
46
47
48# --- RUN ---------------------------------------------------------------
49
50## Sub routine to run the application.
51#
52# @param args Parsed command line arguments of this application.
53# @return RC = 0 or other values in case of error.
54def run(args: argparse.Namespace) -> int:
55 rc: int = 0
56 cwd = os.getcwd()
57 # noinspection PyBroadException
58 try:
59 while True:
61 'Listing Python virtual environments in "pyenv".'
62 )
63 log.verbose('Determining Python versions ...')
64 # Determine Python version, which is capable
65 # to install Python virtual environment.
66 versions_dir = os.path.join(
67 os.environ['PYENV_ROOT'],
68 'versions'
69 )
70 if not os.path.isdir(versions_dir):
71 log.error('Cannot find any Python version in "pyenv".')
72 log.info('Install a Python version 3.3+ into "pyenv".')
73 # noinspection PyUnusedLocal
74 rc = 1
75 break
77 '*',
78 venv_capable=False,
79 as_paths=True
80 )
81 if len(vers) == 0:
82 log.error('Cannot find a Python version in "pyenv".')
83 log.info('Install a Python version 3.3+ into "pyenv".')
84 # noinspection PyUnusedLocal
85 rc = 1
86 break
87 per = os.environ['PYENV_ROOT']
88 # Pass 1: Collect the Python versions.
89 pyts = [
90 [tbl.HEADER, 'A', 'Venv-Capable', 'Version', '"pyenv" Location'],
91 [tbl.SEPARATOR]
92 ]
93 for ver in vers:
94 pyts_item = [
95 tbl.DATA,
98 os.path.basename(ver),
99 '%PYENV_ROOT%' + os.sep + ver[len(per):]
100 ]
101 pyts.append(pyts_item)
102 # End for
103 pyts.append([tbl.SEPARATOR])
104 # Pass 2: Collect the virtual environments.
105 pves = [
106 [tbl.HEADER, 'A', 'Version', 'Name', '"pyenv" Location'],
107 [tbl.SEPARATOR]
108 ]
109 for ver in vers:
110 venvs = hlp.getEnvs(ver,'*', as_paths=True)
111 for venv in venvs:
112 act = ' '
113 if (
114 ('PROMPT' in os.environ)
115 and
116 ('({})'.format(os.path.basename(venv)) in os.environ['PROMPT'])
117 ):
118 act = '*'
119 pves.append([
120 tbl.DATA,
121 act,
122 os.path.basename(ver),
123 os.path.basename(venv),
124 '%PYENV_ROOT%' + os.sep + venv[len(per):]
125 ])
126 # End for
127 pves.append([tbl.SEPARATOR])
128 # Pass 3: Output list of Python versions.
129 table_pyts = tbl.SimpleTable(
130 pyts,
131 headline='INSTALLED PYTHON VERSIONS (A = active):'
132 )
133 table_pyts.run()
134 # Pass 4: Output list of virtual environments.
135 table_pves = tbl.SimpleTable(
136 pves,
137 headline='AVAILABLE PYTHON VIRTUAL ENVIRONMENTS (A = active):'
138 )
139 table_pves.run()
140 # Output list of project properties (if exists)
141 hlp.listProjectProperties(show_tree=args.tree)
142 log.verbose('Done (RC = {}).'.format(rc))
143 # Go on
144 break
145 # End while
146 except:
147 log.error(sys.exc_info())
148 rc = 1
149 finally:
150 os.chdir(cwd)
151 return rc
152
153
154# --- MAIN --------------------------------------------------------------
155
156## Parse CLI arguments for this application.<br>
157# <br>
158# Implement this as required, but don't touch the interface definition
159# for input and output.
160#
161# @return A tuple of:
162# * Namespace to read arguments in "dot" notation or None
163# in case of help or error.
164# * RC = 0 or another value in case of error.
165def parseCliArguments() -> tuple[(argparse.Namespace, None), int]:
166 rc: int = 0
167 # noinspection PyBroadException
168 try:
169 parser = argparse.ArgumentParser(
170# --- BEGIN CHANGE -----------------------------------------------------
171 prog='pyenv virtualenvs',
172 description='Output lists of Python versions, virtual environments and related project properties.'
173 )
174 # Add flag
175 parser.add_argument(
176 '-t', '--tree',
177 dest='tree',
178 action=argparse.BooleanOptionalAction,
179 help='Display project properties in local folder tree view.'
180)
181# --- END CHANGE -------------------------------------------------------
182 return parser.parse_args(), rc
183 except SystemExit:
184 return None, 0 # -h, --help
185 except:
186 log.error(sys.exc_info())
187 return None, 1
188
189## Main routine of the application.
190#
191# @return RC = 0 or other values in case of error.
192def main() -> int:
193 # noinspection PyBroadException
194 try:
195 while True:
196 # Audit the operating system platform
197 rc = hlp.auditPlatform('Windows')
198 if rc != 0:
199 # Deviation: Reject unsupported platform
200 break
201 # Audit the global Python version number
203 if rc != 0:
204 # Deviation: Reject unsupported Python version
205 break
206 # Initialize the colored logging to console
208 # Audit the "pyenv" version number
209 rc = hlp.auditPyEnv('3')
210 if rc != 0:
211 # Deviation: Reject unsupported "pyenv" version
212 break
213 # Parse arguments
214 log.verbose('Parsing arguments ...')
215 args, rc = parseCliArguments()
216 if rc != 0:
217 break
218 if args is None: # -h, --help
219 break
220 # Run this application
221 log.verbose('Running application ...')
222 rc = run(args)
223 if rc != 0:
224 break
225 # Go on
226 break
227 # End while
228 except Exception as exc:
230 log.error(sys.exc_info())
231 else:
232 print(
233 '\x1b[91mERROR: Unexpected error "%s".\x1b[0m'
234 %
235 str(exc)
236 )
237 rc = 1
238 return rc
239
240
241if __name__ == "__main__":
242 sys.exit(main())
243
244# --- END OF CODE ------------------------------------------------------
245
int listProjectProperties(bool show_tree=False)
Display the table, which shows a list about project properties.
Definition hlp.py:868
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
str getGlobalStar(str ver)
Get the "*" marker for this version, if it is the globally selected version in "pyenv".
Definition hlp.py:375
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] getPythonVersions(str version=' *', bool venv_capable=False, bool as_paths=False)
Get list of installed Python version directories in "pyenv".
Definition hlp.py:500
str getColoredVenvCapability(str ver)
Get the colored virtual environment capability str for the specific version number or path.
Definition hlp.py:481
verbose((str, tuple) msg)
Log verbose message colored to console only.
Definition log.py:209
initLogging()
Initialize the logging.
Definition log.py:71
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 run(argparse.Namespace args)
Sub routine to run the application.
int main()
Main routine of the application.
tuple[(argparse.Namespace, None), int] parseCliArguments()
Parse CLI arguments for this application.