diff --git a/scripts/register-completions.bash b/scripts/register-completions.bash new file mode 100644 index 000000000..635e59112 --- /dev/null +++ b/scripts/register-completions.bash @@ -0,0 +1,15 @@ +#!/bin/bash +# Parameter completion for the dotnet CLI + +_dotnet_bash_complete() +{ + local word=${COMP_WORDS[COMP_CWORD]} + local dotnetPath=${COMP_WORDS[1]} + + local completions=("$(./bin/Debug/netcoreapp1.0/osx.10.11-x64/publish/dotnet complete --position ${COMP_POINT} "${COMP_LINE}")") + + # https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html + COMPREPLY=( $(compgen -W "$completions" -- "$word") ) +} + +complete -f -F _dotnet_bash_complete dotnet \ No newline at end of file diff --git a/scripts/register-completions.ps1 b/scripts/register-completions.ps1 new file mode 100644 index 000000000..cc19f9702 --- /dev/null +++ b/scripts/register-completions.ps1 @@ -0,0 +1,6 @@ +Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock { + param($commandName, $wordToComplete, $cursorPosition) + C:\dev\github\cli\artifacts\win10-x64\stage2\dotnet.exe complete --position $cursorPosition "$wordToComplete" | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } + } \ No newline at end of file diff --git a/scripts/register-completions.zsh b/scripts/register-completions.zsh new file mode 100644 index 000000000..727897232 --- /dev/null +++ b/scripts/register-completions.zsh @@ -0,0 +1,12 @@ +# Parameter completion for the dotnet CLI + +_dotnet_zsh_complete() +{ + local dotnetPath=$words[1] + + local completions=("$(./bin/Debug/netcoreapp1.0/osx.10.11-x64/publish/dotnet complete "$words")") + + reply=( "${(ps:\n:)completions}" ) +} + +compctl -K _dotnet_zsh_complete dotnet \ No newline at end of file diff --git a/src/dotnet/MsbuildProject.cs b/src/dotnet/MsbuildProject.cs index 1f5811cd2..860d38799 100644 --- a/src/dotnet/MsbuildProject.cs +++ b/src/dotnet/MsbuildProject.cs @@ -24,6 +24,7 @@ namespace Microsoft.DotNet.Tools private ProjectCollection _projects; private List _cachedTfms = null; + private IEnumerable cachedRuntimeIdentifiers; private MsbuildProject(ProjectCollection projects, ProjectRootElement project) { @@ -149,6 +150,12 @@ namespace Microsoft.DotNet.Tools return ProjectRootElement.GetAllItemsWithElementType(ProjectItemElementType); } + public IEnumerable GetRuntimeIdentifiers() + { + return cachedRuntimeIdentifiers ?? + (cachedRuntimeIdentifiers = GetEvaluatedProject().GetRuntimeIdentifiers()); + } + public IEnumerable GetTargetFrameworks() { if (_cachedTfms != null) diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs index 12aaf631f..38e570881 100644 --- a/src/dotnet/Program.cs +++ b/src/dotnet/Program.cs @@ -12,6 +12,7 @@ using Microsoft.DotNet.PlatformAbstractions; using Microsoft.DotNet.Tools.Add; using Microsoft.DotNet.Tools.Build; using Microsoft.DotNet.Tools.Clean; +using Microsoft.DotNet.Tools.Complete; using Microsoft.DotNet.Tools.Help; using Microsoft.DotNet.Tools.List; using Microsoft.DotNet.Tools.Migrate; @@ -29,6 +30,7 @@ using Microsoft.DotNet.Tools.Test; using Microsoft.DotNet.Tools.VSTest; using Microsoft.DotNet.Tools.Cache; using NuGet.Frameworks; +using Command = Microsoft.DotNet.Cli.Utils.Command; namespace Microsoft.DotNet.Cli { @@ -54,6 +56,7 @@ namespace Microsoft.DotNet.Cli ["sln"] = SlnCommand.Run, ["test"] = TestCommand.Run, ["vstest"] = VSTestCommand.Run, + ["complete"] = CompleteCommand.Run, }; public static int Main(string[] args) diff --git a/src/dotnet/ProjectExtensions.cs b/src/dotnet/ProjectExtensions.cs index 1ed154477..ab5065383 100644 --- a/src/dotnet/ProjectExtensions.cs +++ b/src/dotnet/ProjectExtensions.cs @@ -1,9 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.Build.Construction; using Microsoft.Build.Evaluation; -using Microsoft.DotNet.ProjectJsonMigration; using NuGet.Frameworks; using System.Collections.Generic; using System.Linq; @@ -12,6 +10,15 @@ namespace Microsoft.DotNet.Tools.ProjectExtensions { internal static class ProjectExtensions { + public static IEnumerable GetRuntimeIdentifiers(this Project project) + { + return project + .GetPropertyCommaSeparatedValues("RuntimeIdentifier") + .Concat(project.GetPropertyCommaSeparatedValues("RuntimeIdentifiers")) + .Select(value => value.ToLower()) + .Distinct(); + } + public static IEnumerable GetTargetFrameworks(this Project project) { var targetFramewoksStrings = project diff --git a/src/dotnet/commands/dotnet-complete/CompleteCommand.cs b/src/dotnet/commands/dotnet-complete/CompleteCommand.cs new file mode 100644 index 000000000..ed05473af --- /dev/null +++ b/src/dotnet/commands/dotnet-complete/CompleteCommand.cs @@ -0,0 +1,68 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IO; +using System.Linq; +using System.Text; +using Microsoft.DotNet.Cli.CommandLine; +using Microsoft.DotNet.Cli.Utils; +using Command = Microsoft.DotNet.Cli.CommandLine.Command; + +namespace Microsoft.DotNet.Tools.Complete +{ + public class CompleteCommand + { + private static readonly Command dotnetCommand = Create.DotnetCommand(); + + public static int Run(string[] args) + { + DebugHelper.HandleDebugSwitch(ref args); + + var log = new StringBuilder(); + log.AppendLine($"args: {string.Join(" ", args.Select(a => $"\"{a}\""))}"); + + var result = dotnetCommand["complete"].Parse(args); + + log.AppendLine("diagram (1): " + result.Diagram()); + + var complete = result["complete"]; + + var suggestions = Suggestions(complete, log); + + log.AppendLine($"suggestions: {Environment.NewLine}{string.Join(Environment.NewLine, suggestions)}"); + + File.WriteAllText("parse.log", log.ToString()); + + foreach (var suggestion in suggestions) + { + Console.WriteLine(suggestion); + } + + return 0; + } + + private static string[] Suggestions(AppliedOption complete, StringBuilder log) + { + var input = complete.Arguments.SingleOrDefault() ?? ""; + + var positionOption = complete.AppliedOptions.SingleOrDefault(a => a.Name == "position"); + if (positionOption != null) + { + var position = positionOption.Value(); + + if (position > input.Length) + { + input += " "; + } + } + + var result = dotnetCommand.Parse(input); + + log.AppendLine("diagram (2): " + result.Diagram()); + + return result.Suggestions() + .ToArray(); + } + } +} \ No newline at end of file diff --git a/src/dotnet/dotnet-complete/commands/Create.cs b/src/dotnet/dotnet-complete/commands/Create.cs new file mode 100644 index 000000000..0650a6079 --- /dev/null +++ b/src/dotnet/dotnet-complete/commands/Create.cs @@ -0,0 +1,529 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using Microsoft.Build.Evaluation; +using Microsoft.DotNet.Cli.CommandLine; +using Newtonsoft.Json.Linq; +using static Microsoft.DotNet.Cli.CommandLine.Accept; +using static Microsoft.DotNet.Cli.CommandLine.Create; +using Command = Microsoft.DotNet.Cli.CommandLine.Command; + +namespace Microsoft.DotNet.Tools.Complete +{ + public static class Create + { + public static Command DotnetCommand() => + Command("dotnet", + ".NET Command Line Tools (2.0.0-alpha-alpha-004866)", + NoArguments, + New(), + Restore(), + Build(), + Publish(), + Run(), + Test(), + Pack(), + Migrate(), + Clean(), + Sln(), + Add(), + Remove(), + List(), + NuGet(), + Command("msbuild", ""), + Command("vstest", ""), + Complete(), + HelpOption(), + Option("--info", ""), + VerbosityOption()); + + private static Command Complete() => + Command("complete", "", + ExactlyOneArgument + .With(name: "path"), + Option("--position", "", + ExactlyOneArgument + .With(name: "command"), + o => int.Parse(o.Arguments.Single()))); + + private static Command Add() => + Command("add", "", + ExactlyOneArgument, + Package(), + Reference(), + HelpOption()); + + private static Command Build() => + Command("build", + ".NET Builder", + HelpOption(), + Option("-o|--output", + "Output directory in which to place built artifacts.", + ExactlyOneArgument + .With(name: "OUTPUT_DIR")), + Option("-f|--framework", + "Target framework to build for. The target framework has to be specified in the project file.", + AnyOneOf(TargetFrameworksFromProjectFile)), + Option("-r|--runtime", + "Target runtime to build for. The default is to build a portable application.", + WithSuggestionsFrom(_ => RunTimesFromProjectFile())), + Option("-c|--configuration", + "Configuration to use for building the project. Default for most projects is \"Debug\".", + ExactlyOneArgument + .With(name: "CONFIGURATION") + .WithSuggestionsFrom(_ => new[] { "DEBUG", "RELEASE" })), + Option("--version-suffix", "Defines the value for the $(VersionSuffix) property in the project", + ExactlyOneArgument + .With(name: "VERSION_SUFFIX")), + Option("--no-incremental", "Disables incremental build."), + Option("--no-dependencies", "Set this flag to ignore project-to-project references and only build the root project"), + VerbosityOption()); + + private static Command Clean() => + Command("clean", + ".NET Clean Command", + HelpOption(), + Option("-o|--output", "Directory in which the build outputs have been placed.", + ExactlyOneArgument + .With(name: "OUTPUT_DIR")), + Option("-f|--framework", "Clean a specific framework.", + ExactlyOneArgument + .With(name: "FRAMEWORK") + .WithSuggestionsFrom(_ => TargetFrameworksFromProjectFile())), + Option("-c|--configuration", + "Clean a specific configuration.", + ExactlyOneArgument + .With(name: "CONFIGURATION") + .WithSuggestionsFrom(_ => new[] { "DEBUG", "RELEASE" }))); + + private static Command List() => + Command("list", "", + ExactlyOneArgument + .With(name: "PROJECT", + description: + "The project file to operate on. If a file is not specified, the command will search the current directory for one."), + HelpOption(), + Command("reference", "Command to list project to project references", + ExactlyOneArgument + .With(name: "PROJECT") + .With(description: "The project file to operate on. If a file is not specified, the command will search the current directory for one."), + HelpOption())); + + private static Command Migrate() => + Command("migrate", + ".NET Migrate Command", + HelpOption(), + Option("-t|--template-file", + "Base MSBuild template to use for migrated app. The default is the project included in dotnet new."), + Option("-v|--sdk-package-version", + "The version of the SDK package that will be referenced in the migrated app. The default is the version of the SDK in dotnet new."), + Option("-x|--xproj-file", + "The path to the xproj file to use. Required when there is more than one xproj in a project directory."), + Option("-s|--skip-project-references", + "Skip migrating project references. By default, project references are migrated recursively."), + Option("-r|--report-file", + "Output migration report to the given file in addition to the console."), + Option("--format-report-file-json", + "Output migration report file as json rather than user messages."), + Option("--skip-backup", + "Skip moving project.json, global.json, and *.xproj to a `backup` directory after successful migration.")); + + private static Command New() => + Command("new", + "Initialize .NET projects.", + WithSuggestionsFrom("console", + "classlib", + "mstest", + "xunit", + "web", + "mvc", + "webapi", + "sln"), + Option("-l|--list", + "List templates containing the specified name."), + Option("-lang|--language", + "Specifies the language of the template to create", + WithSuggestionsFrom("C#", "F#") + .With(defaultValue: () => "C#")), + Option("-n|--name", + "The name for the output being created. If no name is specified, the name of the current directory is used."), + Option("-o|--output", + "Location to place the generated output."), + Option("-h|--help", + "Displays help for this command."), + Option("-all|--show-all", + "Shows all templates")); + + private static Command NuGet() => + Command("nuget", + "NuGet Command Line 4.0.0.0", + HelpOption(), + Option("--version", + "Show version information"), + Option("-v|--verbosity", + "The verbosity of logging to use. Allowed values: Debug, Verbose, Information, Minimal, Warning, Error.", + ExactlyOneArgument + .With(name: "verbosity")), + Command("delete", + "Deletes a package from the server.", + ExactlyOneArgument + .With(name: "root", + description: "The Package Id and version."), + HelpOption(), + Option("--force-english-output", + "Forces the application to run using an invariant, English-based culture."), + Option("-s|--source", + "Specifies the server URL", + ExactlyOneArgument + .With(name: "source")), + Option("--non-interactive", + "Do not prompt for user input or confirmations."), + Option("-k|--api-key", + "The API key for the server.", + ExactlyOneArgument + .With(name: "apiKey"))), + Command("locals", + "Clears or lists local NuGet resources such as http requests cache, packages cache or machine-wide global packages folder.", + AnyOneOf(@"all", @"http-cache", @"global-packages", @"temp") + .With(description: "Cache Location(s) Specifies the cache location(s) to list or clear."), + HelpOption(), + Option("--force-english-output", + "Forces the application to run using an invariant, English-based culture."), + Option("-c|--clear", "Clear the selected local resources or cache location(s)."), + Option("-l|--list", "List the selected local resources or cache location(s).")), + Command("push", + "Pushes a package to the server and publishes it.", + HelpOption(), + Option("--force-english-output", + "Forces the application to run using an invariant, English-based culture."), + Option("-s|--source", + "Specifies the server URL", + ExactlyOneArgument + .With(name: "source")), + Option("-ss|--symbol-source", + "Specifies the symbol server URL. If not specified, nuget.smbsrc.net is used when pushing to nuget.org.", + ExactlyOneArgument + .With(name: "source")), + Option("-t|--timeout", + "Specifies the timeout for pushing to a server in seconds. Defaults to 300 seconds (5 minutes).", + ExactlyOneArgument + .With(name: "timeout")), + Option("-k|--api-key", "The API key for the server.", + ExactlyOneArgument + .With(name: "apiKey")), + Option("-sk|--symbol-api-key", "The API key for the symbol server.", + ExactlyOneArgument + .With(name: "apiKey")), + Option("-d|--disable-buffering", + "Disable buffering when pushing to an HTTP(S) server to decrease memory usage."), + Option("-n|--no-symbols", + "If a symbols package exists, it will not be pushed to a symbols server."))); + + private static Command Pack() => + Command("pack", + ".NET Core NuGet Package Packer", + HelpOption(), + Option("-o|--output", + "Directory in which to place built packages.", + ExactlyOneArgument + .With(name: "OUTPUT_DIR")), + Option("--no-build", + "Skip building the project prior to packing. By default, the project will be built."), + Option("--include-symbols", + "Include packages with symbols in addition to regular packages in output directory."), + Option("--include-source", + "Include PDBs and source files. Source files go into the src folder in the resulting nuget package"), + Option("-c|--configuration", + "Configuration to use for building the project. Default for most projects is \"Debug\".", + ExactlyOneArgument + .With(name: "CONFIGURATION") + .WithSuggestionsFrom(_ => new[] { "DEBUG", "RELEASE" })), + Option("--version-suffix", + "Defines the value for the $(VersionSuffix) property in the project.", + ExactlyOneArgument + .With(name: "VERSION_SUFFIX")), + Option("-s|--serviceable", + "Set the serviceable flag in the package. For more information, please see https://aka.ms/nupkgservicing."), + VerbosityOption() + ); + + private static Command Package() => + Command("package", + ".NET Add Package reference Command", + ExactlyOneArgument + .WithSuggestionsFrom(QueryNuGet), + HelpOption(), + Option("-v|--version", + "Version for the package to be added.", + ExactlyOneArgument + .With(name: "VERSION")), + Option("-f|--framework", + "Add reference only when targetting a specific framework", + ExactlyOneArgument + .With(name: "FRAMEWORK")), + Option("-n|--no-restore ", + "Add reference without performing restore preview and compatibility check."), + Option("-s|--source", + "Use specific NuGet package sources to use during the restore."), + Option("--package-directory", + "Restore the packages to this Directory .", + ExactlyOneArgument + .With(name: "PACKAGE_DIRECTORY"))); + + private static Command Publish() => + Command("publish", + ".NET Publisher", + ExactlyOneArgument, + HelpOption(), + Option("-f|--framework", + "Target framework to publish for. The target framework has to be specified in the project file.", + AnyOneOf(TargetFrameworksFromProjectFile) + .With(name: "FRAMEWORK")), + Option("-r|--runtime", + "Publish the project for a given runtime. This is used when creating self-contained deployment. Default is to publish a framework-dependent app.", + ExactlyOneArgument + .With(name: "RUNTIME_IDENTIFIER")), + Option("-o|--output", + "Output directory in which to place the published artifacts.", + ExactlyOneArgument + .With(name: "OUTPUT_DIR")), + Option("-c|--configuration", "Configuration to use for building the project. Default for most projects is \"Debug\".", + ExactlyOneArgument + .With(name: "CONFIGURATION") + .WithSuggestionsFrom(_ => new[] { "DEBUG", "RELEASE" })), + Option("--version-suffix", "Defines the value for the $(VersionSuffix) property in the project.", + ExactlyOneArgument + .With(name: "VERSION_SUFFIX")), + VerbosityOption()); + + private static Command Remove() => + Command("remove", + "", + HelpOption(), + Command("package", + "Command to remove package reference.", + HelpOption()), + Command("reference", + "Command to remove project to project reference", + WithSuggestionsFrom(_ => ProjectReferencesFromProjectFile()), + HelpOption(), + Option("-f|--framework", + "Remove reference only when targetting a specific framework", + ExactlyOneArgument + .With(name: "FRAMEWORK")))); + + private static Command Reference() => + Command("reference", + "Command to add project to project reference", + OneOrMoreArguments, + HelpOption(), + Option("-f|--framework", + "Add reference only when targetting a specific framework", + ExactlyOneArgument + .WithSuggestionsFrom( + _ => TargetFrameworksFromProjectFile().ToArray()) + // .With(name: "FRAMEWORK") + )); + + private static Command Restore() => + Command("restore", + ".NET dependency restorer", + HelpOption(), + Option("-s|--source", + "Specifies a NuGet package source to use during the restore.", + ExactlyOneArgument + .With(name: "SOURCE")), + Option("-r|--runtime", + "Target runtime to restore packages for.", + WithSuggestionsFrom(_ => RunTimesFromProjectFile()) + .With(name: "RUNTIME_IDENTIFIER")), + Option("--packages", + "Directory to install packages in.", + ExactlyOneArgument + .With(name: "PACKAGES_DIRECTORY")), + Option("--disable-parallel", + "Disables restoring multiple projects in parallel."), + Option("--configfile", + "The NuGet configuration file to use.", + ExactlyOneArgument + .With(name: "FILE")), + Option("--no-cache", + "Do not cache packages and http requests."), + Option("--ignore-failed-sources", + "Treat package source failures as warnings."), + Option("--no-dependencies", + "Set this flag to ignore project to project references and only restore the root project"), + VerbosityOption()); + + private static Command Run() => + Command("run", + ".NET Run Command", + HelpOption(), + Option("-c|--configuration", + @"Configuration to use for building the project. Default for most projects is ""Debug"".", + ExactlyOneArgument + .WithSuggestionsFrom(_ => new[] { "DEBUG", "RELEASE" })), + Option("-f|--framework", + "Build and run the app using the specified framework. The framework has to be specified in the project file.", + AnyOneOf(TargetFrameworksFromProjectFile)), + Option("-p|--project", + "The path to the project file to run (defaults to the current directory if there is only one project).", + ZeroOrOneArgument)); + + private static Command Sln() => + Command("sln", + ".NET modify solution file command", + HelpOption(), + Command("add", + ".NET Add project(s) to a solution file Command", + ExactlyOneArgument + .With(name: "SLN_FILE"), + HelpOption()), + Command("list", + "List all projects in the solution.", + ExactlyOneArgument + .With(name: "SLN_FILE"), + HelpOption()), + Command("remove", + "Remove the specified project(s) from the solution. The project is not impacted.")); + + private static Command Test() => + Command("test", + ".NET Test Driver", + Option("-h|--help", + "Show help information"), + Option("-s|--settings", + "Settings to use when running tests.", + ExactlyOneArgument + .With(name: "SETTINGS_FILE")), + Option("-t|--list-tests", + "Lists discovered tests"), + Option("--filter", + @"Run tests that match the given expression. + Examples: + Run tests with priority set to 1: --filter ""Priority = 1"" + Run a test with the specified full name: --filter ""FullyQualifiedName=Namespace.ClassName.MethodName"" + Run tests that contain the specified name: --filter ""FullyQualifiedName~Namespace.Class"" + More info on filtering support: https://aka.ms/vstest-filtering", + ExactlyOneArgument + .With(name: "EXPRESSION")), + Option("-a|--test-adapter-path", + "Use custom adapters from the given path in the test run.\r\n Example: --test-adapter-path "), + Option("-l|--logger", + "Specify a logger for test results.\r\n Example: --logger \"trx[;LogFileName=]\"", + ExactlyOneArgument + .With(name: "LoggerUri/FriendlyName")), + Option("-c|--configuration", "Configuration to use for building the project. Default for most projects is \"Debug\".", + ExactlyOneArgument + .With(name: "CONFIGURATION") + .WithSuggestionsFrom(_ => new[] { "DEBUG", "RELEASE" })), + Option("-f|--framework", + "Looks for test binaries for a specific framework", + AnyOneOf(() => TargetFrameworksFromProjectFile().ToArray()) + .With(name: "FRAMEWORK")), + Option("-o|--output", + "Directory in which to find the binaries to be run", + ExactlyOneArgument + .With(name: "OUTPUT_DIR")), + Option("-d|--diag", + "Enable verbose logs for test platform.\r\n Logs are written to the provided file.", + ExactlyOneArgument + .With(name: "PATH_TO_FILE")), + Option("--no-build", + "Do not build project before testing."), + VerbosityOption()); + + private static Option HelpOption() => + Option("-h|--help", + "Show help information", + NoArguments, + materialize: o => o.Option.Command().HelpView()); + + private static Option VerbosityOption() => + Option("-v|--verbosity", + "Set the verbosity level of the command. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]", + AnyOneOf("q[uiet]", + "m[inimal]", + "n[ormal]", + "d[etailed]")); + + public static string[] KnownRuntimes = + { + "win10-x86", + "win10-x64", + "win10-arm64", + "osx.10.11-x64", + "centos.7-x64", + "debian.8-x64", + "linuxmint.17-x64", + "opensuse.13.2-x64", + "rhel.7.2-x64", + "ubuntu.14.04-x64", + "ubuntu.16.04-x64", + }; + + private static IEnumerable QueryNuGet(string match) + { + var httpClient = new HttpClient(); + + string result = null; + + try + { + var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(10)); + var response = httpClient.GetAsync($"https://api-v2v3search-0.nuget.org/query?q={match}&skip=0&take=100&prerelease=true", cancellation.Token) + .Result; + + result = response.Content.ReadAsStringAsync().Result; + } + catch (Exception) + { + yield break; + } + + var json = JObject.Parse(result); + + foreach (var id in json["data"]) + { + yield return id["id"].Value(); + } + } + + private static IEnumerable TargetFrameworksFromProjectFile() + { + var msbuildProj = MsbuildProject.FromFileOrDirectory( + new ProjectCollection(), + Directory.GetCurrentDirectory()); + + foreach (var tfm in msbuildProj.GetTargetFrameworks()) + { + yield return tfm.GetShortFolderName(); + } + } + + private static IEnumerable RunTimesFromProjectFile() + { + var msbuildProj = MsbuildProject.FromFileOrDirectory( + new ProjectCollection(), + Directory.GetCurrentDirectory()); + + return msbuildProj.GetRuntimeIdentifiers(); + } + + private static IEnumerable ProjectReferencesFromProjectFile() + { + var msbuildProj = MsbuildProject.FromFileOrDirectory( + new ProjectCollection(), + Directory.GetCurrentDirectory()); + + return msbuildProj.GetProjectToProjectReferences() + .Select(r => r.Include); + } + } +} \ No newline at end of file diff --git a/src/dotnet/dotnet.csproj b/src/dotnet/dotnet.csproj index a855b26b8..01bf57817 100644 --- a/src/dotnet/dotnet.csproj +++ b/src/dotnet/dotnet.csproj @@ -39,6 +39,7 @@ +