Skip to content

Commit

Permalink
Added pyenv-latest support.
Browse files Browse the repository at this point in the history
Usage and behavior is the same as in the original version of pyenv-latest.

Prefix auto-resolution to the latest version also turned on for such commands: install, global, local

So, from now user can just execute the following commands without the need of searching for latest patch version (or even minor)

pyenv install 3.10
pyenv global 3.10
  • Loading branch information
uhx authored and Darsstar committed Dec 27, 2023
1 parent 3201b6c commit 70c1edf
Show file tree
Hide file tree
Showing 10 changed files with 305 additions and 17 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ This project was forked from [rbenv-win][3] and modified for [pyenv][1]. It is n
```yml
commands List all available pyenv commands
local Set or show the local application-specific Python version
latest Print the latest installed or known version with the given prefix
global Set or show the global Python version
shell Set or show the shell-specific Python version
install Install 1 or more versions of Python
install Install 1 or more versions of Python
uninstall Uninstall 1 or more versions of Python
update Update the cached version DB
rehash Rehash pyenv shims (run this after switching Python versions)
Expand Down Expand Up @@ -105,7 +106,7 @@ Please see the [Installation](./docs/installation.md) page for more details.

If you are getting "**command not found**" error, check the below note and [manually check the settings](#manually-check-the-settings)

For Visual Studio Code or another IDE with a built in terminal, restart it and check again
For Visual Studio Code or another IDE with a built in terminal, restart it and check again

***

Expand All @@ -114,10 +115,10 @@ For Visual Studio Code or another IDE with a built in terminal, restart it and c
Ensure all environment variables are properly set with high priority via the GUI:

```plaintext
This PC
This PC
→ Properties
→ Advanced system settings
→ Advanced → Environment Variables...
→ Advanced system settings
→ Advanced → Environment Variables...
→ PATH
```

Expand Down Expand Up @@ -195,7 +196,7 @@ Both releases can install 64bit and 32bit python versions; the difference is in
3.8.2-amd64
....
```

Support for Python versions below 2.4 have been dropped since their installers don't install "cleanly" like versions from 2.4 onward and they're predominantly out of use/support in most environments now.

## FAQ
Expand Down Expand Up @@ -228,7 +229,7 @@ Please see the [Changelog](./docs/changelog.md) page.

## Author and Thanks

