feat(command): allow bypassing custom logic

resolves #4835
This commit is contained in:
Jan De Dobbeleer 2024-04-20 09:35:11 +02:00 committed by Jan De Dobbeleer
parent 9d1b9e2b7c
commit 6c44459b6f
3 changed files with 60 additions and 25 deletions

View file

@ -21,6 +21,8 @@ const (
Command properties.Property = "command" Command properties.Property = "command"
// Command to execute // Command to execute
Script properties.Property = "script" Script properties.Property = "script"
// Interpret execution, or not
Interpret properties.Property = "interpret"
) )
func (c *Cmd) Template() string { func (c *Cmd) Template() string {
@ -32,18 +34,28 @@ func (c *Cmd) Enabled() bool {
if !c.env.HasCommand(shell) { if !c.env.HasCommand(shell) {
return false return false
} }
command := c.props.GetString(Command, "") command := c.props.GetString(Command, "")
if len(command) != 0 { if len(command) != 0 {
return c.runCommand(shell, command) return c.runCommand(shell, command)
} }
script := c.props.GetString(Script, "") script := c.props.GetString(Script, "")
if len(script) != 0 { if len(script) != 0 {
return c.runScript(shell, script) return c.runScript(shell, script)
} }
return false return false
} }
func (c *Cmd) runCommand(shell, command string) bool { func (c *Cmd) runCommand(shell, command string) bool {
interpret := c.props.GetBool(Interpret, true)
if !interpret {
c.Output = c.env.RunShellCommand(shell, command)
return len(c.Output) != 0
}
if strings.Contains(command, "||") { if strings.Contains(command, "||") {
commands := strings.Split(command, "||") commands := strings.Split(command, "||")
for _, cmd := range commands { for _, cmd := range commands {
@ -54,6 +66,7 @@ func (c *Cmd) runCommand(shell, command string) bool {
} }
} }
} }
if strings.Contains(command, "&&") { if strings.Contains(command, "&&") {
var output string var output string
commands := strings.Split(command, "&&") commands := strings.Split(command, "&&")
@ -63,6 +76,7 @@ func (c *Cmd) runCommand(shell, command string) bool {
c.Output = output c.Output = output
return len(c.Output) != 0 return len(c.Output) != 0
} }
c.Output = c.env.RunShellCommand(shell, strings.TrimSpace(command)) c.Output = c.env.RunShellCommand(shell, strings.TrimSpace(command))
return len(c.Output) != 0 return len(c.Output) != 0
} }

View file

@ -136,6 +136,23 @@ func TestExecuteMultipleCommandsOrDisabled(t *testing.T) {
assert.False(t, enabled) assert.False(t, enabled)
} }
func TestExecuteNonInterpretedCommand(t *testing.T) {
env := new(mock.MockedEnvironment)
env.On("HasCommand", "bash").Return(true)
env.On("RunShellCommand", "bash", "echo hello && echo world").Return("hello world")
props := properties.Map{
Command: "echo hello && echo world",
Interpret: false,
}
c := &Cmd{
props: props,
env: env,
}
enabled := c.Enabled()
assert.True(t, enabled)
assert.Equal(t, "hello world", renderTemplate(env, c.Template(), c))
}
func TestExecuteScript(t *testing.T) { func TestExecuteScript(t *testing.T) {
cases := []struct { cases := []struct {
Case string Case string

View file

@ -18,35 +18,39 @@ When the command errors or returns an empty string, this segment isn't rendered.
You have the ability to use `||` or `&&` to stitch commands together and achieve complex results. When using `||` You have the ability to use `||` or `&&` to stitch commands together and achieve complex results. When using `||`
the first command that returns a string will be used (or none when they all fail to produce output that's not an the first command that returns a string will be used (or none when they all fail to produce output that's not an
error). The `&&` functionality will join the output of the commands when successful. error). The `&&` functionality will join the output of the commands when successful. If you want to run the command
as is, you can set `interpret` to `false`.
## Sample Configuration ## Sample Configuration
import Config from '@site/src/components/Config.js'; import Config from "@site/src/components/Config.js";
<Config data={{ <Config
"type": "prompt", data={{
"alignment": "right", type: "prompt",
"segments": [ alignment: "right",
{ segments: [
"type": "command", {
"style": "plain", type: "command",
"foreground": "#ffffff", style: "plain",
"properties": { foreground: "#ffffff",
"shell": "bash", properties: {
"command": "git log --pretty=format:%cr -1 || date +%H:%M:%S" shell: "bash",
} command: "git log --pretty=format:%cr -1 || date +%H:%M:%S",
} },
] },
}}/> ],
}}
/>
## Properties ## Properties
| Name | Type | Default | Description | | Name | Type | Default | Description |
| --------- | :------: | :-----: | --------------------------------------------------------------------------------- | | ----------- | :-------: | :-----: | -------------------------------------------------------------------------------- |
| `shell` | `string` | `bash` | the shell in which to run the command in. Uses `shell -c command` under the hood. | | `shell` | `string` | `bash` | the shell in which to run the command in. Uses `shell -c command` under the hood |
| `command` | `string` | | the command(s) to run | | `interpret` | `boolean` | `true` | interpret the command or run as is |
| `script` | `string` | | the path to a script to run | | `command` | `string` | | the command(s) to run |
| `script` | `string` | | the path to a script to run |
## Template ([info][templates]) ## Template ([info][templates])
@ -60,9 +64,9 @@ import Config from '@site/src/components/Config.js';
### Properties ### Properties
| Name | Type | Description | | Name | Type | Description |
| ------- | ------ | ---------------------------------- | | --------- | -------- | ------------------------------------ |
|`.Output`|`string`|the output of the command or script.| | `.Output` | `string` | the output of the command or script. |
[env]: /docs/configuration/templates#environment-variables [env]: /docs/configuration/templates#environment-variables
[templates]: /docs/configuration/templates [templates]: /docs/configuration/templates