2015-11-16 11:21:57 -08:00
|
|
|
|
// 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.
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2016-10-27 18:46:43 -07:00
|
|
|
|
using Microsoft.DotNet.Internal.ProjectModel.Files;
|
|
|
|
|
using Microsoft.DotNet.Internal.ProjectModel.Utilities;
|
2016-03-31 16:25:52 -07:00
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
using NuGet.Frameworks;
|
2016-09-23 15:30:53 -07:00
|
|
|
|
using NuGet.LibraryModel;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
using NuGet.Versioning;
|
|
|
|
|
|
2016-10-27 18:46:43 -07:00
|
|
|
|
namespace Microsoft.DotNet.Internal.ProjectModel
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-10-27 18:46:43 -07:00
|
|
|
|
internal class ProjectReader : IProjectReader
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-04-11 19:25:28 -07:00
|
|
|
|
public static bool TryGetProject(string path, out Project project, ProjectReaderSettings settings = null)
|
2015-10-17 22:42:50 -07:00
|
|
|
|
{
|
|
|
|
|
project = null;
|
|
|
|
|
|
|
|
|
|
string projectPath = null;
|
|
|
|
|
|
|
|
|
|
if (string.Equals(Path.GetFileName(path), Project.FileName, StringComparison.OrdinalIgnoreCase))
|
|
|
|
|
{
|
|
|
|
|
projectPath = path;
|
|
|
|
|
path = Path.GetDirectoryName(path);
|
|
|
|
|
}
|
|
|
|
|
else if (!HasProjectFile(path))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
projectPath = Path.Combine(path, Project.FileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Assume the directory name is the project name if none was specified
|
|
|
|
|
var projectName = PathUtility.GetDirectoryName(Path.GetFullPath(path));
|
|
|
|
|
projectPath = Path.GetFullPath(projectPath);
|
|
|
|
|
|
|
|
|
|
if (!File.Exists(projectPath))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using (var stream = File.OpenRead(projectPath))
|
|
|
|
|
{
|
|
|
|
|
var reader = new ProjectReader();
|
2016-04-11 19:25:28 -07:00
|
|
|
|
project = reader.ReadProject(stream, projectName, projectPath, settings);
|
2015-10-17 22:42:50 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw FileFormatException.Create(ex, projectPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 19:25:28 -07:00
|
|
|
|
public static Project GetProject(string projectPath, ProjectReaderSettings settings = null)
|
2016-08-22 21:29:14 -07:00
|
|
|
|
{
|
|
|
|
|
return new ProjectReader().ReadProject(projectPath, settings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Project ReadProject(string projectPath, ProjectReaderSettings settings)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-04-28 09:15:41 -05:00
|
|
|
|
projectPath = ProjectPathHelper.NormalizeProjectFilePath(projectPath);
|
2016-03-01 17:42:44 -08:00
|
|
|
|
|
|
|
|
|
var name = Path.GetFileName(Path.GetDirectoryName(projectPath));
|
2016-01-04 12:36:46 -08:00
|
|
|
|
|
2016-03-01 17:42:44 -08:00
|
|
|
|
using (var stream = new FileStream(projectPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-08-22 21:29:14 -07:00
|
|
|
|
return ReadProject(stream, name, projectPath, settings);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 19:25:28 -07:00
|
|
|
|
public Project ReadProject(Stream stream, string projectName, string projectPath, ProjectReaderSettings settings = null)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2015-12-09 00:47:57 -08:00
|
|
|
|
settings = settings ?? new ProjectReaderSettings();
|
2015-10-13 14:31:29 -07:00
|
|
|
|
var project = new Project();
|
|
|
|
|
|
2015-10-15 15:09:37 -07:00
|
|
|
|
var reader = new StreamReader(stream);
|
2016-04-22 15:01:56 -07:00
|
|
|
|
JObject rawProject;
|
|
|
|
|
using (var jsonReader = new JsonTextReader(reader))
|
|
|
|
|
{
|
|
|
|
|
rawProject = JObject.Load(jsonReader);
|
|
|
|
|
|
|
|
|
|
// Try to read another token to ensure we're at the end of the document.
|
|
|
|
|
// This will no-op if we are, and throw a JsonReaderException if there is additional content (which is what we want)
|
|
|
|
|
jsonReader.Read();
|
|
|
|
|
}
|
2016-03-31 16:25:52 -07:00
|
|
|
|
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (rawProject == null)
|
|
|
|
|
{
|
|
|
|
|
throw FileFormatException.Create(
|
|
|
|
|
"The JSON file can't be deserialized to a JSON object.",
|
|
|
|
|
projectPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Meta-data properties
|
2016-03-31 16:25:52 -07:00
|
|
|
|
project.Name = rawProject.Value<string>("name") ?? projectName;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
project.ProjectFilePath = Path.GetFullPath(projectPath);
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var version = rawProject.Value<string>("version");
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (version == null)
|
|
|
|
|
{
|
|
|
|
|
project.Version = new NuGetVersion("1.0.0");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2016-01-03 08:18:25 -08:00
|
|
|
|
var buildVersion = settings.VersionSuffix;
|
2015-10-15 15:09:37 -07:00
|
|
|
|
project.Version = SpecifySnapshot(version, buildVersion);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw FileFormatException.Create(ex, version, project.ProjectFilePath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-03 08:18:25 -08:00
|
|
|
|
var fileVersion = settings.AssemblyFileVersion;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (string.IsNullOrWhiteSpace(fileVersion))
|
|
|
|
|
{
|
|
|
|
|
project.AssemblyFileVersion = project.Version.Version;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var simpleVersion = project.Version.Version;
|
|
|
|
|
project.AssemblyFileVersion = new Version(simpleVersion.Major,
|
|
|
|
|
simpleVersion.Minor,
|
|
|
|
|
simpleVersion.Build,
|
|
|
|
|
int.Parse(fileVersion));
|
|
|
|
|
}
|
|
|
|
|
catch (FormatException ex)
|
|
|
|
|
{
|
|
|
|
|
throw new FormatException("The assembly file version is invalid: " + fileVersion, ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
project.Description = rawProject.Value<string>("description");
|
|
|
|
|
project.Copyright = rawProject.Value<string>("copyright");
|
|
|
|
|
project.Title = rawProject.Value<string>("title");
|
|
|
|
|
project.EntryPoint = rawProject.Value<string>("entryPoint");
|
|
|
|
|
project.TestRunner = rawProject.Value<string>("testRunner");
|
|
|
|
|
project.Authors =
|
|
|
|
|
rawProject.Value<JToken>("authors")?.Values<string>().ToArray() ?? EmptyArray<string>.Value;
|
|
|
|
|
project.Language = rawProject.Value<string>("language");
|
2015-10-17 22:42:50 -07:00
|
|
|
|
|
2015-10-17 08:05:35 -07:00
|
|
|
|
// REVIEW: Move this to the dependencies node?
|
2016-03-31 16:25:52 -07:00
|
|
|
|
project.EmbedInteropTypes = rawProject.Value<bool>("embedInteropTypes");
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
2016-09-23 15:30:53 -07:00
|
|
|
|
project.Dependencies = new List<ProjectLibraryDependency>();
|
2016-10-27 18:46:43 -07:00
|
|
|
|
|
2016-09-23 15:30:53 -07:00
|
|
|
|
project.Tools = new List<ProjectLibraryDependency>();
|
2016-10-27 18:46:43 -07:00
|
|
|
|
|
|
|
|
|
project.Runtimes = new List<string>();
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
|
|
|
|
// Project files
|
|
|
|
|
project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath);
|
2016-04-30 19:09:43 -07:00
|
|
|
|
AddProjectFilesCollectionDiagnostics(rawProject, project);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var commands = rawProject.Value<JToken>("commands") as JObject;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (commands != null)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
foreach (var command in commands)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var commandValue = command.Value.Type == JTokenType.String ? command.Value.Value<string>() : null;
|
|
|
|
|
if (commandValue != null)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
project.Commands[command.Key] = commandValue;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var scripts = rawProject.Value<JToken>("scripts") as JObject;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (scripts != null)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
foreach (var script in scripts)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var stringValue = script.Value.Type == JTokenType.String ? script.Value.Value<string>() : null;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (stringValue != null)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
project.Scripts[script.Key] = new string[] { stringValue };
|
2015-10-13 14:31:29 -07:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var arrayValue =
|
|
|
|
|
script.Value.Type == JTokenType.Array ? script.Value.Values<string>().ToArray() : null;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (arrayValue != null)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
project.Scripts[script.Key] = arrayValue;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw FileFormatException.Create(
|
|
|
|
|
string.Format("The value of a script in {0} can only be a string or an array of strings", Project.FileName),
|
2016-03-31 16:25:52 -07:00
|
|
|
|
script.Value,
|
2015-10-13 14:31:29 -07:00
|
|
|
|
project.ProjectFilePath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 19:25:28 -07:00
|
|
|
|
project.PackOptions = GetPackOptions(rawProject, project) ?? new PackOptions();
|
|
|
|
|
project.RuntimeOptions = GetRuntimeOptions(rawProject) ?? new RuntimeOptions();
|
|
|
|
|
project.PublishOptions = GetPublishInclude(rawProject, project);
|
|
|
|
|
|
|
|
|
|
BuildTargetFrameworksAndConfigurations(project, rawProject);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
|
|
|
|
PopulateDependencies(
|
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
project.Dependencies,
|
|
|
|
|
rawProject,
|
|
|
|
|
"dependencies",
|
|
|
|
|
isGacOrFrameworkReference: false);
|
|
|
|
|
|
2016-01-04 12:36:46 -08:00
|
|
|
|
PopulateDependencies(
|
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
project.Tools,
|
|
|
|
|
rawProject,
|
|
|
|
|
"tools",
|
|
|
|
|
isGacOrFrameworkReference: false);
|
2016-10-27 18:46:43 -07:00
|
|
|
|
|
|
|
|
|
PopulateRuntimes(project.Runtimes, rawProject);
|
|
|
|
|
|
2016-10-26 22:23:40 +00:00
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
JToken runtimeOptionsToken;
|
|
|
|
|
if (rawProject.TryGetValue("runtimeOptions", out runtimeOptionsToken))
|
|
|
|
|
{
|
|
|
|
|
var runtimeOptions = runtimeOptionsToken as JObject;
|
|
|
|
|
if (runtimeOptions == null)
|
|
|
|
|
{
|
|
|
|
|
throw FileFormatException.Create("The runtimeOptions must be an object", runtimeOptionsToken);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project.RawRuntimeOptions = runtimeOptions.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-13 14:31:29 -07:00
|
|
|
|
return project;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static NuGetVersion SpecifySnapshot(string version, string snapshotValue)
|
|
|
|
|
{
|
|
|
|
|
if (version.EndsWith("-*"))
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(snapshotValue))
|
|
|
|
|
{
|
|
|
|
|
version = version.Substring(0, version.Length - 2);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
version = version.Substring(0, version.Length - 1) + snapshotValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-15 15:09:37 -07:00
|
|
|
|
return new NuGetVersion(version);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void PopulateDependencies(
|
|
|
|
|
string projectPath,
|
2016-09-23 15:30:53 -07:00
|
|
|
|
IList<ProjectLibraryDependency> results,
|
2016-03-31 16:25:52 -07:00
|
|
|
|
JObject settings,
|
2015-10-13 14:31:29 -07:00
|
|
|
|
string propertyName,
|
|
|
|
|
bool isGacOrFrameworkReference)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var dependencies = settings.Value<JToken>(propertyName) as JObject;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (dependencies != null)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
foreach (var dependency in dependencies)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
if (string.IsNullOrEmpty(dependency.Key))
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
throw FileFormatException.Create(
|
|
|
|
|
"Unable to resolve dependency ''.",
|
2016-03-31 16:25:52 -07:00
|
|
|
|
dependency.Key,
|
2015-10-13 14:31:29 -07:00
|
|
|
|
projectPath);
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var dependencyValue = dependency.Value;
|
2015-10-15 15:09:37 -07:00
|
|
|
|
var dependencyTypeValue = LibraryDependencyType.Default;
|
2016-09-26 21:40:11 -07:00
|
|
|
|
|
|
|
|
|
var dependencyIncludeFlagsValue = LibraryIncludeFlags.All;
|
|
|
|
|
var dependencyExcludeFlagsValue = LibraryIncludeFlags.None;
|
|
|
|
|
var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent;
|
|
|
|
|
|
2016-09-26 13:47:55 -07:00
|
|
|
|
var target = isGacOrFrameworkReference ? LibraryDependencyTarget.Reference : LibraryDependencyTarget.All;
|
2016-03-31 16:25:52 -07:00
|
|
|
|
string dependencyVersionAsString = null;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
if (dependencyValue.Type == JTokenType.Object)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
// "dependencies" : { "Name" : { "version": "1.0", "type": "build", "target": "project" } }
|
2016-03-31 16:25:52 -07:00
|
|
|
|
dependencyVersionAsString = dependencyValue.Value<string>("version");
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var type = dependencyValue.Value<string>("type");
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (type != null)
|
|
|
|
|
{
|
2016-09-23 15:30:53 -07:00
|
|
|
|
dependencyTypeValue = LibraryDependencyType.Parse(new [] { type });
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read the target if specified
|
|
|
|
|
if (!isGacOrFrameworkReference)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var targetStr = dependencyValue.Value<string>("target");
|
2016-09-23 15:30:53 -07:00
|
|
|
|
target = LibraryDependencyTargetUtils.Parse(targetStr);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
2016-09-26 21:40:11 -07:00
|
|
|
|
|
|
|
|
|
IEnumerable<string> strings;
|
|
|
|
|
if (TryGetStringEnumerable(dependencyValue["include"], out strings))
|
|
|
|
|
{
|
|
|
|
|
dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TryGetStringEnumerable(dependencyValue["exclude"], out strings))
|
|
|
|
|
{
|
|
|
|
|
dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TryGetStringEnumerable(dependencyValue["suppressParent"], out strings))
|
|
|
|
|
{
|
|
|
|
|
// This overrides any settings that came from the type property.
|
|
|
|
|
suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
|
|
|
|
|
}
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
2016-03-31 16:25:52 -07:00
|
|
|
|
else if (dependencyValue.Type == JTokenType.String)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
// "dependencies" : { "Name" : "1.0" }
|
2016-03-31 16:25:52 -07:00
|
|
|
|
dependencyVersionAsString = dependencyValue.Value<string>();
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw FileFormatException.Create(
|
2016-03-31 16:25:52 -07:00
|
|
|
|
string.Format(
|
|
|
|
|
"Invalid dependency version: {0}. The format is not recognizable.",
|
|
|
|
|
dependency.Key),
|
2015-10-13 14:31:29 -07:00
|
|
|
|
dependencyValue,
|
|
|
|
|
projectPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VersionRange dependencyVersionRange = null;
|
2016-03-31 16:25:52 -07:00
|
|
|
|
if (!string.IsNullOrEmpty(dependencyVersionAsString))
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
dependencyVersionRange = VersionRange.Parse(dependencyVersionAsString);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
throw FileFormatException.Create(ex, dependencyValue, projectPath);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-26 21:40:11 -07:00
|
|
|
|
// the dependency flags are: Include flags - Exclude flags
|
|
|
|
|
var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue;
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var lineInfo = (IJsonLineInfo)dependencyValue;
|
2016-09-23 15:30:53 -07:00
|
|
|
|
results.Add(new ProjectLibraryDependency
|
|
|
|
|
{
|
|
|
|
|
LibraryRange = new LibraryRange(
|
|
|
|
|
dependency.Key,
|
|
|
|
|
dependencyVersionRange,
|
|
|
|
|
target),
|
2016-09-26 13:47:55 -07:00
|
|
|
|
Type = dependencyTypeValue,
|
2016-09-26 21:40:11 -07:00
|
|
|
|
IncludeType = includeFlags,
|
|
|
|
|
SuppressParent = suppressParentFlagsValue,
|
2016-09-26 13:47:55 -07:00
|
|
|
|
SourceFilePath = projectPath,
|
|
|
|
|
SourceLine = lineInfo.LineNumber,
|
|
|
|
|
SourceColumn = lineInfo.LinePosition
|
2016-09-23 15:30:53 -07:00
|
|
|
|
});
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-27 18:46:43 -07:00
|
|
|
|
|
|
|
|
|
private static void PopulateRuntimes(IList<string> results, JObject settings)
|
|
|
|
|
{
|
|
|
|
|
var runtimes = settings.Value<JToken>("runtimes") as JObject;
|
|
|
|
|
if (runtimes != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var runtime in runtimes)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(runtime.Key))
|
|
|
|
|
{
|
|
|
|
|
results.Add(runtime.Key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-26 22:23:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 19:25:28 -07:00
|
|
|
|
private void BuildTargetFrameworksAndConfigurations(Project project, JObject projectJsonObject)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
// Get the shared compilationOptions
|
2016-03-31 16:25:52 -07:00
|
|
|
|
project._defaultCompilerOptions =
|
2016-04-11 19:25:28 -07:00
|
|
|
|
GetCompilationOptions(projectJsonObject, project) ?? new CommonCompilerOptions { CompilerName = "csc" };
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
|
|
|
|
project._defaultTargetFrameworkConfiguration = new TargetFrameworkInformation
|
|
|
|
|
{
|
2016-09-23 15:30:53 -07:00
|
|
|
|
Dependencies = new List<ProjectLibraryDependency>()
|
2015-10-13 14:31:29 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Add default configurations
|
2015-10-20 13:27:56 -07:00
|
|
|
|
project._compilerOptionsByConfiguration["Debug"] = new CommonCompilerOptions
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
Defines = new[] { "DEBUG", "TRACE" },
|
|
|
|
|
Optimize = false
|
|
|
|
|
};
|
|
|
|
|
|
2015-10-20 13:27:56 -07:00
|
|
|
|
project._compilerOptionsByConfiguration["Release"] = new CommonCompilerOptions
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
Defines = new[] { "RELEASE", "TRACE" },
|
|
|
|
|
Optimize = true
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// The configuration node has things like debug/release compiler settings
|
|
|
|
|
/*
|
|
|
|
|
{
|
|
|
|
|
"configurations": {
|
|
|
|
|
"Debug": {
|
|
|
|
|
},
|
|
|
|
|
"Release": {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var configurationsSection = projectJsonObject.Value<JToken>("configurations") as JObject;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (configurationsSection != null)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
foreach (var configKey in configurationsSection)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var compilerOptions = GetCompilationOptions(configKey.Value as JObject, project);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
|
|
|
|
// Only use this as a configuration if it's not a target framework
|
2016-03-31 16:25:52 -07:00
|
|
|
|
project._compilerOptionsByConfiguration[configKey.Key] = compilerOptions;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The frameworks node is where target frameworks go
|
|
|
|
|
/*
|
|
|
|
|
{
|
|
|
|
|
"frameworks": {
|
|
|
|
|
"net45": {
|
|
|
|
|
},
|
|
|
|
|
"dnxcore50": {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var frameworks = projectJsonObject.Value<JToken>("frameworks") as JObject;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (frameworks != null)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
foreach (var framework in frameworks)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var frameworkToken = framework.Value as JObject;
|
|
|
|
|
var success = BuildTargetFrameworkNode(project, framework.Key, frameworkToken);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (!success)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var lineInfo = (IJsonLineInfo)framework.Value;
|
2016-04-30 19:09:43 -07:00
|
|
|
|
project.Diagnostics.Add(
|
2015-10-13 14:31:29 -07:00
|
|
|
|
new DiagnosticMessage(
|
|
|
|
|
ErrorCodes.NU1008,
|
2016-03-31 16:25:52 -07:00
|
|
|
|
$"\"{framework.Key}\" is an unsupported framework.",
|
2015-10-13 14:31:29 -07:00
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
DiagnosticMessageSeverity.Error,
|
2016-03-31 16:25:52 -07:00
|
|
|
|
lineInfo.LineNumber,
|
|
|
|
|
lineInfo.LinePosition));
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
throw FileFormatException.Create(ex, framework.Value, project.ProjectFilePath);
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Parse a Json object which represents project configuration for a specified framework
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="frameworkKey">The name of the framework</param>
|
|
|
|
|
/// <param name="frameworkValue">The Json object represent the settings</param>
|
|
|
|
|
/// <returns>Returns true if it successes.</returns>
|
2016-03-31 16:25:52 -07:00
|
|
|
|
private bool BuildTargetFrameworkNode(Project project, string frameworkKey, JObject frameworkValue)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
|
|
|
|
// If no compilation options are provided then figure them out from the node
|
2016-01-18 15:14:19 -08:00
|
|
|
|
var compilerOptions = GetCompilationOptions(frameworkValue, project) ??
|
2015-10-20 13:27:56 -07:00
|
|
|
|
new CommonCompilerOptions();
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
|
|
|
|
var frameworkName = NuGetFramework.Parse(frameworkKey);
|
|
|
|
|
|
|
|
|
|
// If it's not unsupported then keep it
|
|
|
|
|
if (frameworkName.IsUnsupported)
|
|
|
|
|
{
|
|
|
|
|
// REVIEW: Should we skip unsupported target frameworks
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add the target framework specific define
|
|
|
|
|
var defines = new HashSet<string>(compilerOptions.Defines ?? Enumerable.Empty<string>());
|
|
|
|
|
|
|
|
|
|
compilerOptions.Defines = defines;
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var lineInfo = (IJsonLineInfo)frameworkValue;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
var targetFrameworkInformation = new TargetFrameworkInformation
|
|
|
|
|
{
|
|
|
|
|
FrameworkName = frameworkName,
|
2016-09-23 15:30:53 -07:00
|
|
|
|
Dependencies = new List<ProjectLibraryDependency>(),
|
2015-10-28 02:21:00 -07:00
|
|
|
|
CompilerOptions = compilerOptions,
|
2016-03-31 16:25:52 -07:00
|
|
|
|
Line = lineInfo.LineNumber,
|
2016-09-26 21:40:11 -07:00
|
|
|
|
Column = lineInfo.LinePosition,
|
|
|
|
|
Imports = GetImports(frameworkValue)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
};
|
|
|
|
|
|
2016-09-23 15:30:53 -07:00
|
|
|
|
var frameworkDependencies = new List<ProjectLibraryDependency>();
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
|
|
|
|
PopulateDependencies(
|
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
frameworkDependencies,
|
|
|
|
|
frameworkValue,
|
|
|
|
|
"dependencies",
|
|
|
|
|
isGacOrFrameworkReference: false);
|
|
|
|
|
|
2016-09-23 15:30:53 -07:00
|
|
|
|
var frameworkAssemblies = new List<ProjectLibraryDependency>();
|
2015-10-13 14:31:29 -07:00
|
|
|
|
PopulateDependencies(
|
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
frameworkAssemblies,
|
|
|
|
|
frameworkValue,
|
|
|
|
|
"frameworkAssemblies",
|
|
|
|
|
isGacOrFrameworkReference: true);
|
|
|
|
|
|
|
|
|
|
frameworkDependencies.AddRange(frameworkAssemblies);
|
|
|
|
|
targetFrameworkInformation.Dependencies = frameworkDependencies;
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
targetFrameworkInformation.WrappedProject = frameworkValue.Value<string>("wrappedProject");
|
2015-10-13 14:31:29 -07:00
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var binNode = frameworkValue.Value<JToken>("bin") as JObject;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (binNode != null)
|
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
targetFrameworkInformation.AssemblyPath = binNode.Value<string>("assembly");
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project._targetFrameworks[frameworkName] = targetFrameworkInformation;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-26 21:40:11 -07:00
|
|
|
|
private IEnumerable<string> GetImports(JObject frameworkValue)
|
|
|
|
|
{
|
|
|
|
|
var prop = frameworkValue.Property("imports");
|
|
|
|
|
if (prop == null)
|
|
|
|
|
{
|
|
|
|
|
return Enumerable.Empty<string>();
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-11 15:22:18 -07:00
|
|
|
|
if (prop.Value.Type == JTokenType.Array)
|
2016-09-26 21:40:11 -07:00
|
|
|
|
{
|
2016-10-11 15:22:18 -07:00
|
|
|
|
return (prop.Value as JArray).Select(i => i.Value<string>());
|
2016-09-26 21:40:11 -07:00
|
|
|
|
}
|
2016-10-11 15:22:18 -07:00
|
|
|
|
else if (prop.Value.Type == JTokenType.String)
|
2016-09-26 21:40:11 -07:00
|
|
|
|
{
|
2016-10-11 15:22:18 -07:00
|
|
|
|
return new [] { prop.Value.ToString() };
|
2016-09-26 21:40:11 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
private static CommonCompilerOptions GetCompilationOptions(JObject rawObject, Project project)
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-04-11 19:25:28 -07:00
|
|
|
|
var compilerName = rawObject.Value<string>("compilerName");
|
|
|
|
|
if (compilerName != null)
|
|
|
|
|
{
|
|
|
|
|
var lineInfo = rawObject.Value<IJsonLineInfo>("compilerName");
|
2016-04-30 19:09:43 -07:00
|
|
|
|
project.Diagnostics.Add(
|
2016-04-11 19:25:28 -07:00
|
|
|
|
new DiagnosticMessage(
|
|
|
|
|
ErrorCodes.DOTNET1016,
|
|
|
|
|
$"The 'compilerName' option in the root is deprecated. Use it in 'buildOptions' instead.",
|
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
DiagnosticMessageSeverity.Warning,
|
|
|
|
|
lineInfo.LineNumber,
|
|
|
|
|
lineInfo.LinePosition));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rawOptions = rawObject.Value<JToken>("buildOptions") as JObject;
|
2015-10-13 14:31:29 -07:00
|
|
|
|
if (rawOptions == null)
|
|
|
|
|
{
|
2016-04-11 19:25:28 -07:00
|
|
|
|
rawOptions = rawObject.Value<JToken>("compilationOptions") as JObject;
|
|
|
|
|
if (rawOptions == null)
|
|
|
|
|
{
|
|
|
|
|
return new CommonCompilerOptions
|
|
|
|
|
{
|
|
|
|
|
CompilerName = compilerName ?? "csc"
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var lineInfo = (IJsonLineInfo)rawOptions;
|
|
|
|
|
|
2016-04-30 19:09:43 -07:00
|
|
|
|
project.Diagnostics.Add(
|
2016-04-11 19:25:28 -07:00
|
|
|
|
new DiagnosticMessage(
|
|
|
|
|
ErrorCodes.DOTNET1015,
|
|
|
|
|
$"The 'compilationOptions' option is deprecated. Use 'buildOptions' instead.",
|
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
DiagnosticMessageSeverity.Warning,
|
|
|
|
|
lineInfo.LineNumber,
|
|
|
|
|
lineInfo.LinePosition));
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
var analyzerOptionsJson = rawOptions.Value<JToken>("analyzerOptions") as JObject;
|
2016-01-18 15:14:19 -08:00
|
|
|
|
if (analyzerOptionsJson != null)
|
|
|
|
|
{
|
|
|
|
|
var analyzerOptions = new AnalyzerOptions();
|
|
|
|
|
|
2016-03-31 16:25:52 -07:00
|
|
|
|
foreach (var analyzerOption in analyzerOptionsJson)
|
2016-01-18 15:14:19 -08:00
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
switch (analyzerOption.Key)
|
2016-01-18 15:14:19 -08:00
|
|
|
|
{
|
|
|
|
|
case "languageId":
|
2016-03-31 16:25:52 -07:00
|
|
|
|
if (analyzerOption.Value.Type != JTokenType.String)
|
2016-01-18 15:14:19 -08:00
|
|
|
|
{
|
|
|
|
|
throw FileFormatException.Create(
|
|
|
|
|
"The analyzer languageId must be a string",
|
2016-03-31 16:25:52 -07:00
|
|
|
|
analyzerOption.Value.ToString(),
|
2016-01-18 15:14:19 -08:00
|
|
|
|
project.ProjectFilePath);
|
|
|
|
|
}
|
2016-05-11 23:26:54 +02:00
|
|
|
|
analyzerOptions = new AnalyzerOptions(analyzerOption.Value.ToString());
|
2016-01-18 15:14:19 -08:00
|
|
|
|
break;
|
|
|
|
|
|
2016-03-01 17:42:44 -08:00
|
|
|
|
default:
|
2016-01-18 15:14:19 -08:00
|
|
|
|
throw FileFormatException.Create(
|
2016-03-31 16:25:52 -07:00
|
|
|
|
$"Unrecognized analyzerOption key: {analyzerOption.Key}",
|
2016-01-18 15:14:19 -08:00
|
|
|
|
project.ProjectFilePath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project.AnalyzerOptions = analyzerOptions;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-20 13:27:56 -07:00
|
|
|
|
return new CommonCompilerOptions
|
2015-10-13 14:31:29 -07:00
|
|
|
|
{
|
2016-03-31 16:25:52 -07:00
|
|
|
|
Defines = rawOptions.Value<JToken>("define")?.Values<string>().ToArray(),
|
|
|
|
|
SuppressWarnings = rawOptions.Value<JToken>("nowarn")?.Values<string>().ToArray(),
|
|
|
|
|
AdditionalArguments = rawOptions.Value<JToken>("additionalArguments")?.Values<string>().ToArray(),
|
|
|
|
|
LanguageVersion = rawOptions.Value<string>("languageVersion"),
|
|
|
|
|
AllowUnsafe = rawOptions.Value<bool?>("allowUnsafe"),
|
|
|
|
|
Platform = rawOptions.Value<string>("platform"),
|
|
|
|
|
WarningsAsErrors = rawOptions.Value<bool?>("warningsAsErrors"),
|
|
|
|
|
Optimize = rawOptions.Value<bool?>("optimize"),
|
|
|
|
|
KeyFile = rawOptions.Value<string>("keyFile"),
|
|
|
|
|
DelaySign = rawOptions.Value<bool?>("delaySign"),
|
|
|
|
|
PublicSign = rawOptions.Value<bool?>("publicSign"),
|
|
|
|
|
DebugType = rawOptions.Value<string>("debugType"),
|
|
|
|
|
EmitEntryPoint = rawOptions.Value<bool?>("emitEntryPoint"),
|
|
|
|
|
GenerateXmlDocumentation = rawOptions.Value<bool?>("xmlDoc"),
|
|
|
|
|
PreserveCompilationContext = rawOptions.Value<bool?>("preserveCompilationContext"),
|
2016-04-11 19:25:28 -07:00
|
|
|
|
OutputName = rawOptions.Value<string>("outputName"),
|
|
|
|
|
CompilerName = rawOptions.Value<string>("compilerName") ?? compilerName ?? "csc",
|
|
|
|
|
CompileInclude = GetIncludeContext(
|
|
|
|
|
project,
|
|
|
|
|
rawOptions,
|
|
|
|
|
"compile",
|
2017-01-12 11:22:41 -08:00
|
|
|
|
defaultBuiltInInclude: ProjectFilesCollection.SdkInjectedDefaultCompileBuiltInPatterns,
|
2016-04-11 19:25:28 -07:00
|
|
|
|
defaultBuiltInExclude: ProjectFilesCollection.DefaultBuiltInExcludePatterns),
|
|
|
|
|
EmbedInclude = GetIncludeContext(
|
|
|
|
|
project,
|
|
|
|
|
rawOptions,
|
|
|
|
|
"embed",
|
2017-01-12 11:22:41 -08:00
|
|
|
|
defaultBuiltInInclude: null,
|
2016-04-11 19:25:28 -07:00
|
|
|
|
defaultBuiltInExclude: ProjectFilesCollection.DefaultBuiltInExcludePatterns),
|
|
|
|
|
CopyToOutputInclude = GetIncludeContext(
|
|
|
|
|
project,
|
|
|
|
|
rawOptions,
|
|
|
|
|
"copyToOutput",
|
|
|
|
|
defaultBuiltInInclude: null,
|
2017-01-12 11:22:41 -08:00
|
|
|
|
defaultBuiltInExclude: null)
|
2016-04-11 19:25:28 -07:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IncludeContext GetIncludeContext(
|
|
|
|
|
Project project,
|
|
|
|
|
JObject rawOptions,
|
|
|
|
|
string option,
|
|
|
|
|
string[] defaultBuiltInInclude,
|
|
|
|
|
string[] defaultBuiltInExclude)
|
|
|
|
|
{
|
|
|
|
|
var contextOption = rawOptions.Value<JToken>(option);
|
|
|
|
|
if (contextOption != null)
|
|
|
|
|
{
|
|
|
|
|
return new IncludeContext(
|
|
|
|
|
project.ProjectDirectory,
|
|
|
|
|
option,
|
|
|
|
|
rawOptions,
|
|
|
|
|
defaultBuiltInInclude,
|
|
|
|
|
defaultBuiltInExclude);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static PackOptions GetPackOptions(JObject rawProject, Project project)
|
|
|
|
|
{
|
|
|
|
|
var rawPackOptions = rawProject.Value<JToken>("packOptions") as JObject;
|
|
|
|
|
|
|
|
|
|
// Files to be packed along with the project
|
|
|
|
|
IncludeContext packInclude = null;
|
|
|
|
|
if (rawPackOptions != null && rawPackOptions.Value<JToken>("files") != null)
|
|
|
|
|
{
|
|
|
|
|
packInclude = new IncludeContext(
|
|
|
|
|
project.ProjectDirectory,
|
|
|
|
|
"files",
|
|
|
|
|
rawPackOptions,
|
|
|
|
|
defaultBuiltInInclude: null,
|
|
|
|
|
defaultBuiltInExclude: ProjectFilesCollection.DefaultBuiltInExcludePatterns);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var repository = GetPackOptionsValue<JToken>("repository", rawProject, rawPackOptions, project) as JObject;
|
|
|
|
|
|
|
|
|
|
return new PackOptions
|
|
|
|
|
{
|
|
|
|
|
ProjectUrl = GetPackOptionsValue<string>("projectUrl", rawProject, rawPackOptions, project),
|
|
|
|
|
LicenseUrl = GetPackOptionsValue<string>("licenseUrl", rawProject, rawPackOptions, project),
|
|
|
|
|
IconUrl = GetPackOptionsValue<string>("iconUrl", rawProject, rawPackOptions, project),
|
|
|
|
|
Owners = GetPackOptionsValue<JToken>("owners", rawProject, rawPackOptions, project)?.Values<string>().ToArray() ?? EmptyArray<string>.Value,
|
|
|
|
|
Tags = GetPackOptionsValue<JToken>("tags", rawProject, rawPackOptions, project)?.Values<string>().ToArray() ?? EmptyArray<string>.Value,
|
|
|
|
|
ReleaseNotes = GetPackOptionsValue<string>("releaseNotes", rawProject, rawPackOptions, project),
|
|
|
|
|
RequireLicenseAcceptance = GetPackOptionsValue<bool>("requireLicenseAcceptance", rawProject, rawPackOptions, project),
|
|
|
|
|
Summary = GetPackOptionsValue<string>("summary", rawProject, rawPackOptions, project),
|
|
|
|
|
RepositoryType = repository?.Value<string>("type"),
|
|
|
|
|
RepositoryUrl = repository?.Value<string>("url"),
|
|
|
|
|
PackInclude = packInclude
|
2015-10-13 14:31:29 -07:00
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 19:25:28 -07:00
|
|
|
|
private static T GetPackOptionsValue<T>(
|
|
|
|
|
string option,
|
|
|
|
|
JObject rawProject,
|
|
|
|
|
JObject rawPackOptions,
|
|
|
|
|
Project project)
|
|
|
|
|
{
|
|
|
|
|
var rootValue = rawProject.Value<T>(option);
|
|
|
|
|
if (rawProject.GetValue(option) != null)
|
|
|
|
|
{
|
|
|
|
|
var lineInfo = rawProject.Value<IJsonLineInfo>(option);
|
2016-04-30 19:09:43 -07:00
|
|
|
|
project.Diagnostics.Add(
|
2016-04-11 19:25:28 -07:00
|
|
|
|
new DiagnosticMessage(
|
|
|
|
|
ErrorCodes.DOTNET1016,
|
|
|
|
|
$"The '{option}' option in the root is deprecated. Use it in 'packOptions' instead.",
|
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
DiagnosticMessageSeverity.Warning,
|
|
|
|
|
lineInfo.LineNumber,
|
|
|
|
|
lineInfo.LinePosition));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rawPackOptions != null)
|
|
|
|
|
{
|
|
|
|
|
var packOptionValue = rawPackOptions.Value<T>(option);
|
|
|
|
|
if (packOptionValue != null)
|
|
|
|
|
{
|
|
|
|
|
return packOptionValue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rootValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static RuntimeOptions GetRuntimeOptions(JObject rawProject)
|
|
|
|
|
{
|
|
|
|
|
var rawRuntimeOptions = rawProject.Value<JToken>("runtimeOptions") as JObject;
|
|
|
|
|
if (rawRuntimeOptions == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new RuntimeOptions
|
|
|
|
|
{
|
|
|
|
|
// Value<T>(null) will return default(T) which is false in this case.
|
|
|
|
|
GcServer = rawRuntimeOptions.Value<bool>("gcServer"),
|
|
|
|
|
GcConcurrent = rawRuntimeOptions.Value<bool>("gcConcurrent")
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static IncludeContext GetPublishInclude(JObject rawProject, Project project)
|
|
|
|
|
{
|
|
|
|
|
var rawPublishOptions = rawProject.Value<JToken>("publishOptions");
|
|
|
|
|
if (rawPublishOptions != null)
|
|
|
|
|
{
|
|
|
|
|
return new IncludeContext(
|
|
|
|
|
project.ProjectDirectory,
|
|
|
|
|
"publishOptions",
|
|
|
|
|
rawProject,
|
|
|
|
|
defaultBuiltInInclude: null,
|
2017-01-12 11:22:41 -08:00
|
|
|
|
defaultBuiltInExclude: null);
|
2016-04-11 19:25:28 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-17 22:42:50 -07:00
|
|
|
|
private static bool HasProjectFile(string path)
|
|
|
|
|
{
|
|
|
|
|
string projectPath = Path.Combine(path, Project.FileName);
|
|
|
|
|
|
|
|
|
|
return File.Exists(projectPath);
|
|
|
|
|
}
|
2016-04-30 19:09:43 -07:00
|
|
|
|
|
|
|
|
|
private static void AddProjectFilesCollectionDiagnostics(JObject rawProject, Project project)
|
|
|
|
|
{
|
|
|
|
|
var compileWarning = "'compile' in 'buildOptions'";
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "compile", compileWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "compileExclude", compileWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "compileFiles", compileWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "compileBuiltIn", compileWarning);
|
|
|
|
|
|
|
|
|
|
var resourceWarning = "'embed' in 'buildOptions'";
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "resource", resourceWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "resourceExclude", resourceWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "resourceFiles", resourceWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "resourceBuiltIn", resourceWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "namedResource", resourceWarning);
|
|
|
|
|
|
|
|
|
|
var contentWarning = "'publishOptions' to publish or 'copyToOutput' in 'buildOptions' to copy to build output";
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "content", contentWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "contentExclude", contentWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "contentFiles", contentWarning);
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "contentBuiltIn", contentWarning);
|
|
|
|
|
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "packInclude", "'files' in 'packOptions'");
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "publishExclude", "'publishOptions'");
|
|
|
|
|
AddDiagnosticMesage(rawProject, project, "exclude", "'exclude' within 'compile' or 'embed'");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void AddDiagnosticMesage(
|
|
|
|
|
JObject rawProject,
|
|
|
|
|
Project project,
|
|
|
|
|
string option,
|
|
|
|
|
string message)
|
|
|
|
|
{
|
|
|
|
|
var lineInfo = rawProject.Value<IJsonLineInfo>(option);
|
|
|
|
|
if (lineInfo == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project.Diagnostics.Add(
|
|
|
|
|
new DiagnosticMessage(
|
|
|
|
|
ErrorCodes.DOTNET1015,
|
|
|
|
|
$"The '{option}' option is deprecated. Use {message} instead.",
|
|
|
|
|
project.ProjectFilePath,
|
|
|
|
|
DiagnosticMessageSeverity.Warning,
|
|
|
|
|
lineInfo.LineNumber,
|
|
|
|
|
lineInfo.LinePosition));
|
|
|
|
|
}
|
2016-09-26 21:40:11 -07:00
|
|
|
|
|
|
|
|
|
private static bool TryGetStringEnumerable(JToken token, out IEnumerable<string> result)
|
|
|
|
|
{
|
|
|
|
|
IEnumerable<string> values;
|
|
|
|
|
if (token == null)
|
|
|
|
|
{
|
|
|
|
|
result = null;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else if (token.Type == JTokenType.String)
|
|
|
|
|
{
|
|
|
|
|
values = new[]
|
|
|
|
|
{
|
|
|
|
|
token.Value<string>()
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2016-10-10 16:19:57 -07:00
|
|
|
|
values = token.Values<string>();
|
2016-09-26 21:40:11 -07:00
|
|
|
|
}
|
|
|
|
|
result = values
|
|
|
|
|
.SelectMany(value => value.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2015-10-13 14:31:29 -07:00
|
|
|
|
}
|
|
|
|
|
}
|