Beispiel #1
0
 public ProjectDescription(
     LibraryRange libraryRange,
     Project project,
     IEnumerable<LibraryRange> dependencies,
     TargetFrameworkInformation targetFrameworkInfo,
     bool resolved)
     : base(new LibraryIdentity(project.Name, project.Version, LibraryType.Project),
             string.Empty, // Projects don't have hashes
             project.ProjectFilePath,
             dependencies,
             targetFrameworkInfo.FrameworkName,
             resolved,
             compatible: true)
 {
     Project = project;
     TargetFrameworkInfo = targetFrameworkInfo;
 }
Beispiel #2
0
        public static bool TryGetProject(string path, out Project project, ICollection<DiagnosticMessage> diagnostics = null)
        {
            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();
                    project = reader.ReadProject(stream, projectName, projectPath, diagnostics);
                }
            }
            catch (Exception ex)
            {
                throw FileFormatException.Create(ex, projectPath);
            }

            return true;
        }
Beispiel #3
0
        /// <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>
        private bool BuildTargetFrameworkNode(Project project, string frameworkKey, JsonObject frameworkValue)
        {
            // If no compilation options are provided then figure them out from the node
            var compilerOptions = GetCompilationOptions(frameworkValue) ??
                                  new CommonCompilerOptions();

            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>());
            var frameworkDefine = MakeDefaultTargetFrameworkDefine(frameworkName);

            if (!string.IsNullOrEmpty(frameworkDefine))
            {
                defines.Add(frameworkDefine);
            }

            compilerOptions.Defines = defines;

            var targetFrameworkInformation = new TargetFrameworkInformation
            {
                FrameworkName = frameworkName,
                Dependencies = new List<LibraryRange>(),
                CompilerOptions = compilerOptions,
                Line = frameworkValue.Line,
                Column = frameworkValue.Column
            };

            var frameworkDependencies = new List<LibraryRange>();

            PopulateDependencies(
                project.ProjectFilePath,
                frameworkDependencies,
                frameworkValue,
                "dependencies",
                isGacOrFrameworkReference: false);

            var frameworkAssemblies = new List<LibraryRange>();
            PopulateDependencies(
                project.ProjectFilePath,
                frameworkAssemblies,
                frameworkValue,
                "frameworkAssemblies",
                isGacOrFrameworkReference: true);

            frameworkDependencies.AddRange(frameworkAssemblies);
            targetFrameworkInformation.Dependencies = frameworkDependencies;

            targetFrameworkInformation.WrappedProject = frameworkValue.ValueAsString("wrappedProject");

            var binNode = frameworkValue.ValueAsJsonObject("bin");
            if (binNode != null)
            {
                targetFrameworkInformation.AssemblyPath = binNode.ValueAsString("assembly");
                targetFrameworkInformation.PdbPath = binNode.ValueAsString("pdb");
            }

            project._targetFrameworks[frameworkName] = targetFrameworkInformation;

            return true;
        }
Beispiel #4
0
        // REVIEW: This code copying kinda sucks
        private static string GetProjectOutputName(Project project, NuGetFramework framework, string configuration)
        {
            var compilationOptions = project.GetCompilerOptions(framework, configuration);
            var outputExtension = ".dll";

            if (framework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault())
            {
                outputExtension = ".exe";
            }

            return project.Name + outputExtension;
        }
Beispiel #5
0
 private static string GetPackagePath(Project project, string outputPath, bool symbols = false)
 {
     string fileName = $"{project.Name}.{project.Version}{(symbols ? ".symbols" : string.Empty)}{NuGet.Constants.PackageExtension}";
     return Path.Combine(outputPath, fileName);
 }
Beispiel #6
0
        private static string GetOutputPath(Project project, string configuration, string outputOptionValue)
        {
            var outputPath = string.Empty;

            if (string.IsNullOrEmpty(outputOptionValue))
            {
                outputPath = Path.Combine(
                    GetDefaultRootOutputPath(project, outputOptionValue),
                    Cli.Utils.Constants.BinDirectoryName,
                    configuration);
            }
            else
            {
                outputPath = outputOptionValue;
            }

            return outputPath;
        }
