Skip to content

Commit

Permalink
Start getting v3 core functionality working
Browse files Browse the repository at this point in the history
  • Loading branch information
TomWright committed Sep 30, 2024
1 parent 20f73ab commit e09907d
Show file tree
Hide file tree
Showing 76 changed files with 1,818 additions and 385 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
- name: Set env
run: echo RELEASE_VERSION=development >> $GITHUB_ENV
- name: Build
run: GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} CGO_ENABLED=0 go build -o target/release/${{ matrix.artifact_name }} -ldflags="-X 'github.com/tomwright/dasel/v2/internal.Version=${{ env.RELEASE_VERSION }}'" ./cmd/dasel
run: GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} CGO_ENABLED=0 go build -o target/release/${{ matrix.artifact_name }} -ldflags="-X 'github.com/tomwright/dasel/v3/internal.Version=${{ env.RELEASE_VERSION }}'" ./cmd/dasel
- name: Test version
if: matrix.test_version == true
run: ./target/release/${{ matrix.artifact_name }} --version
2 changes: 1 addition & 1 deletion .github/workflows/build-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
- name: Set env
run: echo RELEASE_VERSION=development >> $GITHUB_ENV
- name: Build
run: GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} CGO_ENABLED=0 go build -o target/release/${{ matrix.artifact_name }} -ldflags="-X 'github.com/tomwright/dasel/v2/internal.Version=${{ env.RELEASE_VERSION }}'" ./cmd/dasel
run: GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} CGO_ENABLED=0 go build -o target/release/${{ matrix.artifact_name }} -ldflags="-X 'github.com/tomwright/dasel/v3/internal.Version=${{ env.RELEASE_VERSION }}'" ./cmd/dasel
- name: Test version
if: matrix.test_version == true
run: ./target/release/${{ matrix.artifact_name }} --version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
- name: Set env
run: echo RELEASE_VERSION=${GITHUB_REF:10} >> $GITHUB_ENV
- name: Build
run: GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} CGO_ENABLED=0 go build -o target/release/${{ matrix.artifact_name }} -ldflags="-X 'github.com/tomwright/dasel/v2/internal.Version=${{ env.RELEASE_VERSION }}'" ./cmd/dasel
run: GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} CGO_ENABLED=0 go build -o target/release/${{ matrix.artifact_name }} -ldflags="-X 'github.com/tomwright/dasel/v3/internal.Version=${{ env.RELEASE_VERSION }}'" ./cmd/dasel
- name: Test version
if: matrix.test_version == true
run: ./target/release/${{ matrix.artifact_name }} --version
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Changed go module to `github.com/tomwright/dasel/v2` to ensure it works correctly with go modules.
- Changed go module to `github.com/tomwright/dasel/v3` to ensure it works correctly with go modules.

## [v2.1.0] - 2023-01-11

Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# dasel

