go-rocket-update icon indicating copy to clipboard operation
go-rocket-update copied to clipboard

Suggestion: allow basic templating in `ArchiveName` & `ExecutableName`

Open axllent opened this issue 4 years ago • 6 comments

Certain projects use the release tag in the archive name, eg awesome-package_0.1.2_linux_amd64.tar.gz, and I seem to recall some that even use it in the binary name too (not that I think the latter is a good idea).

My suggestion is to allow some basic go templating on both the Provider ArchiveName and Updater .ExecutableName of at least some common variables, such as {{.Tag}} {{.GOOS}}&{{.GOARCH}}. Whilst certain variables can be generated before the request (runtime.GOOS&runtime.GOARCH`), others are dependent on the remote info.

u := &updater.Updater{
    Provider: &provider.Github{
        RepositoryURL: "github.com/user/awesome-package",
        ArchiveName:   `awesome-package_{{.Tag}}_{{.GOOS}}_{{.GOARCH}}`,
    },
    ExecutableName: "awesome-package_{{.Tag}}",
    Version:        "0.1.1",
}

This would of course still remain completely backwards compatible with the current system, and one could even mix the two: ArchiveName: fmt.Sprintf("awesome-package_{{.Tag}}_%s_%s.tar.gz", runtime.GOOS, runtime.GOARCH).

The backstory is I've been meaning to rewrite a simple GitHub binary updater I wrote some time ago (far more primitive than yours), although I have been putting it off while I collect ideas etc. I just came across go-rocket-update which I think has a lot of potential, so rather than me spend time rewriting mine from scratch, I'd first check to see if you were open to suggestions to yours instead? I also have some other suggestions too if you're open to it.

axllent avatar Mar 19 '21 02:03 axllent

Thank you for the suggestion! Yes I think it could be a good idea! Today what you can do is call the provider by yourself to get the version (and then the updater) but I agree that variables would make things a lot easier :)

Implementation:

I think we should add the whole templating logic outside the updater. The updater would just use an interface to get the variables. We would have a default implementation for the basic {{.Tag}} {{.GOOS}} {{.GOARCH}} variables, and if a dev wants to add his own variables then he could make his own implementation of that interface.

mouuff avatar Mar 19 '21 12:03 mouuff

I hadn't considered running it twice as an interim workaround, although I haven't implemented go-rocket-update yet in anything as I'm still in the testing phase, and seeing where this project is headed. I think that your implementation proposal makes good sense though, and hopefully doesn't add too much bulk or complication.

axllent avatar Mar 19 '21 19:03 axllent

Not exactly running it twice, just running the provider to get the latest version, then setup the updater with this information. But indeed GetLatestVersion will be called a second time by the updater. I m not afraid of the bulk/complications. It's just another interface. But fell free to make a PR with your own implementation :)

mouuff avatar Mar 19 '21 20:03 mouuff

Here is a workaround for now. Example with ticker:

func selfUpdate() (updater.UpdateStatus, error) {
	provider := &provider.Github{
		RepositoryURL: "github.com/achannarasappa/ticker",
	}
	latestVersion, err := provider.GetLatestVersion()
	if err != nil {
		return updater.Unknown, err
	}
	if len(latestVersion) > 0 {
		latestVersion = latestVersion[1:] // removes the 'v' prefix to match github archive
	}
	provider.ArchiveName = fmt.Sprintf("ticker-%s-%s-%s.tar.gz", latestVersion, runtime.GOOS, runtime.GOARCH)
	u := &updater.Updater{
		Provider:       provider,
		ExecutableName: "ticker",
		Version:        c.Version,
	}
	return u.Update()
}

mouuff avatar Mar 21 '21 10:03 mouuff

I think I will try to find some time this or next month to implement that. except if you fell like making a PR :) I think it could be a great addition!

mouuff avatar Mar 21 '21 16:03 mouuff

It's unlikely I'll be able to spend much time on this in the next two months as well, as I just returned to work last week after a shoulder operation two months ago (long recovery, and now a huge backlog of work to catch up on). This was actually the main reason I was looking for existing self updater modules last week, as I just don't have the time to reinvent the wheel right now again :-) I'm also not in any rush either. If I do manage to spend some time on it I'll let you know though!

axllent avatar Mar 21 '21 18:03 axllent