Skip to content
Snippets Groups Projects
Verified Commit 1d4d8117 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: setting the paths does not always work smoothly #9

parent 4746b5f3
No related branches found
No related tags found
No related merge requests found
# THIS FILE IS AUTOGENERATED BY THE DEVENVSHELL
# DO NOT EDIT THIS FILE MANUALLY
# INSTEAD EDIT THE DEVENVSHELL CONFIGURATION FILE devenv.nix
# AND OPEN A SHELL WITH THE COMMAND devenv shell
#
image: docker-registry.schukai.com:443/nixos-ci-devenv:latest
services:
- docker:dind
variables:
# The repo name as used in
# https://github.com/nix-community/NUR/blob/master/repos.json
......@@ -13,7 +19,6 @@ variables:
DOCKER_DRIVER: overlay2
GIT_DEPTH: 10
stages:
- test
- deploy
......
# THIS FILE IS AUTOGENERATED BY THE DEVENVSHELL
# DO NOT EDIT THIS FILE MANUALLY
# INSTEAD EDIT THE DEVENVSHELL CONFIGURATION FILE devenv.nix
# AND OPEN A SHELL WITH THE COMMAND devenv shell
#
# Information about the task runner can be found here:
# https://taskfile.dev
version: '3'
......@@ -5,29 +12,36 @@ version: '3'
tasks:
default:
cmds:
- task --list-all
- task --list
silent: true
test:
desc: Execute unit tests in Go.
cmds:
cmds:
- echo "Execute unit tests in Go."
- go test -cover -v ./...
- go test -bench .
- go test -race .
- go test -bench -v ./...
- go test -race -v ./...
test-fuzz:
desc: Conduct fuzzing tests.#
cmds:
- echo "Conduct fuzzing tests."
- go test -v -fuzztime=10s -fuzz=Fuzz ./...
- go test -v -fuzztime=30s -fuzz=Fuzz ./...
add-licenses:
desc: Attach license headers to Go files.
cmds:
- echo "Attach license headers to Go files."
- go install github.com/google/addlicense@latest
- addlicense -c "schukai GmbH" -s -l "AGPL-3.0" ./*.go
silent: true
check-licenses:
desc: Check license headers of Go files.
silent: true
cmds:
- go-licenses save "$(get-go-default-packages)" --ignore "gitlab.schukai.com" --force --save_path ${DEVENV_ROOT}/licenses/
check:
desc: Confirm repository status.
......@@ -35,17 +49,11 @@ tasks:
- git diff-index --quiet HEAD || (echo "There are uncommitted changes after running make. Please commit or stash them before running make."; exit 1)
silent: true
build:
desc: Compile the application,
commit:
desc: Commit changes to the repository.
aliases:
- b
vars:
DEVENV_ROOT:
sh: echo "$DEVENV_ROOT"
- c
- ci
- git-commit
cmds:
- devenv shell build-app
sources:
- source/**/*.go
- source/**/*.mod
- dist/**
- do-git-commit
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true">
<buildTags>
<option name="customFlags">
<array>
<option value="" />
</array>
</option>
</buildTags>
</component>
<module type="JAVA_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/licenses" />
<sourceFolder url="file://$MODULE_DIR$/.devenv/state/go/pkg/mod/github.com/google/addlicense@v1.1.1/testdata/expected" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/.devenv/state/go/pkg/mod/github.com/google/addlicense@v1.1.1/testdata/initial" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
......
This diff is collapsed.
......@@ -66,6 +66,26 @@ gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.3.1 h1:oyElaqEiyr2Xg
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.3.1/go.mod h1:UvdD4NAf3gLKYafabJD7e9ZCOetzM9JZ9y4GkZukPVU=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.5.2 h1:R+dL2NJCM+AQNPK4DPDmfvx1eomi1Xb1dl0XKEFj7Ek=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.5.2/go.mod h1:UvdD4NAf3gLKYafabJD7e9ZCOetzM9JZ9y4GkZukPVU=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.5.3 h1:pl5XnGS6lxBCI98pnqNU0D0qt19X7g7/Qf/ycM4Do44=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.5.3/go.mod h1:0vlu9GwsHHuFTm49FSOs60UN3KDgcrcfDeCxsG3Ygyg=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.6.0 h1:1edcW7HB2VvTqzFUEGnnJih316sJvBvwGxBwMP8m3ho=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.6.0/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.7.0 h1:ReofKz+Ys4d2l4y4Whwfbtj7CQPEL1ew46QTf1kPW7A=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.7.0/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.7.1 h1:NRlSHy8DlWhkmZkHzjjdPj7hQMrpL8K8V9an9JW9UAk=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.7.1/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.7.2 h1:LF9b1UiWpShxld9Re4VnvkRt3oi3KqTqpSaU21F9tKg=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.7.2/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.8.0 h1:jG/kDUsBgaqIHLoMiF4cJA627neqf9BwaoKFMaMMB6U=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.8.0/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.8.1 h1:A3KvLvu4rV3OstgEn6xHulhQaXawVvzFzbafYHWHUfs=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.8.1/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.8.2 h1:Gs06CcP/pvywyO86dAsv2fmJfwPoJrTjN9fX7CqT/54=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.8.2/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.9.0 h1:YJHX4IDO+1c+AufidfYBcfZA8OlvLsqs8K9Hq4R8icY=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.9.0/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.9.1 h1:WpM6PcFqQZWPBGDEuMILWHq98dPVBLAxi8ae9QMWWbM=
gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.9.1/go.mod h1:MqCBFv7DXKoBE2rZDc51LGvl2QI7Kz0D+XkQ0izj+ws=
gitlab.schukai.com/oss/libraries/go/utilities/watch v0.1.0 h1:FAKHmf9p3NKyzuM0cIXYBxmhdQ7zJ+6wj5qqeoIMbGc=
gitlab.schukai.com/oss/libraries/go/utilities/watch v0.1.0/go.mod h1:tMFl68peRKHgFQLltrTN3JLredofMqvGi3C0SEAj73Y=
gitlab.schukai.com/oss/libraries/go/utilities/watch v0.2.0 h1:tLjN9Wyv+LJhtiiQDzdzaDelEq2LVCDP3Ndo7ZPIWfQ=
......
......@@ -6,15 +6,16 @@ package configuration
import (
"bytes"
"encoding/json"
"reflect"
"fmt"
"github.com/imdario/mergo"
"github.com/magiconair/properties"
"github.com/pelletier/go-toml/v2"
"gitlab.schukai.com/oss/libraries/go/utilities/pathfinder"
"gopkg.in/yaml.v3"
"io"
"os"
"path"
"reflect"
)
func importJson[C any](config *C, reader io.Reader) error {
......@@ -94,87 +95,65 @@ func (s *Settings[C]) importStreams() {
}
}
func replacePath(p string, c interface{}) {
cValue := reflect.ValueOf(c)
var typeOfPathValue PathValue
// If c is of type PathValue (which implements pathInterface), modify the path
if cValue.Type() == reflect.TypeOf(PathValue("")) {
pathVal := cValue.Interface().(PathValue)
if !path.IsAbs(pathVal.String()) {
newPath := PathValue(path.Join(p, pathVal.String()))
if cValue.CanSet() {
cValue.Set(reflect.ValueOf(newPath))
}
}
return
}
// replacePath replaces all relative paths with absolute paths
func replacePath[C any](basePath string, c C) error {
// If c is not a struct, simply return
if cValue.Kind() != reflect.Ptr || cValue.Elem().Kind() != reflect.Struct {
return
}
paths := []string{}
fields := reflect.VisibleFields(cValue.Elem().Type())
for _, field := range fields {
r := cValue.Elem().FieldByName(field.Name)
handleField(p, r)
}
}
top := reflect.TypeOf(typeOfPathValue)
toc := reflect.ValueOf(c)
ptp := &paths
func handleField(p string, r reflect.Value) {
switch r.Kind() {
case reflect.Struct:
if r.CanAddr() {
replacePath(p, r.Addr().Interface())
pathfinder.FindPaths(toc, top, []string{}, ptp)
for _, px := range paths {
p, err := pathfinder.GetValue[C](c, px)
if err != nil {
return err
}
case reflect.Slice:
for i := 0; i < r.Len(); i++ {
elem := r.Index(i)
if elem.Type() == reflect.TypeOf(PathValue("")) {
pathVal := elem.Interface().(PathValue)
if !path.IsAbs(pathVal.String()) {
newPath := PathValue(path.Join(p, pathVal.String()))
if elem.CanSet() {
elem.Set(reflect.ValueOf(newPath))
}
}
} else if elem.CanAddr() {
replacePath(p, elem.Addr().Interface())
switch p.(type) {
case PathValue:
tp, ok := p.(PathValue)
if !ok {
return fmt.Errorf("type assertion failed")
}
}
case reflect.Map:
for _, k := range r.MapKeys() {
elem := r.MapIndex(k)
if elem.Type() == reflect.TypeOf(PathValue("")) {
pathVal := elem.Interface().(PathValue)
if !path.IsAbs(pathVal.String()) {
newPath := PathValue(path.Join(p, pathVal.String()))
r.SetMapIndex(k, reflect.ValueOf(newPath))
if !path.IsAbs(p.(PathValue).String()) {
newPath := PathValue(path.Join(basePath, tp.String()))
switch reflect.TypeOf(p).Kind() {
case reflect.Ptr:
err = pathfinder.SetValue[C](c, px, &newPath)
case reflect.String:
if px == "G.I.key1GI.A" {
}
err = pathfinder.SetValue[C](c, px, newPath.String())
default:
err = pathfinder.SetValue[C](c, px, newPath)
}
} else if elem.CanAddr() {
replacePath(p, elem.Addr().Interface())
}
}
default:
// Check for pathInterface
if v, ok := r.Interface().(pathInterface); ok {
// Check if r is nil
if r.Kind() == reflect.Ptr && r.IsNil() {
return
}
currentPath := v.String()
if r.CanSet() && !path.IsAbs(currentPath) {
if r.Type() == reflect.TypeOf(PathValue("")) {
r.Set(reflect.ValueOf(PathValue(path.Join(p, currentPath))))
if err != nil {
return err
}
}
}
}
return nil
}
func (s *Settings[C]) importFiles() {
defer func() {
defer func() {
s.notifyErrorHooks()
}()
......@@ -190,7 +169,7 @@ func (s *Settings[C]) importFiles() {
r := (io.Reader)(f)
s.importStream(reader{s.files.format, r}, func(c *C) {
replacePath(d, c)
replacePath[*C](d, c)
})
_ = f.Close()
}
......@@ -206,7 +185,10 @@ func (s *Settings[C]) importFiles() {
s.importStream(reader{f.format, r}, func(c *C) {
d := path.Dir(f.path)
replacePath(d, c)
err := replacePath[*C](d, c)
if err != nil {
return
}
})
_ = r.Close()
......
// Copyright 2022 schukai GmbH
// Copyright 2023 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package configuration
import (
"github.com/stretchr/testify/assert"
"path/filepath"
"testing"
)
......@@ -27,3 +28,85 @@ func TestReadExample3(t *testing.T) {
assert.Equal(t, c.Config().Host, "localhost")
}
type TestStruct struct {
Path1 PathValue
Path2 string
Path3 []PathValue
}
func TestReplacePath2(t *testing.T) {
testData := TestStruct{
Path1: "relative/path1",
Path2: "relative/path2",
Path3: []PathValue{"relative/path3", "relative/path4"},
}
basePath := "/base"
err := replacePath[*TestStruct](basePath, &testData)
assert.Nil(t, err)
expectedPath1 := PathValue(filepath.Join(basePath, "relative/path1"))
if testData.Path1 != expectedPath1 {
t.Errorf("Expected %s, got %s", expectedPath1, testData.Path1)
}
// no pathValue
expectedPath2 := "relative/path2"
if testData.Path2 != expectedPath2 {
t.Errorf("Expected %s, got %s", expectedPath2, testData.Path2)
}
expectedPath3 := []PathValue{PathValue(filepath.Join(basePath, "relative/path3")), PathValue(filepath.Join(basePath, "relative/path4"))}
if testData.Path3[0] != expectedPath3[0] {
t.Errorf("Expected %s, got %s", expectedPath3[0], testData.Path3[0])
}
if testData.Path3[1] != expectedPath3[1] {
t.Errorf("Expected %s, got %s", expectedPath3[1], testData.Path3[1])
}
}
type SubTestSubPaths struct {
Template PathValue
Definitions []PathValue
}
type SubTest2Def struct {
Paths SubTestSubPaths
}
type SubTestStruct1 map[string]SubTest2Def
type MainTestStruct struct {
Sub SubTestStruct1
}
func TestReplacePathForConfig(t *testing.T) {
config := MainTestStruct{
Sub: SubTestStruct1{
"Default": SubTest2Def{
Paths: SubTestSubPaths{
Template: "../../../default.html",
Definitions: []PathValue{"../../../legacy.yaml"},
},
},
},
}
basePath := "/base/1/2/3/"
err := replacePath[*MainTestStruct](basePath, &config)
if err != nil {
t.Error(err)
}
expectedTemplatePath := PathValue(filepath.Join(basePath, "../../../default.html"))
if config.Sub["Default"].Paths.Template != expectedTemplatePath {
t.Errorf("Expected %s, got %s", expectedTemplatePath, config.Sub["Default"].Paths.Template)
}
expectedDefinitionPath := PathValue(filepath.Join(basePath, "../../../legacy.yaml"))
if config.Sub["Default"].Paths.Definitions[0] != expectedDefinitionPath {
t.Errorf("Expected %s, got %s", expectedDefinitionPath, config.Sub["Default"].Paths.Definitions[0])
}
}
......@@ -4,7 +4,6 @@
package configuration
import (
"fmt"
"os"
"testing"
)
......@@ -21,7 +20,6 @@ func Fuzz1Test(f *testing.F) {
s := New(config)
fmt.Println("A:", a, "B:", b, "F:", f)
if s == nil {
t.Error("Expected not nil")
......
......@@ -5,7 +5,6 @@ package configuration
import (
"github.com/stretchr/testify/assert"
"io/ioutil"
"os"
"path"
"path/filepath"
......@@ -26,7 +25,7 @@ type Issue7Config struct {
}
func createIssue7TempFile(content string) (string, error) {
file, err := ioutil.TempFile("", "tempfile")
file, err := os.CreateTemp("", "tempfile")
if err != nil {
return "", err
}
......@@ -100,7 +99,8 @@ func TestIssue7ReplacePath(t *testing.T) {
C: 42,
}
replacePath(basePath, &ts1)
err := replacePath[*Issue7TestStruct1](basePath, &ts1)
assert.Nil(t, err)
if ts1.A != PathValue(path.Join(basePath, "relative/path")) {
t.Errorf("Expected '%s', got '%s'", path.Join(basePath, "relative/path"), ts1.A)
......@@ -118,7 +118,8 @@ func TestIssue7ReplacePath(t *testing.T) {
E: "justastring",
}
replacePath(basePath, &ts2)
err = replacePath[*Issue7TestStruct2](basePath, &ts2)
assert.Nil(t, err)
if ts2.A != PathValue(path.Join(basePath, "another/relative/path")) {
t.Errorf("Expected '%s', got '%s'", path.Join(basePath, "another/relative/path"), ts2.A)
......@@ -220,7 +221,8 @@ func TestReplacePath(t *testing.T) {
// Copy the struct to compare later
original := *s
replacePath(basePath, s)
err := replacePath[*MyStruct](basePath, s)
assert.Nil(t, err)
// Checking each field to ensure replacePath works as expected
if s.A != original.A && !path.IsAbs(s.A.String()) {
......
The MIT License (MIT)
Copyright (c) 2013 - 2022 Thomas Pelletier, Eric Anderton
go-toml v2
Copyright (c) 2021 - 2023 Thomas Pelletier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment