Skip to content

Support embed package. #1145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 26 commits into from
Closed

Support embed package. #1145

wants to merge 26 commits into from

Conversation

visualfc
Copy link
Contributor

@visualfc visualfc commented Sep 10, 2022

support go:embed

  • gopherjs build/test/serve pkg
  • gopherjs run/build simple.go

dep pkg github.com/visualfc/goembed

Fixes #997

Copy link
Member

@nevkontakte nevkontakte left a comment

Choose a reason for hiding this comment

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

@visualfc thank you for this request, it is something I wished to do for a long time, although couldn't find time for.

I left a new minor comments, and I have a few more general questions and suggestions:

  • Have you attempted to measure how much more space the embedded data occupies in the compiled source compared to the original? Although this isn't something we have to do in this PR, investigating if we could compress the embedded data somehow would be a great improvement (from the issue #136 perspective especially).
  • To help me better understand how this PR works, could you post the generated js_embed.go source for some package? embed/internal/embedtest would be a good test subject.
  • How does gopherjs handle //go:embed instructions in files that do not import the embed package? Does it ignore them or error out? Is it the same as the official compiler?
  • A good first step to test this PR would be removing embed/internal/embedtest package from .std_test_pkg_exclusions and making sure the CI still passes.

build/build.go Outdated
Comment on lines 561 to 577
root := dirList[0]
ctx := build.Default
ctx.UseAllFiles = true
ctx.ReadDir = func(dir string) (infos []fs.FileInfo, err error) {
for _, f := range filenames {
info, err := os.Stat(f)
if err != nil {
return nil, err
}
infos = append(infos, info)
}
return
}
p, err := ctx.Import(".", root, 0)
if err != nil {
return err
}
Copy link
Member

Choose a reason for hiding this comment

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

Interesting, am I correctly understanding that what this does is limits the list of files the build context will see when importing the package to only the files listed in the command line, and then delegate the rest of the build.Package construction?

I think this new code might behave differently from the old one in case the user lists a mix of regular and test sources. We might have to combine all of the GoFiles flavors to get the correct behavior.

Copy link
Member

Choose a reason for hiding this comment

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

@visualfc can you please confirm I understood this code correctly?

@nevkontakte
Copy link
Member

Also cc @flimzy who at some point planned to work on this feature, in case he has additional insights.

@nevkontakte nevkontakte changed the title support embed Support embed package. Sep 10, 2022
Copy link
Member

@flimzy flimzy left a comment

Choose a reason for hiding this comment

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

I'm really happy to see this PR! Thanks for doing it!

I haven't tried running any of it yet, but left a couple comments inline, mostly stylistic.

It looks like all the heavy lifting is done in github.com/visualfc/goembed. I see it's being used by at least a couple other packages, but I do wonder if it would make sense to copy that logic into gopherjs directly. I'm curious of @nevkontakte 's thoughts.

I may be wrong, but I don't think we have any precedent for core compiler logic in an external package that doesn't come from upstream. But maybe that's not important anyway.

@visualfc
Copy link
Contributor Author

visualfc commented Sep 11, 2022

this PR current embed generate code on gopherjs/build used by ast.
not support embed/internal/embedtest.TestAliases.
maybe move to gopherjs/compiler for used by types.Type to support aliases.
remove github.com/visualfc/goembed. like linkname parse //go:embed to direct translate js pkg init code.

embed go1.16 : use ast
embed go1.17 : use types for support aliases

// +build go 1.17
var (
	//go:embed "testdata/hello.txt"
	helloT []T
)

type T byte

@nevkontakte
Copy link
Member

I may be wrong, but I don't think we have any precedent for core compiler logic in an external package that doesn't come from upstream. But maybe that's not important anyway.

@flimzy this is not entirely unprecedented, github.com/neelance/astrewrite or github.com/shurcooL/httpfs, which are pretty important to the project. So for the purposes of this PR, I don't mind adding github.com/visualfc/goembed as a dependency, although I am equally open to moving the core logic into the gopherjs repository as an internal package.

this PR current embed generate code on gopherjs/build used by ast. not support embed/internal/embedtest.TestAliases. maybe move to gopherjs/compiler for used by types.Type to support aliases. remove github.com/visualfc/goembed. like linkname parse //go:embed to direct translate js pkg init code.

embed go1.16 : use ast embed go1.17 : use types for support aliases

// +build go 1.17
var (
	//go:embed "testdata/hello.txt"
	helloT []T
)

type T byte

Considering we are only targeting compatibility with a single Go version (1.18.x at this time), I think we only need to worry about Go 1.17+ behavior. That said, I am open to accepting this PR with TestAliases skipped, and then addressing it in a separate PR. Which ever way you prefer :)

@visualfc
Copy link
Contributor Author

visualfc commented Sep 12, 2022

@nevkontakte

refactoring embedFiles code and support alias string or []byte, but valid check by next types.check ( compiler ) .

  • embedFiles rewrite ast for go:embed vars
  • embedFiles generate js_embed.go only __gopherjs_embed_buildFS__ and go:embed const data
package main

import (
	"embed"
	_ "unsafe"
)

//go:linkname __gopherjs_embed_buildFS__ embed.buildFS
func __gopherjs_embed_buildFS__(list []struct {
	name string
	data string
	hash [16]byte
}) (f embed.FS)

const (
	__gopherjs_embed_74657374646174612f64617461312e747874__ = "\x68\x65\x6c\x6c\x6f\x20\x64\x61\x74\x61\x31"
	__gopherjs_embed_74657374646174612f64617461322e747874__ = "\x68\x65\x6c\x6c\x6f\x20\x64\x61\x74\x61\x32"
	__gopherjs_embed_74657374646174612f7375622f64617461312e747874__ = "\x73\x75\x62\x20\x64\x61\x74\x61\x31"
	__gopherjs_embed_74657374646174612f7375622f64617461322e747874__ = "\x73\x75\x62\x20\x64\x61\x74\x61\x32"
)

@nevkontakte
Copy link
Member

@visualfc thank you for making these fixes. This week has been kind of busy for me so far, but I'll try to take a detailed look at your PR and so some additional testing in the next couple of days. Sorry about the delay.

@nevkontakte
Copy link
Member

@visualfc I left what I think is the final round of comments, all of which a minor style suggestions.

I also familiarized myself with the with the github.com/visualfc/goembed and I think I mostly understand what's going on :)

One thing to note though. https://github.com/visualfc/goembed/blob/main/fsys/fsys.go seems to be derived from https://github.com/golang/go/blob/master/src/cmd/go/internal/fsys/fsys.go. Would you mind adding the appropriate attribution notice to it, similar to what you have in https://github.com/visualfc/goembed/blob/master/resolve/resolve.go?

Copy link
Member

@nevkontakte nevkontakte left a comment

Choose a reason for hiding this comment

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

The pull request looks good to me! 🎉

@visualfc could you please squash all commits into one? We should be good to merge then.

@visualfc
Copy link
Contributor Author

The pull request looks good to me! 🎉

@visualfc could you please squash all commits into one? We should be good to merge then.

create new PR #1153

@nevkontakte
Copy link
Member

Force-pushing into this PR would have been fine too, but in any case #1153 has been merged, so I'm closing this one. Thank you again for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Go 1.16 embed package
3 participants