diff --git a/cmd/common_konnect.go b/cmd/common_konnect.go index 1eb0b9fb6..e4caf1efd 100644 --- a/cmd/common_konnect.go +++ b/cmd/common_konnect.go @@ -33,6 +33,8 @@ func syncKonnect(ctx context.Context, return err } + targetContent.StripLocalDocumentPath() + // get Konnect client konnectClient, err := utils.GetKonnectClient(httpClient, konnectConfig.Debug) if err != nil { diff --git a/file/konnect.go b/file/konnect.go index 2d5bf4bfe..819334cae 100644 --- a/file/konnect.go +++ b/file/konnect.go @@ -17,12 +17,13 @@ func (c Content) PopulateDocumentContent(filenames []string) error { return errors.New("cannot populate documents without a location") } // TODO decK actually allows you to use _multiple_ state files - // How should we choose which to use as the search path for documents? + // We currently choose the first arbitrarily and assume document content is under its directory + // Future plans are to rework the multiple state file functionality to require all state files + // be in the same directory. root := filepath.Dir(filenames[0]) for _, sp := range c.ServicePackages { - spPath := utils.NameToFilename(*sp.Name) if sp.Document != nil { - path := filepath.Join(root, spPath, utils.NameToFilename(*sp.Document.Path)) + path := filepath.Join(root, utils.FilenameToName(*sp.Document.Path)) content, err := os.ReadFile(path) if err != nil { return errors.Wrap(err, "error reading document file") @@ -31,8 +32,7 @@ func (c Content) PopulateDocumentContent(filenames []string) error { } for _, sv := range sp.Versions { if sv.Document != nil { - path := filepath.Join(root, spPath, utils.NameToFilename(*sv.Version), - utils.NameToFilename(*sv.Document.Path)) + path := filepath.Join(root, utils.FilenameToName(*sv.Document.Path)) content, err := os.ReadFile(path) if err != nil { return errors.Wrap(err, "error reading document file") @@ -43,3 +43,19 @@ func (c Content) PopulateDocumentContent(filenames []string) error { } return nil } + +// StripLocalDocum +func (c Content) StripLocalDocumentPath() { + for _, sp := range c.ServicePackages { + if sp.Document != nil { + trunc := "/" + filepath.Base(utils.FilenameToName(*sp.Document.Path)) + sp.Document.Path = &trunc + } + for _, sv := range sp.Versions { + if sv.Document != nil { + trunc := "/" + filepath.Base(utils.FilenameToName(*sv.Document.Path)) + sv.Document.Path = &trunc + } + } + } +} diff --git a/file/writer.go b/file/writer.go index 554a139cf..521ef893a 100644 --- a/file/writer.go +++ b/file/writer.go @@ -12,6 +12,7 @@ import ( ghodss "github.com/ghodss/yaml" "github.com/kong/deck/state" "github.com/kong/deck/utils" + "github.com/kong/go-kong/kong" "github.com/pkg/errors" ) @@ -132,6 +133,7 @@ func populateServicePackages(kongState *state.KongState, file *Content, } for _, sp := range packages { + safePackageName := utils.NameToFilename(*sp.Name) p := FServicePackage{ ID: sp.ID, Name: sp.Name, @@ -147,9 +149,10 @@ func populateServicePackages(kongState *state.KongState, file *Content, } for _, d := range documents { + safeDocPath := utils.NameToFilename(*d.Path) fDocument := FDocument{ ID: d.ID, - Path: d.Path, + Path: kong.String(filepath.Join(safePackageName, safeDocPath)), Published: d.Published, Content: d.Content, } @@ -161,6 +164,7 @@ func populateServicePackages(kongState *state.KongState, file *Content, } for _, v := range versions { + safeVersionName := utils.NameToFilename(*v.Version) fVersion := FServiceVersion{ ID: v.ID, Version: v.Version, @@ -186,9 +190,10 @@ func populateServicePackages(kongState *state.KongState, file *Content, } for _, d := range documents { + safeDocPath := utils.NameToFilename(*d.Path) fDocument := FDocument{ ID: d.ID, - Path: d.Path, + Path: kong.String(filepath.Join(safePackageName, safeVersionName, safeDocPath)), Published: d.Published, Content: d.Content, } @@ -627,25 +632,21 @@ func writeFile(content *Content, filename string, format Format) error { return errors.Wrap(err, "writing file") } for _, sp := range content.ServicePackages { - safePackageName := utils.NameToFilename(*sp.Name) if sp.Document != nil { - if err := os.MkdirAll(filepath.Join(prefix, safePackageName), 0700); err != nil { + if err := os.MkdirAll(filepath.Join(prefix, filepath.Dir(*sp.Document.Path)), 0700); err != nil { return errors.Wrap(err, "creating document directory") } - safeDocPath := utils.NameToFilename(*sp.Document.Path) - if err := os.WriteFile(filepath.Join(prefix, safePackageName, safeDocPath), + if err := os.WriteFile(filepath.Join(prefix, *sp.Document.Path), []byte(*sp.Document.Content), 0600); err != nil { return errors.Wrap(err, "writing document file") } } for _, v := range sp.Versions { if v.Document != nil { - safeVersionName := utils.NameToFilename(*v.Version) - if err := os.MkdirAll(filepath.Join(prefix, safePackageName, safeVersionName), 0700); err != nil { + if err := os.MkdirAll(filepath.Join(prefix, filepath.Dir(*v.Document.Path)), 0700); err != nil { return errors.Wrap(err, "creating document directory") } - safeDocPath := utils.NameToFilename(*v.Document.Path) - if err := os.WriteFile(filepath.Join(prefix, safePackageName, safeVersionName, safeDocPath), + if err := os.WriteFile(filepath.Join(prefix, *v.Document.Path), []byte(*v.Document.Content), 0600); err != nil { return errors.Wrap(err, "writing document file") } diff --git a/utils/utils.go b/utils/utils.go index eff36555b..251d8a86f 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -79,3 +79,10 @@ func NameToFilename(name string) string { s = strings.ReplaceAll(s, string(os.PathSeparator), url.PathEscape(string(os.PathSeparator))) return s } + +// FilenameToName (partially) reverses NameToFilename, replacing all URL-encoded path separator characters +// with the path separator character. It does not re-add a leading separator, because there is no way to know +// if that separator was included originally, and only some names (document paths) typically include one. +func FilenameToName(filename string) string { + return strings.ReplaceAll(filename, url.PathEscape(string(os.PathSeparator)), string(os.PathSeparator)) +}