Skip to content

Commit

Permalink
Add config options ParameterMode + RemoveComments
Browse files Browse the repository at this point in the history
Signed-off-by: Philipp Sessler <sessler.phil@googlemail.com>
  • Loading branch information
lemoony committed Feb 16, 2022
1 parent bb08569 commit 2becc2c
Show file tree
Hide file tree
Showing 26 changed files with 307 additions and 64 deletions.
106 changes: 84 additions & 22 deletions docs/configuration/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ snipkit config init

This command creates a config file in the SnipKit home directory. The initial config file looks similar to this:

```yaml
version: 1.0.0
```yaml title="config.yaml"
version: 1.1.0
config:
style:
# The theme defines the terminal colors used by Snipkit.
Expand Down Expand Up @@ -58,34 +58,20 @@ When typing `snipkit config edit` the configuration file will be opened in an ed
The default editor is defined by the `$VISUAL` or `$EDITOR` environment variables. This behavior can be overwritten by
setting the `editor` field in the configuration file to a non-empty string, e.g.:

```yaml
version: 1.0.0
```yaml title="config.yaml"
version: 1.1.0
config:
editor: "code"
```

If no value is provided at all, SnipKit will try to use `vim`.

### Shell

The shell for script executions is defined by the `$SHELL` environment variable. This behavior can be overwritten by
setting the `shell` option to a non-empty string, e.g.:

```yaml
version: 1.0.0
config:
shell: "/bin/zsh"
```

If neither `$SHELL` nor the config option `shell` is defined, SnipKit will try to use `/bin/bash` as a fallback value.


### Theme

SnipKit supports multiple themes out of the box and also allows you to define your own themes:

```yaml
version: 1.0.0
```yaml title="config.yaml"
version: 1.1.0
config:
theme: "default"
```
Expand All @@ -100,15 +86,90 @@ For a list of supported default themes, have a look at the [Themes][themes] page
Most of the time, you want to call the same subcommand, e.g. `print` or `exec`. You can configure `snipkit` so that this
command gets executed by default:

```yaml
version: 1.0.0
```yaml title="config.yaml"
version: 1.1.0
config:
defaultRootCommand: "exec"
```

This way, calling `snipkit` will yield the same result as `snipkit exec`. If you want to call the `print` command instead,
you can still call `snipkit print`.

### Script Options

#### Shell

The shell for script executions is defined by the `$SHELL` environment variable. This behavior can be overwritten by setting
the `shell` option to a non-empty string, e.g.:

```yaml title="config.yaml"
version: 1.1.0
config:
script:
shell: "/bin/zsh"
```

If neither `$SHELL` nor the config option `shell` is defined, SnipKit will try to use `/bin/bash` as a fallback value.

#### Parameter mode

How values are injected into your snippet for the defined parameters is defined by the `parameterMode` option:

```yaml title="config.yaml"
version: 1.1.0
config:
script:
parameterMode: SET
```

The default value is `SET`, defining that values should be set as variables. This means that the following script

```sh title="Raw snippet before execution"
# ${VAR} Description: What to print
echo ${VAR}
```

will be updated in the following way, e.g. for `VAR = "Hello word"`:

```sh title="Example for parameterMode SET"
# ${VAR} Description: What to print
VAR="Hello world"
echo ${VAR}
```

Alternatively, all occurrences of a parameter can be replaced with the actual value when
specifying `REPLACE` for `parameterMode`:

```sh title="Example for parameterMode = REPLACE"
echo "Hello world"
```

#### Remove Comments

SnipKit will remove all parameter comments from a snippet when specifying `removeComments`:

```yaml title="config.yaml"
version: 1.1.0
config:
script:
removeComments: true
```

This means that the following script

```sh title="Raw snippet before execution"
# ${VAR} Description: What to print
echo ${VAR}
```

will be formatted in the following way:

```sh title="Example for removeComments = true"
echo ${VAR}
```

!!! info
Comments will always be removed if `parameterMode` is set to `REPLACE`.

## Clean up

Expand All @@ -122,4 +183,5 @@ The cleanup method is a way to remove all SnipKit artifacts from your hard drive
home directory. If this directory is empty at the end of the cleanup process, it will be deleted as well.

[managers]: ../managers/overview.md

[themes]: themes.md
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ require (
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/kr/pty v1.1.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
Expand Down
4 changes: 3 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ github.com/corbym/gocrest v1.0.5/go.mod h1:lF3xBPnOU5DYDpa/vUq63SMxUhd5UAwGgmA8Z
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/danieljoos/wincred v1.1.0 h1:3RNcEpBg4IhIChZdFRSdlQt1QjCp1sMAPIrOnm7Yf8g=
github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -295,8 +296,9 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lemoony/tview v0.0.0-20220108075851-caa9ee4cec2d h1:0yBL9dq9G56KsVHb+KYqesB0tlTgDR8GZP2VlyWb8ZY=
Expand Down
17 changes: 16 additions & 1 deletion internal/app/app_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"emperror.dev/errors"
"github.com/phuslu/log"

"github.com/lemoony/snipkit/internal/config"
"github.com/lemoony/snipkit/internal/model"
"github.com/lemoony/snipkit/internal/ui"
"github.com/lemoony/snipkit/internal/utils/stringutil"
)
Expand All @@ -21,7 +23,7 @@ func (a *appImpl) LookupAndExecuteSnippet() {

parameters := snippet.GetParameters()
if parameterValues, ok := a.tui.ShowParameterForm(parameters, ui.OkButtonExecute); ok {
executeScript(snippet.Format(parameterValues), a.config.Shell)
executeScript(snippet.Format(parameterValues, formatOptions(a.config.Script)), a.config.Script.Shell)
}
}

Expand All @@ -43,3 +45,16 @@ func executeScript(script, configuredShell string) {
log.Info().Err(err)
}
}

func formatOptions(cfg config.ScriptConfig) model.SnippetFormatOptions {
var paramMode model.SnippetParamMode
if cfg.ParameterMode == config.ParameterModeReplace {
paramMode = model.SnippetParamModeReplace
} else {
paramMode = model.SnippetParamModeSet
}
return model.SnippetFormatOptions{
RemoveComments: cfg.RemoveComments,
ParamMode: paramMode,
}
}
25 changes: 25 additions & 0 deletions internal/app/app_exec_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package app

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

"github.com/lemoony/snipkit/internal/config"
"github.com/lemoony/snipkit/internal/config/configtest"
"github.com/lemoony/snipkit/internal/model"
"github.com/lemoony/snipkit/internal/utils/testutil"
Expand Down Expand Up @@ -43,3 +46,25 @@ echo "${VAR1}"`

