List should show all global tool installed on the machine along with the version and command name
We should try to only use the folder structure as possible. It might be perf issue on getting all command names. However, if we ever want to have a cache or extra list for bookkeeping, keep in mind, CLI don't have a infrastructure to handle multi threading. Any read/write to disk has the risk of corrupting that file.
reference https://github.com/dotnet/cli/issues/8492#issuecomment-361351137
@KathleenDollard should it be dotnet list tool -g
? verb first vs noun first?
You ask the good questions!
Yes. It will list what is in the global location. If we do something else in the future, we will want this specificity available.
Sound good?
Unfortunately, dotnet list
accepts the project as an argument, as the expected format is dotnet list <PROJECT> reference
for the reference command currently.
This means that:
dotnet list --help
displays <PROJECT>
as the optional argument even though this won't be used by dotnet list tool
.dotnet list tool
would need to check that a project argument was passed in and error (i.e. dotnet list foo.csproj tool
=> Error: the list tool command does not support project arguments.
).While this will work, it is a clunky UX. Ideally, it would be dotnet list reference <PROJECT>
(i.e. to not have the list
command expect all sub-commands to have a project argument and instead have it as an argument to the reference
subcommand), but this would be a breaking change.
Thoughts?
However, if we were to go with the comments in dotnet/sdk#9040, a dotnet tool
command (install
, uninstall
, and list
being subcommands) could be designed with a proper UX and leave dotnet list
as-is for project references. Personally, I like this approach as it makes the UX consistent and discoverable; dotnet tool
thus being the entrypoint to all things "tool" related (I think the existing sln
command being related to all things "solution" being an apt comparison).
I'm going with the "error if a project is given to dotnet list tool
" approach for now and we can re-examine if this UX is undesirable. cc: @KathleenDollard @wli3 (see above comments)
@KathleenDollard @livarcocc this is a pretty serious problem. We need to design it property. (although it only blocks on parser's code). I can't find a perfect one yet. dotnet list tool
should be the most user friendly option. However that means the parser result will depend on state of the disk which we try to avoid cc @jonsequitur. Currently, the parser is a pure function. Also if a user calls his/her project "tool", it would be ambiguous. And the name "tool" is not uncommon.
We don't automatically append a file extension for an explicitly provided project file, so unless the project file is literally named tool
(which breaks all sorts of heuristics based on file extension), there shouldn't be a conflict with the tool
subcommand. It also seems like the tool
subcommand "wins" over a project file named tool
when parsing the command.
Personally, this UX is just broken. Arguments meant for the subcommands shouldn't come before the subcommand name (i.e. this should have been dotnet list reference foo.csproj
). While I know this is a breaking change, if we leave it as-is and we still want dotnet list tool
, this is the help we'll have to live with:
$ dotnet list tool --help
Usage: dotnet list <PROJECT> tool [options]
Arguments:
<PROJECT> The project file to operate on. If a file is not specified, the command will search the current directory for one.
Options:
-g, --global List user wide tools.
-h, --help Show help information.
Note it must inherit the list
command's argument even though it doesn't use it.
I'm really leaning toward using tool
as the top-level command with install
, uninstall
, and list
as subcommands, given the parallels with the sln
command (not a verb either, but the command you use to interact with all things solution-file-related). The list
command, for better or worse, is a project command now.
I was originally against this approach, but had a nice chat with Azure CLI folks today, and think this may be a good approach for list. Is it worth a meeting to discuss this?
Let's meet.
Just set a meeting for tomorrow. Forward as needed.
btw the 2.1 roadmap blog post has dotnet tool install -g awesome-tool
https://blogs.msdn.microsoft.com/dotnet/2018/02/02/net-core-2-1-roadmap/
Regarding the output of the command (whatever we call it):
$ dotnet list tool -g
Name Version Commands
---------------------------------------------------------------------------------
a.really.long.tool.package.id 1.0.0 somereallylongcommand
another.test.package.id 1.0.0 somereallyreallyreallylongcommand
global.tool.console.demo 1.0.4 demo
test.tool 1.0.0 somecommand
Is this roughly what we want? Commands
is a comma-delimited list (useful for when we eventually support multi-command tools).
Maybe Package Id
instead of Name
since the help for dotnet install tool
explicitly asks for a package id?
Updated to:
$ dotnet list tool -g
Package Id Version Commands
---------------------------------------------------------------------------------
a.really.long.tool.package.id 1.0.0 somereallylongcommand
another.test.package.id 1.0.0 somereallyreallyreallylongcommand
global.tool.console.demo 1.0.4 demo
test.tool 1.0.0 somecommand
I imagine if a package id is too big it will wrap into the next line?
I wasn't doing anything that complicated in the formatting of the table, but I could implement maximum column widths with wrapping if we think it's important. I can easily implement that.
Can we make it more like dotnet add
?
dotnet add:
Commands:
package <PACKAGE_NAME> .NET Add Package reference Command
reference <args> .NET Add Project to Project reference Command
And just have 2 sub command. reference or tool
and reference
need to take an argument and tool
will not . I don't think it is a breaking change for dotnet list reference
dotnet add
has the exact same problem. The add
command takes the <PROJECT>
argument, making every subcommand inherit that argument.
it is a re config of the parser, however it is just a help text change from the outside
I see, can we make list not taking this argument?
Then it'd be a breaking change as dotnet list foo.csproj reference
would no longer work because foo.csproj
would be treated as an unknown subcommand.
dotnet list reference foo.csproj
is currently legal as well because the reference
subcommand accepts one argument with no argument name or help text and then doesn't use it for anything (i.e. defaults to searching for the project in the current directory). This is a bug and should probably be fixed to remove the argument; not a breaking change because this behavior is broken anyway (although, a breaking change if you explicitly specified the name of the project in the current directory...it just happened to "work").
ah.. i see, that is a breaking change
@livarcocc With an example "maximum width" for the package id column set to 10 graphemes (for illustration purposes):
$ dotnet list tool -g
Package Id Version Commands
--------------------------------------------------------------
a.really.l 1.0.0 somereallylongcommand
ong.tool.p
ackage.id
another.te 1.0.0 somereallyreallyreallylongcommand
st.package
.id
global.too 1.0.4 demo
l.console.
demo
test.tool 1.0.0 somecommand
Do you think we need row separators given how that reads? I'm leaning towards yes.
it would be pretty hard to awk. Although is it a good thing?
I think the only other place where we use a list is dotnet new --help
. Not row separator there. I think we should try to stay consistent.
Agreed that it would be very difficult to awk consistently if wrapping is implemented. I'm fine with not wrapping, personally, but no strong opinion either way.
If we do want to wrap, suggested column maximums? 100, 25, 50
? 100, unbounded, unbounded
?
I am fine with not wrapping. We can see how it works out and take steps if anything comes up.
I agree. Let's skip wrapping for now.
Most helpful comment
I am fine with not wrapping. We can see how it works out and take steps if anything comes up.