diff --git a/DotNetTools.sln b/DotNetTools.sln index f5b20b9..c681039 100644 --- a/DotNetTools.sln +++ b/DotNetTools.sln @@ -34,6 +34,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Watcher.To EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Extensions.Caching.SqlConfig.Tools", "src\Microsoft.Extensions.Caching.SqlConfig.Tools\Microsoft.Extensions.Caching.SqlConfig.Tools.xproj", "{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{59E02BDF-98DE-4D64-B576-2D0299D5E052}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "NuGetPackager", "tools\NuGetPackager\NuGetPackager.xproj", "{8B781D87-1FC3-4A34-9089-2BDF6B562B85}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -80,6 +84,10 @@ Global {53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Debug|Any CPU.Build.0 = Debug|Any CPU {53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Release|Any CPU.ActiveCfg = Release|Any CPU {53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Release|Any CPU.Build.0 = Release|Any CPU + {8B781D87-1FC3-4A34-9089-2BDF6B562B85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8B781D87-1FC3-4A34-9089-2BDF6B562B85}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8B781D87-1FC3-4A34-9089-2BDF6B562B85}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8B781D87-1FC3-4A34-9089-2BDF6B562B85}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -96,5 +104,6 @@ Global {7B331122-83B1-4F08-A119-DC846959844C} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134} {8A2E6961-6B12-4A8E-8215-3E7301D52EAC} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134} {53F3B53D-303A-4DAA-9C38-4F55195FA5B9} = {66517987-2A5A-4330-B130-207039378FD4} + {8B781D87-1FC3-4A34-9089-2BDF6B562B85} = {59E02BDF-98DE-4D64-B576-2D0299D5E052} EndGlobalSection EndGlobal diff --git a/NuGetPackageVerifier.json b/NuGetPackageVerifier.json index 6f028d9..a8c79fa 100644 --- a/NuGetPackageVerifier.json +++ b/NuGetPackageVerifier.json @@ -1,17 +1,38 @@ -{ - "adx": { // Packages written by the ADX team and that ship on NuGet.org - "rules": [ - "AdxVerificationCompositeRule" - ], - "packages": { - "Microsoft.DotNet.Watcher.Tools": { }, - "Microsoft.Extensions.Caching.SqlConfig.Tools": { }, - "Microsoft.Extensions.SecretManager.Tools": { } - } - }, - "Default": { // Rules to run for packages not listed in any other set. - "rules": [ - "DefaultCompositeRule" - ] - } +{ + "adx": { + "rules": [ + "AdxVerificationCompositeRule" + ], + "packages": { + "Microsoft.DotNet.Watcher.Tools": { + "nowarn": { + "DOC_MISSING": { + "lib/netcoreapp1.0/dotnet-watch.dll": "xmldocs not required for DotnetCliTool packages" + } + }, + "packageTypes": ["DotnetCliTool"] + }, + "Microsoft.Extensions.Caching.SqlConfig.Tools": { + "nowarn": { + "DOC_MISSING": { + "lib/netcoreapp1.0/dotnet-sql-cache.dll": "xmldocs not required for DotnetCliTool packages" + } + }, + "packageTypes": ["DotnetCliTool"] + }, + "Microsoft.Extensions.SecretManager.Tools": { + "nowarn": { + "DOC_MISSING": { + "lib/netcoreapp1.0/dotnet-user-secrets.dll": "xmldocs not required for DotnetCliTool packages" + } + }, + "packageTypes": ["DotnetCliTool"] + } + } + }, + "Default": { + "rules": [ + "DefaultCompositeRule" + ] + } } \ No newline at end of file diff --git a/makefile.shade b/makefile.shade index 2493f0f..83ca855 100644 --- a/makefile.shade +++ b/makefile.shade @@ -1,7 +1,25 @@ +use namespace="System.IO" + +default BASE_DIR_LOCAL='${Directory.GetCurrentDirectory()}' +default BUILD_DIR_LOCAL='${Path.Combine(BASE_DIR_LOCAL, "artifacts", "build")}' + var VERSION='0.1' var FULL_VERSION='0.1' var AUTHORS='Microsoft Open Technologies, Inc.' -BuildQuality = "preview3"; use-standard-lifecycle -k-standard-goals \ No newline at end of file +k-standard-goals + +#build-pack .build-compile target='compile' + @{ + if (Directory.Exists("src") && !IsLinux) + { + Directory.CreateDirectory(BUILD_DIR_LOCAL); + Dotnet("run -p tools/NuGetPackager -- -c " + E("Configuration") + + " -o artifacts/build/ "+ + "-n src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec " + + "-n src/Microsoft.Extensions.Caching.SqlConfig.Tools/Microsoft.Extensions.Caching.SqlConfig.Tools.nuspec " + + "-n src/Microsoft.DotNet.Watcher.Tools/Microsoft.DotNet.Watcher.Tools.nuspec "); + } + } \ No newline at end of file diff --git a/src/Microsoft.DotNet.Watcher.Tools/Microsoft.DotNet.Watcher.Tools.nuspec b/src/Microsoft.DotNet.Watcher.Tools/Microsoft.DotNet.Watcher.Tools.nuspec new file mode 100644 index 0000000..21ccd58 --- /dev/null +++ b/src/Microsoft.DotNet.Watcher.Tools/Microsoft.DotNet.Watcher.Tools.nuspec @@ -0,0 +1,30 @@ + + + + Microsoft.DotNet.Watcher.Tools + $version$ + Microsoft + Microsoft + false + Command line tool to watch for source file changes during development and restart the dotnet command. + dotnet,watch + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.DotNet.Watcher.Tools/project.json b/src/Microsoft.DotNet.Watcher.Tools/project.json index 3779fdc..0fb7148 100644 --- a/src/Microsoft.DotNet.Watcher.Tools/project.json +++ b/src/Microsoft.DotNet.Watcher.Tools/project.json @@ -11,14 +11,9 @@ "outputName": "dotnet-watch", "warningsAsErrors": true, "emitEntryPoint": true, - "keyFile": "../../tools/Key.snk", - "nowarn": [ - "CS1591" - ], - "xmlDoc": true + "keyFile": "../../tools/Key.snk" }, "dependencies": { - "System.Runtime.InteropServices.RuntimeInformation": "4.0.0", "Microsoft.DotNet.Cli.Utils": "1.0.0-*", "Microsoft.Extensions.CommandLineUtils": "1.1.0-*", "Microsoft.Extensions.Logging": "1.1.0-*", @@ -26,16 +21,14 @@ "Microsoft.Extensions.Process.Sources": { "type": "build", "version": "1.1.0-*" - } + }, + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0" + }, + "System.Runtime.InteropServices.RuntimeInformation": "4.0.0" }, "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "type": "platform", - "version": "1.0.0" - } - } - } + "netcoreapp1.0": {} } } \ No newline at end of file diff --git a/src/Microsoft.Extensions.Caching.SqlConfig.Tools/Microsoft.Extensions.Caching.SqlConfig.Tools.nuspec b/src/Microsoft.Extensions.Caching.SqlConfig.Tools/Microsoft.Extensions.Caching.SqlConfig.Tools.nuspec new file mode 100644 index 0000000..82ab837 --- /dev/null +++ b/src/Microsoft.Extensions.Caching.SqlConfig.Tools/Microsoft.Extensions.Caching.SqlConfig.Tools.nuspec @@ -0,0 +1,29 @@ + + + + Microsoft.Extensions.Caching.SqlConfig.Tools + $version$ + Microsoft + Microsoft + false + Command line tool to create tables and indexes in a Microsoft SQL Server database for distributed caching. + cache,distributedcache,sqlserver + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Extensions.Caching.SqlConfig.Tools/project.json b/src/Microsoft.Extensions.Caching.SqlConfig.Tools/project.json index b8ffffd..5d67000 100644 --- a/src/Microsoft.Extensions.Caching.SqlConfig.Tools/project.json +++ b/src/Microsoft.Extensions.Caching.SqlConfig.Tools/project.json @@ -1,32 +1,12 @@ { "version": "1.0.0-*", - "dependencies": { - "Microsoft.Extensions.CommandLineUtils": "1.1.0-*", - "Microsoft.Extensions.Logging": "1.1.0-*", - "Microsoft.Extensions.Logging.Console": "1.1.0-*", - "System.Data.SqlClient": "4.1.0-*" - }, - "description": "Command line tool to create tables and indexes in a Microsoft SQL Server database for distributed caching.", - "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "version": "1.0.0-*", - "type": "platform" - } - } - } - }, "buildOptions": { "outputName": "dotnet-sql-cache", "emitEntryPoint": true, "warningsAsErrors": true, - "keyFile": "../../tools/Key.snk", - "nowarn": [ - "CS1591" - ], - "xmlDoc": true + "keyFile": "../../tools/Key.snk" }, + "description": "Command line tool to create tables and indexes in a Microsoft SQL Server database for distributed caching.", "packOptions": { "repository": { "type": "git", @@ -37,5 +17,18 @@ "distributedcache", "sqlserver" ] + }, + "dependencies": { + "Microsoft.Extensions.CommandLineUtils": "1.1.0-*", + "Microsoft.Extensions.Logging": "1.1.0-*", + "Microsoft.Extensions.Logging.Console": "1.1.0-*", + "Microsoft.NETCore.App": { + "version": "1.0.0-*", + "type": "platform" + }, + "System.Data.SqlClient": "4.1.0-*" + }, + "frameworks": { + "netcoreapp1.0": {} } } \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec b/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec new file mode 100644 index 0000000..18d5b24 --- /dev/null +++ b/src/Microsoft.Extensions.SecretManager.Tools/Microsoft.Extensions.SecretManager.Tools.nuspec @@ -0,0 +1,33 @@ + + + + + Microsoft.Extensions.SecretManager.Tools + $version$ + Microsoft + Microsoft + false + Command line tool to manage user secrets for Microsoft.Extensions.Configuration. + configuration,secrets,usersecrets + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Extensions.SecretManager.Tools/project.json b/src/Microsoft.Extensions.SecretManager.Tools/project.json index bd470ff..f057bf1 100644 --- a/src/Microsoft.Extensions.SecretManager.Tools/project.json +++ b/src/Microsoft.Extensions.SecretManager.Tools/project.json @@ -4,11 +4,7 @@ "outputName": "dotnet-user-secrets", "emitEntryPoint": true, "warningsAsErrors": true, - "keyFile": "../../tools/Key.snk", - "nowarn": [ - "CS1591" - ], - "xmlDoc": true + "keyFile": "../../tools/Key.snk" }, "description": "Command line tool to manage user secrets for Microsoft.Extensions.Configuration.", "packOptions": { @@ -26,18 +22,15 @@ "Microsoft.Extensions.Configuration.UserSecrets": "1.1.0-*", "Microsoft.Extensions.CommandLineUtils": "1.1.0-*", "Microsoft.Extensions.Logging": "1.1.0-*", + "Microsoft.NETCore.App": { + "version": "1.0.0", + "type": "platform" + }, "Newtonsoft.Json": "9.0.1", "System.Runtime.InteropServices.RuntimeInformation": "4.0.0", "System.Runtime.Serialization.Primitives": "4.1.1" }, "frameworks": { - "netcoreapp1.0": { - "dependencies": { - "Microsoft.NETCore.App": { - "version": "1.0.0", - "type": "platform" - } - } - } + "netcoreapp1.0": {} } } \ No newline at end of file diff --git a/tools/NuGetPackager/NuGetPackager.xproj b/tools/NuGetPackager/NuGetPackager.xproj new file mode 100644 index 0000000..57c243c --- /dev/null +++ b/tools/NuGetPackager/NuGetPackager.xproj @@ -0,0 +1,19 @@ + + + + 14.0.25420 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 8b781d87-1fc3-4a34-9089-2bdf6b562b85 + NuGetPackager + .\obj + .\bin\ + + + + 2.0 + + + \ No newline at end of file diff --git a/tools/NuGetPackager/PackCommand.cs b/tools/NuGetPackager/PackCommand.cs new file mode 100644 index 0000000..687d0e0 --- /dev/null +++ b/tools/NuGetPackager/PackCommand.cs @@ -0,0 +1,150 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.ProjectModel.Graph; +using Microsoft.DotNet.ProjectModel.Utilities; +using NuGet.Frameworks; +using NuGet.Versioning; + +namespace NuGetPackager +{ + internal class PackCommand + { + private readonly string _baseDir; + + public PackCommand(string baseDir) + { + _baseDir = baseDir; + } + + public async Task PackAsync(string nuspec, string config, string outputDir) + { + var project = ProjectContext.Create(Path.GetDirectoryName(nuspec), FrameworkConstants.CommonFrameworks.NetCoreApp10); + var props = "configuration=" + config; + var idx = 0; + foreach (var depVersion in GetDependencies(project).OrderBy(p => p.Item1).Select(p => p.Item2)) + { + props += $";dep_{++idx}={depVersion}"; + } + + var buildCommand = Command.CreateDotNet("build", + new[] { project.ProjectFile.ProjectFilePath, "--configuration", config }, + configuration: config); + + if (buildCommand.Execute().ExitCode != 0) + { + throw new GracefulException("Build failed"); + } + + Directory.CreateDirectory(outputDir); + + var version = project.ProjectFile.Version.ToNormalizedString(); + await Nuget("pack", + nuspec, + "-Verbosity", "detailed", + "-OutputDirectory", outputDir, + "-Version", version, + "-Properties", props); + } + + private IEnumerable> GetDependencies(ProjectContext context) + { + // copied from https://github.com/dotnet/cli/blob/da0e365264e0ab555cdde978bdfd2e504bada49a/src/dotnet/commands/dotnet-pack/PackageGenerator.cs + var project = context.RootProject; + + foreach (var dependency in project.Dependencies) + { + if (dependency.Type.Equals(LibraryDependencyType.Build)) + { + continue; + } + + // TODO: Efficiency + var dependencyDescription = context.LibraryManager.GetLibraries().First(l => l.RequestedRanges.Contains(dependency)); + + // REVIEW: Can we get this far with unresolved dependencies + if (!dependencyDescription.Resolved) + { + continue; + } + + if (dependencyDescription.Identity.Type == LibraryType.Project && + ((ProjectDescription)dependencyDescription).Project.EmbedInteropTypes) + { + continue; + } + + VersionRange dependencyVersion = null; + + if (dependency.VersionRange == null || + dependency.VersionRange.IsFloating) + { + dependencyVersion = new VersionRange(dependencyDescription.Identity.Version); + } + else + { + dependencyVersion = dependency.VersionRange; + } + + Reporter.Verbose.WriteLine($"Adding dependency {dependency.Name.Yellow()} {VersionUtility.RenderVersion(dependencyVersion).Yellow()}"); + + yield return new Tuple(dependency.Name, dependencyVersion.MinVersion.ToString()); + } + } + + private static string GetLockFileVersion(ProjectContext project, string name) => + project + .LockFile + .PackageLibraries + .First(l => l.Name.Equals(name)) + .Version + .ToNormalizedString(); + + private async Task Nuget(params string[] args) + { + var pInfo = new ProcessStartInfo + { + Arguments = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args), + FileName = await GetNugetExePath() + }; + Console.WriteLine("command: ".Bold().Blue() + pInfo.FileName); + Console.WriteLine("arguments: ".Bold().Blue() + pInfo.Arguments); + + Process.Start(pInfo).WaitForExit(); + } + + private async Task GetNugetExePath() + { + if (Environment.GetEnvironmentVariable("KOREBUILD_NUGET_EXE") != null) + { + return Environment.GetEnvironmentVariable("KOREBUILD_NUGET_EXE"); + } + + var nugetPath = Path.Combine(_baseDir, ".build", "nuget.3.5.0-rc1.exe"); + if (File.Exists(nugetPath)) + { + return nugetPath; + } + + Console.WriteLine("log : Downloading nuget.exe 3.5.0-rc1".Bold().Black()); + + var response = await new HttpClient().GetAsync("https://dist.nuget.org/win-x86-commandline/v3.5.0-rc1/NuGet.exe"); + using (var file = new FileStream(nugetPath, FileMode.CreateNew)) + { + response.EnsureSuccessStatusCode(); + await response.Content.LoadIntoBufferAsync(); + await response.Content.CopyToAsync(file); + } + return nugetPath; + } + } +} \ No newline at end of file diff --git a/tools/NuGetPackager/Program.cs b/tools/NuGetPackager/Program.cs new file mode 100644 index 0000000..a553dec --- /dev/null +++ b/tools/NuGetPackager/Program.cs @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.IO; +using System.Linq; +using Microsoft.Extensions.CommandLineUtils; +using Microsoft.DotNet.Cli.Utils; + +namespace NuGetPackager +{ + /// + /// This replaces the "dotnet-pack" command, which doesn't not yet support "package types" + /// and probably won't in time for the next release. + /// TODO remove this once CLI supports package type + /// + public class Program + { + public static int Main(string[] args) + { + var app = new CommandLineApplication(); + var optOutput = app.Option("-o|--output-dir ", "Output dir", CommandOptionType.SingleValue); + var optConfig = app.Option("-c|--configuration ", "Config", CommandOptionType.SingleValue); + var optsNuspec = app.Option("-n|--nuspec ", "nuspec", CommandOptionType.MultipleValue); + + app.OnExecute(async () => + { + if (!optsNuspec.Values.Any()) + { + Reporter.Error.WriteLine("Missing values for --nuspec"); + return 1; + } + + var config = optConfig.HasValue() + ? optConfig.Value() + : "Debug"; + var output = optOutput.Value() ?? Directory.GetCurrentDirectory(); + + var packer = new PackCommand(Directory.GetCurrentDirectory()); + foreach (var nuspec in optsNuspec.Values) + { + await packer.PackAsync(nuspec, config, output); + } + + return 0; + }); + + return app.Execute(args); + } + } +} \ No newline at end of file diff --git a/tools/NuGetPackager/project.json b/tools/NuGetPackager/project.json new file mode 100644 index 0000000..1465613 --- /dev/null +++ b/tools/NuGetPackager/project.json @@ -0,0 +1,22 @@ +{ + "version": "1.0.0-*", + "buildOptions": { + "emitEntryPoint": true + }, + + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0" + }, + "Microsoft.DotNet.ProjectModel": "1.0.0-*", + "Microsoft.DotNet.Cli.Utils": "1.0.0-*", + "Microsoft.Extensions.CommandLineUtils": "1.1.0-*" + }, + + "frameworks": { + "netcoreapp1.0": { + "imports": "dnxcore50" + } + } +} \ No newline at end of file