pyenv-win was developed by [Kiran Kumar Kotari](https://github.com/kirankotari) and [Contributors](https://github.com/pyenv-win/pyenv-win/graphs/contributors)
pyenv-win was developed by [Kiran Kumar Kotari](https://github.com/kirankotari) and [Contributors](https://github.com/pyenv-win/pyenv-win/graphs/contributors)
Thanks for all Contributors and Supports for patience for the latest major release.

[1]: https://github.com/pyenv/pyenv
Expand Down
109 changes: 109 additions & 0 deletions pyenv-win/libexec/libs/pyenv-install-lib.vbs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Const VRX_x64 = 5
Const VRX_ARM = 6
Const VRX_Web = 7
Const VRX_Ext = 8
Const VRX_Arch = 5

' Version definition array from LoadVersionsXML.
Const LV_Code = 0
Expand All @@ -38,14 +39,21 @@ Const IP_Quiet = 9
Const IP_Dev = 10

Dim regexVer
Dim regexVerArch
Dim regexFile
Set regexVer = New RegExp
Set regexVerArch = New RegExp
Set regexFile = New RegExp
With regexVer
.Pattern = "^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:([a-z]+)(\d*))?$"
.Global = True
.IgnoreCase = True
End With
With regexVerArch
.Pattern = "^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:([a-z]+)(\d*))?([\.-](?:amd64|arm64|win32))?$"
.Global = True
.IgnoreCase = True
End With
With regexFile
.Pattern = "^python-(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:([a-z]+)(\d*))?([\.-]amd64)?([\.-]arm64)?(-webinstall)?\.(exe|msi)$"
.Global = True
Expand Down Expand Up @@ -278,3 +286,104 @@ Sub SaveVersionsXML(xmlPath, versArray)
.Close
End With
End Sub

Function SymanticComparePatch(ver1, ver2)
' Check if ver1 < ver2
Dim comp1, comp2

' Major
comp1 = ver1(VRX_Major)
comp2 = ver2(VRX_Major)
If Len(comp1) = 0 Then comp1 = 0: Else comp1 = CLng(comp1)
If Len(comp2) = 0 Then comp2 = 0: Else comp2 = CLng(comp2)
SymanticComparePatch = comp1 < comp2
If comp1 <> comp2 Then Exit Function

' Minor
comp1 = ver1(VRX_Minor)
comp2 = ver2(VRX_Minor)
If Len(comp1) = 0 Then comp1 = 0: Else comp1 = CLng(comp1)
If Len(comp2) = 0 Then comp2 = 0: Else comp2 = CLng(comp2)
SymanticComparePatch = comp1 < comp2
If comp1 <> comp2 Then Exit Function

' Patch
comp1 = ver1(VRX_Patch)
comp2 = ver2(VRX_Patch)
If Len(comp1) = 0 Then comp1 = 0: Else comp1 = CLng(comp1)
If Len(comp2) = 0 Then comp2 = 0: Else comp2 = CLng(comp2)
SymanticComparePatch = comp1 < comp2
If comp1 <> comp2 Then Exit Function
End Function

Function JoinVersionString(pieces)
' WScript.echo "kkotari: pyenv-install-lib.vbs JoinVersionString..!"
JoinVersionString = ""
If Len(pieces(VRX_Major)) Then JoinVersionString = JoinVersionString & pieces(VRX_Major)
If Len(pieces(VRX_Minor)) Then JoinVersionString = JoinVersionString &"."& pieces(VRX_Minor)
If Len(pieces(VRX_Patch)) Then JoinVersionString = JoinVersionString &"."& pieces(VRX_Patch)
If Len(pieces(VRX_Release)) Then JoinVersionString = JoinVersionString & pieces(VRX_Release)
If Len(pieces(VRX_RelNumber)) Then JoinVersionString = JoinVersionString & pieces(VRX_RelNumber)
If Len(pieces(VRX_Arch)) Then JoinVersionString = JoinVersionString & pieces(VRX_Arch)
End Function

Function FindLatestVersion(prefix, known)
Dim candidates

if known Then
Dim cachedVersions
Set cachedVersions = LoadVersionsXML(strDBFile)

Dim cachedVersion

Dim convertor()
ReDim Preserve convertor(-1)

For Each cachedVersion In cachedVersions.Keys
ReDim Preserve convertor(UBound(convertor) + 1)
convertor(UBound(convertor)) = cachedVersion
Next

candidates = convertor
else
candidates = GetInstalledVersions()
end if

Dim x
Dim matches

Dim bestMatch
Dim arch

arch = GetArchPostfix()

For x = 0 To UBound(candidates) Step 1
If InStr(candidates(x), prefix) = 1 Then
' To avoid edge cases like prefix="3.1" resulting in "3.11"/"3.11.x"...
' 3.1.1-win32 = len(3.1.1) + len(-win32) Or 3.1.1-win32[len(3.1)] = '.'
If Len(candidates(x)) = (Len(prefix) + Len(arch)) Or Mid(candidates(x), Len(prefix) + 1, 1) = "." Then
Set matches = regexVerArch.Execute(candidates(x))

if matches.Count = 1 Then
' Skip dev builds, releases and so on
' Comparing each version by <major>.<minor>.<patch>
If matches(0).SubMatches(VRX_Release) = "" And matches(0).SubMatches(VRX_Arch) = arch Then
If IsEmpty(bestMatch) Then
Set bestMatch = matches(0).SubMatches
Else
If SymanticComparePatch(bestMatch, matches(0).SubMatches) Then
Set bestMatch = matches(0).SubMatches
End If
End If
End If
End If
End If
End If
Next

if IsEmpty(bestMatch) Then
FindLatestVersion = ""
else
FindLatestVersion = JoinVersionString(bestMatch)
end if
End Function
15 changes: 13 additions & 2 deletions pyenv-win/libexec/libs/pyenv-lib.vbs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ End Function
Function GetInstalledVersions()
' WScript.echo "kkotari: pyenv-lib.vbs get installed versions..!"
Dim rootBinDir, winBinDir, version, versions()
ReDim Preserve versions(0)
ReDim Preserve versions(-1)
If objfs.FolderExists(strDirVers) Then
Set rootBinDir = objfs.GetFolder(strDirVers)
For Each winBinDir in rootBinDir.SubFolders
Expand Down Expand Up @@ -367,7 +367,7 @@ Sub WriteLinuxScript(baseName)
.Close
End With
End If

End If
End Sub

Expand Down Expand Up @@ -423,6 +423,17 @@ Sub Rehash()
Next
End Sub

Function GetArchPostfix()
Dim arch

arch = objws.Environment("Process")("PYENV_FORCE_ARCH")
If arch = "" Then arch = objws.Environment("System")("PROCESSOR_ARCHITECTURE")

If UCase(arch) = "AMD64" Then GetArchPostfix = ""
If UCase(arch) = "X86" Then GetArchPostfix = "-win32"
If UCase(arch) = "ARM64" Then GetArchPostfix = "-arm64" ' NOT TESTED
End Function

' SYSTEM:PROCESSOR_ARCHITECTURE = AMD64 on 64-bit computers. (even when using 32-bit cmd.exe)
Function Is32Bit()
' WScript.echo "kkotari: pyenv-lib.vbs is32bit..!"
Expand Down
1 change: 1 addition & 0 deletions pyenv-win/libexec/pyenv-help.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ echo.
echo Some useful pyenv commands are:
echo commands List all available pyenv commands
echo local Set or show the local application-specific Python version
echo latest Print the latest installed or known version with the given prefix
echo global Set or show the global Python version
echo shell Set or show the shell-specific Python version
echo install Install a Python version using python-build
Expand Down
11 changes: 8 additions & 3 deletions pyenv-win/libexec/pyenv-install.vbs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ Sub main(arg)
Dim optReg
Dim optClear
Dim installVersions
Dim fixedVersion

optForce = False
optSkip = False
Expand Down Expand Up @@ -384,13 +385,17 @@ Sub main(arg)
Case "-r" optReg = True
Case "--register" optReg = True
Case Else
installVersions.Item(Check32Bit(arg(idx))) = Empty
fixedVersion = FindLatestVersion(arg(idx), True)

If fixedVersion = "" Then fixedVersion = arg(idx)

installVersions.Item(Check32Bit(fixedVersion)) = Empty
End Select
Next
If Is32Bit Then
opt32 = False
opt64 = False
End If
End If
If opt32 And opt64 Then
WScript.Echo "pyenv-install: only --32only or --64only may be specified, not both."
WScript.Quit 1
Expand Down Expand Up @@ -473,7 +478,7 @@ Sub main(arg)
installVersions.Item(ary(0)) = Empty
Else
ShowHelp
End If
End If
End If
End If

Expand Down
86 changes: 86 additions & 0 deletions pyenv-win/libexec/pyenv-latest.vbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
Option Explicit

Sub Import(importFile)
Dim fso, libFile
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
Set libFile = fso.OpenTextFile(fso.getParentFolderName(WScript.ScriptFullName) &"\"& importFile, 1)
ExecuteGlobal libFile.ReadAll
If Err.number <> 0 Then
WScript.Echo "Error importing library """& importFile &"""("& Err.Number &"): "& Err.Description
WScript.Quit 1
End If
libFile.Close
End Sub

Import "libs\pyenv-lib.vbs"
Import "libs\pyenv-install-lib.vbs"

Sub ShowHelp(exitcode)
' WScript.echo "kkotari: pyenv-latest.vbs..!"
WScript.Echo "Usage: pyenv latest [-k|--known] [-q|--quiet] <prefix>"
WScript.Echo ""
WScript.Echo " -k/--known Select from all known versions instead of installed"
WScript.Echo " -q/--quiet Do not print an error message on resolution failure"
WScript.Echo ""
WScript.Quit exitcode
End Sub

Sub main(arg)
' WScript.echo "kkotari: pyenv-latest.vbs Main..!"

Dim optKnown
Dim optQuiet
Dim optPrefix

optKnown = False
optQuiet = False
optPrefix = ""

Dim idx

For idx = 0 To arg.Count - 1
Select Case arg(idx)
Case "--help" ShowHelp 0
Case "-k" optKnown = True
Case "--known" optKnown = True
Case "-q" optQuiet = True
Case "--quiet" optQuiet = True
Case Else
optPrefix = arg(idx)
End Select
Next

If arg.Count = 0 Then
If optQuiet <> True Then
ShowHelp 1
End If
End If

If optPrefix = "" Then
If optQuiet <> True Then
WScript.Echo "pyenv-latest: missing <prefix> argument"
End If

WScript.Quit 1
End If

Dim latest
latest = FindLatestVersion(optPrefix, optKnown)

If latest <> "" Then
WScript.Echo latest
Else
If optQuiet <> True Then
if optKnown Then
WScript.Echo "pyenv-latest: no known versions match the prefix '" & optPrefix & "'."
else
WScript.Echo "pyenv-latest: no installed versions match the prefix '" & optPrefix & "'."
end if
End If

WScript.Quit 1
End If
End Sub

main(WScript.Arguments)
13 changes: 10 additions & 3 deletions pyenv-win/libexec/pyenv-uninstall.vbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Sub Import(importFile)
End Sub

Import "libs\pyenv-lib.vbs"
Import "libs\pyenv-install-lib.vbs"

Sub ShowHelp()
WScript.Echo "Usage: pyenv uninstall [-f|--force] <version> [<version> ...]"
Expand Down Expand Up @@ -48,11 +49,13 @@ Sub main(arg)
Dim optForce
Dim optAll
Dim uninstallVersions
Dim fixedVersion

optForce = False
optAll = False
Set uninstallVersions = CreateObject("Scripting.Dictionary")


For idx = 0 To arg.Count - 1
Select Case arg(idx)
Case "--help" ShowHelp
Expand All @@ -61,11 +64,15 @@ Sub main(arg)
Case "-a" optAll = True
Case "--all" optAll = True
Case Else
If Not IsVersion(arg(idx)) Then
WScript.Echo "pyenv: Unrecognized python version: "& arg(idx)
fixedVersion = FindLatestVersion(arg(idx), False)

If fixedVersion = "" Then fixedVersion = arg(idx)

If Not IsVersion(fixedVersion) Then
WScript.Echo "pyenv: Unrecognized python version: "& fixedVersion
WScript.Quit 1
End If
uninstallVersions.Item(arg(idx)) = Empty
uninstallVersions.Item(fixedVersion) = Empty
End Select
Next

Expand Down
Loading

0 comments on commit 70c1edf

Please sign in to comment.