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

dotnet sln add should allow non-project files to be added to the solution #9611

Open
TheRSP opened this issue Jul 19, 2018 · 16 comments · May be fixed by #45072
Open

dotnet sln add should allow non-project files to be added to the solution #9611

TheRSP opened this issue Jul 19, 2018 · 16 comments · May be fixed by #45072
Labels
Area-CLI Cost:M 4 to 10 person weeks of work per central guidance good first issue Issues that would be a good fit for someone new to the repository. Narrow in scope, well-defined. help wanted Issues that we would accept external contributions on. Also known as up-for-grabs. new-hire-issue Priority:2 Work that is important, but not critical for the release
Milestone

Comments

@TheRSP
Copy link

TheRSP commented Jul 19, 2018

In my company we often have a small number of files at the solution level for each solution. These include, for example:

  • .tfignore/.gitignore file
  • .editorconfig

I can't find anyway to add to these to a solution. The following image shows the result I would like in visual studio.
image

I would propose a command format such as
dotnet sln <SLN_FILE> add file [file1 [file2 [...]]] for adding items to a 'Solution Items' folder (as above) and
dotnet sln <SLN_FILE> add --directory=MyFolderName file [file1 [file2 [...]]] for adding items to a custom named folder

@TheRSP TheRSP changed the title dotnet sln add should allow non-project files to be added to the solution dotnet sln add should allow non-project files to be added to the solution Jul 19, 2018
@msftgits msftgits transferred this issue from dotnet/cli Jan 31, 2020
@msftgits msftgits added this to the Backlog milestone Jan 31, 2020
@KathleenDollard
Copy link

We had a comment on Twitter on this https://twitter.com/peval27/status/1404920313289269248?s=20

Anyone know why we do not already do this?

@peval27
Copy link

peval27 commented Sep 8, 2021

is this issue been considered at all?

@KathleenDollard

@jpactor
Copy link

jpactor commented Aug 23, 2022

Can this be considered for an upcoming release? The ability to script adding non-project solution files to the solution would be ideal.

@forensicmike
Copy link

Just throwing my hat in the ring as 😱 that this is still not possible in 2022

@tahq69
Copy link

tahq69 commented Feb 17, 2023

and 5 years later, still is not implemented 👎

@baronfel baronfel added Area-CLI help wanted Issues that we would accept external contributions on. Also known as up-for-grabs. good first issue Issues that would be a good fit for someone new to the repository. Narrow in scope, well-defined. labels Aug 1, 2023
@baronfel
Copy link
Member

baronfel commented Aug 1, 2023

Hey folks - this one got lost in the tagging/labeling shuffle. I'd love to see this implemented - I've marked it up for grabs in case anyone has the desire to contribute. The spec that @TheRSP laid out is a good guideline to follow here. Some additional behavior clarifications:

  • multiple input files should be allowed, at least one should be required
  • the folder to place the files in should be an optional parameter, defaulting to the 'Solution Items' folder
  • Any intermediate folders in the 'destination folder' should be created as necessary
  • If the 'destination folder' exists, the files should be added to it, a new folder should not be created

@dileep-hegde
Copy link

dileep-hegde commented Sep 22, 2023

Edit: I just realized that the issue is only related to the dotnet CLI. and which is still not possible.

In Case, anyone trying to do this in VS Code using the NEW C# Dev Kit Extension.

Here are the Steps to add files at the solution level.

  1. In Solution Explorer, Click on New Solution Folder option on the main Solution.
  2. Create a Solution folder named "Solution Items".
  3. Right-Click on that Solution folder and select Add Existing Files to add the files which are located on the main Solution where sln file exists.

At the moment, we don't have a dedicated Add File option at the Solution Level.

Also, I doubt, whether it is possible without Solution Explorer as Solution Items is a Solution folder and Solution folders are not a physical folder on the disk.

@jpactor
Copy link

jpactor commented Sep 22, 2023

Users can already add a project directly to a solution folder with the CLI with the "--solution-folder" option, which even creates the intermediary folders if they don't already exist. Is there a particular reason why a project and a single file are completely different?

@nagilson nagilson added new-hire-issue Priority:2 Work that is important, but not critical for the release Cost:M 4 to 10 person weeks of work per central guidance labels May 2, 2024
@dominikjeske
Copy link

