Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: show available version if no version provided #236

Merged
merged 9 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions cmd/commands/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ package commands
import (
"errors"
"fmt"
"os"
"strings"

"github.com/pterm/pterm"
"github.com/urfave/cli/v2"
"github.com/version-fox/vfox/internal"
"github.com/version-fox/vfox/internal/printer"
"github.com/version-fox/vfox/internal/toolset"
"os"
"strings"
)

var Install = &cli.Command{
Expand All @@ -47,32 +49,53 @@ func installCmd(ctx *cli.Context) error {
return installAll()
}

args := ctx.Args()
sdkArg := ctx.Args().First()
if sdkArg == "" {
return cli.Exit("sdk name is required", 1)
}
argArr := strings.Split(sdkArg, "@")
argsLen := len(argArr)

manager := internal.NewSdkManager()
defer manager.Close()
if argsLen > 2 {
return cli.Exit("sdk version is invalid", 1)
} else {
var name string
var version internal.Version
if argsLen == 2 {
name = strings.ToLower(argArr[0])
version = internal.Version(argArr[1])

for i := 0; i < args.Len(); i++ {
bytemain marked this conversation as resolved.
Show resolved Hide resolved
sdkArg := args.Get(i)
argArr := strings.Split(sdkArg, "@")
argsLen := len(argArr)

if argsLen > 2 {
return cli.Exit(fmt.Sprintf("Your input(%s) is invalid", sdkArg), 1)
} else {
name = strings.ToLower(argArr[0])
version = ""
}
source, err := manager.LookupSdkWithInstall(name)
if err != nil {
return err
var name string
var version internal.Version
if argsLen == 2 {
name = strings.ToLower(argArr[0])
version = internal.Version(argArr[1])
} else {
name = strings.ToLower(argArr[0])
version = ""
}
source, err := manager.LookupSdkWithInstall(name)
if err != nil {
return err
}
err = source.Install(version)
if errors.Is(err, internal.ErrNoVersionProvided) {
// show prompt to let user select version
showAvailable, err := printer.Prompt("No version provided, do you want to select a version to install?")
bytemain marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}
if showAvailable {
return RunSearch(name, []string{})
}
} else if err != nil {
return err
}
}
return source.Install(version)
}

return nil
}

func installAll() error {
Expand Down
25 changes: 15 additions & 10 deletions cmd/commands/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,14 @@ var Search = &cli.Command{
Category: CategorySDK,
}

func searchCmd(ctx *cli.Context) error {
sdkName := ctx.Args().First()
if sdkName == "" {
return cli.Exit("sdk name is required", 1)
}
func RunSearch(sdkName string, availableArgs []string) error {
manager := internal.NewSdkManager()
defer manager.Close()
source, err := manager.LookupSdkWithInstall(sdkName)
if err != nil {
return fmt.Errorf("%s not supported, error: %w", sdkName, err)
}
result, err := source.Available(ctx.Args().Tail())
result, err := source.Available(availableArgs)
if err != nil {
return fmt.Errorf("plugin [Available] method error: %w", err)
}
Expand Down Expand Up @@ -76,17 +72,18 @@ func searchCmd(ctx *cli.Context) error {
})
}

highlightOptions := util.NewSet[string]()
installedVersions := util.NewSet[string]()
for _, version := range source.List() {
highlightOptions.Add(string(version))
installedVersions.Add(string(version))
}

_, height, _ := terminal.GetSize(int(os.Stdout.Fd()))
kvSelect := printer.PageKVSelect{
TopText: "Please select a version of " + sdkName,
TopText: "Please select a version of " + sdkName + " to install",
Filter: true,
Size: int(math.Min(math.Max(float64(height-3), 1), 20)),
HighlightOptions: highlightOptions,
HighlightOptions: installedVersions,
DisabledOptions: installedVersions,
Options: options,
SourceFunc: func(page, size int, options []*printer.KV) ([]*printer.KV, error) {
start := page * size
Expand All @@ -111,3 +108,11 @@ func searchCmd(ctx *cli.Context) error {
}
return source.Install(internal.Version(version.Key))
}

func searchCmd(ctx *cli.Context) error {
sdkName := ctx.Args().First()
if sdkName == "" {
return cli.Exit("sdk name is required", 1)
}
return RunSearch(sdkName, ctx.Args().Tail())
}
2 changes: 2 additions & 0 deletions docs/plugins/create/howto.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ directory
in advance. If it is a compressed package such as `tar`, `tar.gz`, `tar.xz`, `zip`, `vfox` will help you to decompress
it directly.

if the return value of version is empty, it means that the version is not found, and `vfox` will ask the user whether to perform a search operation.

```lua
function PLUGIN:PreInstall(ctx)
--- input parameters
Expand Down
2 changes: 2 additions & 0 deletions docs/zh-hans/plugins/create/howto.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@

返回预安装信息, 例如具体版本号、下载源等信息。 `vfox`会帮你提前将这些文件下载到特定目录下。如果是压缩包如`tar`、`tar.gz`、`tar.xz`、`zip`这四种压缩包, `vfox`会直接帮你解压处理。

如果版本的返回值为空,表示未找到版本,`vfox`会询问用户是否进行搜索操作。

**位置**: `hooks/pre_install.lua`
```lua
function PLUGIN:PreInstall(ctx)
Expand Down
7 changes: 5 additions & 2 deletions internal/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
package internal

import (
"fmt"
"errors"

lua "github.com/yuin/gopher-lua"
)

Expand Down Expand Up @@ -105,9 +106,11 @@ type PreInstallHookResult struct {
Addition []*PreInstallHookResultAdditionItem `luai:"addition"`
}

var ErrNoVersionProvided = errors.New("no version number provided")

func (i *PreInstallHookResult) Info() (*Info, error) {
if i.Version == "" {
return nil, fmt.Errorf("no version number provided")
return nil, ErrNoVersionProvided
}

sum := LuaCheckSum{
Expand Down
5 changes: 3 additions & 2 deletions internal/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ import (
_ "embed"
"errors"
"fmt"
"path/filepath"
"regexp"

"github.com/pterm/pterm"
"github.com/version-fox/vfox/internal/env"
"github.com/version-fox/vfox/internal/logger"
"github.com/version-fox/vfox/internal/luai"
"github.com/version-fox/vfox/internal/util"
lua "github.com/yuin/gopher-lua"
"path/filepath"
"regexp"
)

const (
Expand Down
67 changes: 67 additions & 0 deletions internal/printer/prompt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2024 Han Li and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package printer

import (
"fmt"

"atomicgo.dev/keyboard"

"atomicgo.dev/keyboard/keys"
)

// show {message} (y/n)
// return true if user press y or Enter, otherwise false
func Prompt(message string) (bool, error) {
fmt.Println(message + " (y/n)")

result := false

err := keyboard.Listen(func(key keys.Key) (stop bool, err error) {
switch key.Code {
case keys.CtrlC:
{
return true, nil // Stop listener by returning true on Ctrl+C
}
case keys.RuneKey:
if key.String() == "y" {
fmt.Printf("\rYou pressed: %s\n", key)
result = true
return true, nil
}
if key.String() == "n" {
fmt.Printf("\rYou pressed: %s\n", key)
result = false
return true, nil
}
case keys.Escape:
result = false
return true, nil
case keys.Enter:
result = true
return true, nil
}

return false, nil
})

if err != nil {
return false, err
}

return result, nil
}
17 changes: 12 additions & 5 deletions internal/printer/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,25 @@
package printer

import (
"fmt"
"sort"
"strings"

"atomicgo.dev/cursor"
"atomicgo.dev/keyboard"
"atomicgo.dev/keyboard/keys"
"fmt"
"github.com/lithammer/fuzzysearch/fuzzy"
"github.com/pterm/pterm"
"github.com/version-fox/vfox/internal/logger"
"github.com/version-fox/vfox/internal/util"
"sort"
"strings"
)

type PageKVSelect struct {
index int
HighlightOptions util.Set[string]
index int
// Options to highlight with green color
HighlightOptions util.Set[string]
// Options to disable
DisabledOptions util.Set[string]
Options []*KV
searchOptions []*KV
pageOptions []*KV
Expand Down Expand Up @@ -217,6 +221,9 @@ func (s *PageKVSelect) Show() (*KV, error) {
case keys.Enter:
if s.index < len(s.pageOptions) {
s.result = s.pageOptions[s.index]
if (s.result != nil) && s.DisabledOptions.Contains(s.result.Key) {
return false, nil
}
} else {
s.result = nil
logger.Info("No search, program stopped.")
Expand Down
Loading