Example #1
0
        public Project ReadProject(Stream stream, string projectName, string projectPath, ProjectReaderSettings settings = null)
        {
            settings = settings ?? new ProjectReaderSettings();
            var project = new Project();

            var     reader = new StreamReader(stream);
            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();
            }

            if (rawProject == null)
            {
                throw FileFormatException.Create(
                          "The JSON file can't be deserialized to a JSON object.",
                          projectPath);
            }

            // Meta-data properties
            project.Name            = rawProject.Value <string>("name") ?? projectName;
            project.ProjectFilePath = Path.GetFullPath(projectPath);

            var version = rawProject.Value <string>("version");

            if (version == null)
            {
                project.Version = new NuGetVersion("1.0.0");
            }
            else
            {
                try
                {
                    var buildVersion = settings.VersionSuffix;
                    project.Version = SpecifySnapshot(version, buildVersion);
                }
                catch (Exception ex)
                {
                    throw FileFormatException.Create(ex, version, project.ProjectFilePath);
                }
            }

            var fileVersion = settings.AssemblyFileVersion;

            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);
                }
            }

            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");

            // REVIEW: Move this to the dependencies node?
            project.EmbedInteropTypes = rawProject.Value <bool>("embedInteropTypes");

            project.Dependencies = new List <ProjectLibraryDependency>();

            project.Tools = new List <ProjectLibraryDependency>();

            project.Runtimes = new List <string>();

            // Project files
            project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath);
            AddProjectFilesCollectionDiagnostics(rawProject, project);

            var commands = rawProject.Value <JToken>("commands") as JObject;

            if (commands != null)
            {
                foreach (var command in commands)
                {
                    var commandValue = command.Value.Type == JTokenType.String ? command.Value.Value <string>() : null;
                    if (commandValue != null)
                    {
                        project.Commands[command.Key] = commandValue;
                    }
                }
            }

            var scripts = rawProject.Value <JToken>("scripts") as JObject;

            if (scripts != null)
            {
                foreach (var script in scripts)
                {
                    var stringValue = script.Value.Type == JTokenType.String ? script.Value.Value <string>() : null;
                    if (stringValue != null)
                    {
                        project.Scripts[script.Key] = new string[] { stringValue };
                        continue;
                    }

                    var arrayValue =
                        script.Value.Type == JTokenType.Array ? script.Value.Values <string>().ToArray() : null;
                    if (arrayValue != null)
                    {
                        project.Scripts[script.Key] = arrayValue;
                        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),
                              script.Value,
                              project.ProjectFilePath);
                }
            }

            project.PackOptions    = GetPackOptions(rawProject, project) ?? new PackOptions();
            project.RuntimeOptions = GetRuntimeOptions(rawProject) ?? new RuntimeOptions();
            project.PublishOptions = GetPublishInclude(rawProject, project);

            BuildTargetFrameworksAndConfigurations(project, rawProject);

            PopulateDependencies(
                project.ProjectFilePath,
                project.Dependencies,
                rawProject,
                "dependencies",
                isGacOrFrameworkReference: false);

            PopulateDependencies(
                project.ProjectFilePath,
                project.Tools,
                rawProject,
                "tools",
                isGacOrFrameworkReference: false);

            PopulateRuntimes(project.Runtimes, rawProject);


            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();
            }

            return(project);
        }
