I’ve been doing quite a few dotnet global tools and had a need for a long-running tool to update itself over time, as updates are pushed to a nuget feed.
This is tricky, since you cannot update a tool that is currently running
(dotnet update
will try to uninstall the existing version and that will
fail since the tool will be running). You could resort to starting an
external process with a shell script that would wait for the tool process
to exit, then run dotnet update
and then launch the tool again, but
you would lose the current terminal, for example, and it’s quite ad-hoc
and looks messy.
What I really wanted was something as close to dotnet native as possible.
Kind of like dotnet watch
, but that watches for updates and restarts the
tool. So dotnet-evergreen
was born.
dotnet evergreen
Let’s say you need to run dotnet-tor
and want it to self-update as new versions are published. With dotnet-evergreen
this is trivial:
> dotnet evergreen dotnet-tor
If the tool being run is not installed, evergreen
will automatically
install it on first run, then monitor for changes as long as the tool
continues to run. Since no parameters have been provided, changes will be
polled from the nuget.org feed. This can be overriden to point to a custom
feed. I use the offitial NuGet.Protocol
for this.
Here you can see side by side dotnet-echo
running via evergreen
on Windows and dotnet-tor
running on Ubuntu:
Note how the output, even the fancy progress under Ubuntu, is properly displayed.
The tool usage is mostly self explanatory:
dotnet evergreen
Run an evergreen version of a tool
Usage:
dotnet evergreen [options] [<tool> [<args>...]]
Arguments:
<tool> Package Id of tool to run.
<args> Additional arguments and options supported by the tool
Options:
-s, --source <source> NuGet feed to check for updates. [default: https://api.nuget.org/v3/index.json]
-i, --interval <interval> Time interval in seconds for the update checks. [default: 5]
-q, --quiet Do not display any informational messages.
-?, -h, --help Show help and usage information
--version Show version information
Any options for evergreen
come before the tool
argument, and all arguments
after that are passed as-is to the tool. The tool command doesn’t need to
match the package id. Internally, evergreen
will lookup the installed tool by
package id and execute the actual command provided by it, as shown when you
run dotnet tool list -g
manually.
When the tool needs to be restarted for updates, I use
dotnet-stop, which properly signals
Ctrl+C
(or SIGINT
) to it and waits for termination, so the tool can properly
shutdown just as if the user had hit Ctrl+C
himself.