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; }
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; }
/// <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; }
// 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; }
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); }
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; }
private static string GetDefaultRootOutputPath(Project project, string outputOptionValue) { string rootOutputPath = string.Empty; if (string.IsNullOrEmpty(outputOptionValue)) { rootOutputPath = project.ProjectDirectory; } return rootOutputPath; }
public static Command CreateCommandForScript(Project project, string scriptCommandLine, IDictionary<string, string> variables) { return CreateCommandForScript(project, scriptCommandLine, WrapVariableDictionary(variables)); }
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; }
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); } }
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; }
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); }; }
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); }
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); } } } }
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; }
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; }