Example #2
0
        private void BuildTargetFrameworksAndConfigurations(Project project, JObject projectJsonObject)
        {
            // Get the shared compilationOptions
            project._defaultCompilerOptions =
                GetCompilationOptions(projectJsonObject, project) ?? new CommonCompilerOptions {
                CompilerName = "csc"
            };

            project._defaultTargetFrameworkConfiguration = new TargetFrameworkInformation
            {
                Dependencies = new List <ProjectLibraryDependency>()
            };

            // Add default configurations
            project._compilerOptionsByConfiguration["Debug"] = new CommonCompilerOptions
            {
                Defines  = new[] { "DEBUG", "TRACE" },
                Optimize = false
            };

            project._compilerOptionsByConfiguration["Release"] = new CommonCompilerOptions
            {
                Defines  = new[] { "RELEASE", "TRACE" },
                Optimize = true
            };

            // The configuration node has things like debug/release compiler settings

            /*
             *  {
             *      "configurations": {
             *          "Debug": {
             *          },
             *          "Release": {
             *          }
             *      }
             *  }
             */

            var configurationsSection = projectJsonObject.Value <JToken>("configurations") as JObject;

            if (configurationsSection != null)
            {
                foreach (var configKey in configurationsSection)
                {
                    var compilerOptions = GetCompilationOptions(configKey.Value as JObject, project);

                    // Only use this as a configuration if it's not a target framework
                    project._compilerOptionsByConfiguration[configKey.Key] = compilerOptions;
                }
            }

            // The frameworks node is where target frameworks go

            /*
             *  {
             *      "frameworks": {
             *          "net45": {
             *          },
             *          "dnxcore50": {
             *          }
             *      }
             *  }
             */

            var frameworks = projectJsonObject.Value <JToken>("frameworks") as JObject;

            if (frameworks != null)
            {
                foreach (var framework in frameworks)
                {
                    try
                    {
                        var frameworkToken = framework.Value as JObject;
                        var success        = BuildTargetFrameworkNode(project, framework.Key, frameworkToken);
                        if (!success)
                        {
                            var lineInfo = (IJsonLineInfo)framework.Value;
                            project.Diagnostics.Add(
                                new DiagnosticMessage(
                                    ErrorCodes.NU1008,
                                    $"\"{framework.Key}\" is an unsupported framework.",
                                    project.ProjectFilePath,
                                    DiagnosticMessageSeverity.Error,
                                    lineInfo.LineNumber,
                                    lineInfo.LinePosition));
                        }
                    }
                    catch (Exception ex)
                    {
                        throw FileFormatException.Create(ex, framework.Value, project.ProjectFilePath);
                    }
                }
            }
        }
