Coder Social home page Coder Social logo

Custom build args to revel package about cmd HOT 13 CLOSED

revel avatar revel commented on June 11, 2024
Custom build args to revel package

from cmd.

Comments (13)

brendensoares avatar brendensoares commented on June 11, 2024

That sounds like a reasonable request, but can you not make use of the existing app version method (https://github.com/revel/revel/blob/master/harness/build.go#L120)?

Where are you using build date in your app? I could see that being useful enough for others to justify adding it to Revel.

If custom flags are still useful, we could add it to app.conf in the Revel framework's harness code since that is what builds the actual Revel app binary.

Thoughts? @revel/core chime in?

from cmd.

viblo avatar viblo commented on June 11, 2024

Let me expand a little about our use case.

We have a rather large number of go services with rest endpoints which is not using revel, and then I recently converted a very basic php admin web to use revel instead as an experiment.

To build our services for "release" we use a makefile, like this:

VERSIONCMD = "`git symbolic-ref HEAD | cut -b 12-`-`git rev-parse HEAD`"
VERSION = $(shell echo $(VERSIONCMD))
DATE = $(shell echo `date +%FT%T%z`)
LDFLAGS += -X myorg/version.version $(VERSION) -X myorg/version.date $(DATE)

build:
    export GOPATH="$(CURDIR)/vendor:$(CURDIR)/../.." && \
    go install  -tags="$(BUILD_TAGS)" -ldflags "$(LDFLAGS)" myorg/cmd/... && \

And inside myorg/version:

package version

import (
    "flag"
    "fmt"
    "html"
    "io"
    "net/http"
    "os"
)

var showVersion = flag.Bool("version", false, "Print version of this binary (only valid if compiled with make)")

var (
    version string
    date    string
)

func printVersion(w io.Writer, version string, date string) {
    fmt.Fprintf(w, "Version: %s\n", version)
    fmt.Fprintf(w, "Binary: %s\n", os.Args[0])
    fmt.Fprintf(w, "Compile date: %s\n", date)
    fmt.Fprintf(w, "(version and date only valid if compiled with make)\n")
}

// Init initializes the version flag and /debug/version/ http endpoint.
// Note that this method will call flag.Parse if the flags are not already
// parsed.
func Init() {
    if !flag.Parsed() {
        flag.Parse()
    }
    if showVersion != nil && *showVersion {
        printVersion(os.Stdout, version, date)
        os.Exit(0)
    }

    http.Handle("/debug/version/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        printVersion(w, html.EscapeString(version), html.EscapeString(date))
    }))
}

With this setup if you ever want to know what version a specific binary is, you just call it with the -version flag and you will get output like this:

➜  bin  ./myorg-service -version
Version: branchname-ea856cf5961b4f45394eddf15861d087bafb4c01
Binary: ./myorg-service
Compile date: 2014-08-05T11:26:25+0800
(version and date only valid if compiled with make)

We use the same setup for everything and it helps us keep track of exactly whats deployed, and we have found it a very useful know exactly when a binary was compiled and what version of the code it contains.

Then for build tags we also need specific tags. We use this imagemagick lib: https://github.com/rainycape/magick
To specify if you want to link with graphicsmagick you pass it the build tag gm and otherwise imagemagick will be used. Therefor we must be able to specify build tags when building. (Now it happens that no imagehandling is done from our small revel experiment, but we will need it in the future if we are to use revel for more)

I would prefer if we could reuse our current solution also for our new revel web.

from cmd.

brendensoares avatar brendensoares commented on June 11, 2024

This looks like a nice solution. Well done!

First a disclaimer: I am not the author of Revel, I simply have volunteered to maintain it. I'm more of a steward. That said, I don't have an expert knowledge of ALL of Revel's code.

My concern is that you may not be able to build Revel manually due to how routes, modules, etc are compiled. See https://github.com/revel/revel/blob/master/harness/build.go#L74

The best we can do, off the top of my head, is inject ldflags via the app.conf.

Alternatively, we could "pop the why stack" and understand what you're trying to accomplish. It seems to me that you're trying to is inject a version into the binary which we already support via git describe or a environment variable (See https://github.com/revel/revel/blob/master/harness/build.go#L120). The only thing we're missing is a build date.

If we were able to accommodate these needs, would that negate your need for ldflags?

from cmd.

viblo avatar viblo commented on June 11, 2024

Re build tags: Thanks to your link I figured out its already possible to define build tags with build.tags in the app.conf (and now I see they are also mentioned in the documentation). Totally workable.

Re ldflags: Right, with the APP_VERSION its only compile date that is missing. Since version is already there I guess it makes sense to also add date in a similar way? Like for example APP_COMPILE_DATE (but without environment variable override).

On the other hand, maybe ldflags in general would be good to have in app.conf like build tags, other people could have some use for them.

I should add that Im not totally sold on the idea of having these compile time configuration values in the app.conf. If I change for example http.port or app.secret I would expect the app to use the new value after a restart. But that wont work for these values which can make it confusing.

On the other hand I see that there is a text in the docs under "Areas for development" that say "Allow inserting command line arguments as config values or otherwise specifying config values from the command line." If that was available then all would be good I think.

from cmd.

brendensoares avatar brendensoares commented on June 11, 2024

Glad you found a workable solution. This is something we can consider down the road to help developers gain more control over the output of the Revel build process.

from cmd.

viblo avatar viblo commented on June 11, 2024

I just realized that I forgot one part. With my current solution I can pass -version to the binary and it will print out the version and exit, before it has done much work. This is useful when you have a binary that might miss some things (for example in case of revel you might have the compiled binary by itself without any support files such as templates) but still want to check what version it is.

Is something like that possible currently?

from cmd.

brendensoares avatar brendensoares commented on June 11, 2024

No, there is no flag support for version, but it wouldn't be hard to add it. We'll need to make changes on the revel/revel repo to support it. From this repo I would say there are 2 goals:

  • Add version flag to revel app binary that outputs version and build date details, like what you have in your custom implementation
  • Add build date tracking similar to app version

Anything else?

from cmd.

viblo avatar viblo commented on June 11, 2024

Those two things should be all.

However, about the -version flag. Another option is to make it possible to hook into the flag thing myself so that I can add flags at will, and have somewhere to read them and process them early. I tried to add them to the init function in app/init.go, but there they are not parsed, and I cant parse the flags because not all other flags are defined at that point. So I guess that this would be more work to implement..

from cmd.

brendensoares avatar brendensoares commented on June 11, 2024

@viblo that's a possible enhancement in the future :)

from cmd.

ptman avatar ptman commented on June 11, 2024

I'd also like to change -ldflags, primarily to add -s -w in order to produce smaller binaries. Also CGO_ENABLED, would be interesting to set, but that is kept from the environment currently.

from cmd.

ptman avatar ptman commented on June 11, 2024

Actually, with the release of 0.13 I ran into an issue with https://github.com/revel/cmd/blob/master/harness/build.go#L83 as well. I use a distro provided go compiler and compile using CGO_ENABLED=0. This fails with

go install net: open /usr/lib/go/pkg/linux_amd64/net.a: permission denied

unless I remove the -i argument. This should probably also be configurable.

from cmd.

brendensoares avatar brendensoares commented on June 11, 2024

Reviewing open issues, this seems like it would still be valuable. Now it's just a matter of coordinating a solution.

from cmd.

notzippy avatar notzippy commented on June 11, 2024

Grouped with #81

from cmd.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.