71def fName(natural_name: str) -> str:
73 r"[/\\?$%#+\-*:|\"'<>()\[\]{}\x7F\x00-\x20]",
74 "_", natural_name.strip()
75 ).casefold().strip(
'_')
91 (
'LOG_LEVEL' in os.environ)
93 (int(os.environ[
'LOG_LEVEL']) <= 15)
96 '\x1b[94mVERBOSE 1) Auditing platform is "%s" ...\x1b[0m' % name,
99 if not platform.system() == name:
101 '\x1b[91mERROR Platform "%s" is not supported to execute this program.\x1b[0m' % platform.system(),
105 '\x1b[95mNOTICE Run this program on "%s" only\x1b[0m' % name,
111 '\x1b[94mVERBOSE No deviation detected at observation 1.\x1b[0m',
115 '\x1b[94mVERBOSE Audit result: Zero deviations.\x1b[0m',
123 '\x1b[91mERROR Cancelling program.\x1b[0m',
127 '\x1b[37mINFO See detected deviation and remediation proposals/instructions above.\x1b[0m',
131 except Exception
as exc:
133 '\x1b[91mERROR Unexpected error "%s".\x1b[0m' % str(exc),
154 (
'LOG_LEVEL' in os.environ)
156 (int(os.environ[
'LOG_LEVEL']) <= 15)
159 '\x1b[94mVERBOSE 1) Auditing global Python version is %s+ ...\x1b[0m' % min_ver,
162 tup_cur = tuple(map(int, platform.python_version_tuple()))
163 tup_min = tuple(map(int, tuple(min_ver.split(
'.'))))
164 if tup_cur < tup_min:
166 '\x1b[91mERROR Using outdated "Python %s".\x1b[0m' % (
167 platform.python_version()
172 '\x1b[95mNOTICE Install "Python %s+" into "pyenv". Then try again.\x1b[0m' % (
173 platform.python_version()
180 '\x1b[94mVERBOSE No deviation detected at observation 1.\x1b[0m',
184 '\x1b[94mVERBOSE Audit result: Zero deviations.\x1b[0m',
192 '\x1b[91mERROR Cancelling program.\x1b[0m',
196 '\x1b[95mNOTICE See detected deviation and remediation proposals/instructions above.\x1b[0m',
200 except Exception
as exc:
202 '\x1b[91mERROR Unexpected error "%s".\x1b[0m' % str(exc),
218 log.verbose(
'1) Auditing pyenv and path environment variables are correctly set ...')
220 if not (key
in os.environ):
221 log.error(
'Cannot find environment variable "{}".'.format(key))
223 'Check/install/repair "pyenv". See: "%USERPROFILE%.pyenv". Then try again.'
228 if not (key
in os.environ):
229 log.error(
'Cannot find environment variable "{}".'.format(key))
231 'Check/restart the terminal shell. Then try again. If this doses not help further on, reboot your computer.'
235 path = os.environ[
'PATH'].strip()
237 log.error(
'The PATH environment variable is empty.')
239 'Check/restart the terminal shell. Then try again. If this doses not help further on, reboot your computer.'
243 log.verbose(
'No deviation detected at observation 1.')
244 log.verbose(
'2) Auditing "pyenv" version is {}+ ...'.format(min_ver))
246 if len(current_version) == 0:
247 log.error(
'Cannot determine the "pyenv" version.')
248 log.notice(
'Install/configure "pyenv". Then try again.')
251 tup_cur = tuple(map(int, tuple(current_version.split(
'.'))))
252 tup_min = tuple(map(int, tuple(min_ver.split(
'.'))))
253 if tup_cur < tup_min:
254 log.error(
'"pyenv {}" is not supported.'.format(current_version))
255 log.notice(
'Install/configure "pyenv {}+". Then try again.'.format(min_ver))
258 log.verbose(
'No deviation detected at observation 2.')
259 log.verbose(
'3) Auditing "pyenv" Python versions are virtual environment capable ...')
260 pyenv_root_dir = os.environ[
'PYENV_ROOT']
261 if not os.path.isdir(pyenv_root_dir):
263 'Cannot find "pyenv" root directory "{}".'.format(pyenv_root_dir)
266 'Check/install/repair "pyenv". See: "%USERPROFILE%.pyenv".'
270 log.verbose(
'No deviation detected at observation 3.')
271 log.verbose(
'4) Auditing "pyenv" has virtual environment-capable Python versions ...')
274 versions_dir = os.path.join(
275 os.environ[
'PYENV_ROOT'],
278 if not os.path.isdir(versions_dir):
279 log.error(
'Cannot find any Python version in "pyenv".')
280 log.notice(
'Install a Python version 3.3+ into "pyenv".')
290 'Cannot find a virtual environment capable version in "pyenv".'
292 log.notice(
'Install a Python version 3.3+ into "pyenv".')
295 log.verbose(
'No deviation detected at observation 4.')
302 'Cancelling program.'
305 'See deviating error messages and remediation proposals/instructions above.'
316 file_path = os.path.abspath(
317 os.path.join(os.environ[
'PYENV_ROOT'],
'..',
'.version')
319 if not os.path.isfile(file_path):
322 with open(file_path,
'r')
as f:
323 ver = f.read().strip()
335 if len(ver_path) > 0:
336 with open(ver_path,
'r')
as f:
337 ver = f.read().strip()
341 ver_path = os.path.join(os.environ[
'PYENV_ROOT'],
'version')
342 if not os.path.isfile(ver_path):
345 with open(ver_path,
'r')
as f:
346 ver = f.read().strip()
354 dir_path: str = os.getcwd()
357 file_path = os.path.join(dir_path, file_name)
358 if os.path.isfile(file_path):
362 if len(dir_path) <= 3:
366 dir_path = os.path.dirname(dir_path)
377 if os.path.isdir(ver1):
378 ver2 = os.path.basename(ver1)
396 if os.path.isdir(ver):
397 ver1 = os.path.basename(ver)
400 ver2 = re.search(
r'\s*([\d.]+)', ver1).group(1)
403 lst = ver2.split(
'.')
406 maj, mno, _ = tuple(lst)
435) -> tuple[(str,
None), int]:
441 venv_capable=venv_capable,
445 ver1 = re.search(
r'\s*([\d.]+)', ver).group(1)
447 log.error(
'Version number "{}" is not matching itself (match = "{}".'.format(ver, ver1))
448 log.info(
'Check/correct the version sourced from "({})". Then try again.'.format(realm))
450 tup1 = tuple(ver1.split(
'.'))
455 log.debug(
'Filtered version: {}'.format(dir1))
456 ver2 = os.path.basename(dir1)
457 tup2 = tuple(ver2.split(
'.'))
458 if tup2[:len(tup1)] == tup1:
463 max_nam =
'.'.join(list(max_tup))
465 if os.path.basename(dir2) == max_nam:
470 log.error(
'Cannot find a Python version, which matches "{}".'.format(ver1))
471 log.info(
'Calling "pyenv virtualenvs", ensure that the wanted version is installed. Then try again.')
483 return '\x1b[92mTrue\x1b[0m'
485 return'\x1b[93mFalse\x1b[0m'
498 venv_capable: bool=
False,
502 vers_path = os.path.join(
503 os.environ[
'PYENV_ROOT'],
506 vers = glob.glob(os.path.join(vers_path, version))
510 exe_path = os.path.join(ver,
'python.exe')
511 cfg_path = os.path.join(ver,
'pyvenv.cfg')
513 (os.path.isfile(exe_path))
515 (
not os.path.isfile(cfg_path))
520 item = os.path.basename(ver)
525 for i1
in range(len(result)):
527 v1: list = os.path.basename(p1).split(
'.')
528 t1: tuple = tuple(map(int, v1))
529 for i2
in range(i1 + 1, len(result)):
531 v2: list = os.path.basename(p2).split(
'.')
532 t2: tuple = tuple(map(int, v2))
535 m: str =
'{}'.format(result[i1])
536 result[i1] = result[i2]
552 return bool(os.readlink(path))
565 version_dir = os.path.join(
566 os.environ[
'PYENV_ROOT'],
569 vers = glob.glob(os.path.join(
576 link = os.readlink(ver)
579 if link.startswith(pref):
580 link = link.removeprefix(pref)
598 with open(file_path,
'r')
as f:
599 result = f.read().strip()
617 'Configuring project properties ...'
620 ver_prop_path = os.path.join(
624 env_prop_path = os.path.join(
630 ver1 = re.search(
r'\s*([\d.]+)', ver.strip()).group(1)
632 log.notice(
'Automatically corrected version from "{}" to "{}".'.format(ver, ver1))
634 ver_path = os.path.join(
635 os.environ[
'PYENV_ROOT'],
639 exe_path = os.path.join(
644 os.path.isdir(ver_path)
646 os.path.isfile(exe_path)
649 '"Python "{}" is not installed in "pyenv".'.format(ver1)
652 'Select version from {}.'.format(
663 with open(ver_prop_path,
'w')
as ver_f:
669 log.notice(
'Automatically corrected name from "{}" to "{}".'.format(env, env1))
671 env_path = os.path.join(
672 os.environ[
'PYENV_ROOT'],
678 exe_path = os.path.join(
684 os.path.isdir(env_path)
686 os.path.isfile(exe_path)
688 log.error(
'"Python {}" has no virtual environment "{}" in "pyenv".'.format(ver1, env1))
693 with open(env_prop_path,
'w')
as ver_f:
719 result: list[str] = []
720 if os.path.isdir(ver):
721 envs_path = os.path.join(
726 envs_path = os.path.join(
727 os.environ[
'PYENV_ROOT'],
732 envs = glob.glob(os.path.join(envs_path, name))
735 cfg_path = os.path.join(
739 exe_path = os.path.join(
745 (os.path.isfile(cfg_path))
747 (os.path.isfile(exe_path))
752 item = os.path.basename(env)
769 result: list[str] = []
775 if os.path.isdir(ver):
776 envs_path = os.path.join(
781 envs_path = os.path.join(
782 os.environ[
'PYENV_ROOT'],
787 envs = glob.glob(os.path.join(envs_path, name))
790 cfg_path = os.path.join(
794 exe_path = os.path.join(
800 (os.path.isfile(cfg_path))
802 (os.path.isfile(exe_path))
807 item = os.path.basename(env)
820 items: list[str] = os.path.abspath(env_dir).split(os.sep)
823 items1 = [
'%USERPROFILE%'] + items[3:]
824 path = os.sep.join(items1)
825 return version, name, path
836 'Configuring project properties ...'
838 ver_path = os.path.join(
842 env_path = os.path.join(
846 if os.path.isfile(ver_path):
850 if os.path.isfile(env_path):
874 'Listing project properties ...'
876 up = os.environ[
'USERPROFILE']
879 fnv =
'.python-version'
881 log.debug(
'Version file path: "{}".'.format(fpv))
884 if os.path.isfile(fpv):
886 if fnv.startswith(up):
887 fnv =
'%USERPROFILE%' + fnv[len(up):]
888 with open(fpv,
'r')
as f:
889 dtv = f.read().strip()
897 log.debug(
'Name file path: "{}".'.format(fpn))
899 if os.path.isfile(fpn):
901 if fnn.startswith(up):
902 fnn =
'%USERPROFILE%' + fnn[len(up):]
903 with open(fpn,
'r')
as f:
904 dtn = f.read().strip()
908 prn =
'({})'.format(dtn)
911 (
'PROMPT' in os.environ)
913 (prn
in os.environ[
'PROMPT'])
917 fne =
'.tree-excludes'
919 log.debug(
'Excludes file path: "{}".'.format(fpe))
921 if os.path.isfile(fpe):
923 if fne.startswith(up):
924 fne =
'%USERPROFILE%' + fne[len(up):]
925 with open(fpe,
'r')
as f:
926 dte = f.read().strip()
935 [tbl.HEADER,
'A',
'Property Path',
'ID',
'"pyenv" Location/Content'],
938 dtv_dir = os.path.join(
939 os.environ[
'PYENV_ROOT'],
943 if (len(dtv) > 0)
and os.path.isdir(dtv_dir):
948 '\x1b[96m{}\x1b[0m'.format(dtv),
951 dtn_dir = os.path.join(
952 os.environ[
'PYENV_ROOT'],
958 if os.path.isdir(dtn_dir):
963 '\x1b[93m{}\x1b[0m'.format(dtn),
971 '\x1b[95m:tuple\x1b[0m',
974 data.append([tbl.SEPARATOR])
978 headline=
'LOCAL PROJECT PROPERTIES (A = active):'
983 'Listing project properties in files and folders tree ...'
986 print(
'\nLOCAL FOLDER TREE:\n')
1006 with open(file_path,
'r')
as f:
1007 result_str = f.read().strip()
1010 result: (tuple, tuple[str]) = eval(result_str)
1011 if not isinstance(result, (tuple, tuple[str])):
1014 log.error(
'Content of file "{}", "{}" cannot be interpreted as "empty tuple" or "tuple of str".'.format(
1018 log.info(
'Check/repair this file. Content example: "(\'docs\', \'.idea\', \'__pycache__\')".')
tuple[(str, None), int] selectVersionDir(str ver, str realm, venv_capable=False)
Find the best version, matching the requirements.
int listProjectProperties(bool show_tree=False)
Display the table, which shows a list about project properties.
int auditPyEnv(str min_ver)
Check if "pyenv" version is greater or equal the given minimal version.
int auditGlobalPythonVersion(str min_ver)
Check if Python version is greater or equal the given minimal version.
str fName(str natural_name)
Convert a natural name into stripped functional name, without spaces, which is lowercase,...
(tuple, tuple[str]) getTreeFoldersToExclude()
Get the directory tree folder names to exclude from project property file ".tree-excludes".
int auditPlatform(str name)
Check if the program in running on the required platform.
(str, str) getPythonVersion()
Get selected global/local Python version in "pyenv".
bool isJunction(str path)
Check if path is a junction, which has been created e.g.
str getGlobalStar(str ver)
Get the "*" marker for this version, if it is the globally selected version in "pyenv".
str getProjectPropertyFileStr(str file_path)
Get the content of project property file.
tuple[str, str, str] parseEnvDir(str env_dir)
Parse virtual environment directory path.
list[str] getAllEnvs(str name=' *', bool as_paths=False)
Get list of installed virtual environments for a specific Python version in "pyenv".
list[str] getEnvs(str ver, str name=' *', bool as_paths=False)
Get list of installed virtual environments for a specific Python version in "pyenv".
int unsetProjectProperties()
Set project property files.
str getPyEnvVersion()
Get "pyenv" version.
int setProjectProperties(str ver, str env)
Set/override project property files.
str scanCwdAndAncestorsForFile(str file_name)
Scan the CWD and its path ancestors for a specific file.
list[str] getEnvJunctions(str path)
Scan the Pythons versions in "pyenv" for junctions, which points to a specific virtual environment di...
bool isPythonVenvVersion(str ver)
Check if the Python version is capable to run virtual environment.
list[str] getPythonVersions(str version=' *', bool venv_capable=False, bool as_paths=False)
Get list of installed Python version directories in "pyenv".
str getColoredVenvCapability(str ver)
Get the colored virtual environment capability str for the specific version number or path.
debug((str, tuple) msg)
Log debug message colored to console only.
warning((str, tuple) msg)
Log warning message colored to console only.
notice((str, tuple) msg)
Log notice message colored to console only.
verbose((str, tuple) msg)
Log verbose message colored to console only.
info((str, tuple) msg)
Log info message colored to console only.
error((str, tuple) msg)
Log error message colored to console only.
tree((Path, str) root_path, int recursion_level=-1, bool limit_to_directories=False, int length_limit=1000, tuple exclude=())
Given a directory path, print a visual tree structure.