Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When installing a .NET local tool, create the tool manifest if one does not exist #15254

Closed
Tracked by #29436
augustoproiete opened this issue Jan 11, 2021 · 17 comments
Closed
Tracked by #29436
Assignees
Milestone

Comments

@augustoproiete
Copy link

When a user tries to install a .NET tool as a local tool on a folder that does not contain the manifest, we get an error Cannot find a manifest file.

> dotnet tool install --local Cake.Tool --version 0.38.4
Cannot find a manifest file.
For a list of locations searched, specify the "-d" option before the tool name.
If you intended to install a global tool, add `--global` to the command.
If you would like to create a manifest, use `dotnet new tool-manifest`, usually in the repo root directory.

However, if the user tries to update an existing local tool, dotnet tool is able to update the existing manifest:

dotnet new tool-manifest
dotnet tool install --local Cake.Tool --version 0.38.4
dotnet tool update --local Cake.Tool
Tool 'cake.tool' was successfully updated from version '0.38.4' to version '0.38.5' (manifest file /Users/augustoproiete/.config/dotnet-tools.json).

TL;DR; It would be great if dotnet tool install automatically created the tool manifest, if one does not exist when installing a local tool, instead of failing with an error.

@marcpopMSFT marcpopMSFT added the untriaged Request triage from a team member label Jan 12, 2021
@wli3 wli3 removed the untriaged Request triage from a team member label Jan 12, 2021
@wli3 wli3 added this to the Discussion milestone Jan 12, 2021
@wli3
Copy link

wli3 commented Jan 12, 2021

The side of doing that is we could potentially generating manifest file accidentally on unexpected locations. And people could run unexpected tool.

@augustoproiete
Copy link
Author

augustoproiete commented Jan 12, 2021

The side of doing that is we could potentially generating manifest file accidentally on unexpected locations. And people could run unexpected tool.

Add a --force or --trust-me parameter so users can convince dotnet tool that they know what they are doing? 😄

@wli3
Copy link

wli3 commented Feb 17, 2021

Prefer to NuGet/NuGetGallery#8373 (comment)

@wli3
Copy link

wli3 commented Feb 17, 2021

The side of doing that is we could potentially generating manifest file accidentally on unexpected locations. And people could run unexpected tool.

Add a --force or --trust-me parameter so users can convince dotnet tool that they know what they are doing? 😄

The current behavior -- asking the user to run dotnet new tool-manifest is about the same level of work comparing with asking the user to add a parameter to dotnet tool ... command. I think it is fine adding another option. But I don't think it should be the default

@augustoproiete
Copy link
Author

@wli3 The end goal is to be able to run a command (or set of commands) that ensures that a particular dotnet tool, of a particular version, is installed.

Use-case: Write a set of instructions on how to add a dotnet tool, that someone can copy/paste and run, and it always works.

Let's examine the following example:

dotnet new tool-manifest
dotnet tool install --local toolname --version toolversion

At the moment, it's impossible to guarantee that the instructions above will work for everyone, because:

  • dotnet new tool-manifest throws an error if a manifest already exists (exit code != 0)
  • dotnet new tool-manifest --force replaces the existing manifest - which is not the goal when you just want to add a new tool to the existing manifest
  • dotnet tool install toolname fails if the manifest does not exist (exit code != 0)

As you can see, it's impossible to send someone a set of instructions that will always work when they run.


Would it be possible to have along the lines of the following:

dotnet new tool-manifest --ignore-if-exists
dotnet tool install toolname --ignore-if-installed

So that both commands above do not throw an error, and return exit code = 0.

I also suggested an alternative approach on #10310 (comment) which aims to achieve the same goal: Ensure that a dotnet tool is installed, without throwing errors.

dotnet tool ensure --local toolname --version toolversion

The above would mean that the manifest is created automatically, so that everything can be done with one command.

