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
Let’s say you need to run dotnet-tor
and want it to self-update as new versions are published. With
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
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
dotnet tool list -g manually.
When the tool needs to be restarted for updates, I use
dotnet-stop, which properly signals
SIGINT) to it and waits for termination, so the tool can properly
shutdown just as if the user had hit