diff --git a/config/config.go b/config/config.go index 17c6d34..3587c5a 100644 --- a/config/config.go +++ b/config/config.go @@ -6,6 +6,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Package config contains support for Amsterdam site-wide configuration data. package config import ( @@ -14,6 +16,7 @@ import ( "gopkg.in/yaml.v3" ) +// AmConfig holds the configuration of the application as read from YAML. type AmConfig struct { Site struct { Title string `yaml:"title"` @@ -23,10 +26,14 @@ type AmConfig struct { //go:embed default.yaml var defaultConfigData []byte +// GlobalConfig holds the global configuration. var GlobalConfig AmConfig +// init prepares the default configuration for the application. func init() { var defaultConfig AmConfig - yaml.Unmarshal(defaultConfigData, &defaultConfig) + if err := yaml.Unmarshal(defaultConfigData, &defaultConfig); err != nil { + panic(err) // can't happen + } GlobalConfig = defaultConfig } diff --git a/logging.go b/logging.go index 2509259..97ea51c 100644 --- a/logging.go +++ b/logging.go @@ -6,6 +6,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Package main contains the high-level Amsterdam logic. package main import ( @@ -17,6 +19,7 @@ import ( log "github.com/sirupsen/logrus" ) +// init sets up the initial configuration for Logrus logging. func init() { log.SetFormatter(&log.TextFormatter{ FullTimestamp: true, @@ -25,6 +28,12 @@ func init() { log.SetLevel(log.InfoLevel) } +/* toglog converts a Logrus logging level to a glog one. + * Parameters: + * l - The Logrus log level to be converted. + * Returns: + * The equivalent glog log level. + */ func toglog(l log.Level) glog.Lvl { switch l { case log.DebugLevel: @@ -40,6 +49,12 @@ func toglog(l log.Level) glog.Lvl { } } +/* fromglog converts a glog logging level to a Logrus one. + * Parameters: + * l - The glog log level to be converted. + * Returns: + * The equivalent Logrus log level. + */ func fromglog(l glog.Lvl) log.Level { switch l { case glog.DEBUG: @@ -55,7 +70,7 @@ func fromglog(l glog.Lvl) log.Level { } } -// EchoLogrusAdapter implements echo.Logger using logrus +// EchoLogrusAdapter implements echo.Logger using logrus. type EchoLogrusAdapter struct{} func (l *EchoLogrusAdapter) Output() io.Writer { return log.StandardLogger().Out } @@ -87,7 +102,7 @@ func (l *EchoLogrusAdapter) Panicf(format string, args ...interface{}) { log.Pan func (l *EchoLogrusAdapter) Panicj(j glog.JSON) { log.WithFields(log.Fields(j)).Panic() } func (l *EchoLogrusAdapter) SetHeader(h string) {} -// Custom Logrus middleware +// LogrusMiddleware installs Logrus logging into the Echo middleware chain. func LogrusMiddleware(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { start := time.Now() diff --git a/main.go b/main.go index b5193d0..c8dce1b 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Package main contains the high-level Amsterdam logic. package main import ( @@ -14,6 +16,7 @@ import ( "github.com/labstack/echo/v4/middleware" ) +// setupEcho creates, configures, and returns a new Echo instance. func setupEcho() *echo.Echo { e := echo.New() e.Logger = &EchoLogrusAdapter{} @@ -30,6 +33,7 @@ func setupEcho() *echo.Echo { return e } +// main is Ye Olde Main Function. func main() { e := setupEcho() diff --git a/ui/amcontext.go b/ui/amcontext.go index fd13693..1927966 100644 --- a/ui/amcontext.go +++ b/ui/amcontext.go @@ -6,6 +6,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Package ui holds the support for the Amsterdam user interface, wrapping Echo and Jet templates. package ui import ( @@ -16,6 +18,7 @@ import ( "github.com/labstack/echo/v4" ) +// AmContext is the interface for Amsterdam's wapper context that exposes the required functionality. type AmContext interface { RC() int OutputType() string @@ -27,6 +30,7 @@ type AmContext interface { VarMap() jet.VarMap } +// amContext is the internal structure that implements AmContext. type amContext struct { echoContext echo.Context httprc int @@ -34,18 +38,33 @@ type amContext struct { outputType string } +// RC returns the HTTP result code for the current operation. func (c *amContext) RC() int { return c.httprc } +// OutputType returns the MIME output type set for the current operation. func (c *amContext) OutputType() string { return c.outputType } +/* Render renders a template to the output. Called at the top level only. + * Parameters: + * name = The name of the tempate to be rendered. + * Returns: + * Standard Go error status. + */ func (c *amContext) Render(name string) error { return c.echoContext.Render(c.httprc, name, c) } +/* SubRender renders a subtemplate to the output. + * Parameters: + * name = The name of the template to be rendered. + * Returns: + * Byte array with the rendered data to be output + * Standard Go error status + */ func (c *amContext) SubRender(name string) ([]byte, error) { view, err := views.GetTemplate(name) if err != nil { @@ -56,22 +75,32 @@ func (c *amContext) SubRender(name string) ([]byte, error) { return buf.Bytes(), err } +// SetOutputType sets the MIME output type for the current operation. func (c *amContext) SetOutputType(typ string) { c.outputType = typ } +// SetRC sets the HTTP result code for the current operation. func (c *amContext) SetRC(rc int) { c.httprc = rc } +// URLPath returns the path component of the request URL. func (c *amContext) URLPath() string { return c.echoContext.Request().URL.Path } +// VarMap provides access to the Jet variable map for setting variable data. func (c *amContext) VarMap() jet.VarMap { return c.rendervars } +/* NewAmContext creates a new AmContext wrapping the Echo context. + * Parameters: + * ctxt - The Echo context to be wrapped. + * Returns: + * A new Amsterdam context wrapping that context. + */ func NewAmContext(ctxt echo.Context) AmContext { rc := amContext{ echoContext: ctxt, @@ -83,6 +112,12 @@ func NewAmContext(ctxt echo.Context) AmContext { return &rc } +/* AmContextFromEchoContext returns the AmContext associated with an Echo context. + * Parameters: + * ctxt - The Echo context to have the AmContext extracted. + * Returns: + * The associated AmContext, or nil if there is none. + */ func AmContextFromEchoContext(ctxt echo.Context) AmContext { myctxt := ctxt.Get("amsterdam_context") if myctxt != nil { diff --git a/ui/images.go b/ui/images.go index 12ba134..137001f 100644 --- a/ui/images.go +++ b/ui/images.go @@ -6,6 +6,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Package ui holds the support for the Amsterdam user interface, wrapping Echo and Jet templates. package ui import ( @@ -19,10 +21,24 @@ import ( //go:embed static_images/* var static_images embed.FS +/* mimeTypeFromFilenane returns the MIME type of a file, given its filename. + * Parameters: + * filaname - The name of the file to be tested. + * Returns: + * The file's inferred MIME type. + */ func mimeTypeFromFilename(filename string) string { return mime.TypeByExtension(filename[strings.LastIndex(filename, "."):]) } +/* AmServeImage serves an image from internal storage. + * Parameters: + * ctxt - The AmContext for the request. + * Returns: + * Type of content to be rendered + * Content to be rendered + * Standard Go error return + */ func AmServeImage(ctxt AmContext) (string, any, error) { components := strings.SplitAfter(ctxt.URLPath(), "/") var err error = nil @@ -35,5 +51,6 @@ func AmServeImage(ctxt AmContext) (string, any, error) { } } ctxt.SetRC(http.StatusNotFound) + // TODO: improve this error reporting return "string", fmt.Sprintf("File not found: %s", ctxt.URLPath()), err } diff --git a/ui/render_wrap.go b/ui/render_wrap.go index 730dbd4..d083947 100644 --- a/ui/render_wrap.go +++ b/ui/render_wrap.go @@ -6,6 +6,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Package ui holds the support for the Amsterdam user interface, wrapping Echo and Jet templates. package ui import ( @@ -14,6 +16,13 @@ import ( "github.com/labstack/echo/v4" ) +/* AmWrap wraps the Amsterdam handler function in a wrapper that implements the spec for + * Echo handler functions. + * Parameters: + * myfunc - The Amsterdam handler to be wrapped. + * Returns: + * The wrapped function. + */ func AmWrap(myfunc func(AmContext) (string, any, error)) echo.HandlerFunc { return func(ctxt echo.Context) error { amctxt := NewAmContext(ctxt) @@ -33,10 +42,10 @@ func AmWrap(myfunc func(AmContext) (string, any, error)) echo.HandlerFunc { err = fmt.Errorf("unknown rendering type: %s", what) } if err != nil { - ctxt.Logger().Error("Rendering error: %v", err) + ctxt.Logger().Errorf("Rendering error: %v", err) } } else { - ctxt.Logger().Error("Page function error: %v", err) + ctxt.Logger().Errorf("Page function error: %v", err) } return err } diff --git a/ui/templates.go b/ui/templates.go index c537831..ac31412 100644 --- a/ui/templates.go +++ b/ui/templates.go @@ -6,6 +6,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +// Package ui holds the support for the Amsterdam user interface, wrapping Echo and Jet templates. package ui import ( @@ -16,18 +18,29 @@ import ( "github.com/labstack/echo/v4" ) +// views is the main Jet template repository. var views = jet.NewSet( jet.NewOSFileSystemLoader("./views"), jet.DevelopmentMode(true), ) +// init adds additional configuration for the views object. func init() { views.AddGlobal("GlobalConfig", config.GlobalConfig) } -type TemplateRenderer struct { -} +// TemplateRenderer is the Renderer instance set into the Echo context at creation time, to render Jet templates. +type TemplateRenderer struct{} +/* Render renders a Jet template to the Echo output stream. + * Parameters: + * w - Echo's output stream writer. + * name - Name of the template to be rendered. + * data - Context data to pass to the template. + * c - The Echo context for the request being processed. + * Returns: + * Standard Go error status. + */ func (r *TemplateRenderer) Render(w io.Writer, name string, data any, c echo.Context) error { view, err := views.GetTemplate(name) if err != nil {