Skip to content

Commit

Permalink
feat: add 'if' conditional processor to serial and parallel execs (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
jahvon authored Dec 24, 2024
1 parent 6c7084e commit e7ef96a
Show file tree
Hide file tree
Showing 25 changed files with 781 additions and 33 deletions.
17 changes: 10 additions & 7 deletions cmd/internal/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ import (
func RegisterStoreCmd(ctx *context.Context, rootCmd *cobra.Command) {
subCmd := &cobra.Command{
Use: "store",
Short: "Manage the data store.",
Args: cobra.NoArgs,
Short: "Manage the data store for persisting key-value data.",
Long: "Manage the flow data store - a key-value store that persists data within and across executable runs. " +
"Values set outside executables persist globally, while values set within executables persist only for " +
"that execution scope.",
Args: cobra.NoArgs,
}
registerStoreSetCmd(ctx, subCmd)
registerStoreGetCmd(ctx, subCmd)
Expand All @@ -28,7 +31,7 @@ func RegisterStoreCmd(ctx *context.Context, rootCmd *cobra.Command) {
func registerStoreSetCmd(ctx *context.Context, rootCmd *cobra.Command) {
subCmd := &cobra.Command{
Use: "set KEY [VALUE]",
Short: "Set a key-value pair in the data store.",
Short: "Set a key-value pair in the store.",
Long: dataStoreDescription + "This will overwrite any existing value for the key.",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -89,7 +92,7 @@ func registerStoreGetCmd(ctx *context.Context, rootCmd *cobra.Command) {
subCmd := &cobra.Command{
Use: "get KEY",
Aliases: []string{"view"},
Short: "Get a value from the data store.",
Short: "Get a value from the store by its key.",
Long: dataStoreDescription + "This will retrieve the value for the given key.",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -125,7 +128,7 @@ func registerStoreClearCmd(ctx *context.Context, rootCmd *cobra.Command) {
subCmd := &cobra.Command{
Use: "clear",
Aliases: []string{"reset"},
Short: "Clear the data store.",
Short: "Clear data from the store. Use --full to remove all stored data.",
Long: dataStoreDescription + "This will remove all keys and values from the data store.",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
Expand All @@ -142,7 +145,7 @@ func storeClearFunc(ctx *context.Context, cmd *cobra.Command, _ []string) {
if err := store.DestroyStore(); err != nil {
ctx.Logger.FatalErr(err)
}
ctx.Logger.PlainTextSuccess("Data store cleared")
ctx.Logger.PlainTextSuccess("Store store cleared")
return
}
s, err := store.NewStore()
Expand All @@ -157,7 +160,7 @@ func storeClearFunc(ctx *context.Context, cmd *cobra.Command, _ []string) {
if err := s.DeleteBucket(store.EnvironmentBucket()); err != nil {
ctx.Logger.FatalErr(err)
}
ctx.Logger.PlainTextSuccess("Data store cleared")
ctx.Logger.PlainTextSuccess("Store store cleared")
}

var dataStoreDescription = "The data store is a key-value store that can be used to persist data across executions. " +
Expand Down
2 changes: 2 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
- [Workspaces](guide/workspace.md "Managing workspaces")
- [Executables](guide/executable.md "Managing executables")
- [Templating](guide/templating.md "Using flowfile templates")
- [Managing state](guide/state.md "Managing executable state")
- [Conditional execution](guide/conditional.md "Conditional execution")

- Reference

Expand Down
2 changes: 1 addition & 1 deletion docs/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ See github.com/jahvon/flow for more information.
* [flow library](flow_library.md) - View and manage your library of workspaces and executables.
* [flow logs](flow_logs.md) - List and view logs for previous flow executions.
* [flow secret](flow_secret.md) - Manage flow secrets.
* [flow store](flow_store.md) - Manage the data store.
* [flow store](flow_store.md) - Manage the data store for persisting key-value data.
* [flow sync](flow_sync.md) - Scan workspaces and update flow cache.
* [flow template](flow_template.md) - Manage flowfile templates.
* [flow workspace](flow_workspace.md) - Manage flow workspaces.
Expand Down
12 changes: 8 additions & 4 deletions docs/cli/flow_store.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
## flow store

Manage the data store.
Manage the data store for persisting key-value data.

### Synopsis

Manage the flow data store - a key-value store that persists data within and across executable runs. Values set outside executables persist globally, while values set within executables persist only for that execution scope.

### Options

Expand All @@ -19,7 +23,7 @@ Manage the data store.
### SEE ALSO

* [flow](flow.md) - flow is a command line interface designed to make managing and running development workflows easier.
* [flow store clear](flow_store_clear.md) - Clear the data store.
* [flow store get](flow_store_get.md) - Get a value from the data store.
* [flow store set](flow_store_set.md) - Set a key-value pair in the data store.
* [flow store clear](flow_store_clear.md) - Clear data from the store. Use --full to remove all stored data.
* [flow store get](flow_store_get.md) - Get a value from the store by its key.
* [flow store set](flow_store_set.md) - Set a key-value pair in the store.

4 changes: 2 additions & 2 deletions docs/cli/flow_store_clear.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## flow store clear

Clear the data store.
Clear data from the store. Use --full to remove all stored data.

### Synopsis

Expand Down Expand Up @@ -29,5 +29,5 @@ flow store clear [flags]

### SEE ALSO

* [flow store](flow_store.md) - Manage the data store.
* [flow store](flow_store.md) - Manage the data store for persisting key-value data.

4 changes: 2 additions & 2 deletions docs/cli/flow_store_get.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## flow store get

Get a value from the data store.
Get a value from the store by its key.

### Synopsis

Expand Down Expand Up @@ -28,5 +28,5 @@ flow store get KEY [flags]

### SEE ALSO

* [flow store](flow_store.md) - Manage the data store.
* [flow store](flow_store.md) - Manage the data store for persisting key-value data.

4 changes: 2 additions & 2 deletions docs/cli/flow_store_set.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## flow store set

Set a key-value pair in the data store.
Set a key-value pair in the store.

### Synopsis

Expand Down Expand Up @@ -28,5 +28,5 @@ flow store set KEY [VALUE] [flags]

### SEE ALSO

* [flow store](flow_store.md) - Manage the data store.
* [flow store](flow_store.md) - Manage the data store for persisting key-value data.

3 changes: 3 additions & 0 deletions docs/guide/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@
- [Workspaces](workspace.md "Managing workspaces")
- [Executables](executable.md "Managing executables")
- [Templating](templating.md "Using flowfile templates")
- [Managing state](guide/state.md "Managing executable state")
- [Conditional execution](guide/conditional.md "Conditional execution")

126 changes: 126 additions & 0 deletions docs/guide/conditional.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Conditional Expressions

flow CLI uses conditional expressions to control [executable](executable.md) behavior based on runtime conditions. These expressions are written
using a simple expression language that provides access to system information, environment variables, and stored data.

## Expression Language

Flow uses the [Expr](https://expr-lang.org) language for evaluating conditions. The language supports common
operators and functions while providing access to flow executable-specific context data.

**See the [Expr language documentation](https://expr-lang.org/docs/language-definition) for more information on the
expression syntax.**

### Basic Operators

The expression language supports standard comparison and logical operators:

- Comparison: `==`, `!=`, `<`, `>`, `<=`, `>=`
- Logical: `and`, `or`, `not`
- String: `+` (concatenation), `matches` (regex matching)
- Length: `len()`

### Available Context

When writing conditions, you have access to several context variables:

- `os`: Operating system (e.g., "linux", "darwin", "windows")
- `arch`: System architecture (e.g., "amd64", "arm64")
- `ctx`: Flow context information
- `workspace`: Current workspace name
- `namespace`: Current namespace
- `workspacePath`: Path to current workspace
- `flowFilePath`: Path to current flow file
- `flowFileDir`: Directory containing current flow file
- `store`: Key-value map of data store contents
- `env`: Map of environment variables

## Writing Conditions

Conditions can be used in various places within flow, most commonly in the `if` field of executable configurations. Here are
some examples of common conditional patterns:

### Operating System and Architecture Checks

Check for specific operating systems or architectures:

```yaml
executables:
- verb: install
name: system-specific
serial:
execs:
- if: os == "darwin"
cmd: brew install myapp
- if: os == "linux"
cmd: apt-get install myapp
- if: arch == "amd64"
cmd: make build-amd64
- if: arch == "arm64"
cmd: make build-arm64
```
### Environment Variable Checks
Make decisions based on environment variables:
```yaml
executables:
- verb: deploy
name: env-check
serial:
execs:
- if: env["ENVIRONMENT"] == "production"
cmd: echo "Deploying to production"
- if: env["DEBUG"] == "true"
cmd: echo "Debug mode enabled"
```
### Data Store Conditions
Use stored data to control execution:
```yaml
executables:
- verb: run
name: data-check
serial:
execs:
- cmd: flow store set feature-flag enabled
- if: data["feature-flag"] == "enabled"
cmd: echo "Feature is enabled"
- if: len(data["optional-key"]) > 0
cmd: echo "Optional key exists"
```
### Complex Conditions
Combine multiple conditions using logical operators:
```yaml
executables:
- verb: build
name: complex-check
serial:
execs:
- if: os == "linux" and env["CI"] == "true"
cmd: echo "Running in Linux CI environment"
- if: len(data["build-id"]) > 0 and (os == "darwin" or os == "linux")
cmd: echo "Valid build on Unix-like system"
```
### Path and Location Checks
Use context information to make path-based decisions:
```yaml
executables:
- verb: setup
name: path-check
serial:
execs:
- if: ctx.workspace == "development"
cmd: echo "development workspace is active"
- if: ctx.flowFileDir matches ".*/scripts$"
cmd: echo "In scripts directory"
```
Loading

0 comments on commit e7ef96a

Please sign in to comment.