Skip to content

feat: translation support fs loader#974

Merged
devhaozi merged 8 commits intomasterfrom
haozi/fs
Apr 10, 2025
Merged

feat: translation support fs loader#974
devhaozi merged 8 commits intomasterfrom
haozi/fs

Conversation

@devhaozi
Copy link
Member

📑 Description

Closes goravel/goravel#456

✅ Checks

  • Added test cases for my code

Copilot AI review requested due to automatic review settings March 27, 2025 07:47
@devhaozi devhaozi requested a review from a team as a code owner March 27, 2025 07:47
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces translation support using a filesystem loader and updates related services to handle translation files more flexibly. Key changes include:

  • Introducing a new FSLoader implementation in translation/fs_loader.go to load translation JSON files using fs.FS.
  • Adding comprehensive tests for FSLoader functionality in translation/fs_loader_test.go.
  • Updating the service provider in translation/service_provider.go to detect and use FSLoader when provided with an fs.FS, and adjusting the file loader return type in translation/file_loader.go.

Reviewed Changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated no comments.

File Description
translation/fs_loader.go Implements FSLoader for translations using fs.FS and JSON unmarshaling.
translation/fs_loader_test.go Adds unit tests and benchmarks to validate FSLoader behavior.
translation/service_provider.go Updates registration to use FSLoader when the language path is of type fs.FS.
translation/file_loader.go Adjusts NewFileLoader signature to conform to the Loader interface.
Files not reviewed (1)
  • tests/go.mod: Language not supported

@devhaozi devhaozi enabled auto-merge (squash) March 27, 2025 07:51
@codecov
Copy link

codecov bot commented Mar 27, 2025

Codecov Report

Attention: Patch coverage is 85.00000% with 6 lines in your changes missing coverage. Please review.

Project coverage is 70.09%. Comparing base (804d217) to head (bb0f5a6).
Report is 7 commits behind head on master.

Files with missing lines Patch % Lines
translation/service_provider.go 0.00% 5 Missing ⚠️
translation/fs_loader.go 95.45% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #974      +/-   ##
==========================================
+ Coverage   70.04%   70.09%   +0.04%     
==========================================
  Files         168      169       +1     
  Lines       11353    11381      +28     
==========================================
+ Hits         7952     7977      +25     
- Misses       3050     3053       +3     
  Partials      351      351              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👍 Could you enrich the description to show how to use the new feature?

@devhaozi
Copy link
Member Author

Nice 👍 Could you enrich the description to show how to use the new feature?

//go:embed all:lang/*
var f embed.FS

and pass f to config app.lang_fs.

@hwbrzzl
Copy link
Contributor

hwbrzzl commented Mar 27, 2025

Where should var f embed.FS be added?

@devhaozi
Copy link
Member Author

Where should var f embed.FS be added?

Anywhere, if use capital letters.

@hwbrzzl
Copy link
Contributor

hwbrzzl commented Mar 28, 2025

I mean should a new go file be created like the image below?

image

The process is similar with the comment, we just implement inject the FS to the lang configuration.

@almas-x
Copy link
Contributor

almas-x commented Mar 28, 2025

Can FSLoader and FileLoader be used together instead of being mutually exclusive? I am thinking of having FileLoader override FSLoader. This way, when the embedded language package project goes live, we can use FileLoader to replace or add new language entries, making it more flexible.

@devhaozi
Copy link
Member Author

I mean should a new go file be created like the image below?

image The process is similar with [the comment](https://github.com/goravel/goravel/issues/456#issuecomment-2268977686), we just implement inject the FS to the lang configuration.

Yes

@devhaozi
Copy link
Member Author

Can FSLoader and FileLoader be used together instead of being mutually exclusive? I am thinking of having FileLoader override FSLoader. This way, when the embedded language package project goes live, we can use FileLoader to replace or add new language entries, making it more flexible.

Will optimize it.

@hwbrzzl
Copy link
Contributor

hwbrzzl commented Mar 29, 2025

Can FSLoader and FileLoader be used together instead of being mutually exclusive? I am thinking of having FileLoader override FSLoader. This way, when the embedded language package project goes live, we can use FileLoader to replace or add new language entries, making it more flexible.

@almas1992 Do you mean that user doesn't need to rebuild project to add the lang file via the FileLoader? And the FSLoader is used at that time.

@almas-x
Copy link
Contributor

almas-x commented Mar 29, 2025

Can FSLoader and FileLoader be used together instead of being mutually exclusive? I am thinking of having FileLoader override FSLoader. This way, when the embedded language package project goes live, we can use FileLoader to replace or add new language entries, making it more flexible.

@almas1992 Do you mean that user doesn't need to rebuild project to add the lang file via the FileLoader? And the FSLoader is used at that time.

Initially, FSLoader is used to load the embedded language files. Users can use FileLoader to load new language files without needing to rebuild.

Comment on lines +364 to +397
func (t *TranslatorTestSuite) TestLoadFS() {
mockFS := fstest.MapFS{
"lang/cn/test.json": &fstest.MapFile{Data: []byte(`{"foo": "bar", "baz": {"foo": "bar"}}`)},
}

translator := NewTranslator(t.ctx, NewFSLoader("lang", mockFS, json.NewJson()), t.mockLoader, "en", "en", t.mockLog)
t.mockLoader.On("Load", "en", "test").Once().Return(map[string]any{
"foo": "one",
"bar": "two",
}, nil)

// Case: Not loaded, successful load
err := translator.load("en", "test")
t.NoError(err)
t.Equal("one", loaded["en"]["test"]["foo"])

// Case: Already loaded
err = translator.load("en", "test")
t.NoError(err)
t.Equal("two", loaded["en"]["test"]["bar"])

// Case: Loaded from FS
t.mockLoader.On("Load", "cn", "test").Once().Return(nil, errors.LangFileNotExist)
err = translator.load("cn", "test")
t.NoError(err)
t.Equal("bar", loaded["cn"]["test"]["foo"])

// Case: Not loaded, loader returns an error
t.mockLoader.On("Load", "es", "folder3").Once().Return(nil, errors.LangFileNotExist)
err = translator.load("es", "folder3")
t.EqualError(err, "translation file does not exist")
t.Nil(loaded["folder3"])
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, see this test case

Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome 👍

@devhaozi devhaozi merged commit 4dc9b57 into master Apr 10, 2025
13 checks passed
@devhaozi devhaozi deleted the haozi/fs branch April 10, 2025 03:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ [Feature] static file support use go:embed

5 participants