Skip to content

Commit

Permalink
feat: add config command to manipulate configuration (version-fox#211)
Browse files Browse the repository at this point in the history
Only string and boolean type are supported.


---------
Co-authored-by: Han Li <[email protected]>
  • Loading branch information
Chance-fyi authored and aooohan committed Apr 18, 2024
1 parent 1db028c commit dedb6c2
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 10 deletions.
1 change: 1 addition & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func newCmd() *cmd {
commands.Add,
commands.Activate,
commands.Env,
commands.Config,
commands.Cd,
}

Expand Down
123 changes: 123 additions & 0 deletions cmd/commands/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package commands

import (
"fmt"
"github.com/urfave/cli/v2"
"github.com/version-fox/vfox/internal"
"reflect"
"strconv"
"strings"
)

var Config = &cli.Command{
Name: "config",
Usage: "Setup, view config",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "list",
Aliases: []string{"l"},
Usage: "list all config",
},
&cli.BoolFlag{
Name: "unset",
Aliases: []string{"un"},
Usage: "remove a config",
},
},
Action: configCmd,
}

func configCmd(ctx *cli.Context) error {
manager := internal.NewSdkManager()
defer manager.Close()
config := reflect.ValueOf(manager.Config)

if ctx.Bool("list") {
configList("", config)
return nil
}

args := ctx.Args()
if args.Len() == 0 {
return ctx.App.Run([]string{"CMD", "config", "-h"})
}

keys := strings.Split(args.First(), ".")
unset := ctx.Bool("unset")
if !unset && args.Len() == 1 {
configGet(config, keys)
return nil
}

value := args.Get(1)
if unset {
value = ""
}
configSet(config, keys, value)
return manager.Config.SaveConfig(manager.PathMeta.HomePath)
}

func configList(prefix string, v reflect.Value) {
if v.Kind() == reflect.Ptr {
v = v.Elem()
}

for i := 0; i < v.NumField(); i++ {
key := v.Type().Field(i).Tag.Get("yaml")
value := v.Field(i)
if (value.Kind() == reflect.Ptr && value.Elem().Kind() == reflect.Struct) || value.Kind() == reflect.Struct {
configList(prefix+key+".", value)
} else {
if value.Kind() == reflect.String && value.IsZero() {
continue
}
fmt.Printf(prefix+key+" = %v\n", value.Interface())
}
}
}

func configGet(v reflect.Value, keys []string) {
var foundCount int
for _, key := range keys {
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
for i := 0; i < v.NumField(); i++ {
if v.Type().Field(i).Tag.Get("yaml") == key {
v = v.Field(i)
foundCount = foundCount + 1
break
}
}
}
if foundCount == len(keys) {
if (v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct) || v.Kind() == reflect.Struct {
configList(strings.Join(keys, ".")+".", v)
} else {
fmt.Printf("%v\n", v.Interface())
}
}
}

func configSet(v reflect.Value, keys []string, value string) {
key := keys[0]
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
for i := 0; i < v.NumField(); i++ {
if v.Type().Field(i).Tag.Get("yaml") == key {
if len(keys) > 1 {
configSet(v.Field(i), keys[1:], value)
} else {
switch v.Field(i).Kind() {
case reflect.Bool:
parseBool, _ := strconv.ParseBool(value)
v.Field(i).SetBool(parseBool)
default:
v.Field(i).SetString(value)
}
}
break
}
}
}
27 changes: 25 additions & 2 deletions docs/guides/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ legacyVersionFile:
```
::: warning
1. If both `.tool-versions` and other version manager's configuration files (`.nvmrc`, `.sdkmanrc`, etc.) exist in the
directory, `vfox` **priority read** the `.tool-versions` file.
2. Enabling this feature may cause `vfox` to refresh environment variables slightly slower, **please enable it according
to your needs**.
:::
:::

## Proxy Settings

Expand Down Expand Up @@ -61,11 +62,33 @@ If you want to use **your own registry or third-party mirror registry**, please

```yaml
registry:
address: 'https://vfox-plugins.lhan.me'
address: "https://vfox-plugins.lhan.me"
```

::: tip Available Mirrors

- https://cdn.jsdelivr.net/gh/version-fox/vfox-plugins/plugins
- https://rawcdn.githack.com/version-fox/vfox-plugins/plugins
:::

## Config Command <Badge type="tip" text=">= 0.4.0" vertical="middle" />

Setup, view config

**Usage**

```shell
vfox config [<key>] [<value>]
vfox config proxy.enable true
vfox config proxy.url http://localhost:7890
vfox config storage.sdkPath /tmp
```

`key`: Configuration item, separated by `. `.
`value`: If not passed, look at the value of the configuration item.

**Options**

- `-l, --list`: list all config.
- `-un, --unset`: remove a config.
1 change: 1 addition & 0 deletions docs/usage/all-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ vfox uninstall <sdk-name>@<version> Uninstall the specified version of SDK
vfox use [--global --project --session] <sdk-name>[@<version>] Use the specified version of SDK for different scope
vfox list [<sdk-name>] List all installed versions of SDK
vfox current [<sdk-name>] Show the current version of SDK
vfox config [<key>] [<value>] Setup, view config
vfox cd [--plugin] [<sdk-name>] Launch a shell in the VFOX_HOME, SDK directory, or plugin directory
vfox help Show this help message
```
38 changes: 30 additions & 8 deletions docs/zh-hans/guides/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
`vfox` 允许你修改一些配置, 所有配置信息都存放在`$HOME/.version-fox/config.yaml`文件中。

::: tip 注意
如果你是首次运行`vfox`, 则会自动创建一个空的config.yaml文件
如果你是首次运行`vfox`, 则会自动创建一个空的 config.yaml 文件
:::

## 兼容版本文件 <Badge type="tip" text=">= 0.4.0" vertical="middle" />


插件 **支持** 读取其他版本管理器的配置文件, 例如: Nodejs的`nvm``.nvmrc`文件, Java的`SDKMAN``.sdkmanrc`文件等。
插件 **支持** 读取其他版本管理器的配置文件, 例如: Nodejs 的`nvm``.nvmrc`文件, Java 的`SDKMAN``.sdkmanrc`文件等。

此能力**默认是关闭的**, 如果你想开启, 请按照以下方式配置:

Expand All @@ -19,15 +18,16 @@ legacyVersionFile:
```
::: warning
1. 如果目录里同时存在`.tool-versions`和其他版本管理器的配置文件(`.nvmrc`, `.sdkmanrc`等),
`vfox` **优先加载**`.tool-versions`文件.
`vfox` **优先加载**`.tool-versions`文件.
2. 开启此功能可能会导致`vfox`刷新环境变量时略微变慢, **请根据自己的需求开启**。
:::
:::

## 代理设置

::: tip 注意
当前仅支持http(s)代理协议
当前仅支持 http(s)代理协议
:::

**格式**: `http[s]://[username:password@]host:port`
Expand All @@ -40,7 +40,7 @@ proxy:

## 存储路径

`vfox`默认将SDK缓存文件存储在`$HOME/.version-fox/cache`目录下。
`vfox`默认将 SDK 缓存文件存储在`$HOME/.version-fox/cache`目录下。

::: danger !!!
在配置之前, 请确保`vfox`有文件夹的写权限。⚠⚠⚠
Expand All @@ -59,7 +59,7 @@ storage:

```yaml
registry:
address: 'https://vfox-plugins.lhan.me'
address: "https://vfox-plugins.lhan.me"
```

::: tip 可用镜像
Expand All @@ -68,3 +68,25 @@ registry:
- https://cdn.jsdelivr.net/gh/version-fox/vfox-plugins/plugins
- https://rawcdn.githack.com/version-fox/vfox-plugins/plugins
:::

## Config 命令 <Badge type="tip" text=">= 0.4.0" vertical="middle" />

设置,查看配置

**用法**

```shell
vfox config [<key>] [<value>]
vfox config proxy.enable true
vfox config proxy.url http://localhost:7890
vfox config storage.sdkPath /tmp
```

`key`:配置项,以`.`分割。
`value`:不传为查看配置项的值。

**选项**

- `-l, --list`:列出所有配置。
- `-un, --unset`:删除一个配置。
1 change: 1 addition & 0 deletions docs/zh-hans/usage/all-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ vfox uninstall <sdk-name>@<version> Uninstall the specified version of SDK
vfox use [--global --project --session] <sdk-name>[@<version>] Use the specified version of SDK for different scope
vfox list [<sdk-name>] List all installed versions of SDK
vfox current [<sdk-name>] Show the current version of SDK
vfox config [<key>] [<value>] Setup, view config
vfox cd [--plugin] [<sdk-name>] Launch a shell in the VFOX_HOME, SDK directory, or plugin directory
vfox help Show this help message
```
9 changes: 9 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,12 @@ func NewConfig(path string) (*Config, error) {
p := filepath.Join(path, filename)
return NewConfigWithPath(p)
}

func (c *Config) SaveConfig(path string) error {
p := filepath.Join(path, filename)
content, err := yaml.Marshal(c)
if err != nil {
return err
}
return os.WriteFile(p, content, 0644)
}

0 comments on commit dedb6c2

Please sign in to comment.