I hope slnx (#40913) will have this up front

@Bartleby2718
Copy link

@baronfel I'm considering this issue as my potential first contribution to this repository, but I want to align on the design first.

There are a few options here:

No Full command Description Cons
1 dotnet sln add file Adds a new "sub-subcomamnd" (Proposed in the original description) There is no precedent for having a sub-subcommand. In the current dotnet CLI, this only happens in some dotnet nuget commands like dotnet nuget add source.
2 dotnet add solution-item (or dotnet add file) Adds a new subcommand to dotnet add, as opposed to dotnet sln
  1. There is no precedent for using a compound word in subcommands, although there is for commands (i.e. dotnet build-server and dotnet dev-certs.
  2. Arguably inconsistent with dotnet add package, which assumes that a project file will be used.
3 dotnet sln add --type <TYPE> Adds a new optional parameter --type that defaults to project Verbose
4 dotnet sln add Updates the existing dotnet sln add subcommand to support both <FILE_PATH> and <PROJECT_PATH>

Given the cons listed, I'm actually leaning towards options 3 or 4 (to be consistent with rest of the CLI), as opposed to the proposed option 1.

  1. What do you think?
  2. In either case, is there a sample PR that will be helpful?

@Bartleby2718
Copy link

Having thought more about this, I've concluded that option 4 doesn't work because it cannot distinguish between a solution item, a solution folder, and a project with the same name.

Will go with option 3. Would appreciate it if I could be assigned to the ticket.

@baronfel
Copy link
Member

baronfel commented Nov 3, 2024

My quick thoughts are that I disagree with some of the cons you have listed for option 1, and it remains my preference. There is no technical or grammatical difference between a single subcommand and N subcommands - they are all just Commands and all that matters is the chain you use to get to them. Right now aside from nuget, we also have prior art for this in the dotnet workload family of commands. You also don't need the forwarding you mention in the cons in the general case for this kind of arrangement - we only do that because the NuGet team prefers keeping the implementations of their commands in one place.

Of the remaining, option 3 is my most favored, but I still disagree with that approach. Establishing a top-level command for dotnet sln add file 'scopes' the command and allows for a more narrow overall grammar. You don't have to worry about potentially invalid combinations of flags on sln add, etc - it's a much cleaner approach to CLI design.

@Bartleby2718
Copy link

Thanks for the input @baronfel! I agree that option 1 is the most intuitive and straightforward from the user's perspective, but as a first-time contributor, I wasn't sure how to go about it.

Right now aside from nuget, we also have prior art for this in the dotnet workload family of commands.

Are you referring to something like this? https://github.com/dotnet/sdk/blob/main/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs#L146-L156

@baronfel
Copy link
Member

baronfel commented Nov 3, 2024

Yeah, that's a good example. In System.CommandLine, you can add a SubCommand (which is really just another CliCommand) to any existing CliCommand. So you could make a new SlnAddFileCommand to hold the logic you'd implement, and in that class definition you'd set the 'name' of the command to "file". Then in SlnAddParser.cs add a line like command.Subcommands.Add(new SlnAddFileCommand()); in the ConstructCommand() method that exists today.

Here's a quick example of what the simplest kind of nested-subcommand registration for this might look like:

        private static CliCommand ConstructCommand()
        {
            CliCommand command = new("add", LocalizableStrings.AddAppFullName);

            command.Arguments.Add(ProjectPathArgument);
            command.Options.Add(InRootOption);
            command.Options.Add(SolutionFolderOption);

+            command.Subcommands.Add(new CliCommand("file"));

            command.SetAction((parseResult) => new AddProjectToSolutionCommand(parseResult).Execute());

            return command;
        }

It's just that for anything 'real' we want to make a standalone class for the Command, so that's what the additional bit of ceremony is about.

@baronfel
Copy link
Member

baronfel commented Nov 3, 2024

Oh - and for a sample PR to look at to pattern your new command off of, I'd take a look at the dotnet workload search version PR that @Forgind did recently: #42652

That PR had to tackle basically the exact same scenario, grammar-wise.

@Bartleby2718
Copy link

Thanks @baronfel! A few more immediate questions:

  1. re: Any intermediate folders in the 'destination folder' should be created as necessary, is the "destination folder" referring to the argument --solution-folder?
  2. If you run dotnet sln add folder a/b --solution-folder foo/bar, then what should happen? Should I create a solution folder b inside a inside bar inside foo, or reject it because it has a nested folder as an argument?
  3. My machine isn't really powerful, and it takes like 10 minutes to build. What's the best way to work around this? Should I delete some projects from the .sln file? I think I'll need a pretty small subset of projects (probably just src\Cli\dotnet\dotnet.csproj and test\dotnet-sln.Tests\dotnet-sln.Tests.csproj).
  4. In your sample code snippet, command.Arguments.Add(ProjectPathArgument);, is still there, so if I just add a subcommand to that, dotnet sln add file --help looks something like this:
    Description:
  Add one or more solution items to a solution file.

Usage:
  dotnet solution [<SLN_FILE>] add [<PROJECT_PATH>...] file <FILE_PATH>... [options]

Arguments:
  <SLN_FILE>      The solution file to operate on. If not specified, the command will search the current directory for one. [default: C:\Users\bartl\Documents\GitHub\sdk\artifacts\bin\Tests\dotnet-sln.Tests\Debug\]
  <PROJECT_PATH>  The paths to the projects to add to the solution.
  <FILE_PATH>     The paths to the solution items to add to the solution.

Options:
  --in-root                                Place project in root of the solution, rather than creating a solution folder.
  -s, --solution-folder <solution-folder>  The destination solution folder path to add the projects to.
  -?, -h, --help                           Show command line help.

This looks confusing to me, because dotnet sln add file doesn't need ProjectPathArgument. How can you make the argument show up only for dotnet sln add (but not dotnet sln add file or dotnet sln add folder)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-CLI Cost:M 4 to 10 person weeks of work per central guidance good first issue Issues that would be a good fit for someone new to the repository. Narrow in scope, well-defined. help wanted Issues that we would accept external contributions on. Also known as up-for-grabs. new-hire-issue Priority:2 Work that is important, but not critical for the release
Projects
None yet
Development

Successfully merging a pull request may close this issue.