Beispiel #7
0
        private static string GetDefaultRootOutputPath(Project project, string outputOptionValue)
        {
            string rootOutputPath = string.Empty;

            if (string.IsNullOrEmpty(outputOptionValue))
            {
                rootOutputPath = project.ProjectDirectory;
            }

            return rootOutputPath;
        }
Beispiel #8
0
 public static Command CreateCommandForScript(Project project, string scriptCommandLine, IDictionary<string, string> variables)
 {
     return CreateCommandForScript(project, scriptCommandLine, WrapVariableDictionary(variables));
 }
Beispiel #9
0
        private static PackageBuilder CreatePackageBuilder(Project project)
        {
            var builder = new PackageBuilder();
            builder.Authors.AddRange(project.Authors);
            builder.Owners.AddRange(project.Owners);

            if (builder.Authors.Count == 0)
            {
                var defaultAuthor = Environment.GetEnvironmentVariable("NUGET_AUTHOR");
                if (string.IsNullOrEmpty(defaultAuthor))
                {
                    builder.Authors.Add(project.Name);
                }
                else
                {
                    builder.Authors.Add(defaultAuthor);
                }
            }

            builder.Description = project.Description ?? project.Name;
            builder.Id = project.Name;
            builder.Version = project.Version;
            builder.Title = project.Title;
            builder.Summary = project.Summary;
            builder.Copyright = project.Copyright;
            builder.RequireLicenseAcceptance = project.RequireLicenseAcceptance;
            builder.ReleaseNotes = project.ReleaseNotes;
            builder.Language = project.Language;
            builder.Tags.AddRange(project.Tags);

            if (!string.IsNullOrEmpty(project.IconUrl))
            {
                builder.IconUrl = new Uri(project.IconUrl);
            }

            if (!string.IsNullOrEmpty(project.ProjectUrl))
            {
                builder.ProjectUrl = new Uri(project.ProjectUrl);
            }

            if (!string.IsNullOrEmpty(project.LicenseUrl))
            {
                builder.LicenseUrl = new Uri(project.LicenseUrl);
            }

            return builder;
        }
Beispiel #10
0
        private static void AddPackageFiles(Project project, IEnumerable<PackIncludeEntry> packageFiles, PackageBuilder packageBuilder, IList<DiagnosticMessage> diagnostics)
        {
            var rootDirectory = new DirectoryInfoWrapper(new DirectoryInfo(project.ProjectDirectory));

            foreach (var match in CollectAdditionalFiles(rootDirectory, packageFiles, project.ProjectFilePath, diagnostics))
            {
                packageBuilder.Files.Add(match);
            }
        }
Beispiel #11
0
        private static bool AddResources(Project project, List<string> compilerArgs, string intermediateOutputPath)
        {
            string root = PathUtility.EnsureTrailingSlash(project.ProjectDirectory);

            foreach (var resourceFile in project.Files.ResourceFiles)
            {
                string resourceName = null;
                string rootNamespace = null;

                var resourcePath = resourceFile.Key;

                if (string.IsNullOrEmpty(resourceFile.Value))
                {
                    // No logical name, so use the file name
                    resourceName = ResourcePathUtility.GetResourceName(root, resourcePath);
                    rootNamespace = project.Name;
                }
                else
                {
                    resourceName = CreateCSharpManifestResourceName.EnsureResourceExtension(resourceFile.Value, resourcePath);
                    rootNamespace = null;
                }

                var name = CreateCSharpManifestResourceName.CreateManifestName(resourceName, rootNamespace);
                var fileName = resourcePath;

                if (ResourcePathUtility.IsResxResourceFile(fileName))
                {
                    var ext = Path.GetExtension(fileName);

                    if (string.Equals(ext, ".resx", StringComparison.OrdinalIgnoreCase))
                    {
                        // {file}.resx -> {file}.resources
                        var resourcesFile = Path.Combine(intermediateOutputPath, name);

                        var result = Command.Create("resgen", $"\"{fileName}\" \"{resourcesFile}\"")
                                            .ForwardStdErr()
                                            .ForwardStdOut()
                                            .Execute();

                        if (result.ExitCode != 0)
                        {
                            return false;
                        }

                        // Use this as the resource name instead
                        fileName = resourcesFile;
                    }
                }

                compilerArgs.Add($"--resource:\"{fileName}\",{name}");
            }

            return true;
        }
 public ProjectContextBuilder WithProject(Project project)
 {
     Project = project;
     return this;
 }
