From e402d91ee199afcace8ae75da6c3587bb8089ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 30 Dec 2022 09:20:58 +0100 Subject: [PATCH] Misc doc, code refactoring to improve documentation --- codegen/methods.go | 16 +++++---- commands/config.go | 1 + common/docs.go | 2 ++ common/maps/scratch.go | 1 + common/paths/path.go | 11 ++++++ common/text/position.go | 2 ++ config/security/whitelist.go | 1 + hugofs/fileinfo.go | 1 + hugolib/content_map_page.go | 6 ++-- hugolib/gitinfo.go | 10 ++++-- hugolib/hugo_sites.go | 7 ++-- hugolib/page.go | 4 +-- hugolib/page__common.go | 4 +-- hugolib/page__meta.go | 2 +- hugolib/site.go | 8 ++--- langs/language.go | 1 + markup/converter/hooks/hooks.go | 26 ++++++++++++++ markup/highlight/highlight.go | 2 ++ markup/markup.go | 1 + media/mediaType.go | 1 + navigation/menu.go | 3 +- navigation/menu_cache.go | 2 +- output/outputFormat.go | 2 ++ resources/docs.go | 15 ++++++++ resources/images/exif/exif.go | 3 ++ resources/images/image_resource.go | 10 ++++++ resources/page/page.go | 41 +++++++++++++++++----- resources/page/page_marshaljson.autogen.go | 13 ++++--- resources/page/page_nop.go | 5 ++- resources/page/pagination.go | 4 ++- resources/page/site.go | 7 ++-- {hugolib => resources/page}/taxonomy.go | 27 ++++++-------- resources/page/testhelpers_test.go | 5 ++- resources/resource/resources.go | 3 +- resources/resource/resourcetypes.go | 3 ++ source/fileInfo.go | 30 ++++++++++++++++ source/sourceSpec.go | 3 +- tpl/diagrams/init.go | 1 + tpl/images/images.go | 1 + tpl/openapi/docs.go | 2 ++ tpl/openapi/openapi3/openapi3.go | 2 ++ tpl/os/os_test.go | 6 ++-- tpl/path/path.go | 19 +++------- tpl/path/path_test.go | 11 +++--- tpl/resources/resources.go | 1 + tpl/strings/truncate.go | 6 ++-- tpl/template.go | 1 + 47 files changed, 238 insertions(+), 95 deletions(-) create mode 100644 common/docs.go create mode 100644 resources/docs.go rename {hugolib => resources/page}/taxonomy.go (87%) create mode 100644 tpl/openapi/docs.go diff --git a/codegen/methods.go b/codegen/methods.go index 9bc80cc3e..65a7cc2b7 100644 --- a/codegen/methods.go +++ b/codegen/methods.go @@ -452,12 +452,16 @@ func collectMethodsRecursive(pkg string, f []*ast.Field) []string { } if ident, ok := m.Type.(*ast.Ident); ok && ident.Obj != nil { - // Embedded interface - methodNames = append( - methodNames, - collectMethodsRecursive( - pkg, - ident.Obj.Decl.(*ast.TypeSpec).Type.(*ast.InterfaceType).Methods.List)...) + switch tt := ident.Obj.Decl.(*ast.TypeSpec).Type.(type) { + case *ast.InterfaceType: + // Embedded interface + methodNames = append( + methodNames, + collectMethodsRecursive( + pkg, + tt.Methods.List)...) + } + } else { // Embedded, but in a different file/package. Return the // package.Name and deal with that later. diff --git a/commands/config.go b/commands/config.go index 7fda2d40e..a5d8aab22 100644 --- a/commands/config.go +++ b/commands/config.go @@ -126,6 +126,7 @@ type modMount struct { Lang string `json:"lang,omitempty"` } +// MarshalJSON is for internal use only. func (m *modMounts) MarshalJSON() ([]byte, error) { var mounts []modMount diff --git a/common/docs.go b/common/docs.go new file mode 100644 index 000000000..041a62a01 --- /dev/null +++ b/common/docs.go @@ -0,0 +1,2 @@ +// Package common provides common helper functionality for Hugo. +package common diff --git a/common/maps/scratch.go b/common/maps/scratch.go index d4745d27c..e9f412540 100644 --- a/common/maps/scratch.go +++ b/common/maps/scratch.go @@ -30,6 +30,7 @@ type Scratch struct { // Scratcher provides a scratching service. type Scratcher interface { + // Scratch returns a "scratch pad" that can be used to store state. Scratch() *Scratch } diff --git a/common/paths/path.go b/common/paths/path.go index 3a7f3e790..11d221bb1 100644 --- a/common/paths/path.go +++ b/common/paths/path.go @@ -263,3 +263,14 @@ func (n NamedSlice) String() string { } return fmt.Sprintf("%s%s{%s}", n.Name, FilePathSeparator, strings.Join(n.Slice, ",")) } + +// DirFile holds the result from path.Split. +type DirFile struct { + Dir string + File string +} + +// Used in test. +func (df DirFile) String() string { + return fmt.Sprintf("%s|%s", df.Dir, df.File) +} diff --git a/common/text/position.go b/common/text/position.go index cc1eda354..eb9de5624 100644 --- a/common/text/position.go +++ b/common/text/position.go @@ -24,6 +24,8 @@ import ( // Positioner represents a thing that knows its position in a text file or stream, // typically an error. type Positioner interface { + // Position returns the current position. + // Useful in error logging, e.g. {{ errorf "error in code block: %s" .Position }}. Position() Position } diff --git a/config/security/whitelist.go b/config/security/whitelist.go index 0d2c187c6..4aff9e9c4 100644 --- a/config/security/whitelist.go +++ b/config/security/whitelist.go @@ -33,6 +33,7 @@ type Whitelist struct { patternsStrings []string } +// MarshalJSON is for internal use only. func (w Whitelist) MarshalJSON() ([]byte, error) { if w.acceptNone { return json.Marshal(acceptNoneKeyword) diff --git a/hugofs/fileinfo.go b/hugofs/fileinfo.go index 1d46a7464..c33997278 100644 --- a/hugofs/fileinfo.go +++ b/hugofs/fileinfo.go @@ -130,6 +130,7 @@ func (f *FileMeta) JoinStat(name string) (FileMetaInfo, error) { type FileMetaInfo interface { os.FileInfo + // Meta is for internal use. Meta() *FileMeta } diff --git a/hugolib/content_map_page.go b/hugolib/content_map_page.go index 7e6b6e670..d8f28286c 100644 --- a/hugolib/content_map_page.go +++ b/hugolib/content_map_page.go @@ -266,7 +266,7 @@ func (m *pageMap) newResource(fim hugofs.FileMetaInfo, owner *pageState) (resour } func (m *pageMap) createSiteTaxonomies() error { - m.s.taxonomies = make(TaxonomyList) + m.s.taxonomies = make(page.TaxonomyList) var walkErr error m.taxonomies.Walk(func(s string, v any) bool { n := v.(*contentNode) @@ -275,7 +275,7 @@ func (m *pageMap) createSiteTaxonomies() error { viewName := t.name if t.termKey == "" { - m.s.taxonomies[viewName.plural] = make(Taxonomy) + m.s.taxonomies[viewName.plural] = make(page.Taxonomy) } else { taxonomy := m.s.taxonomies[viewName.plural] if taxonomy == nil { @@ -285,7 +285,7 @@ func (m *pageMap) createSiteTaxonomies() error { m.taxonomyEntries.WalkPrefix(s, func(ss string, v any) bool { b2 := v.(*contentNode) info := b2.viewInfo - taxonomy.add(info.termKey, page.NewWeightedPage(info.weight, info.ref.p, n.p)) + taxonomy[info.termKey] = append(taxonomy[info.termKey], page.NewWeightedPage(info.weight, info.ref.p, n.p)) return false }) diff --git a/hugolib/gitinfo.go b/hugolib/gitinfo.go index 17717ed52..d051b10bc 100644 --- a/hugolib/gitinfo.go +++ b/hugolib/gitinfo.go @@ -20,6 +20,7 @@ import ( "github.com/bep/gitmap" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/resources/page" + "github.com/gohugoio/hugo/source" ) type gitInfo struct { @@ -27,11 +28,14 @@ type gitInfo struct { repo *gitmap.GitRepo } -func (g *gitInfo) forPage(p page.Page) *gitmap.GitInfo { +func (g *gitInfo) forPage(p page.Page) source.GitInfo { name := strings.TrimPrefix(filepath.ToSlash(p.File().Filename()), g.contentDir) name = strings.TrimPrefix(name, "/") - - return g.repo.Files[name] + gi, found := g.repo.Files[name] + if !found { + return source.GitInfo{} + } + return source.NewGitInfo(*gi) } func newGitInfo(cfg config.Provider) (*gitInfo, error) { diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go index 6be26d60e..569c27be5 100644 --- a/hugolib/hugo_sites.go +++ b/hugolib/hugo_sites.go @@ -41,7 +41,6 @@ import ( "github.com/gohugoio/hugo/source" - "github.com/bep/gitmap" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/publisher" @@ -202,13 +201,13 @@ func (h *HugoSites) Data() map[string]any { return h.data } -func (h *HugoSites) gitInfoForPage(p page.Page) (*gitmap.GitInfo, error) { +func (h *HugoSites) gitInfoForPage(p page.Page) (source.GitInfo, error) { if _, err := h.init.gitInfo.Do(); err != nil { - return nil, err + return source.GitInfo{}, err } if h.gitInfo == nil { - return nil, nil + return source.GitInfo{}, nil } return h.gitInfo.forPage(p), nil diff --git a/hugolib/page.go b/hugolib/page.go index 5acfbc677..97f1ed351 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -31,8 +31,6 @@ import ( "github.com/gohugoio/hugo/hugofs/files" - "github.com/bep/gitmap" - "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/common/herrors" @@ -150,7 +148,7 @@ func (p *pageState) GetIdentity() identity.Identity { return identity.NewPathIdentity(files.ComponentFolderContent, filepath.FromSlash(p.Pathc())) } -func (p *pageState) GitInfo() *gitmap.GitInfo { +func (p *pageState) GitInfo() source.GitInfo { return p.gitInfo } diff --git a/hugolib/page__common.go b/hugolib/page__common.go index 59f0bc776..0527a0682 100644 --- a/hugolib/page__common.go +++ b/hugolib/page__common.go @@ -16,7 +16,6 @@ package hugolib import ( "sync" - "github.com/bep/gitmap" "github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/compare" "github.com/gohugoio/hugo/lazy" @@ -24,6 +23,7 @@ import ( "github.com/gohugoio/hugo/output" "github.com/gohugoio/hugo/resources/page" "github.com/gohugoio/hugo/resources/resource" + "github.com/gohugoio/hugo/source" ) type treeRefProvider interface { @@ -106,7 +106,7 @@ type pageCommon struct { shortcodeState *shortcodeHandler // Set if feature enabled and this is in a Git repo. - gitInfo *gitmap.GitInfo + gitInfo source.GitInfo codeowners []string // Positional navigation diff --git a/hugolib/page__meta.go b/hugolib/page__meta.go index daf989f42..8d2495ddc 100644 --- a/hugolib/page__meta.go +++ b/hugolib/page__meta.go @@ -404,7 +404,7 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron } var gitAuthorDate time.Time - if p.gitInfo != nil { + if !p.gitInfo.IsZero() { gitAuthorDate = p.gitInfo.AuthorDate } diff --git a/hugolib/site.go b/hugolib/site.go index 8fb39a1ea..2ffc3a346 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -110,9 +110,9 @@ type Site struct { *PageCollections - taxonomies TaxonomyList + taxonomies page.TaxonomyList - Sections Taxonomy + Sections page.Taxonomy Info *SiteInfo language *langs.Language @@ -172,7 +172,7 @@ type Site struct { init *siteInit } -func (s *Site) Taxonomies() TaxonomyList { +func (s *Site) Taxonomies() page.TaxonomyList { s.init.taxonomies.Do() return s.taxonomies } @@ -708,7 +708,7 @@ func (s *SiteInfo) Menus() navigation.Menus { } // TODO(bep) type -func (s *SiteInfo) Taxonomies() any { +func (s *SiteInfo) Taxonomies() page.TaxonomyList { return s.s.Taxonomies() } diff --git a/langs/language.go b/langs/language.go index d6b30ec10..42aefda5e 100644 --- a/langs/language.go +++ b/langs/language.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package langs contains the language related types and function. package langs import ( diff --git a/markup/converter/hooks/hooks.go b/markup/converter/hooks/hooks.go index a59da939e..7eede0710 100644 --- a/markup/converter/hooks/hooks.go +++ b/markup/converter/hooks/hooks.go @@ -26,30 +26,56 @@ import ( var _ AttributesOptionsSliceProvider = (*attributes.AttributesHolder)(nil) type AttributesProvider interface { + // Attributes passed in from Markdown (e.g. { attrName1=attrValue1 attrName2="attr Value 2" }). Attributes() map[string]any } type LinkContext interface { + // The Page being rendered. Page() any + + // The link URL. Destination() string + + // The link title attribute. Title() string + + // The rendered (HTML) text. Text() hstring.RenderedString + + // The plain variant of Text. PlainText() string } type ImageLinkContext interface { LinkContext + + // Returns true if this is a standalone image and the config option + // markup.goldmark.parser.wrapStandAloneImageWithinParagraph is disabled. IsBlock() bool + + // Zero-based ordinal for all the images in the current document. Ordinal() int } +// CodeblockContext is the context passed to a code block render hook. type CodeblockContext interface { AttributesProvider text.Positioner + + // Chroma highlighting processing options. This will only be filled if Type is a known Chroma Lexer. Options() map[string]any + + // The type of code block. This will be the programming language, e.g. bash, when doing code highlighting. Type() string + + // The text between the code fences. Inner() string + + // Zero-based ordinal for all code blocks in the current document. Ordinal() int + + // The owning Page. Page() any } diff --git a/markup/highlight/highlight.go b/markup/highlight/highlight.go index 010c941f7..b74997700 100644 --- a/markup/highlight/highlight.go +++ b/markup/highlight/highlight.go @@ -157,10 +157,12 @@ type HightlightResult struct { highlighted template.HTML } +// Wrapped returns the highlighted code wrapped in a
,
 and  tag.
 func (h HightlightResult) Wrapped() template.HTML {
 	return h.highlighted
 }
 
+// Inner returns the highlighted code without the wrapping 
,
 and  tag, suitable for inline use.
 func (h HightlightResult) Inner() template.HTML {
 	return h.highlighted[h.innerLow:h.innerHigh]
 }
diff --git a/markup/markup.go b/markup/markup.go
index 1345867f9..aefa50867 100644
--- a/markup/markup.go
+++ b/markup/markup.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Package markup contains the markup handling (e.g. Markdown).
 package markup
 
 import (
diff --git a/media/mediaType.go b/media/mediaType.go
index e47acb1e3..cdfb1c654 100644
--- a/media/mediaType.go
+++ b/media/mediaType.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Package media containes Media Type (MIME type) related types and functions.
 package media
 
 import (
diff --git a/navigation/menu.go b/navigation/menu.go
index 5e4996f39..cb280823c 100644
--- a/navigation/menu.go
+++ b/navigation/menu.go
@@ -1,4 +1,4 @@
-// Copyright 2019 The Hugo Authors. All rights reserved.
+// Copyright 2023 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.
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Package navigation provides the menu functionality.
 package navigation
 
 import (
diff --git a/navigation/menu_cache.go b/navigation/menu_cache.go
index 6a3266431..4287ed875 100644
--- a/navigation/menu_cache.go
+++ b/navigation/menu_cache.go
@@ -10,7 +10,7 @@
 // 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 navigation
 
 import (
diff --git a/output/outputFormat.go b/output/outputFormat.go
index 722079df9..0bc08e490 100644
--- a/output/outputFormat.go
+++ b/output/outputFormat.go
@@ -11,6 +11,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+// Package output contains Output Format types and functions.
 package output
 
 import (
@@ -400,6 +401,7 @@ func (f Format) BaseFilename() string {
 }
 
 // MarshalJSON returns the JSON encoding of f.
+// For internal use only.
 func (f Format) MarshalJSON() ([]byte, error) {
 	type Alias Format
 	return json.Marshal(&struct {
diff --git a/resources/docs.go b/resources/docs.go
new file mode 100644
index 000000000..f992893da
--- /dev/null
+++ b/resources/docs.go
@@ -0,0 +1,15 @@
+// Copyright 2023 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 resources contains Resource related types.
+package resources
diff --git a/resources/images/exif/exif.go b/resources/images/exif/exif.go
index 487f250d5..8df348b23 100644
--- a/resources/images/exif/exif.go
+++ b/resources/images/exif/exif.go
@@ -254,8 +254,10 @@ func init() {
 	}
 }
 
+// Tags is a map of EXIF tags.
 type Tags map[string]any
 
+// UnmarshalJSON is for internal use only.
 func (v *Tags) UnmarshalJSON(b []byte) error {
 	vv := make(map[string]any)
 	if err := tcodec.Unmarshal(b, &vv); err != nil {
@@ -267,6 +269,7 @@ func (v *Tags) UnmarshalJSON(b []byte) error {
 	return nil
 }
 
+// MarshalJSON is for internal use only.
 func (v Tags) MarshalJSON() ([]byte, error) {
 	return tcodec.Marshal(v)
 }
diff --git a/resources/images/image_resource.go b/resources/images/image_resource.go
index 4e66b010c..846959006 100644
--- a/resources/images/image_resource.go
+++ b/resources/images/image_resource.go
@@ -29,6 +29,7 @@ type ImageResource interface {
 type ImageResourceOps interface {
 	// Height returns the height of the Image.
 	Height() int
+
 	// Width returns the width of the Image.
 	Width() int
 
@@ -37,8 +38,17 @@ type ImageResourceOps interface {
 	// Use the anchor option to change the crop box anchor point.
 	//    {{ $image := $image.Crop "600x400" }}
 	Crop(spec string) (ImageResource, error)
+
+	// Fill scales the image to the smallest possible size that will cover the specified dimensions in spec,
+	// crops the resized image to the specified dimensions using the given anchor point.
+	// The spec is space delimited, e.g. `200x300 TopLeft`.
 	Fill(spec string) (ImageResource, error)
+
+	// Fit scales down the image using the given spec.
 	Fit(spec string) (ImageResource, error)
+
+	// Resize resizes the image to the given spec. If one of width or height is 0, the image aspect
+	// ratio is preserved.
 	Resize(spec string) (ImageResource, error)
 
 	// Filter applies one or more filters to an Image.
diff --git a/resources/page/page.go b/resources/page/page.go
index 929f04d93..eeb2cdb28 100644
--- a/resources/page/page.go
+++ b/resources/page/page.go
@@ -21,7 +21,6 @@ import (
 	"github.com/gohugoio/hugo/identity"
 	"github.com/gohugoio/hugo/markup/converter"
 
-	"github.com/bep/gitmap"
 	"github.com/gohugoio/hugo/config"
 	"github.com/gohugoio/hugo/tpl"
 
@@ -61,18 +60,17 @@ type AuthorProvider interface {
 
 // ChildCareProvider provides accessors to child resources.
 type ChildCareProvider interface {
+	// Pages returns a list of pages of all kinds.
 	Pages() Pages
 
 	// RegularPages returns a list of pages of kind 'Page'.
-	// In Hugo 0.57 we changed the Pages method so it returns all page
-	// kinds, even sections. If you want the old behaviour, you can
-	// use RegularPages.
 	RegularPages() Pages
 
 	// RegularPagesRecursive returns all regular pages below the current
 	// section.
 	RegularPagesRecursive() Pages
 
+	// Resources returns a list of all resources.
 	Resources() resource.Resources
 }
 
@@ -103,16 +101,21 @@ type ContentProvider interface {
 	ReadingTime() int
 
 	// Len returns the length of the content.
+	// This is for internal use only.
 	Len() int
 }
 
 // ContentRenderer provides the content rendering methods for some content.
 type ContentRenderer interface {
+	// RenderContent renders the given content.
+	// For internal use only.
 	RenderContent(content []byte, renderTOC bool) (converter.Result, error)
 }
 
 // FileProvider provides the source file.
 type FileProvider interface {
+	// File returns the source file for this Page,
+	// or a zero File if this Page is not backed by a file.
 	File() source.File
 }
 
@@ -131,13 +134,17 @@ type GetPageProvider interface {
 
 // GitInfoProvider provides Git info.
 type GitInfoProvider interface {
-	GitInfo() *gitmap.GitInfo
+	// GitInfo returns the Git info for this object.
+	GitInfo() source.GitInfo
+	// CodeOwners returns the code owners for this object.
 	CodeOwners() []string
 }
 
 // InSectionPositioner provides section navigation.
 type InSectionPositioner interface {
+	// NextInSection returns the next page in the same section.
 	NextInSection() Page
+	// PrevInSection returns the previous page in the same section.
 	PrevInSection() Page
 }
 
@@ -149,6 +156,7 @@ type InternalDependencies interface {
 
 // OutputFormatsProvider provides the OutputFormats of a Page.
 type OutputFormatsProvider interface {
+	// OutputFormats returns the OutputFormats for this Page.
 	OutputFormats() OutputFormats
 }
 
@@ -229,6 +237,7 @@ type PageMetaProvider interface {
 	SectionsPath() string
 
 	// Sitemap returns the sitemap configuration for this page.
+	// This is for internal use only.
 	Sitemap() config.Sitemap
 
 	// Type is a discriminator used to select layouts etc. It is typically set
@@ -242,7 +251,15 @@ type PageMetaProvider interface {
 
 // PageRenderProvider provides a way for a Page to render content.
 type PageRenderProvider interface {
+	// Render renders the given layout with this Page as context.
 	Render(layout ...string) (template.HTML, error)
+	// RenderString renders the first value in args with tPaginatorhe content renderer defined
+	// for this Page.
+	// It takes an optional map as a second argument:
+	//
+	// display (“inline”):
+	// - inline or block. If inline (default), surrounding 

on short snippets will be trimmed. + // markup (defaults to the Page’s markup) RenderString(args ...any) (template.HTML, error) } @@ -311,7 +328,9 @@ type PageWithoutContent interface { // Positioner provides next/prev navigation. type Positioner interface { + // Next points up to the next regular page (sorted by Hugo’s default sort). Next() Page + // Prev points down to the previous regular page (sorted by Hugo’s default sort). Prev() Page // Deprecated: Use Prev. Will be removed in Hugo 0.57 @@ -323,16 +342,19 @@ type Positioner interface { // RawContentProvider provides the raw, unprocessed content of the page. type RawContentProvider interface { + // RawContent returns the raw, unprocessed content of the page excluding any front matter. RawContent() string } // RefProvider provides the methods needed to create reflinks to pages. type RefProvider interface { + // Ref returns an absolute URl to a page. Ref(argsm map[string]any) (string, error) // RefFrom is for internal use only. RefFrom(argsm map[string]any, source any) (string, error) + // RelRef returns a relative URL to a page. RelRef(argsm map[string]any) (string, error) // RefFrom is for internal use only. @@ -356,12 +378,15 @@ type ShortcodeInfoProvider interface { // SitesProvider provide accessors to get sites. type SitesProvider interface { + // Site returns the current site. Site() Site + // Sites returns all sites. Sites() Sites } // TableOfContentsProvider provides the table of contents for a Page. type TableOfContentsProvider interface { + // TableOfContents returns the table of contents for the page rendered as HTML. TableOfContents() template.HTML } @@ -382,7 +407,7 @@ type TranslationsProvider interface { // TreeProvider provides section tree navigation. type TreeProvider interface { - // IsAncestor returns whether the current page is an ancestor of the given + // IsAncestor returns whether the current page is an ancestor of other. // Note that this method is not relevant for taxonomy lists and taxonomy terms pages. IsAncestor(other any) (bool, error) @@ -390,7 +415,7 @@ type TreeProvider interface { // Note that this will return nil for pages that is not regular, home or section pages. CurrentSection() Page - // IsDescendant returns whether the current page is a descendant of the given + // IsDescendant returns whether the current page is a descendant of other. // Note that this method is not relevant for taxonomy lists and taxonomy terms pages. IsDescendant(other any) (bool, error) @@ -398,7 +423,7 @@ type TreeProvider interface { // For the home page, this will return itself. FirstSection() Page - // InSection returns whether the given page is in the current section. + // InSection returns whether other is in the current section. // Note that this will always return false for pages that are // not either regular, home or section pages. InSection(other any) (bool, error) diff --git a/resources/page/page_marshaljson.autogen.go b/resources/page/page_marshaljson.autogen.go index 0f73d81ae..373257878 100644 --- a/resources/page/page_marshaljson.autogen.go +++ b/resources/page/page_marshaljson.autogen.go @@ -17,7 +17,6 @@ package page import ( "encoding/json" - "github.com/bep/gitmap" "github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/hugofs/files" @@ -82,6 +81,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) { language := p.Language() file := p.File() gitInfo := p.GitInfo() + codeOwners := p.CodeOwners() outputFormats := p.OutputFormats() alternativeOutputFormats := p.AlternativeOutputFormats() menus := p.Menus() @@ -89,10 +89,11 @@ func MarshalPageToJSON(p Page) ([]byte, error) { isTranslated := p.IsTranslated() allTranslations := p.AllTranslations() translations := p.Translations() + store := p.Store() getIdentity := p.GetIdentity() s := struct { - Content any + Content interface{} Plain string PlainWords []string Summary template.HTML @@ -110,7 +111,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) { Name string Title string Params maps.Params - Data any + Data interface{} Date time.Time Lastmod time.Time PublishDate time.Time @@ -139,7 +140,8 @@ func MarshalPageToJSON(p Page) ([]byte, error) { Weight int Language *langs.Language File source.File - GitInfo *gitmap.GitInfo + GitInfo source.GitInfo + CodeOwners []string OutputFormats OutputFormats AlternativeOutputFormats OutputFormats Menus navigation.PageMenus @@ -147,6 +149,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) { IsTranslated bool AllTranslations Pages Translations Pages + Store *maps.Scratch GetIdentity identity.Identity }{ Content: content, @@ -197,6 +200,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) { Language: language, File: file, GitInfo: gitInfo, + CodeOwners: codeOwners, OutputFormats: outputFormats, AlternativeOutputFormats: alternativeOutputFormats, Menus: menus, @@ -204,6 +208,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) { IsTranslated: isTranslated, AllTranslations: allTranslations, Translations: translations, + Store: store, GetIdentity: getIdentity, } diff --git a/resources/page/page_nop.go b/resources/page/page_nop.go index 15f8c3950..c4af3f554 100644 --- a/resources/page/page_nop.go +++ b/resources/page/page_nop.go @@ -28,7 +28,6 @@ import ( "github.com/gohugoio/hugo/hugofs" - "github.com/bep/gitmap" "github.com/gohugoio/hugo/navigation" "github.com/gohugoio/hugo/common/hugo" @@ -200,8 +199,8 @@ func (p *nopPage) GetTerms(taxonomy string) Pages { return nil } -func (p *nopPage) GitInfo() *gitmap.GitInfo { - return nil +func (p *nopPage) GitInfo() source.GitInfo { + return source.GitInfo{} } func (p *nopPage) CodeOwners() []string { diff --git a/resources/page/pagination.go b/resources/page/pagination.go index 9f4bfcff5..46d9fda82 100644 --- a/resources/page/pagination.go +++ b/resources/page/pagination.go @@ -27,8 +27,10 @@ import ( // PaginatorProvider provides two ways to create a page paginator. type PaginatorProvider interface { + // Paginator creates a paginator with the default page set. Paginator(options ...any) (*Pager, error) - Paginate(seq any, options ...any) (*Pager, error) + // Paginate creates a paginator with the given page set in pages. + Paginate(pages any, options ...any) (*Pager, error) } // Pager represents one of the elements in a paginator. diff --git a/resources/page/site.go b/resources/page/site.go index f5806280c..8daff95ae 100644 --- a/resources/page/site.go +++ b/resources/page/site.go @@ -26,8 +26,7 @@ import ( "github.com/gohugoio/hugo/navigation" ) -// Site represents a site in the build. This is currently a very narrow interface, -// but the actual implementation will be richer, see hugolib.SiteInfo. +// Site represents a site. There can be multople sites in a multilingual setup. type Site interface { // Returns the Language configured for this Site. Language() *langs.Language @@ -63,7 +62,7 @@ type Site interface { BaseURL() template.URL // Retuns a taxonomy map. - Taxonomies() any + Taxonomies() TaxonomyList // Returns the last modification date of the content. LastChange() time.Time @@ -142,7 +141,7 @@ func (t testSite) Menus() navigation.Menus { return nil } -func (t testSite) Taxonomies() any { +func (t testSite) Taxonomies() TaxonomyList { return nil } diff --git a/hugolib/taxonomy.go b/resources/page/taxonomy.go similarity index 87% rename from hugolib/taxonomy.go rename to resources/page/taxonomy.go index 6b3c2b961..f50152f90 100644 --- a/hugolib/taxonomy.go +++ b/resources/page/taxonomy.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Hugo Authors. All rights reserved. +// Copyright 2023 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. @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package hugolib +package page import ( "fmt" @@ -19,8 +19,6 @@ import ( "github.com/gohugoio/hugo/compare" "github.com/gohugoio/hugo/langs" - - "github.com/gohugoio/hugo/resources/page" ) // The TaxonomyList is a list of all taxonomies and their values @@ -33,9 +31,10 @@ func (tl TaxonomyList) String() string { // A Taxonomy is a map of keywords to a list of pages. // For example -// TagTaxonomy['technology'] = page.WeightedPages -// TagTaxonomy['go'] = page.WeightedPages -type Taxonomy map[string]page.WeightedPages +// +// TagTaxonomy['technology'] = WeightedPages +// TagTaxonomy['go'] = WeightedPages +type Taxonomy map[string]WeightedPages // OrderedTaxonomy is another representation of an Taxonomy using an array rather than a map. // Important because you can't order a map. @@ -43,7 +42,7 @@ type OrderedTaxonomy []OrderedTaxonomyEntry // getOneOPage returns one page in the taxonomy, // nil if there is none. -func (t OrderedTaxonomy) getOneOPage() page.Page { +func (t OrderedTaxonomy) getOneOPage() Page { if len(t) == 0 { return nil } @@ -51,24 +50,20 @@ func (t OrderedTaxonomy) getOneOPage() page.Page { } // OrderedTaxonomyEntry is similar to an element of a Taxonomy, but with the key embedded (as name) -// e.g: {Name: Technology, page.WeightedPages: TaxonomyPages} +// e.g: {Name: Technology, WeightedPages: TaxonomyPages} type OrderedTaxonomyEntry struct { Name string - page.WeightedPages + WeightedPages } // Get the weighted pages for the given key. -func (i Taxonomy) Get(key string) page.WeightedPages { +func (i Taxonomy) Get(key string) WeightedPages { return i[key] } // Count the weighted pages for the given key. func (i Taxonomy) Count(key string) int { return len(i[key]) } -func (i Taxonomy) add(key string, w page.WeightedPage) { - i[key] = append(i[key], w) -} - // TaxonomyArray returns an ordered taxonomy with a non defined order. func (i Taxonomy) TaxonomyArray() OrderedTaxonomy { ies := make([]OrderedTaxonomyEntry, len(i)) @@ -117,7 +112,7 @@ func (i Taxonomy) ByCount() OrderedTaxonomy { } // Pages returns the Pages for this taxonomy. -func (ie OrderedTaxonomyEntry) Pages() page.Pages { +func (ie OrderedTaxonomyEntry) Pages() Pages { return ie.WeightedPages.Pages() } diff --git a/resources/page/testhelpers_test.go b/resources/page/testhelpers_test.go index 22346c389..e8275ba40 100644 --- a/resources/page/testhelpers_test.go +++ b/resources/page/testhelpers_test.go @@ -26,7 +26,6 @@ import ( "github.com/gohugoio/hugo/modules" - "github.com/bep/gitmap" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/resources/resource" @@ -250,8 +249,8 @@ func (p *testPage) GetRelatedDocsHandler() *RelatedDocsHandler { return relatedDocsHandler } -func (p *testPage) GitInfo() *gitmap.GitInfo { - return nil +func (p *testPage) GitInfo() source.GitInfo { + return source.GitInfo{} } func (p *testPage) CodeOwners() []string { diff --git a/resources/resource/resources.go b/resources/resource/resources.go index a888d6fb4..a877c8906 100644 --- a/resources/resource/resources.go +++ b/resources/resource/resources.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Hugo Authors. All rights reserved. +// Copyright 2023 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. @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package resource contains Resource related types. package resource import ( diff --git a/resources/resource/resourcetypes.go b/resources/resource/resourcetypes.go index 4ba95c170..4ef5fc5a0 100644 --- a/resources/resource/resourcetypes.go +++ b/resources/resource/resourcetypes.go @@ -64,6 +64,9 @@ type ResourceError interface { // ErrProvider provides an Err. type ErrProvider interface { + + // Err returns an error if this resource is in an error state. + // This will currently only be set for resources obtained from resources.GetRemote. Err() ResourceError } diff --git a/source/fileInfo.go b/source/fileInfo.go index f882eb898..9ce601b5b 100644 --- a/source/fileInfo.go +++ b/source/fileInfo.go @@ -18,7 +18,9 @@ import ( "path/filepath" "strings" "sync" + "time" + "github.com/bep/gitmap" "github.com/gohugoio/hugo/common/paths" "github.com/gohugoio/hugo/hugofs/files" @@ -294,3 +296,31 @@ func (sp *SourceSpec) NewFileInfo(fi hugofs.FileMetaInfo) (*FileInfo, error) { return f, nil } + +func NewGitInfo(info gitmap.GitInfo) GitInfo { + return GitInfo(info) +} + +// GitInfo provides information about a version controled source file. +type GitInfo struct { + // Commit hash. + Hash string `json:"hash"` + // Abbreviated commit hash. + AbbreviatedHash string `json:"abbreviatedHash"` + // The commit message's subject/title line. + Subject string `json:"subject"` + // The author name, respecting .mailmap. + AuthorName string `json:"authorName"` + // The author email address, respecting .mailmap. + AuthorEmail string `json:"authorEmail"` + // The author date. + AuthorDate time.Time `json:"authorDate"` + // The commit date. + CommitDate time.Time `json:"commitDate"` +} + +// IsZero returns true if the GitInfo is empty, +// meaning it will also be falsy in the Go templates. +func (g GitInfo) IsZero() bool { + return g.Hash == "" +} diff --git a/source/sourceSpec.go b/source/sourceSpec.go index 0b7306a75..954167f28 100644 --- a/source/sourceSpec.go +++ b/source/sourceSpec.go @@ -1,4 +1,4 @@ -// Copyright 2017-present The Hugo Authors. All rights reserved. +// Copyright 2023 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. @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package source contains the types and functions related to source files. package source import ( diff --git a/tpl/diagrams/init.go b/tpl/diagrams/init.go index 005e942b7..1ed308c57 100644 --- a/tpl/diagrams/init.go +++ b/tpl/diagrams/init.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package diagrams provides template functions for generating diagrams. package diagrams import ( diff --git a/tpl/images/images.go b/tpl/images/images.go index 1abee1b0c..f4d930570 100644 --- a/tpl/images/images.go +++ b/tpl/images/images.go @@ -91,6 +91,7 @@ func (ns *Namespace) Config(path any) (image.Config, error) { return config, nil } +// Filter applies the given filters to the image given as the last element in args. func (ns *Namespace) Filter(args ...any) (images.ImageResource, error) { if len(args) < 2 { return nil, errors.New("must provide an image and one or more filters") diff --git a/tpl/openapi/docs.go b/tpl/openapi/docs.go new file mode 100644 index 000000000..bb7ed9c75 --- /dev/null +++ b/tpl/openapi/docs.go @@ -0,0 +1,2 @@ +// Package openapi provides functions for generating OpenAPI (Swagger) documentation. +package openapi diff --git a/tpl/openapi/openapi3/openapi3.go b/tpl/openapi/openapi3/openapi3.go index 9b84e9fbe..31d56289e 100644 --- a/tpl/openapi/openapi3/openapi3.go +++ b/tpl/openapi/openapi3/openapi3.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package openapi3 provides functions for generating OpenAPI v3 (Swagger) documentation. package openapi3 import ( @@ -54,6 +55,7 @@ type OpenAPIDocument struct { *kopenapi3.T } +// Unmarshal unmarshals the given resource into an OpenAPI 3 document. func (ns *Namespace) Unmarshal(r resource.UnmarshableResource) (*OpenAPIDocument, error) { key := r.Key() if key == "" { diff --git a/tpl/os/os_test.go b/tpl/os/os_test.go index 98befa061..399adb374 100644 --- a/tpl/os/os_test.go +++ b/tpl/os/os_test.go @@ -38,15 +38,15 @@ func TestReadFile(t *testing.T) { }{ {filepath.FromSlash("/f/f1.txt"), "f1-content"}, {filepath.FromSlash("f/f1.txt"), "f1-content"}, - {filepath.FromSlash("../f2.txt"), false}, + {filepath.FromSlash("../f2.txt"), ""}, {"", false}, - {"b", false}, + {"b", ""}, } { result, err := ns.ReadFile(test.filename) if bb, ok := test.expect.(bool); ok && !bb { - b.Assert(err, qt.Not(qt.IsNil)) + b.Assert(err, qt.Not(qt.IsNil), qt.Commentf("filename: %q", test.filename)) continue } diff --git a/tpl/path/path.go b/tpl/path/path.go index 378b97e03..59add2152 100644 --- a/tpl/path/path.go +++ b/tpl/path/path.go @@ -15,11 +15,11 @@ package path import ( - "fmt" _path "path" "path/filepath" "strings" + "github.com/gohugoio/hugo/common/paths" "github.com/gohugoio/hugo/deps" "github.com/spf13/cast" ) @@ -36,17 +36,6 @@ type Namespace struct { deps *deps.Deps } -// DirFile holds the result from path.Split. -type DirFile struct { - Dir string - File string -} - -// Used in test. -func (df DirFile) String() string { - return fmt.Sprintf("%s|%s", df.Dir, df.File) -} - // Ext returns the file name extension used by path. // The extension is the suffix beginning at the final dot // in the final slash-separated element of path; @@ -117,15 +106,15 @@ func (ns *Namespace) BaseName(path any) (string, error) { // The input path is passed into filepath.ToSlash converting any Windows slashes // to forward slashes. // The returned values have the property that path = dir+file. -func (ns *Namespace) Split(path any) (DirFile, error) { +func (ns *Namespace) Split(path any) (paths.DirFile, error) { spath, err := cast.ToStringE(path) if err != nil { - return DirFile{}, err + return paths.DirFile{}, err } spath = filepath.ToSlash(spath) dir, file := _path.Split(spath) - return DirFile{Dir: dir, File: file}, nil + return paths.DirFile{Dir: dir, File: file}, nil } // Join joins any number of path elements into a single path, adding a diff --git a/tpl/path/path_test.go b/tpl/path/path_test.go index 599d8367a..cc49bf28c 100644 --- a/tpl/path/path_test.go +++ b/tpl/path/path_test.go @@ -18,6 +18,7 @@ import ( "testing" qt "github.com/frankban/quicktest" + "github.com/gohugoio/hugo/common/paths" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/deps" ) @@ -157,7 +158,7 @@ func TestJoin(t *testing.T) { `baz/foo/bar.txt`, }, { - []any{"", "baz", DirFile{"big", "john"}, filepath.FromSlash(`foo/bar.txt`)}, + []any{"", "baz", paths.DirFile{Dir: "big", File: "john"}, filepath.FromSlash(`foo/bar.txt`)}, `baz/big|john/foo/bar.txt`, }, {nil, ""}, @@ -186,10 +187,10 @@ func TestSplit(t *testing.T) { path any expect any }{ - {filepath.FromSlash(`foo/bar.txt`), DirFile{`foo/`, `bar.txt`}}, - {filepath.FromSlash(`foo/bar/txt `), DirFile{`foo/bar/`, `txt `}}, - {`foo.bar.txt`, DirFile{``, `foo.bar.txt`}}, - {``, DirFile{``, ``}}, + {filepath.FromSlash(`foo/bar.txt`), paths.DirFile{Dir: `foo/`, File: `bar.txt`}}, + {filepath.FromSlash(`foo/bar/txt `), paths.DirFile{Dir: `foo/bar/`, File: `txt `}}, + {`foo.bar.txt`, paths.DirFile{Dir: ``, File: `foo.bar.txt`}}, + {``, paths.DirFile{Dir: ``, File: ``}}, // errors {tstNoStringer{}, false}, } { diff --git a/tpl/resources/resources.go b/tpl/resources/resources.go index 9d663cb46..85323f057 100644 --- a/tpl/resources/resources.go +++ b/tpl/resources/resources.go @@ -414,6 +414,7 @@ func (ns *Namespace) PostCSS(args ...any) (resource.Resource, error) { return ns.postcssClient.Process(r, m) } +// PostProcess processes r after the build. func (ns *Namespace) PostProcess(r resource.Resource) (postpub.PostPublishedResource, error) { return ns.deps.ResourceSpec.PostProcess(r) } diff --git a/tpl/strings/truncate.go b/tpl/strings/truncate.go index dd6267280..e8da7b84b 100644 --- a/tpl/strings/truncate.go +++ b/tpl/strings/truncate.go @@ -39,9 +39,9 @@ type htmlTag struct { openTag bool } -// Truncate truncates a given string to the specified length. -func (ns *Namespace) Truncate(a any, options ...any) (template.HTML, error) { - length, err := cast.ToIntE(a) +// Truncate truncates the string in s to the specified length. +func (ns *Namespace) Truncate(s any, options ...any) (template.HTML, error) { + length, err := cast.ToIntE(s) if err != nil { return "", err } diff --git a/tpl/template.go b/tpl/template.go index 738750de7..dd9249ade 100644 --- a/tpl/template.go +++ b/tpl/template.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package tpl contains template functions and related types. package tpl import (