Example #3
0
        private static CommonCompilerOptions GetCompilationOptions(JObject rawObject, Project project)
        {
            var compilerName = rawObject.Value <string>("compilerName");

            if (compilerName != null)
            {
                var lineInfo = rawObject.Value <IJsonLineInfo>("compilerName");
                project.Diagnostics.Add(
                    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;

            if (rawOptions == null)
            {
                rawOptions = rawObject.Value <JToken>("compilationOptions") as JObject;
                if (rawOptions == null)
                {
                    return(new CommonCompilerOptions
                    {
                        CompilerName = compilerName ?? "csc"
                    });
                }

                var lineInfo = (IJsonLineInfo)rawOptions;

                project.Diagnostics.Add(
                    new DiagnosticMessage(
                        ErrorCodes.DOTNET1015,
                        $"The 'compilationOptions' option is deprecated. Use 'buildOptions' instead.",
                        project.ProjectFilePath,
                        DiagnosticMessageSeverity.Warning,
                        lineInfo.LineNumber,
                        lineInfo.LinePosition));
            }

            var analyzerOptionsJson = rawOptions.Value <JToken>("analyzerOptions") as JObject;

            if (analyzerOptionsJson != null)
            {
                var analyzerOptions = new AnalyzerOptions();

                foreach (var analyzerOption in analyzerOptionsJson)
                {
                    switch (analyzerOption.Key)
                    {
                    case "languageId":
                        if (analyzerOption.Value.Type != JTokenType.String)
                        {
                            throw FileFormatException.Create(
                                      "The analyzer languageId must be a string",
                                      analyzerOption.Value.ToString(),
                                      project.ProjectFilePath);
                        }
                        analyzerOptions = new AnalyzerOptions(analyzerOption.Value.ToString());
                        break;

                    default:
                        throw FileFormatException.Create(
                                  $"Unrecognized analyzerOption key: {analyzerOption.Key}",
                                  project.ProjectFilePath);
                    }
                }

                project.AnalyzerOptions = analyzerOptions;
            }

            return(new CommonCompilerOptions
            {
                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"),
                OutputName = rawOptions.Value <string>("outputName"),
                CompilerName = rawOptions.Value <string>("compilerName") ?? compilerName ?? "csc",
                CompileInclude = GetIncludeContext(
                    project,
                    rawOptions,
                    "compile",
                    defaultBuiltInInclude: ProjectFilesCollection.DefaultCompileBuiltInPatterns,
                    defaultBuiltInExclude: ProjectFilesCollection.DefaultBuiltInExcludePatterns),
                EmbedInclude = GetIncludeContext(
                    project,
                    rawOptions,
                    "embed",
                    defaultBuiltInInclude: ProjectFilesCollection.DefaultResourcesBuiltInPatterns,
                    defaultBuiltInExclude: ProjectFilesCollection.DefaultBuiltInExcludePatterns),
                CopyToOutputInclude = GetIncludeContext(
                    project,
                    rawOptions,
                    "copyToOutput",
                    defaultBuiltInInclude: null,
                    defaultBuiltInExclude: ProjectFilesCollection.DefaultPublishExcludePatterns)
            });
        }
Example #4
0
        private static void PopulateDependencies(
            string projectPath,
            IList <ProjectLibraryDependency> results,
            JObject settings,
            string propertyName,
            bool isGacOrFrameworkReference)
        {
            var dependencies = settings.Value <JToken>(propertyName) as JObject;

            if (dependencies != null)
            {
                foreach (var dependency in dependencies)
                {
                    if (string.IsNullOrEmpty(dependency.Key))
                    {
                        throw FileFormatException.Create(
                                  "Unable to resolve dependency ''.",
                                  dependency.Key,
                                  projectPath);
                    }

                    var dependencyValue     = dependency.Value;
                    var dependencyTypeValue = LibraryDependencyType.Default;

                    var dependencyIncludeFlagsValue = LibraryIncludeFlags.All;
                    var dependencyExcludeFlagsValue = LibraryIncludeFlags.None;
                    var suppressParentFlagsValue    = LibraryIncludeFlagUtils.DefaultSuppressParent;

                    var    target = isGacOrFrameworkReference ? LibraryDependencyTarget.Reference : LibraryDependencyTarget.All;
                    string dependencyVersionAsString = null;

                    if (dependencyValue.Type == JTokenType.Object)
                    {
                        // "dependencies" : { "Name" : { "version": "1.0", "type": "build", "target": "project" } }
                        dependencyVersionAsString = dependencyValue.Value <string>("version");

                        var type = dependencyValue.Value <string>("type");
                        if (type != null)
                        {
                            dependencyTypeValue = LibraryDependencyType.Parse(new [] { type });
                        }

                        // Read the target if specified
                        if (!isGacOrFrameworkReference)
                        {
                            var targetStr = dependencyValue.Value <string>("target");
                            target = LibraryDependencyTargetUtils.Parse(targetStr);
                        }

                        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);
                        }
                    }
                    else if (dependencyValue.Type == JTokenType.String)
                    {
                        // "dependencies" : { "Name" : "1.0" }
                        dependencyVersionAsString = dependencyValue.Value <string>();
                    }
                    else
                    {
                        throw FileFormatException.Create(
                                  string.Format(
                                      "Invalid dependency version: {0}. The format is not recognizable.",
                                      dependency.Key),
                                  dependencyValue,
                                  projectPath);
                    }

                    VersionRange dependencyVersionRange = null;
                    if (!string.IsNullOrEmpty(dependencyVersionAsString))
                    {
                        try
                        {
                            dependencyVersionRange = VersionRange.Parse(dependencyVersionAsString);
                        }
                        catch (Exception ex)
                        {
                            throw FileFormatException.Create(ex, dependencyValue, projectPath);
                        }
                    }

                    // the dependency flags are: Include flags - Exclude flags
                    var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue;

                    var lineInfo = (IJsonLineInfo)dependencyValue;
                    results.Add(new ProjectLibraryDependency
                    {
                        LibraryRange = new LibraryRange(
                            dependency.Key,
                            dependencyVersionRange,
                            target),
                        Type           = dependencyTypeValue,
                        IncludeType    = includeFlags,
                        SuppressParent = suppressParentFlagsValue,
                        SourceFilePath = projectPath,
                        SourceLine     = lineInfo.LineNumber,
                        SourceColumn   = lineInfo.LinePosition
                    });
                }
            }
        }