Skip to content
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

proposal: embed: conditional embedding support #44484

Closed
kesuskim opened this issue Feb 22, 2021 · 12 comments
Closed

proposal: embed: conditional embedding support #44484

kesuskim opened this issue Feb 22, 2021 · 12 comments

Comments

@kesuskim
Copy link

Really nice to see embed finally gets arrived to standard library!

Yet I believe, conditional embedding would be desirable in some use cases, seems there aren't any.

I was using packr beforehand to achieve this kind of behavior; mainly because when I want to build for container image, I do not want to embed files (mainly frontend built assets files) packed into binary because it will increase memory usage a lot.

I think it would be enough //go:embed might just ignore embedding by giving buildflags or environment variables in build time.

@gopherbot gopherbot added this to the Proposal milestone Feb 22, 2021
@ianlancetaylor ianlancetaylor added this to Incoming in Proposals (old) Feb 22, 2021
@ianlancetaylor
Copy link
Contributor

Can you just use a build tag?

@kesuskim
Copy link
Author

@ianlancetaylor Is there any option that can be used for such use cases? Build tag is OK, but it seems currently not supported.

@jayconrod
Copy link
Contributor

@kesuskim You should be able to put the //go:embed directive in a file with a build tag like this:

// +build embedallowed

package x

//go:embed somefile.txt
var somefile string

Then build with -tags=embedallowed. This is supported now. go build won't process //go:embed directives in files that were excluded by build constraints.

@kesuskim
Copy link
Author

@jayconrod That will do! Thank you 😄 Maybe it will be enough to have some documents or blogs about it, I should make writing on my blog.

@rsc rsc moved this from Incoming to Declined in Proposals (old) Feb 24, 2021
@frederikhors
Copy link

I think we should re-open this because tags should not be the only way to go.

Why can't I use this code instead?

var somefile string

if embedAllowed {
  //go:embed somefile.txt
  somefile
}

@frederikhors
Copy link

@kesuskim can you re-open please?

@kesuskim
Copy link
Author

@frederikhors

You can achieve similar with build tag. Here is an example for it.

public/box.go

package public

import "embed"

var Box embed.FS

var IsEmbedded bool

func init() {
    Box = ebox
}

public/box_embed.go

// +build embed

package public

import "embed"

//go:embed * index.html
var ebox embed.FS

func init() {
    IsEmbedded = true
}

public/box_noembed.go

// +build !embed

package public

import "embed"

var ebox embed.FS

func init() {
    IsEmbedded = false
}

main.go

package main

import (
    "fmt"
    "log"
    "net/http"

    "myproject/public"
)

const PORT = 8080

var httpRoot http.FileSystem

func main() {
    if public.IsEmbedded {
        httpRoot = http.FS(public.Box)
    } else {
        httpRoot = http.Dir("public/")
    }

    log.Printf("server is listening on :%d", PORT)
    http.Handle("/", http.FileServer(httpRoot))
    if err := http.ListenAndServe(fmt.Sprintf(":%d", PORT), nil); nil != err {
        log.Fatalln(err)
    }
}

To use embed, you can build with build tags like following;

$ go build -tags embed

@kesuskim
Copy link
Author

I think having multiple options on doing one thing (in this case, conditional embed) could be very confusing and diverged in the end, and IMHO it is not a Go-way.

@frederikhors
Copy link

Yeah, I know and I'm using it, but my question is about not using -tags at all for such a thing.

@ianlancetaylor
Copy link
Contributor

@frederikhors I don't understand what it means to write

    var somefile string

    if embedAllowed {
        //go:embed somefile.txt
        somefile
    }

In order to implement that, the file somefile.txt must always be embedded in the binary. So I don't understand what you are asking for.

@frederikhors
Copy link

I'm asking to only embed file if embedAllowed is true.

@ianlancetaylor
Copy link
Contributor

When we build the binary, we have to decide whether to embed the file or not. We can't postpone that decision until the binary is run. But when we build the binary, we don't know whether embedAllowed is true or not. It might change at run time. It might be based on a command line option. It might be based on user input.

@golang golang locked and limited conversation to collaborators Oct 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Development

No branches or pull requests

5 participants