diff --git a/src/dotnet/commands/dotnet-add/Program.cs b/src/dotnet/commands/dotnet-add/Program.cs index 7ddd12e45..e6a5fc452 100644 --- a/src/dotnet/commands/dotnet-add/Program.cs +++ b/src/dotnet/commands/dotnet-add/Program.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Tools.Add.PackageReference; using Microsoft.DotNet.Tools.Add.ProjectToProjectReference; using Microsoft.DotNet.Tools.Add.ProjectToSolution; @@ -18,6 +19,7 @@ namespace Microsoft.DotNet.Tools.Add { AddProjectToSolutionCommand.Create, AddProjectToProjectReferenceCommand.Create, + AddPackageReferenceCommand.Create }; public static int Run(string[] args) @@ -26,4 +28,4 @@ namespace Microsoft.DotNet.Tools.Add return command.RunCommand(args); } } -} +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-add/dotnet-add-package/LocalizableStrings.cs b/src/dotnet/commands/dotnet-add/dotnet-add-package/LocalizableStrings.cs new file mode 100644 index 000000000..570cd0e52 --- /dev/null +++ b/src/dotnet/commands/dotnet-add/dotnet-add-package/LocalizableStrings.cs @@ -0,0 +1,22 @@ +// 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. + +namespace Microsoft.DotNet.Tools.Add.PackageReference +{ + internal class LocalizableStrings + { + public const string AppFullName = ".NET Add Package reference Command"; + + public const string AppDescription = "Command to add package reference"; + + public const string AppHelpText = "Package references to add"; + + public const string CmdFrameworkDescription = "Add reference only when targetting a specific framework"; + + public const string CmdNoRestoreDescription = "Add reference without performing restore preview and compatibility check."; + + public const string CmdSourceDescription = "Use specific NuGet package sources to use during the restore."; + + public const string CmdPackageDirectoryDescription = "Restore the packages to this Directory ."; + } +} \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-add/dotnet-add-package/Program.cs b/src/dotnet/commands/dotnet-add/dotnet-add-package/Program.cs new file mode 100644 index 000000000..34976633d --- /dev/null +++ b/src/dotnet/commands/dotnet-add/dotnet-add-package/Program.cs @@ -0,0 +1,130 @@ +// 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.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using Microsoft.Build.Evaluation; +using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.CommandLine; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Tools.Common; +using Microsoft.DotNet.Tools.MSBuild; +using NuGet.Frameworks; + +namespace Microsoft.DotNet.Tools.Add.PackageReference +{ + internal class AddPackageReferenceCommand : DotNetSubCommandBase + { + private CommandOption _frameworkOption; + private CommandOption _noRestore; + private CommandOption _source; + private CommandOption _packageDirectory; + + public static DotNetSubCommandBase Create() + { + var command = new AddPackageReferenceCommand() + { + Name = "package", + FullName = LocalizableStrings.AppFullName, + Description = LocalizableStrings.AppDescription, + HandleRemainingArguments = true, + ArgumentSeparatorHelpText = LocalizableStrings.AppHelpText, + }; + + command.HelpOption("-h|--help"); + + command._frameworkOption = command.Option( + $"-f|--framework", + LocalizableStrings.CmdFrameworkDescription, + CommandOptionType.SingleValue); + + command._noRestore = command.Option( + $"-n|--no-restore ", + LocalizableStrings.CmdNoRestoreDescription, + CommandOptionType.NoValue); + + command._source = command.Option( + $"-s|--source ", + LocalizableStrings.CmdSourceDescription, + CommandOptionType.SingleValue); + + command._packageDirectory = command.Option( + $"--package-directory", + LocalizableStrings.CmdPackageDirectoryDescription, + CommandOptionType.SingleValue); + + return command; + } + + public override int Run(string fileOrDirectory) + { + WaitForDebugger(); + var projects = new ProjectCollection(); + var msbuildProj = MsbuildProject.FromFileOrDirectory(projects, fileOrDirectory); + + if (RemainingArguments.Count == 0) + { + throw new GracefulException(CommonLocalizableStrings.SpecifyAtLeastOneReferenceToAdd); + } + + var tempDgFilePath = CreateTemporaryFile(".dg"); + + GetProjectDependencyGraph(msbuildProj.ProjectDirectory, tempDgFilePath); + + DisposeTemporaryFile(tempDgFilePath); + + return 0; + } + + private void GetProjectDependencyGraph(string projectFilePath, + string dgFilePath) + { + var args = new List(); + + // Pass the task as generate restore dg file + args.Add("/t:GenerateRestoreGraphFile"); + + // Pass dg file output path + args.Add(string.Format("/p:RestoreGraphOutputPath={0}{1}{2}", '"', dgFilePath, '"')); + + var result = new MSBuildForwardingApp(args).Execute(); + + if (result != 0) + { + throw new GracefulException("Could not generate dg file"); + } + } + + private string CreateTemporaryFile(string extension) + { + var tempDirectory = Path.GetTempPath(); + var tempFile = Path.Combine(tempDirectory, Guid.NewGuid().ToString() + extension); + File.Create(tempFile).Dispose(); + return tempFile; + } + + private void DisposeTemporaryFile(string filePath) + { + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + } + + public void WaitForDebugger() + { + Console.WriteLine("Waiting for debugger to attach."); + Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}"); + + while (!Debugger.IsAttached) + { + System.Threading.Thread.Sleep(100); + } + Debugger.Break(); + } + } +} \ No newline at end of file