Beispiel #13
0
        private static Func<string, string> GetScriptVariable(Project project, Func<string, string> getVariable)
        {
            var keys = new Dictionary<string, Func<string>>(StringComparer.OrdinalIgnoreCase)
            {
                { "project:Directory", () => project.ProjectDirectory },
                { "project:Name", () => project.Name },
                { "project:Version", () => project.Version.ToString() },
            };

            return key =>
            {
                // try returning key from dictionary
                Func<string> valueFactory;
                if (keys.TryGetValue(key, out valueFactory))
                {
                    return valueFactory();
                }

                // try returning command-specific key
                var value = getVariable(key);
                if (!string.IsNullOrEmpty(value))
                {
                    return value;
                }

                // try returning environment variable
                return Environment.GetEnvironmentVariable(key);
            };
        }
Beispiel #14
0
        public static Command CreateCommandForScript(Project project, string scriptCommandLine, Func<string, string> getVariable)
        {
            // Preserve quotation marks around arguments since command is about to be passed to a shell. May need
            // the quotes to ensure the shell groups arguments correctly.
            var scriptArguments = CommandGrammar.Process(
                scriptCommandLine,
                GetScriptVariable(project, getVariable),
                preserveSurroundingQuotes: true);

            // Ensure the array won't be empty and the elements won't be null or empty strings.
            scriptArguments = scriptArguments.Where(argument => !string.IsNullOrEmpty(argument)).ToArray();
            if (scriptArguments.Length == 0)
            {
                return null;
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                // Only forward slashes are used in script blocks. Replace with backslashes to correctly
                // locate the script. The directory separator is platform-specific.
                scriptArguments[0] = scriptArguments[0].Replace(
                    Path.AltDirectorySeparatorChar,
                    Path.DirectorySeparatorChar);

                // Command-lines on Windows are executed via "cmd /S /C" in order to support batch files, &&,
                // built-in commands like echo, et cetera. /S allows quoting the command as well as the arguments.
                // ComSpec is Windows-specific, and contains the full path to cmd.exe
                var comSpec = Environment.GetEnvironmentVariable("ComSpec");
                if (!string.IsNullOrEmpty(comSpec))
                {
                    scriptArguments =
                        new[] { comSpec, "/S", "/C", "\"" }
                        .Concat(scriptArguments)
                        .Concat(new[] { "\"" })
                        .ToArray();
                }
            }
            else
            {
                // Special-case a script name that, perhaps with added .sh, matches an existing file.
                var surroundWithQuotes = false;
                var scriptCandidate = scriptArguments[0];
                if (scriptCandidate.StartsWith("\"", StringComparison.Ordinal) &&
                    scriptCandidate.EndsWith("\"", StringComparison.Ordinal))
                {
                    // Strip surrounding quotes; they were required in project.json to keep the script name
                    // together but confuse File.Exists() e.g. "My Script", lacking ./ prefix and .sh suffix.
                    surroundWithQuotes = true;
                    scriptCandidate = scriptCandidate.Substring(1, scriptCandidate.Length - 2);
                }

                if (!scriptCandidate.EndsWith(".sh", StringComparison.Ordinal))
                {
                    scriptCandidate = scriptCandidate + ".sh";
                }

                if (File.Exists(Path.Combine(project.ProjectDirectory, scriptCandidate)))
                {
                    // scriptCandidate may be a path relative to the project root. If so, likely will not be found
                    // in the $PATH; add ./ to let bash know where to look.
                    var prefix = Path.IsPathRooted(scriptCandidate) ? string.Empty : "./";
                    var quote = surroundWithQuotes ? "\"" : string.Empty;
                    scriptArguments[0] = $"{ quote }{ prefix }{ scriptCandidate }{ quote }";
                }

                // Always use /usr/bin/env bash -c in order to support redirection and so on; similar to Windows case.
                // Unlike Windows, must escape quotation marks within the newly-quoted string.
                scriptArguments = new[] { "/usr/bin/env", "bash", "-c", "\"" }
                    .Concat(scriptArguments.Select(argument => argument.Replace("\"", "\\\"")))
                    .Concat(new[] { "\"" })
                    .ToArray();
            }

            return Command.Create(scriptArguments.FirstOrDefault(), string.Join(" ", scriptArguments.Skip(1)))
                .WorkingDirectory(project.ProjectDirectory);
        }
Beispiel #15
0
        private void BuildTargetFrameworksAndConfigurations(Project project, JsonObject projectJsonObject, ICollection<DiagnosticMessage> diagnostics)
        {
            // Get the shared compilationOptions
            project._defaultCompilerOptions = GetCompilationOptions(projectJsonObject) ?? new CommonCompilerOptions();

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

            // 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.ValueAsJsonObject("configurations");
            if (configurationsSection != null)
            {
                foreach (var configKey in configurationsSection.Keys)
                {
                    var compilerOptions = GetCompilationOptions(configurationsSection.ValueAsJsonObject(configKey));

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

            // The frameworks node is where target frameworks go
            /*
                {
                    "frameworks": {
                        "net45": {
                        },
                        "dnxcore50": {
                        }
                    }
                }
            */

            var frameworks = projectJsonObject.ValueAsJsonObject("frameworks");
            if (frameworks != null)
            {
                foreach (var frameworkKey in frameworks.Keys)
                {
                    try
                    {
                        var frameworkToken = frameworks.ValueAsJsonObject(frameworkKey);
                        var success = BuildTargetFrameworkNode(project, frameworkKey, frameworkToken);
                        if (!success)
                        {
                            diagnostics?.Add(
                                new DiagnosticMessage(
                                    ErrorCodes.NU1008,
                                    $"\"{frameworkKey}\" is an unsupported framework.",
                                    project.ProjectFilePath,
                                    DiagnosticMessageSeverity.Error,
                                    frameworkToken.Line,
                                    frameworkToken.Column));
                        }
                    }
                    catch (Exception ex)
                    {
                        throw FileFormatException.Create(ex, frameworks.Value(frameworkKey), project.ProjectFilePath);
                    }
                }
            }
        }
Beispiel #16
0
        public Project ReadProject(Stream stream, string projectName, string projectPath, ICollection<DiagnosticMessage> diagnostics)
        {
            var project = new Project();

            var reader = new StreamReader(stream);
            var rawProject = JsonDeserializer.Deserialize(reader) as JsonObject;
            if (rawProject == null)
            {
                throw FileFormatException.Create(
                    "The JSON file can't be deserialized to a JSON object.",
                    projectPath);
            }

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

            var version = rawProject.Value("version") as JsonString;
            if (version == null)
            {
                project.Version = new NuGetVersion("1.0.0");
            }
            else
            {
                try
                {
                    var buildVersion = Environment.GetEnvironmentVariable("DOTNET_BUILD_VERSION");
                    project.Version = SpecifySnapshot(version, buildVersion);
                }
                catch (Exception ex)
                {
                    throw FileFormatException.Create(ex, version, project.ProjectFilePath);
                }
            }

            var fileVersion = Environment.GetEnvironmentVariable("DOTNET_ASSEMBLY_FILE_VERSION");
            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.ValueAsString("description");
            project.Summary = rawProject.ValueAsString("summary");
            project.Copyright = rawProject.ValueAsString("copyright");
            project.Title = rawProject.ValueAsString("title");
            project.EntryPoint = rawProject.ValueAsString("entryPoint");
            project.ProjectUrl = rawProject.ValueAsString("projectUrl");
            project.LicenseUrl = rawProject.ValueAsString("licenseUrl");
            project.IconUrl = rawProject.ValueAsString("iconUrl");
            project.CompilerName = rawProject.ValueAsString("compilerName");

            project.Authors = rawProject.ValueAsStringArray("authors") ?? Array.Empty<string>();
            project.Owners = rawProject.ValueAsStringArray("owners") ?? Array.Empty<string>();
            project.Tags = rawProject.ValueAsStringArray("tags") ?? Array.Empty<string>();

            project.Language = rawProject.ValueAsString("language");
            project.ReleaseNotes = rawProject.ValueAsString("releaseNotes");

            project.RequireLicenseAcceptance = rawProject.ValueAsBoolean("requireLicenseAcceptance", defaultValue: false);

            // REVIEW: Move this to the dependencies node?
            project.EmbedInteropTypes = rawProject.ValueAsBoolean("embedInteropTypes", defaultValue: false);

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

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

            var commands = rawProject.Value("commands") as JsonObject;
            if (commands != null)
            {
                foreach (var key in commands.Keys)
                {
                    var value = commands.ValueAsString(key);
                    if (value != null)
                    {
                        project.Commands[key] = value;
                    }
                }
            }

            var scripts = rawProject.Value("scripts") as JsonObject;
            if (scripts != null)
            {
                foreach (var key in scripts.Keys)
                {
                    var stringValue = scripts.ValueAsString(key);
                    if (stringValue != null)
                    {
                        project.Scripts[key] = new string[] { stringValue };
                        continue;
                    }

                    var arrayValue = scripts.ValueAsStringArray(key);
                    if (arrayValue != null)
                    {
                        project.Scripts[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),
                        scripts.Value(key),
                        project.ProjectFilePath);
                }
            }

            BuildTargetFrameworksAndConfigurations(project, rawProject, diagnostics);

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

            return project;
        }
Beispiel #17
0
        private static bool GeneratePackage(Project project, PackageBuilder packageBuilder, string nupkg, List<DiagnosticMessage> packDiagnostics)
        {
            foreach (var sharedFile in project.Files.SharedFiles)
            {
                var file = new PhysicalPackageFile();
                file.SourcePath = sharedFile;
                file.TargetPath = Path.Combine("shared", Path.GetFileName(sharedFile));
                packageBuilder.Files.Add(file);
            }

            var root = project.ProjectDirectory;

            if (project.Files.PackInclude != null && project.Files.PackInclude.Any())
            {
                AddPackageFiles(project, project.Files.PackInclude, packageBuilder, packDiagnostics);
            }

            // Write the packages as long as we're still in a success state.
            if (!packDiagnostics.Any(d => d.Severity == DiagnosticMessageSeverity.Error))
            {
                Reporter.Verbose.WriteLine($"Adding package files");
                foreach (var file in packageBuilder.Files.OfType<PhysicalPackageFile>())
                {
                    if (file.SourcePath != null && File.Exists(file.SourcePath))
                    {
                        Reporter.Verbose.WriteLine($"Adding {file.Path.Yellow()}");
                    }
                }

                Directory.CreateDirectory(Path.GetDirectoryName(nupkg));

                using (var fs = File.Create(nupkg))
                {
                    packageBuilder.Save(fs);
                    Reporter.Output.WriteLine($"{project.Name} -> {Path.GetFullPath(nupkg)}");
                }

                return true;
            }

            return false;
        }