markbates / pkger

Embed static files in Go binaries (replacement for gobuffalo/packr)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How do I use this package?

jay-khatri opened this issue · comments

I'm looking to store a python script in memory within a go binary. In my go code, I'd like to simply write something like pkgr.Open("./foo.py"), expecting the file to already be in memory.

I would think that I'd need to run a command in advance on the python file in order to create a go source file out of it. What command do I use? And what method calls do I use in my go code to read the file in?

The README is quite confusing to me given my simple use case; I'd be happy to contribute some documentation if/when this is resolved.

commented

I was new to Pkger last week with the readme alone, wouldn't have understood how to use it. You are possibly in a better place to make notes NOW about what was missing from the documentation to aid improving it before reading the rest of this comment.

Running "pkger" at the command line will search through your codebase and find any references to "pkger." in your case "Open"

If you run pkger list in the root of your project, you should see "foo.py" printed as being a found file. This is a debug stage that is only needed to see what files would get packaged, you dont HAVE to run this.

Just running just pkger will find the same things, but this time bundle them into a pkged.go file. You do not have to do anything else.

To use the file in your go code, its path should start with / which is the root of your project. If foo.py was in the same directory as your go.mod file then, pkger.Open("/foo.py") would be required.

I would HIGHLY recommend you check out this. https://blog.gobuffalo.io/introducing-pkger-static-file-embedding-in-go-1ce76dc79c65 there is also a video showing how to use it.

commented

But there are still things I don't understand from documentation.

I needed to put my "pkged.go" file in the same package as the command running "Pkger.Walk" even though this was 3 levels deep in my project, but have no idea why. I'm not sure if every sub-package that wants to use Pkger needs to have a pkged.go file in it.

If it was anywhere else it would just result in a "go module not found" err and no indication of why.

Also, there is a pkger serve with little documentation

Hopefully documentation improvements are on the agenda from people who know more than me about it...

I still dont get it running. How exactly would I embed a Spa like react and serve it within a gin Route handler. This doesn't get any clearer, neither reading documentation, nor watching the Video.

The documentation of this library is indeed very unhelpful.
After struggling a bit I figured out the concept though, so if that can save someone's time:

Pkger implements the same interfaces as the standard lib.
Basically, if you want to package a file or a directory that you access in your code, just replace the calls to the filesystem with pkger, for example:

// Before
_, err = os.Stat(path)
file, err = os.Open(path)

// After
_, err = pkger.Stat(path)
file, err = pkger.Open(path)

Or if you want to http serve a directory like @patrickhener :

// Before
http.Handle("/", http.FileServer(http.Dir("/web")))

// After
http.Handle("/", http.FileServer(pkger.Dir("/web")))

It will work as usual when developing.

Now when you want to build your app, you have to run the pkger command in your project's root (don't forget to go get github.com/markbates/pkger/cmd/pkger).
This will scan all your source files and package all the resources using pkger.<something> in a pkged.go source file that will be generated in your project's root (by default).

Then run the usual go build, and your static resources will be included in the final executable as they are now bundled in pkged.go.

You may want to add pkged.go to your .gitignore as you will have to generate it each time you want to build your executable.

Note: If you use a scripted deployment process like using a Dockerfile the build step are:

  • install pkger CLI (go get github.com/markbates/pkger/cmd/pkger)
  • install dependencies via go mod
  • run the pkger command
  • run go build