dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.23k stars 1.35k forks source link

Command-line option for displaying targets #33

Closed eatdrinksleepcode closed 4 years ago

eatdrinksleepcode commented 9 years ago

Most build systems that allow the creation of custom targets also have a command-line option for displaying the available targets in a project:

gradle tasks rake --tasks grunt --help

Developers working on projects that use MSBuild would benefit from a similar feature.

AndyGerlicher commented 9 years ago

MSBuild team triage: Do you know about the /pp flag?

  /preprocess[:file]
                     Creates a single, aggregated project file by
                     inlining all the files that would be imported during a
                     build, with their boundaries marked. This can be
                     useful for figuring out what files are being imported
                     and from where, and what they will contribute to
                     the build. By default the output is written to
                     the console window. If the path to an output file
                     is provided that will be used instead.
                     (Short form: /pp)
                     Example:
                       /pp:out.txt
eatdrinksleepcode commented 9 years ago

I was not aware of that flag; thanks for pointing it out.

However, I don't believe that the /pp flag really addresses the scenarios I am thinking of. As a developer on a project that uses MSBuild, particularly one that uses more than just the standard build targets (like CoreFX), I want to quickly see what targets are available for me to execute. Scrolling through a large aggregated project file doesn't really serve that purpose.

edgeteal commented 9 years ago

I love the idea of having an easy way to display available targets.

The /pp can help. It can be used in connection with find to spot the available targets like this:

msbuild /pp | find "<Target "

An alternative I currently prefer follows the solution outlined here by using a custom or inline task: http://stackoverflow.com/questions/2618201/msbuild-is-there-a-way-to-list-all-the-build-targets-available-in-a-build-file/2781693#2781693

Nevertheless it would feel much better if the possibility to display available targets is a built-in feature of msbuild.

Craig-Campbell-MS commented 9 years ago

Marking this up for grabs. If someone cares to research the change we may be willing to accept it. I'd probably choose to dump the Target names available to the default/or specified *proj file.

One drawback I see is many of the 'common' Targets are not meant for direct consumption and I wouldn't want to encourage folks to use them.

edgeteal commented 9 years ago

I started to make some investigation. Here are some results:

The necessary changes depend on the behaviour we need. For instance rake lists all available tasks (tasks in rake are the equivalent of targets in msbuild) with a description (descriptions in rake are the equivalent of labels in msbuild). Tasks without description are by default ignored. This way it is possible to have 'private' tasks that are not intended for execution by the user. Gradle has a similar behaviour where tasks without a description are handled differently than ones with a description.

Lets break down the necessary changes for this:

  1. Introduce a new parameterless switch. Therefore the enum ParameterlessSwitch must be changed. Alternative: If for some reason a parameterized switch is needed the enum ParameterizedSwitch must be used and also we need to take care to parse the given parameters in the static method MSBuildApp.BuildProject(...).
  2. Introduce the core functionality. Similarly to the pp switch a Project instance is created with the method ProjectCollection.LoadProject(...). A loop iterates over the Project.Targets property to print out the target names. A possible implementation of the core functionality which follows the implementation of the pp switch might look like this (without any bells and whistles):
Project project = projectCollection.LoadProject(projectFile, globalProperties, toolsVersion);
foreach (var target in project.Targets)
{
  Console.Out.WriteLine(target.Key);
}

The method MSBuildApp.BuildProject(...) must be modified to execute the implementation.

  1. To imitate the behaviour in rake that only tasks with a description should be considered for print out, we can use the Label attribute in the Target element. This means targets like this are printed out:
<Target Name="RebuildAll" Label="Rebuilds the whole project from scratch.">

Targets without a Label attribute are ignored. To implement this behaviour a new property ProjectTargetInstance.Label must be introduced and fed with a value, when the XML elements are parsed. This happens in the static method Evaluator.ReadNewTargetElement(...). Depending on if the constructor for the class ProjectTargetInstance needs to be modified for this, this has a ripple effect on several other classes. This needs further investigation.

For point 3 an own issue might be necessary, since at the current point of time I cannot assess the impact of this change. A minimal implementation can however omit point 3.

wallymathieu commented 6 years ago

This feature would make MsBuild a lot more accessible, so this would be helpful! 👍

pellet commented 6 years ago

This sort of caveat makes it painful: 'Specify the target after the /target: switch in the format :. If the project name contains any of the characters %, $, @, ;, ., (, ), or ', replace them with an _ in the specified target name.'

AbhishekTripathi commented 5 years ago

Fast forward four years and still no listing of targets either in msbuild or in the newer dotnet.exe!!

mloskot commented 5 years ago

Every one moves to CMake. Now! (Microsoft has moved, haven't they 😉)

But, seriously, give an intern at Microsoft this perfect first task and a week or two and she will get the msbuild /targets done.

danmoseley commented 5 years ago

@AbhishekTripathi to be fair, it's been up for grabs for 4 years. I do not think it would be terribly difficult.