diff options
author | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2020-06-30 16:11:05 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com> | 2020-07-06 20:03:36 +0200 |
commit | 12a65e76df9470d9563b91a22969ddb41b7c19aa (patch) | |
tree | ab7b7b3cc67fbb9b4a86c1c347081e4e959ed8e8 /tpl | |
parent | 58c0f5e6171cbf8e3ed8d73ac95a7b85168c5b2f (diff) |
Add openapi3.Unmarshal
Fixes #7442
Fixes #7443
Diffstat (limited to 'tpl')
-rw-r--r-- | tpl/openapi/openapi3/init.go | 42 | ||||
-rw-r--r-- | tpl/openapi/openapi3/openapi3.go | 97 | ||||
-rw-r--r-- | tpl/tplimpl/template_funcs.go | 1 | ||||
-rw-r--r-- | tpl/transform/unmarshal.go | 17 | ||||
-rw-r--r-- | tpl/transform/unmarshal_test.go | 2 |
5 files changed, 148 insertions, 11 deletions
diff --git a/tpl/openapi/openapi3/init.go b/tpl/openapi/openapi3/init.go new file mode 100644 index 000000000..1e1a4ae05 --- /dev/null +++ b/tpl/openapi/openapi3/init.go @@ -0,0 +1,42 @@ +// Copyright 2020 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openapi3 + +import ( + "github.com/gohugoio/hugo/deps" + "github.com/gohugoio/hugo/tpl/internal" +) + +const name = "openapi3" + +func init() { + f := func(d *deps.Deps) *internal.TemplateFuncsNamespace { + ctx := New(d) + + ns := &internal.TemplateFuncsNamespace{ + Name: name, + Context: func(args ...interface{}) interface{} { return ctx }, + } + + ns.AddMethodMapping(ctx.Unmarshal, + nil, + [][2]string{}, + ) + + return ns + + } + + internal.AddTemplateFuncsNamespace(f) +} diff --git a/tpl/openapi/openapi3/openapi3.go b/tpl/openapi/openapi3/openapi3.go new file mode 100644 index 000000000..7dfd2f6a7 --- /dev/null +++ b/tpl/openapi/openapi3/openapi3.go @@ -0,0 +1,97 @@ +// Copyright 2020 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package openapi3 + +import ( + "io/ioutil" + + gyaml "github.com/ghodss/yaml" + + "github.com/pkg/errors" + + kopenapi3 "github.com/getkin/kin-openapi/openapi3" + "github.com/gohugoio/hugo/cache/namedmemcache" + "github.com/gohugoio/hugo/deps" + "github.com/gohugoio/hugo/parser/metadecoders" + "github.com/gohugoio/hugo/resources/resource" +) + +// New returns a new instance of the openapi3-namespaced template functions. +func New(deps *deps.Deps) *Namespace { + // TODO1 consolidate when merging that "other branch" -- but be aware of the keys. + cache := namedmemcache.New() + deps.BuildStartListeners.Add( + func() { + cache.Clear() + }) + + return &Namespace{ + cache: cache, + deps: deps, + } +} + +// Namespace provides template functions for the "openapi3". +type Namespace struct { + cache *namedmemcache.Cache + deps *deps.Deps +} + +func (ns *Namespace) Unmarshal(r resource.UnmarshableResource) (*kopenapi3.Swagger, error) { + + key := r.Key() + if key == "" { + return nil, errors.New("no Key set in Resource") + } + + v, err := ns.cache.GetOrCreate(key, func() (interface{}, error) { + f := metadecoders.FormatFromMediaType(r.MediaType()) + if f == "" { + return nil, errors.Errorf("MIME %q not supported", r.MediaType()) + } + + reader, err := r.ReadSeekCloser() + if err != nil { + return nil, err + } + defer reader.Close() + + b, err := ioutil.ReadAll(reader) + if err != nil { + return nil, err + } + + s := &kopenapi3.Swagger{} + switch f { + case metadecoders.YAML: + err = gyaml.Unmarshal(b, s) + default: + err = metadecoders.Default.UnmarshalTo(b, f, s) + } + if err != nil { + return nil, err + } + + err = kopenapi3.NewSwaggerLoader().ResolveRefsIn(s, nil) + + return s, err + }) + + if err != nil { + return nil, err + } + + return v.(*kopenapi3.Swagger), nil + +} diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go index ccf33d8ba..9141de3f1 100644 --- a/tpl/tplimpl/template_funcs.go +++ b/tpl/tplimpl/template_funcs.go @@ -44,6 +44,7 @@ import ( _ "github.com/gohugoio/hugo/tpl/inflect" _ "github.com/gohugoio/hugo/tpl/lang" _ "github.com/gohugoio/hugo/tpl/math" + _ "github.com/gohugoio/hugo/tpl/openapi/openapi3" _ "github.com/gohugoio/hugo/tpl/os" _ "github.com/gohugoio/hugo/tpl/partials" _ "github.com/gohugoio/hugo/tpl/path" diff --git a/tpl/transform/unmarshal.go b/tpl/transform/unmarshal.go index da06b6aa1..b606c870a 100644 --- a/tpl/transform/unmarshal.go +++ b/tpl/transform/unmarshal.go @@ -17,17 +17,20 @@ import ( "io/ioutil" "strings" + "github.com/gohugoio/hugo/resources/resource" + + "github.com/gohugoio/hugo/common/types" + "github.com/mitchellh/mapstructure" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/parser/metadecoders" - "github.com/gohugoio/hugo/resources/resource" "github.com/pkg/errors" "github.com/spf13/cast" ) -// Unmarshal unmarshals the data given, which can be either a string +// Unmarshal unmarshals the data given, which can be either a string, json.RawMessage // or a Resource. Supported formats are JSON, TOML, YAML, and CSV. // You can optionally provide an options map as the first argument. func (ns *Namespace) Unmarshal(args ...interface{}) (interface{}, error) { @@ -55,7 +58,7 @@ func (ns *Namespace) Unmarshal(args ...interface{}) (interface{}, error) { } } - if r, ok := data.(unmarshableResource); ok { + if r, ok := data.(resource.UnmarshableResource); ok { key := r.Key() if key == "" { @@ -87,7 +90,7 @@ func (ns *Namespace) Unmarshal(args ...interface{}) (interface{}, error) { }) } - dataStr, err := cast.ToStringE(data) + dataStr, err := types.ToStringE(data) if err != nil { return nil, errors.Errorf("type %T not supported", data) } @@ -104,12 +107,6 @@ func (ns *Namespace) Unmarshal(args ...interface{}) (interface{}, error) { }) } -// All the relevant resources implements this interface. -type unmarshableResource interface { - resource.ReadSeekCloserResource - resource.Identifier -} - func decodeDecoder(m map[string]interface{}) (metadecoders.Decoder, error) { opts := metadecoders.Default diff --git a/tpl/transform/unmarshal_test.go b/tpl/transform/unmarshal_test.go index 7b0caa07f..183bdefd5 100644 --- a/tpl/transform/unmarshal_test.go +++ b/tpl/transform/unmarshal_test.go @@ -20,11 +20,11 @@ import ( "testing" "github.com/gohugoio/hugo/common/hugio" + "github.com/gohugoio/hugo/resources/resource" "github.com/gohugoio/hugo/media" qt "github.com/frankban/quicktest" - "github.com/gohugoio/hugo/resources/resource" "github.com/spf13/viper" ) |