[![Gitbook](https://badges.aleen42.com/src/gitbook_1.svg)](https://daseldocs.tomwright.me)
[![Go Report Card](https://goreportcard.com/badge/github.com/TomWright/dasel/v2)](https://goreportcard.com/report/github.com/TomWright/dasel/v2)
[![PkgGoDev](https://pkg.go.dev/badge/github.com/tomwright/dasel)](https://pkg.go.dev/github.com/tomwright/dasel/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/tomwright/dasel/v3)](https://goreportcard.com/report/github.com/tomwright/dasel/v3)
[![PkgGoDev](https://pkg.go.dev/badge/github.com/tomwright/dasel)](https://pkg.go.dev/github.com/tomwright/dasel/v3)
![Test](https://github.com/TomWright/dasel/workflows/Test/badge.svg)
![Build](https://github.com/TomWright/dasel/workflows/Build/badge.svg)
[![codecov](https://codecov.io/gh/TomWright/dasel/branch/master/graph/badge.svg)](https://codecov.io/gh/TomWright/dasel)
Expand Down Expand Up @@ -75,7 +75,7 @@ brew install dasel
You can also install a [development version](https://daseldocs.tomwright.me/installation#development-version) with:

```bash
go install github.com/tomwright/dasel/v2/cmd/dasel@master
go install github.com/tomwright/dasel/v3/cmd/dasel@master
```

For more information see the [installation documentation](https://daseldocs.tomwright.me/installation).
Expand Down Expand Up @@ -181,7 +181,7 @@ Please [open a discussion](https://github.com/TomWright/dasel/discussions) if:
- Uses a [standard query/selector syntax](https://daseldocs.tomwright.me/functions/selector-overview) across all data formats.
- Zero runtime dependencies.
- [Available on Linux, Mac and Windows](https://daseldocs.tomwright.me/installation).
- Available to [import and use in your own projects](https://pkg.go.dev/github.com/tomwright/dasel/v2).
- Available to [import and use in your own projects](https://pkg.go.dev/github.com/tomwright/dasel/v3).
- [Run via Docker](https://daseldocs.tomwright.me/installation#docker).
- [Faster than jq/yq](#benchmarks).
- [Pre-commit hooks](#pre-commit).
Expand Down
3 changes: 2 additions & 1 deletion cmd/dasel/main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package main

import (
"github.com/tomwright/dasel/v2/internal/command"
"os"

"github.com/tomwright/dasel/v3/internal/command"
)

func main() {
Expand Down
3 changes: 2 additions & 1 deletion dencoding/json_decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package dencoding_test

import (
"bytes"
"github.com/tomwright/dasel/v2/dencoding"
"io"
"reflect"
"testing"

"github.com/tomwright/dasel/v3/dencoding"
)

func TestJSONDecoder_Decode(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion dencoding/json_encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package dencoding_test

import (
"bytes"
"github.com/tomwright/dasel/v2/dencoding"
"testing"

"github.com/tomwright/dasel/v3/dencoding"
)

func TestJSONEncoder_Encode(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion dencoding/toml_decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package dencoding_test

import (
"bytes"
"github.com/tomwright/dasel/v2/dencoding"
"io"
"reflect"
"testing"

"github.com/tomwright/dasel/v3/dencoding"
)

func TestTOMLDecoder_Decode(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion dencoding/toml_encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package dencoding_test

import (
"bytes"
"github.com/tomwright/dasel/v2/dencoding"
"testing"

"github.com/tomwright/dasel/v3/dencoding"
)

func TestTOMLEncoder_Encode(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion dencoding/yaml_decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strconv"
"time"

"github.com/tomwright/dasel/v2/util"
"github.com/tomwright/dasel/v3/util"
"gopkg.in/yaml.v3"
)

Expand Down
2 changes: 1 addition & 1 deletion dencoding/yaml_decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"reflect"
"testing"

"github.com/tomwright/dasel/v2/dencoding"
"github.com/tomwright/dasel/v3/dencoding"
)

func TestYAMLDecoder_Decode(t *testing.T) {
Expand Down
5 changes: 3 additions & 2 deletions dencoding/yaml_encoder.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package dencoding

import (
"github.com/tomwright/dasel/v2/util"
"gopkg.in/yaml.v3"
"io"
"strconv"

"github.com/tomwright/dasel/v3/util"
"gopkg.in/yaml.v3"
)

// YAMLEncoder wraps a standard yaml encoder to implement custom ordering logic.
Expand Down
3 changes: 2 additions & 1 deletion dencoding/yaml_encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package dencoding_test

import (
"bytes"
"github.com/tomwright/dasel/v2/dencoding"
"testing"

"github.com/tomwright/dasel/v3/dencoding"
)

func TestYAMLEncoder_Encode(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"reflect"
"testing"

"github.com/tomwright/dasel/v2"
"github.com/tomwright/dasel/v3"
)

func TestErrorMessages(t *testing.T) {
Expand Down
157 changes: 157 additions & 0 deletions execution/execute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package execution

import (
"fmt"

"github.com/tomwright/dasel/v3/model"
"github.com/tomwright/dasel/v3/selector/ast"
"github.com/tomwright/dasel/v3/selector/lexer"
"github.com/tomwright/dasel/v3/selector/parser"
)

func ExecuteSelector(selector string, value *model.Value) (*model.Value, error) {
tokens, err := lexer.NewTokenizer(selector).Tokenize()
if err != nil {
return nil, fmt.Errorf("error tokenizing selector: %w", err)
}

expr, err := parser.NewParser(tokens).Parse()
if err != nil {
return nil, fmt.Errorf("error parsing selector: %w", err)
}

res, err := ExecuteAST(expr, value)
if err != nil {
return nil, fmt.Errorf("error executing selector: %w", err)
}

return res, nil
}

type expressionExecutor func(data *model.Value) (*model.Value, error)

func ExecuteAST(expr ast.Expr, value *model.Value) (*model.Value, error) {
executor, err := exprExecutor(expr)
if err != nil {
return nil, fmt.Errorf("error evaluating expression: %w", err)
}
res, err := executor(value)
if err != nil {
return nil, fmt.Errorf("execution error: %w", err)
}

return res, nil
}

func exprExecutor(expr ast.Expr) (expressionExecutor, error) {
switch e := expr.(type) {
case ast.BinaryExpr:
return binaryExprExecutor(e)
case ast.CallExpr:
return callExprExecutor(e)
case ast.ChainedExpr:
return chainedExprExecutor(e)
case ast.SpreadExpr:
return spreadExprExecutor()
case ast.RangeExpr:
return rangeExprExecutor(e)
case ast.IndexExpr:
return indexExprExecutor(e)
case ast.PropertyExpr:
return propertyExprExecutor(e)
case ast.NumberIntExpr:
return numberIntExprExecutor(e)
case ast.NumberFloatExpr:
return numberFloatExprExecutor(e)
case ast.StringExpr:
return stringExprExecutor(e)
case ast.BoolExpr:
return boolExprExecutor(e)
case ast.ObjectExpr:
return objectExprExecutor(e)
case ast.MapExpr:
return mapExprExecutor(e)
default:
return nil, fmt.Errorf("unhandled expression type: %T", e)
}
}

func binaryExprExecutor(e ast.BinaryExpr) (expressionExecutor, error) {
return func(data *model.Value) (*model.Value, error) {
panic("not implemented")
}, nil
}

func chainedExprExecutor(e ast.ChainedExpr) (expressionExecutor, error) {
return func(data *model.Value) (*model.Value, error) {
for _, expr := range e.Exprs {
res, err := ExecuteAST(expr, data)
if err != nil {
return nil, fmt.Errorf("error executing expression: %w", err)
}
data = res
}
return data, nil
}, nil
}

func spreadExprExecutor() (expressionExecutor, error) {
return func(data *model.Value) (*model.Value, error) {
s := model.NewSliceValue()

switch {
case data.IsSlice():
v, err := data.SliceValue()
if err != nil {
return nil, fmt.Errorf("error getting slice value: %w", err)
}
for _, sv := range v {
s.Append(model.NewValue(sv))
}
case data.IsMap():
v, err := data.MapValue()
if err != nil {
return nil, fmt.Errorf("error getting map value: %w", err)
}
for _, kv := range v.KeyValues() {
s.Append(model.NewValue(kv.Value))
}
default:
return nil, fmt.Errorf("cannot spread on type %s", data.Type())
}

return s, nil
}, nil
}

func rangeExprExecutor(e ast.RangeExpr) (expressionExecutor, error) {
return func(data *model.Value) (*model.Value, error) {
panic("not implemented")
}, nil
}

func indexExprExecutor(e ast.IndexExpr) (expressionExecutor, error) {
return func(data *model.Value) (*model.Value, error) {
panic("not implemented")
}, nil
}

func propertyExprExecutor(e ast.PropertyExpr) (expressionExecutor, error) {
return func(data *model.Value) (*model.Value, error) {
if !data.IsMap() {
return nil, fmt.Errorf("expected map, got %s", data.Type())
}
key, err := ExecuteAST(e.Property, data)
if err != nil {
return nil, fmt.Errorf("error evaluating property: %w", err)
}
if !key.IsString() {
return nil, fmt.Errorf("expected property to resolve to string, got %s", key.Type())
}
keyStr, err := key.StringValue()
if err != nil {
return nil, fmt.Errorf("error getting string value: %w", err)
}
return data.GetMapKey(keyStr)
}, nil
}
64 changes: 64 additions & 0 deletions execution/execute_func.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package execution

import (
"fmt"

"github.com/tomwright/dasel/v3/model"
"github.com/tomwright/dasel/v3/selector/ast"
)

func prepareArgs(data *model.Value, argsE ast.Expressions) (model.Values, error) {
args := make(model.Values, 0)
for i, arg := range argsE {
res, err := ExecuteAST(arg, data)
if err != nil {
return nil, fmt.Errorf("error evaluating argument %d: %w", i, err)
}
args = append(args, res)
}
return args, nil
}

func callSingleExecutor(f singleResponseFunc, argsE ast.Expressions) (expressionExecutor, error) {
return func(data *model.Value) (*model.Value, error) {
args, err := prepareArgs(data, argsE)
if err != nil {
return nil, fmt.Errorf("error preparing arguments: %w", err)
}

res, err := f(data, args)
if err != nil {
return nil, fmt.Errorf("error executing function: %w", err)
}

return res, nil
}, nil
}

func callMultiExecutor(f multiResponseFunc, argsE ast.Expressions) (expressionExecutor, error) {
return func(data *model.Value) (*model.Value, error) {
panic("multi response functions are not supported")
//args, err := prepareArgs(data, argsE)
//if err != nil {
// return nil, fmt.Errorf("error preparing arguments: %w", err)
//}

//res, err := f(data, args)
//if err != nil {
// return nil, fmt.Errorf("error executing function: %w", err)
//}

//return res, nil
}, nil
}

func callExprExecutor(e ast.CallExpr) (expressionExecutor, error) {
if f, ok := singleResponseFuncLookup[e.Function]; ok {
return callSingleExecutor(f, e.Args)
}
if f, ok := multiResponseFuncLookup[e.Function]; ok {
return callMultiExecutor(f, e.Args)
}

return nil, fmt.Errorf("unknown function: %q", e.Function)
}
Loading

0 comments on commit e09907d

Please sign in to comment.