Embed translation bundle into binary

This commit is contained in:
Jan Dittberner 2023-05-15 16:47:37 +02:00
parent 2c82ccb324
commit 9fad7ef3a6
9 changed files with 43 additions and 42 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
*.pem
.idea/ .idea/
/cacert-idp /cacert-idp
/static /static

View file

@ -1,6 +1,6 @@
GOFILES = $(wildcard */*.go) GOFILES = $(wildcard */*.go)
TEMPLATES = $(wildcard ui/templates/*.gohtml) TEMPLATES = $(wildcard ui/templates/*.gohtml)
TRANSLATIONS = $(wildcard active.*.toml) TRANSLATIONS = $(wildcard translations/active.*.toml)
RESOURCES = ui/css ui/images ui/js RESOURCES = ui/css ui/images ui/js
all: cacert-idp all: cacert-idp
@ -18,8 +18,9 @@ go.sum: go.mod
go mod tidy go mod tidy
translations: $(TRANSLATIONS) $(GOFILES) translations: $(TRANSLATIONS) $(GOFILES)
goi18n extract . cd translations ; \
goi18n merge active.*.toml goi18n extract .. ; \
goi18n merge active.*.toml ; \
if translate.*.toml 2>/dev/null; then \ if translate.*.toml 2>/dev/null; then \
echo "missing translations"; \ echo "missing translations"; \
goi18n merge active.*.toml translate.*.toml; \ goi18n merge active.*.toml translate.*.toml; \

View file

@ -147,9 +147,10 @@ func main() {
csrf.MaxAge(DefaultCSRFMaxAge)) csrf.MaxAge(DefaultCSRFMaxAge))
errorMiddleware, err := handlers.ErrorHandling( errorMiddleware, err := handlers.ErrorHandling(
context.Background(),
logger, logger,
ui.Templates, ui.Templates,
bundle,
catalog,
) )
if err != nil { if err != nil {
logger.Fatalf("could not initialize request error handling: %v", err) logger.Fatalf("could not initialize request error handling: %v", err)

View file

@ -130,9 +130,10 @@ func (w *errorResponseWriter) Write(content []byte) (int, error) {
} }
func ErrorHandling( func ErrorHandling(
handlerContext context.Context,
logger *log.Logger, logger *log.Logger,
templateFS fs.FS, templateFS fs.FS,
bundle *i18n.Bundle,
messageCatalog *services.MessageCatalog,
) (func(http.Handler) http.Handler, error) { ) (func(http.Handler) http.Handler, error) {
errorTemplates, err := template.ParseFS( errorTemplates, err := template.ParseFS(
templateFS, templateFS,
@ -143,16 +144,6 @@ func ErrorHandling(
return nil, fmt.Errorf("could not parse templates: %w", err) return nil, fmt.Errorf("could not parse templates: %w", err)
} }
bundle, err := services.GetI18nBundle(handlerContext)
if err != nil {
return nil, fmt.Errorf("could not get i18n bundle: %w", err)
}
messageCatalog, err := services.GetMessageCatalog(handlerContext)
if err != nil {
return nil, fmt.Errorf("could not get message catalog: %w", err)
}
return func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
errorBucket := &ErrorBucket{ errorBucket := &ErrorBucket{

View file

@ -18,12 +18,13 @@ limitations under the License.
package services package services
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"git.cacert.org/oidc_idp/translations"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"github.com/nicksnyder/go-i18n/v2/i18n" "github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language" "golang.org/x/text/language"
@ -107,13 +108,6 @@ func AddMessages(catalog *MessageCatalog) error {
return nil return nil
} }
type contextKey int
const (
ctxI18nBundle contextKey = iota
ctxI18nCatalog
)
type MessageCatalog struct { type MessageCatalog struct {
messages map[string]*i18n.Message messages map[string]*i18n.Message
logger *log.Logger logger *log.Logger
@ -227,10 +221,16 @@ func InitI18n(logger *log.Logger, languages []string) (*i18n.Bundle, *MessageCat
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal) bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
for _, lang := range languages { for _, lang := range languages {
_, err := bundle.LoadMessageFile(fmt.Sprintf("active.%s.toml", lang)) bundleName := fmt.Sprintf("active.%s.toml", lang)
bundleBytes, err := translations.Bundles.ReadFile(bundleName)
if err != nil { if err != nil {
logger.Warnf("message bundle %s.toml not found", lang) logger.Warnf("message bundle %s not found", bundleName)
continue
} }
bundle.MustParseMessageFileBytes(bundleBytes, bundleName)
} }
catalog := initMessageCatalog(logger) catalog := initMessageCatalog(logger)
@ -247,19 +247,3 @@ func initMessageCatalog(logger *log.Logger) *MessageCatalog {
return &MessageCatalog{messages: messages, logger: logger} return &MessageCatalog{messages: messages, logger: logger}
} }
func GetI18nBundle(ctx context.Context) (*i18n.Bundle, error) {
if b, ok := ctx.Value(ctxI18nBundle).(*i18n.Bundle); ok {
return b, nil
}
return nil, errors.New("context value is not a Bundle")
}
func GetMessageCatalog(ctx context.Context) (*MessageCatalog, error) {
if c, ok := ctx.Value(ctxI18nCatalog).(*MessageCatalog); ok {
return c, nil
}
return nil, errors.New("context value is not a MessageCatalog")
}

View file

@ -0,0 +1,23 @@
/*
Copyright 2020-2023 CAcert Inc.
SPDX-License-Identifier: Apache-2.0
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 translations
import "embed"
//go:embed active.*.toml
var Bundles embed.FS

View file

@ -32,7 +32,7 @@
</main> </main>
<footer class="footer mt-auto py-3"> <footer class="footer mt-auto py-3">
<div class="container"> <div class="container">
<span class="text-muted small">© 2020-2022 <a href="https://www.cacert.org/">CAcert</a></span> <span class="text-muted small">© 2020-2023 <a href="https://www.cacert.org/">CAcert</a></span>
</div> </div>
</footer> </footer>
<script type="text/javascript" src="/js/cacert.bundle.js"></script> <script type="text/javascript" src="/js/cacert.bundle.js"></script>