Expectations:

  • If the command does not specify version, the latest version is installed. Exit code = 0
  • If the command specify version 2.0.0 and tool 2.0.0 is already installed, do nothing. Exit code = 0
  • If the command specify version 2.0.0 and tool 1.0.0 is already installed, upgrade to 2.0.0. Exit code = 0
  • If the command specify version 2.0.0 and tool 3.0.0 is already installed, downgrade to 2.0.0. Exit code = 0

/cc @KathleenDollard

@timheuer
Copy link
Member

Finding an analog, NPM does this by default as well with package.json and puts it in the right place. Users who do npm install moment for example, get a non-global package and a package.json dropped in the right place. We should have the similar and easy experience reducing the ceremony for such things.

@wli3
Copy link

wli3 commented Apr 2, 2021

"easy experience" -- no, it does not. By default, npm drop it into the package folder and you have no way to call it unless you run it with the full path. That is similar with --tool-path option. (unless install npx)

dotnet tool -g experience is very similar to npm install -g experience.

@timheuer
Copy link
Member

timheuer commented Apr 2, 2021

I just did the example I noted and it did all the right things locally. Yes I know -g is the same for both. We are talking here about local. We need to reduce ceremony here. This shouldn't be hard to do the 90% expected case

@wli3
Copy link

wli3 commented Apr 2, 2021

let's have a meeting. I don't know what is the "right thing". The default npm experience is confusing to me too.

@sayedihashimi
Copy link
Member

My team just went through an exercise where we were trying a .net core tool in a local folder and they were tripped up by this. I think the manifest file should be created by default. Obviously they were able to get it working, but it could have been more streamlined.

The side of doing that is we could potentially generating manifest file accidentally on unexpected locations. And people could run unexpected tool.

I don't understand this risk, because the user would have had to execute dotnet tool --install at some point for the command to execute. And they are then running a command, I assume they expect it to execute.

I'm happy to meet to discuss more.

@wli3
Copy link

wli3 commented Apr 3, 2021

If you are not careful, you could get manifest created in your root, obj folder, bin folder, the folder above the repo or the nested folder for the sub projects. And people will get confused when the tool does not show up.

And only the repo owner should create the manifest file. People need to put thoughts on where the manifest file should be located.

@sayedihashimi @timheuer @KathleenDollard we've been discussing this issue on theoretical base. I prefer not to change one default to another default without any data or objective user study.

@dsplaisted
Copy link
Member

Straw man design: Add a new --create-manifest-if-needed parameter. The parameter will use the following priority to choose the folder where the tool manifest goes (ie it will place a .config/dotnet-tools.json file in that folder:

  • Walk up the directory tree searching for one that has a .git subfolder
  • Walk up the directory tree searching for one that has a .sln file in it
  • Use the current working directory

@baronfel What do you think? Anything suggestions?

I'm thinking of having @JL03-Yue start to work on this.

@dsplaisted
Copy link
Member

Also related: #23561

If we do a dotnet tool init, we should probably use the same logic, or have the option to do so.

@KalleOlaviNiemitalo
Copy link

that has a .git subfolder

If you're going to have a Git-specific feature, then it should recognize a .git file as well, so that it works with git worktree.

@baronfel
Copy link
Member

Sorry, I just saw this ping. I worry that an optional flag (especially a long one!) will get very little use, especially with the very low rates of tab-completion registration and usage. What if we

  • tried the walking algorithm above to locate the 'root'
  • also provided an explicit --manifest-file option to specify the manifest to add to (and side-step the entire walking algorithm if present)
  • provide an explicit --create-manifest-if-needed false that forbids walking (and therefore requires either explicit --manifest-file usage or the .config/dotnet-tools.json to be present in the current directory

That would make the simple usage do what the user intended, while also giving automation tools to more firmly specify the inputs when required.

@JL03-Yue
Copy link
Member

Resolved in #31231

@jarizast
Copy link

jarizast commented May 3, 2024

init first: dotnet new tool-manifest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests