Skip to content

Commit

Permalink
feat: add env var substitution to repo config
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbrdn committed Nov 18, 2024
1 parent dc8d6af commit 134ca5a
Show file tree
Hide file tree
Showing 12 changed files with 292 additions and 170 deletions.
6 changes: 3 additions & 3 deletions internal/app/cli/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ func RepoList() error {
_, _ = fmt.Fprintf(table, "NAME\tTYPE\tENBL\tLOCATION\tDESCRIPTION\n")
for name, value := range config {
typ := fmt.Sprintf("%v", value[repos.KeyRepoType])
e := utils.JsGetBool(value, repos.KeyRepoEnabled)
enbl := e == nil || *e
e, found := utils.JsGetBool(value, repos.KeyRepoEnabled)
enbl := !found || e
var enblS string
if enbl {
enblS = "Y"
Expand Down Expand Up @@ -143,7 +143,7 @@ func RepoSetConfig(name, locStr, jsonConf, confFile string) error {
Stderrf("must specify one of: <location>, --file=<config-file>, or --json=<config-json>")
return nil, ErrInvalidArgs
}
typ := utils.JsGetStringOrEmpty(conf, repos.KeyRepoType)
typ, _ := utils.JsGetString(conf, repos.KeyRepoType)
newConf, err := repos.NewRepoConfig(typ, configBytes)
return newConf, err
})
Expand Down
8 changes: 4 additions & 4 deletions internal/commands/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ func restoreExternalId(ctx context.Context, raw []byte) []byte {
}
var newLinks []map[string]any
for _, eLink := range linksArray {
rel, relOk := eLink["rel"]
href := utils.JsGetString(eLink, "href")
if relOk && rel == "original" && href != nil {
originalId = *href
rel, relFound := utils.JsGetString(eLink, "rel")
href, hrefFound := utils.JsGetString(eLink, "href")
if relFound && rel == "original" && hrefFound {
originalId = href
} else {
newLinks = append(newLinks, eLink)
}
Expand Down
20 changes: 10 additions & 10 deletions internal/commands/fetch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,11 @@ func TestFetchCommand_FetchByTMIDOrName_RestoresId(t *testing.T) {
var js map[string]any
err := json.Unmarshal(b, &js)
assert.NoError(t, err)
jsId := utils.JsGetString(js, "id")
if assert.NotNil(t, jsId) {
assert.Equal(t, test.expId, *jsId)
}
assert.Len(t, utils.JsGetArray(js, "links"), test.expLinksLen)
jsId, found := utils.JsGetString(js, "id")
assert.True(t, found)
assert.Equal(t, test.expId, jsId)
arr := utils.JsGetArray(js, "links")
assert.Len(t, arr, test.expLinksLen)
})
t.Run("with single repo", func(t *testing.T) {
r1.On("Fetch", mock.Anything, "author/manufacturer/mpn/v1.0.0-20231005123243-a49617d2e4fc.tm.json").
Expand All @@ -432,11 +432,11 @@ func TestFetchCommand_FetchByTMIDOrName_RestoresId(t *testing.T) {
var js map[string]any
err := json.Unmarshal(b, &js)
assert.NoError(t, err)
jsId := utils.JsGetString(js, "id")
if assert.NotNil(t, jsId) {
assert.Equal(t, test.expId, *jsId)
}
assert.Len(t, utils.JsGetArray(js, "links"), test.expLinksLen)
jsId, found := utils.JsGetString(js, "id")
assert.True(t, found)
assert.Equal(t, test.expId, jsId)
arr := utils.JsGetArray(js, "links")
assert.Len(t, arr, test.expLinksLen)

})

Expand Down
23 changes: 13 additions & 10 deletions internal/repos/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ type FileRepo struct {
idx *model.Index
}

func NewFileRepo(config map[string]any, spec model.RepoSpec) (*FileRepo, error) {
loc := utils.JsGetString(config, KeyRepoLoc)
if loc == nil {
func NewFileRepo(config ConfigMap, spec model.RepoSpec) (*FileRepo, error) {
loc, found := config.GetString(KeyRepoLoc)
if !found {
return nil, fmt.Errorf("cannot create a file repo from spec %v. Invalid config. loc is either not found or not a string", spec)
}
rootPath, err := utils.ExpandHome(*loc)
rootPath, err := utils.ExpandHome(loc)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -608,22 +608,22 @@ func (f *FileRepo) checkRootValid() error {
return nil
}

func createFileRepoConfig(bytes []byte) (map[string]any, error) {
func createFileRepoConfig(bytes []byte) (ConfigMap, error) {
rc, err := AsRepoConfig(bytes)
if err != nil {
return nil, err
}
if rType := utils.JsGetString(rc, KeyRepoType); rType != nil {
if *rType != RepoTypeFile {
if rType, found := utils.JsGetString(rc, KeyRepoType); found {
if rType != RepoTypeFile {
return nil, fmt.Errorf("invalid json config. type must be \"file\" or absent")
}
}
rc[KeyRepoType] = RepoTypeFile
l := utils.JsGetString(rc, KeyRepoLoc)
if l == nil {
l, found := utils.JsGetString(rc, KeyRepoLoc)
if !found {
return nil, fmt.Errorf("invalid json config. must have string \"loc\"")
}
la, err := makeAbs(*l)
la, err := makeAbs(l)
if err != nil {
return nil, err
}
Expand All @@ -632,6 +632,9 @@ func createFileRepoConfig(bytes []byte) (map[string]any, error) {
}

func makeAbs(dir string) (string, error) {
if isEnvReference(dir) {
return dir, nil
}
if filepath.IsAbs(dir) {
return dir, nil
} else {
Expand Down
96 changes: 42 additions & 54 deletions internal/repos/fs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package repos
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/fs"
"os"
Expand All @@ -21,68 +22,54 @@ import (
)

func TestNewFileRepo(t *testing.T) {
root := "/tmp/tm-catalog1157316148"
repo, err := NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, root, repo.root)

root = "/tmp/tm-catalog1157316148"
repo, err = NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, root, repo.root)

root = "~/tm-catalog"
repo, err = NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
home, _ := os.UserHomeDir()
assert.Equal(t, filepath.Join(home, "tm-catalog"), repo.root)

root = "~/tm-catalog"
repo, err = NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, filepath.Join(home, "tm-catalog"), repo.root)
t.Run("absolute path", func(t *testing.T) {
root := "/tmp/tm-catalog1157316148"
repo, err := NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, root, repo.root)
})

root = "~/tm-catalog"
repo, err = NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, filepath.Join(home, "tm-catalog"), repo.root)
t.Run("relative to home", func(t *testing.T) {
root := "~/tm-catalog"
repo, err := NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
home, _ := os.UserHomeDir()
assert.Equal(t, filepath.Join(home, "tm-catalog"), repo.root)
})

root = "c:\\Users\\user\\Desktop\\tm-catalog"
repo, err = NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, filepath.ToSlash("c:\\Users\\user\\Desktop\\tm-catalog"), filepath.ToSlash(repo.root))
t.Run("abs windows path", func(t *testing.T) {
root := "C:\\Users\\user\\Desktop\\tm-catalog"
repo, err := NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, filepath.ToSlash("C:\\Users\\user\\Desktop\\tm-catalog"), filepath.ToSlash(repo.root))
})

root = "C:\\Users\\user\\Desktop\\tm-catalog"
repo, err = NewFileRepo(map[string]any{
"type": "file",
"loc": root,
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, filepath.ToSlash("C:\\Users\\user\\Desktop\\tm-catalog"), filepath.ToSlash(repo.root))
t.Run("env var path", func(t *testing.T) {
os.Setenv("TMC_TEST_ENV_VAR_PATH", "/some/path")
defer os.Unsetenv("TMC_TEST_ENV_VAR_PATH")
repo, err := NewFileRepo(map[string]any{
"type": "file",
"loc": "$TMC_TEST_ENV_VAR_PATH",
}, model.EmptySpec)
assert.NoError(t, err)
assert.Equal(t, "/some/path", repo.root)
})

}

func TestCreateFileRepoConfig(t *testing.T) {
wd, _ := os.Getwd()

relPathJson, _ := json.Marshal(filepath.Join(wd, "dir/repoName"))
tests := []struct {
fileConf string
expRoot string
Expand All @@ -93,8 +80,9 @@ func TestCreateFileRepoConfig(t *testing.T) {
{`{"loc":"./dir/repoName"}`, filepath.Join(wd, "dir/repoName"), false, ""},
{`{"loc":"/dir/repoName"}`, filepath.Join(filepath.VolumeName(wd), "/dir/repoName"), false, ""},
{`{"loc":"."}`, filepath.Join(wd), false, ""},
{`{"loc":"` + filepath.Join(wd, "dir/repoName") + `"}`, filepath.Join(wd, "dir/repoName"), false, ""},
{`{"loc":` + string(relPathJson) + `}`, filepath.Join(wd, "dir/repoName"), false, ""},
{`{"loc":"~/dir/repoName"}`, "~/dir/repoName", false, ""},
{`{"loc":"$TMC_TEST_SOME_REPO_ROOT"}`, "$TMC_TEST_SOME_REPO_ROOT", false, ""},
{``, "", true, ""},
{`[]`, "", true, ""},
{`{}`, "", true, ""},
Expand Down
11 changes: 5 additions & 6 deletions internal/repos/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,21 +252,20 @@ func cutToNSegments(s string, n int) string {
return strings.Join(segments[0:n], "/")
}

func createHttpRepoConfig(bytes []byte) (map[string]any, error) {
func createHttpRepoConfig(bytes []byte) (ConfigMap, error) {
rc, err := AsRepoConfig(bytes)
if err != nil {
return nil, err
}
if rType := utils.JsGetString(rc, KeyRepoType); rType != nil {
if *rType != RepoTypeHttp {
if rType, found := utils.JsGetString(rc, KeyRepoType); found {
if rType != RepoTypeHttp {
return nil, fmt.Errorf("invalid json config. type must be \"http\" or absent")
}
}
rc[KeyRepoType] = RepoTypeHttp
l := utils.JsGetString(rc, KeyRepoLoc)
if l == nil {
_, found := utils.JsGetString(rc, KeyRepoLoc)
if !found {
return nil, fmt.Errorf("invalid json config. must have string \"loc\"")
}
rc[KeyRepoLoc] = *l
return rc, nil
}
48 changes: 22 additions & 26 deletions internal/repos/http_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,31 @@ type baseHttpRepo struct {
root string
parsedRoot *url.URL
spec model.RepoSpec
auth map[string]any
headers map[string]any
auth ConfigMap
headers ConfigMap
client *http.Client
}

func newBaseHttpRepo(config map[string]any, spec model.RepoSpec) (baseHttpRepo, error) {
loc := utils.JsGetString(config, KeyRepoLoc)
if loc == nil {
func newBaseHttpRepo(config ConfigMap, spec model.RepoSpec) (baseHttpRepo, error) {
loc, found := config.GetString(KeyRepoLoc)
if !found {
return baseHttpRepo{}, fmt.Errorf("invalid http repo config. loc is either not found or not a string")
}
u, err := url.Parse(*loc)
u, err := url.Parse(loc)
if err != nil {
return baseHttpRepo{}, err
}
auth := utils.JsGetMap(config, KeyRepoAuth)
auth, _ := utils.JsGetMap(config, KeyRepoAuth)
client, err := getHttpClient(auth)
if err != nil {
return baseHttpRepo{}, fmt.Errorf("invalid http repo config: %v", err)
}
headers, _ := utils.JsGetMap(config, KeyRepoHeaders)
base := baseHttpRepo{
root: *loc,
root: loc,
spec: spec,
auth: auth,
headers: utils.JsGetMap(config, KeyRepoHeaders),
headers: headers,
client: client,
parsedRoot: u,
}
Expand Down Expand Up @@ -109,31 +110,26 @@ func (b *baseHttpRepo) doGet(ctx context.Context, reqUrl string) (*http.Response

func (b *baseHttpRepo) doHttp(req *http.Request) (*http.Response, error) {
if b.auth != nil {
basicAuth := utils.JsGetMap(b.auth, AuthMethodBasic)
if basicAuth != nil {
empty := ""
username := utils.JsGetString(basicAuth, "username")
if username == nil {
username = &empty
}
password := utils.JsGetString(basicAuth, "password")
if password == nil {
password = &empty
}
req.SetBasicAuth(*username, *password)
basicAuth, found := utils.JsGetMap(b.auth, AuthMethodBasic)
if found {
ba := ConfigMap(basicAuth)
username, _ := ba.GetString("username")
password, _ := ba.GetString("password")
req.SetBasicAuth(username, password)
} else {
bearerToken := utils.JsGetString(b.auth, AuthMethodBearerToken)
if bearerToken != nil {
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", *bearerToken))

bearerToken, tf := b.auth.GetString(AuthMethodBearerToken)
if tf {
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", bearerToken))
}
}
}
for h, v := range b.headers {
if vs, ok := v.(string); ok {
req.Header.Add(h, vs)
req.Header.Add(h, expandVar(vs))
} else if varr, ok := v.([]any); ok {
for _, vv := range varr {
req.Header.Add(h, fmt.Sprintf("%v", vv))
req.Header.Add(h, expandVar(fmt.Sprintf("%v", vv)))
}
}
}
Expand Down
Loading

0 comments on commit 134ca5a

Please sign in to comment.