app.LookupAndExecuteSnippet()
}

func Test_formatOptions(t *testing.T) {
tests := []struct {
config config.ScriptConfig
expected model.SnippetFormatOptions
}{
{
config: config.ScriptConfig{RemoveComments: true, ParameterMode: config.ParameterModeSet},
expected: model.SnippetFormatOptions{RemoveComments: true, ParamMode: model.SnippetParamModeSet},
},
{
config: config.ScriptConfig{RemoveComments: false, ParameterMode: config.ParameterModeReplace},
expected: model.SnippetFormatOptions{RemoveComments: false, ParamMode: model.SnippetParamModeReplace},
},
}

for i, tt := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
assert.Equal(t, tt.expected, formatOptions(tt.config))
})
}
}
2 changes: 1 addition & 1 deletion internal/app/app_print.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func (a *appImpl) LookupAndCreatePrintableSnippet() (string, bool) {

parameters := snippet.GetParameters()
if parameterValues, ok := a.tui.ShowParameterForm(parameters, ui.OkButtonPrint); ok {
return snippet.Format(parameterValues), true
return snippet.Format(parameterValues, formatOptions(a.config.Script)), true
}

return "", false
Expand Down
15 changes: 14 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import (
"github.com/lemoony/snipkit/internal/ui"
)

type ParameterMode string

const (
ParameterModeSet = "SET"
ParameterModeReplace = "Replace"
)

type VersionWrapper struct {
Version string `yaml:"version" mapstructure:"version"`
Config Config `yaml:"config" mapstructure:"config"`
Expand All @@ -13,7 +20,13 @@ type VersionWrapper struct {
type Config struct {
Style ui.Config `yaml:"style" mapstructure:"style"`
Editor string `yaml:"editor" mapstructure:"editor" head_comment:"Your preferred editor to open the config file when typing 'snipkit config edit'." line_comment:"Defaults to a reasonable value for your operation system when empty."`
Shell string `yaml:"shell" mapstructure:"shell" head_comment:"The path to the shell to execute scripts with. If not set or empty, $SHELL will be used instead. Fallback is '/bin/bash'."`
DefaultRootCommand string `yaml:"defaultRootCommand" mapstructure:"defaultRootCommand" head_comment:"The command which should run if you don't provide any subcommand." line_comment:"If not set, the help text will be shown."`
Script ScriptConfig `yaml:"scripts" mapstructure:"Options regarding script handling"`
Manager managers.Config `yaml:"manager" mapstructure:"manager"`
}

type ScriptConfig struct {
Shell string `yaml:"shell" mapstructure:"shell" head_comment:"The path to the shell to execute scripts with. If not set or empty, $SHELL will be used instead. Fallback is '/bin/bash'."`
ParameterMode ParameterMode `yaml:"parameterMode" mapstructure:"parameterMode" head_comment:"Defines how parameters are handled. Allowed values: SET (sets the parameter value as shell variable) and REPLACE (replaces all occurrences of the variable with the actual value)"`
RemoveComments bool `yaml:"removeComments" mapstructure:"removeComments" head_comment:"If set to true, any comments in your scripts will be removed upon executing or printing."`
}
19 changes: 14 additions & 5 deletions internal/config/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,39 @@ const (
yamlCommentHead = yamlCommentKind(2)

yamlDefaultIndent = 2

version = "1.1.0"
)

var sliceIndexRegex = regexp.MustCompile(`\[\d]`)

func wrap(config Config) VersionWrapper {
return VersionWrapper{
Version: "1.0.0",
Version: version,
Config: config,
}
}

func createConfigFile(system *system.System, viper *viper.Viper) {
config := wrap(Config{})

config.Config.Style = ui.DefaultConfig()
config := wrap(defaultConfig())
data := SerializeToYamlWithComment(config)

configPath := viper.ConfigFileUsed()

log.Debug().Msgf("Going to use config path %s", configPath)
system.CreatePath(configPath)
system.WriteFile(configPath, data)
}

func defaultConfig() Config {
return Config{
Style: ui.DefaultConfig(),
Script: ScriptConfig{
ParameterMode: ParameterModeSet,
RemoveComments: false,
},
}
}

func SerializeToYamlWithComment(value interface{}) []byte {
// get all tag comments
commentMap := map[string][]yamlComment{}
Expand Down
6 changes: 4 additions & 2 deletions internal/config/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import (

func Test_serializeToYamlWithComment(t *testing.T) {
var testConfig VersionWrapper
testConfig.Version = "1.0.0"
testConfig.Version = version
testConfig.Config.Editor = "foo-editor"
testConfig.Config.Shell = "/bin/zsh"
testConfig.Config.Script.Shell = "/bin/zsh"
testConfig.Config.Script.RemoveComments = true
testConfig.Config.Script.ParameterMode = ParameterModeSet
testConfig.Config.Style.Theme = "simple"

testConfig.Config.Manager.SnippetsLab = &snippetslab.Config{
Expand Down
4 changes: 4 additions & 0 deletions internal/config/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ func (s *serviceImpl) LoadConfig() (Config, error) {
return invalidConfig, err
}

if wrapper.Version != version {
log.Warn().Msgf("Config version is not up to date - expected %s, actual %s", version, wrapper.Version)
}

s.config = &wrapper.Config

return *s.config, nil
Expand Down
11 changes: 8 additions & 3 deletions internal/config/testdata/example-config.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
version: 1.0.0
version: 1.1.0
config:
style:
# The theme defines the terminal colors used by Snipkit.
# Available themes:default(.light|.dark),simple.
theme: simple
# Your preferred editor to open the config file when typing 'snipkit config edit'.
editor: foo-editor # Defaults to a reasonable value for your operation system when empty.
# The path to the shell to execute scripts with. If not set or empty, $SHELL will be used instead. Fallback is '/bin/bash'.
shell: /bin/zsh
# The command which should run if you don't provide any subcommand.
defaultRootCommand: "" # If not set, the help text will be shown.
scripts:
# The path to the shell to execute scripts with. If not set or empty, $SHELL will be used instead. Fallback is '/bin/bash'.
shell: /bin/zsh
# Defines how parameters are handled. Allowed values: SET (sets the parameter value as shell variable) and REPLACE (replaces all occurrences of the variable with the actual value)
parameterMode: SET
# If set to true, any comments in your scripts will be removed upon executing or printing.
removeComments: true
manager:
snippetsLab:
# Set to true if you want to use SnippetsLab.
Expand Down
2 changes: 1 addition & 1 deletion internal/managers/fslibrary/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func Test_GetSnippets_LazyOpen_HideTitleHeader(t *testing.T) {
assert.Empty(t, snippets[0].GetTags())
assert.Equal(t, model.LanguageBash, snippets[0].GetLanguage())
assert.Empty(t, snippets[0].GetParameters())
assert.Equal(t, "content", snippets[0].Format([]string{}))
assert.Equal(t, "content", snippets[0].Format([]string{}, model.SnippetFormatOptions{}))
}

func Test_checkSuffix(t *testing.T) {
Expand Down

0 comments on commit 2becc2c

Please sign in to comment.