create dotnet-restore.exe

This commit is contained in:
piotrp 2016-01-04 12:36:46 -08:00
parent 12edb9adb4
commit 08dd628172
17 changed files with 339 additions and 9 deletions

View file

@ -13,7 +13,7 @@ using NuGet.Versioning;
namespace Microsoft.DotNet.ProjectModel.Graph
{
internal static class LockFileReader
public static class LockFileReader
{
public static LockFile Read(string filePath)
{

View file

@ -62,6 +62,8 @@ namespace Microsoft.DotNet.ProjectModel
public IList<LibraryRange> Dependencies { get; set; }
public List<LibraryRange> Tools { get; set; }
public string EntryPoint { get; set; }
public string ProjectUrl { get; set; }

View file

@ -1,7 +1,6 @@
// 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;

View file

@ -69,6 +69,7 @@ namespace Microsoft.DotNet.ProjectModel
public static Project GetProject(string projectFile, ICollection<DiagnosticMessage> diagnostics, ProjectReaderSettings settings = null)
{
var name = Path.GetFileName(Path.GetDirectoryName(projectFile));
using (var stream = new FileStream(projectFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return new ProjectReader().ReadProject(stream, name, projectFile, diagnostics, settings);
@ -156,6 +157,7 @@ namespace Microsoft.DotNet.ProjectModel
project.EmbedInteropTypes = rawProject.ValueAsBoolean("embedInteropTypes", defaultValue: false);
project.Dependencies = new List<LibraryRange>();
project.Tools = new List<LibraryRange>();
// Project files
project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath);
@ -208,6 +210,13 @@ namespace Microsoft.DotNet.ProjectModel
"dependencies",
isGacOrFrameworkReference: false);
PopulateDependencies(
project.ProjectFilePath,
project.Tools,
rawProject,
"tools",
isGacOrFrameworkReference: false);
return project;
}

35
src/dotnet-restore/Dnx.cs Normal file
View file

@ -0,0 +1,35 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectModel.Graph;
namespace Microsoft.DotNet.Tools.Restore
{
public static class Dnx
{
public static int RunRestore(IEnumerable<string> args)
{
var result = RunDnx(new List<string> {"restore"}.Concat(args))
.ForwardStdErr()
.ForwardStdOut()
.Execute();
return result.ExitCode;
}
public static int RunPackageInstall(LibraryRange dependency, string projectPath, IEnumerable<string> args)
{
var result = RunDnx(new List<string> { "install", dependency.Name, dependency.VersionRange.OriginalString, projectPath }.Concat(args))
.ForwardStdErr()
.ForwardStdOut()
.Execute();
return result.ExitCode;
}
private static Command RunDnx(IEnumerable<string> dnxArgs)
{
return Command.Create("dotnet-dnx", dnxArgs);
}
}
}

View file

@ -0,0 +1,179 @@
// 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.Text;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Cli.Compiler.Common;
using Microsoft.Dnx.Runtime.Common.CommandLine;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
using NuGet.Frameworks;
namespace Microsoft.DotNet.Tools.Restore
{
public class Program
{
public static int Main(string[] args)
{
DebugHelper.HandleDebugSwitch(ref args);
var app = new CommandLineApplication(false)
{
Name = "dotnet restore",
FullName = ".NET project dependency restorer",
Description = "Restores dependencies listed in project.json"
};
app.OnExecute(() =>
{
try
{
var projectRestoreResult = Dnx.RunRestore(args);
var restoreTasks = GetRestoreTasks(args);
foreach (var restoreTask in restoreTasks)
{
var project = ProjectReader.GetProject(restoreTask.ProjectPath);
RestoreTools(project, restoreTask.Arguments);
}
return projectRestoreResult;
}
catch (InvalidOperationException e)
{
Console.WriteLine(e.Message);
return -1;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return -2;
}
});
return app.Execute(args);
}
private static IEnumerable<RestoreTask> GetRestoreTasks(IEnumerable<string> args)
{
var directory = Directory.GetCurrentDirectory();
if (args.Any())
{
var firstArg = args.First();
if (IsProjectFile(firstArg))
{
return new [] {new RestoreTask { ProjectPath = firstArg, Arguments = args.Skip(1)} };
}
if (Directory.Exists(firstArg))
{
directory = firstArg;
args = args.Skip(1);
}
}
return GetAllProjectFiles(directory)
.Select(p => new RestoreTask {ProjectPath = p, Arguments = args});
}
private static string[] GetAllProjectFiles(string directory)
{
return Directory.GetFiles(directory, Project.FileName, SearchOption.AllDirectories);
}
private static bool IsProjectFile(string firstArg)
{
return firstArg.EndsWith(Project.FileName) && File.Exists(firstArg);
}
private static void RestoreTools(Project project, IEnumerable<string> args)
{
foreach (var tooldep in project.Tools)
{
RestoreTool(tooldep, args);
}
}
private static void RestoreTool(LibraryRange tooldep, IEnumerable<string> args)
{
var tempPath = Path.Combine(Directory.GetCurrentDirectory(), Guid.NewGuid().ToString(), "bin");
RestoreToolToPath(tooldep, args, tempPath);
CreateDepsInPackageCache(tooldep, tempPath);
PersistLockFile(tooldep, tempPath);
Directory.Delete(tempPath, true);
}
private static void PersistLockFile(LibraryRange tooldep, string tempPath)
{
var targetPath = Path.Combine(Directory.GetCurrentDirectory(), "artifacts", "Tools", tooldep.Name);
if (Directory.Exists(targetPath)) Directory.Delete(targetPath, true);
Directory.CreateDirectory(targetPath);
File.Move(Path.Combine(tempPath, "project.lock.json"), Path.Combine(targetPath, "project.lock.json"));
}
private static void CreateDepsInPackageCache(LibraryRange toolLibrary, string projectPath)
{
var context = ProjectContext.Create(projectPath,
FrameworkConstants.CommonFrameworks.DnxCore50, new[] { RuntimeIdentifier.Current });
var toolDescription = context.LibraryManager.GetLibraries()
.Select(l => l as PackageDescription)
.Where(l => l != null)
.FirstOrDefault(l => l.Identity.Name == toolLibrary.Name);
var depsPath = Path.Combine(
toolDescription.Path,
Path.GetDirectoryName(toolDescription.Target.RuntimeAssemblies.First().Path),
toolDescription.Identity.Name + FileNameSuffixes.Deps);
context.MakeCompilationOutputRunnable(context.ProjectDirectory, Constants.DefaultConfiguration);
if (File.Exists(depsPath)) File.Delete(depsPath);
File.Move(Path.Combine(context.ProjectDirectory, "bin" + FileNameSuffixes.Deps), depsPath);
}
private static void RestoreToolToPath(LibraryRange tooldep, IEnumerable<string> args, string tempPath)
{
Directory.CreateDirectory(tempPath);
var projectPath = Path.Combine(tempPath, Project.FileName);
File.WriteAllText(projectPath, GenerateProjectJsonContents(new[] {"dnxcore50"}));
Dnx.RunPackageInstall(tooldep, projectPath, args);
Dnx.RunRestore(new [] { $"\"{projectPath}\"", "--runtime", $"{RuntimeIdentifier.Current}"}.Concat(args));
}
private static string GenerateProjectJsonContents(IEnumerable<string> frameworks = null)
{
var sb = new StringBuilder();
sb.AppendLine("{");
if (frameworks != null)
{
sb.AppendLine(" \"frameworks\":{");
foreach (var framework in frameworks)
{
sb.AppendLine($" \"{framework}\":{{}}");
}
sb.AppendLine(" }");
}
sb.AppendLine("}");
var pjContents = sb.ToString();
return pjContents;
}
}
}

View file

@ -0,0 +1,8 @@
// 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.Reflection;
using System.Resources;
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: NeutralResourcesLanguage("en-us")]

View file

@ -0,0 +1,11 @@
using System.Collections.Generic;
namespace Microsoft.DotNet.Tools.Restore
{
public struct RestoreTask
{
public string ProjectPath { get; set; }
public IEnumerable<string> Arguments { get; set; }
}
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>79620410-4ec7-4a38-a8c3-ee81243f818e</ProjectGuid>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View file

@ -0,0 +1,40 @@
{
"name": "dotnet-restore",
"description": "Restore packages specified in project.json (project file)",
"version": "1.0.0-*",
"repository": {
"type": "git",
"url": "git://github.com/dotnet/cli"
},
"compilationOptions": {
"warningsAsErrors": true,
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.ConsoleHost": "1.0.0-beta-23409",
"NETStandard.Library": "1.0.0-rc2-23608",
"System.Linq": "4.0.1-beta-23504",
"System.Collections": "4.0.11-beta-23504",
"Microsoft.DotNet.Cli.Utils": "1.0.0-*",
"Microsoft.DotNet.Compiler.Common": "1.0.0-*",
"Microsoft.Dnx.Runtime.CommandParsing.Sources": {
"version": "1.0.0-*",
"type": "build"
},
"Microsoft.Extensions.CommandLineUtils.Sources": {
"version": "1.0.0-*",
"type": "build"
},
"Microsoft.Extensions.Logging": "1.0.0-*",
"Newtonsoft.Json": "7.0.1"
},
"frameworks": {
"dnxcore50": {}
},
"scripts": {
"postcompile": [
"../../scripts/build/place-binary \"%compile:OutputDir%/%project:Name%.dll\"",
"../../scripts/build/place-binary \"%compile:OutputDir%/%project:Name%.pdb\""
]
}
}