feat: handling for using versions that are not installed (#14)
* feat: handling for using versions that are not installed * test: coverage for installed version list * chore: increment version to 0.0.8
This commit is contained in:
parent
38450e0f72
commit
1bbd6c1050
6 changed files with 96 additions and 18 deletions
34
commands.go
34
commands.go
|
@ -1,10 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
var DIRECTORIES = []string{
|
var DIRECTORIES = []string{
|
||||||
|
@ -54,6 +53,12 @@ func UninstallPython(args []string, flags Flags, currentState State) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InstallPython(args []string, flags Flags, currentState State) error {
|
||||||
|
version := args[1]
|
||||||
|
|
||||||
|
return InstallPythonDistribution(version, flags.NoCache, flags.Verbose)
|
||||||
|
}
|
||||||
|
|
||||||
func Use(args []string, flags Flags, currentState State) error {
|
func Use(args []string, flags Flags, currentState State) error {
|
||||||
version := args[1]
|
version := args[1]
|
||||||
if err := ValidateVersion(version); err != nil {
|
if err := ValidateVersion(version); err != nil {
|
||||||
|
@ -71,7 +76,8 @@ func Use(args []string, flags Flags, currentState State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
return errors.New("Version not installed.")
|
fmt.Println("Version not installed. Installing it first.")
|
||||||
|
InstallPythonDistribution(version, flags.NoCache, flags.Verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteState(version)
|
WriteState(version)
|
||||||
|
@ -80,20 +86,19 @@ func Use(args []string, flags Flags, currentState State) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func ListVersions(args []string, flags Flags, currentState State) error {
|
func ListVersions(args []string, flags Flags, currentState State) error {
|
||||||
runtimesDir := GetStatePath("runtimes")
|
installedVersions, err := ListInstalledVersions()
|
||||||
entries, err := os.ReadDir(runtimesDir)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(entries) == 0 {
|
if len(installedVersions) == 0 {
|
||||||
fmt.Println("No versions installed!")
|
fmt.Println("No versions installed!")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range entries {
|
for _, d := range installedVersions {
|
||||||
fmt.Println(strings.TrimPrefix(d.Name(), "py-"))
|
fmt.Println(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -102,15 +107,20 @@ func ListVersions(args []string, flags Flags, currentState State) error {
|
||||||
// Which prints out the system path to the executable being used by `python`.
|
// Which prints out the system path to the executable being used by `python`.
|
||||||
func Which(args []string, flags Flags, currentState State) error {
|
func Which(args []string, flags Flags, currentState State) error {
|
||||||
selectedVersion, _ := DetermineSelectedPythonVersion(currentState)
|
selectedVersion, _ := DetermineSelectedPythonVersion(currentState)
|
||||||
|
installedVersions, _ := ListInstalledVersions()
|
||||||
|
isInstalled := slices.Contains(installedVersions, selectedVersion.Version)
|
||||||
|
|
||||||
var printedPath string
|
var printedPath string
|
||||||
|
|
||||||
if selectedVersion.Source == "system" {
|
if selectedVersion.Source == "system" {
|
||||||
_, sysPath := DetermineSystemPython()
|
_, sysPath := DetermineSystemPython()
|
||||||
printedPath = fmt.Sprintf("%s (system)", sysPath)
|
printedPath = fmt.Sprintf("%s (system)", sysPath)
|
||||||
} else {
|
} else if isInstalled {
|
||||||
tag := VersionStringToStruct(selectedVersion.Version)
|
tag := VersionStringToStruct(selectedVersion.Version)
|
||||||
printedPath = GetStatePath("runtimes", fmt.Sprintf("py-%s", selectedVersion.Version), "bin", fmt.Sprintf("python%s", tag.MajorMinor()))
|
printedPath = GetStatePath("runtimes", fmt.Sprintf("py-%s", selectedVersion.Version), "bin", fmt.Sprintf("python%s", tag.MajorMinor()))
|
||||||
|
} else {
|
||||||
|
fmt.Printf("The desired version (%s) is not installed.\n", selectedVersion.Version)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix := "Python path: "
|
prefix := "Python path: "
|
||||||
|
@ -130,6 +140,12 @@ func Which(args []string, flags Flags, currentState State) error {
|
||||||
// under "source", if the system Python is used, "system" is returned as a source.
|
// under "source", if the system Python is used, "system" is returned as a source.
|
||||||
func CurrentVersion(args []string, flags Flags, currentState State) error {
|
func CurrentVersion(args []string, flags Flags, currentState State) error {
|
||||||
selectedVersion, _ := DetermineSelectedPythonVersion(currentState)
|
selectedVersion, _ := DetermineSelectedPythonVersion(currentState)
|
||||||
|
installedVersions, _ := ListInstalledVersions()
|
||||||
|
isInstalled := slices.Contains(installedVersions, selectedVersion.Version)
|
||||||
|
|
||||||
|
if !isInstalled {
|
||||||
|
fmt.Println(Bold(Yellow("WARNING: This version is not installed.")))
|
||||||
|
}
|
||||||
|
|
||||||
if flags.RawOutput {
|
if flags.RawOutput {
|
||||||
fmt.Println(selectedVersion.Version)
|
fmt.Println(selectedVersion.Version)
|
||||||
|
|
|
@ -30,15 +30,12 @@ func (t VersionTag) MajorMinor() string {
|
||||||
return fmt.Sprintf("%s.%s", t.Major, t.Minor)
|
return fmt.Sprintf("%s.%s", t.Major, t.Minor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func InstallPython(args []string, flags Flags, currentState State) error {
|
func InstallPythonDistribution(version string, noCache bool, verbose bool) error {
|
||||||
verbose := flags.Verbose
|
|
||||||
version := args[1]
|
|
||||||
|
|
||||||
if err := ValidateVersion(version); err != nil {
|
if err := ValidateVersion(version); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
packageMetadata, dlerr := downloadSource(version, flags.NoCache)
|
packageMetadata, dlerr := downloadSource(version, noCache)
|
||||||
|
|
||||||
if dlerr != nil {
|
if dlerr != nil {
|
||||||
return dlerr
|
return dlerr
|
||||||
|
|
|
@ -12,6 +12,23 @@ type SelectedVersion struct {
|
||||||
Source string
|
Source string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ListInstalledVersions() ([]string, error) {
|
||||||
|
runtimesDir := GetStatePath("runtimes")
|
||||||
|
entries, err := os.ReadDir(runtimesDir)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
installedVersions := []string{}
|
||||||
|
|
||||||
|
for _, d := range entries {
|
||||||
|
installedVersions = append(installedVersions, strings.TrimPrefix(d.Name(), "py-"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return installedVersions, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SearchForPythonVersionFile crawls up to the system root to find any
|
// SearchForPythonVersionFile crawls up to the system root to find any
|
||||||
// .python-version file that could set the current version.
|
// .python-version file that could set the current version.
|
||||||
func SearchForPythonVersionFile() (SelectedVersion, bool) {
|
func SearchForPythonVersionFile() (SelectedVersion, bool) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -131,5 +132,47 @@ func TestSearchForPythonVersionFileReturnsOnRootIfNoneFound(t *testing.T) {
|
||||||
if versionFound.Version != "" || found {
|
if versionFound.Version != "" || found {
|
||||||
t.Errorf("Did not expect any result, found %s.", versionFound.Version)
|
t.Errorf("Did not expect any result, found %s.", versionFound.Version)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListInstalledVersion(t *testing.T) {
|
||||||
|
defer SetupAndCleanupEnvironment(t)()
|
||||||
|
|
||||||
|
versions := []string{"1.2.3", "4.5.6", "7.8.9"}
|
||||||
|
|
||||||
|
os.Mkdir(GetStatePath("runtimes"), 0750)
|
||||||
|
for _, version := range versions {
|
||||||
|
os.Mkdir(GetStatePath("runtimes", "py-"+version), 0750)
|
||||||
|
}
|
||||||
|
|
||||||
|
installedVersions, _ := ListInstalledVersions()
|
||||||
|
|
||||||
|
if !slices.Equal(installedVersions, versions) {
|
||||||
|
t.Errorf("Expected %s, got %s.", versions, installedVersions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListInstalledVersionNoVersionsInstalled(t *testing.T) {
|
||||||
|
defer SetupAndCleanupEnvironment(t)()
|
||||||
|
|
||||||
|
os.Mkdir(GetStatePath("runtimes"), 0750)
|
||||||
|
|
||||||
|
installedVersions, _ := ListInstalledVersions()
|
||||||
|
|
||||||
|
if len(installedVersions) != 0 {
|
||||||
|
t.Errorf("Expected 0 elements, got %d (%s).", len(installedVersions), installedVersions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListInstalledVersionNoRuntimesDir(t *testing.T) {
|
||||||
|
defer SetupAndCleanupEnvironment(t)()
|
||||||
|
|
||||||
|
installedVersions, err := ListInstalledVersions()
|
||||||
|
|
||||||
|
if len(installedVersions) != 0 {
|
||||||
|
t.Errorf("Expected 0 elements, got %d (%s).", len(installedVersions), installedVersions)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected error to be returned, got nil.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
9
style.go
9
style.go
|
@ -3,10 +3,15 @@ package main
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RESET = "\033[0m"
|
RESET = "\033[0m"
|
||||||
BOLD = "\033[1m"
|
BOLD = "\033[1m"
|
||||||
|
YELLOW = "\033[33m"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Yellow(text string) string {
|
||||||
|
return fmt.Sprintf("%s%s%s", YELLOW, text, RESET)
|
||||||
|
}
|
||||||
|
|
||||||
func Bold(text string) string {
|
func Bold(text string) string {
|
||||||
return fmt.Sprintf("%s%s%s", BOLD, text, RESET)
|
return fmt.Sprintf("%s%s%s", BOLD, text, RESET)
|
||||||
}
|
}
|
||||||
|
|
2
v.go
2
v.go
|
@ -5,7 +5,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "0.0.7"
|
Version = "0.0.8"
|
||||||
Author = "Marc Cataford <hello@karnov.club>"
|
Author = "Marc Cataford <hello@karnov.club>"
|
||||||
Homepage = "https://github.com/mcataford/v"
|
Homepage = "https://github.com/mcataford/v"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue