public void ProjectResolverThrowsWhenResolvingAmbiguousName() { const string ambiguousName = "ProjectA"; var solutionStructure = @"{ 'global.json': '', 'src1': { 'ProjectA': { 'project.json': '{}' } }, 'src2': { 'ProjectA': { 'project.json': '{}' } } }"; using (var solutionPath = new DisposableDir()) { DirTree.CreateFromJson(solutionStructure) .WithFileContents("global.json", @"{ ""projects"": [""src1"", ""src2""] }") .WriteTo(solutionPath); var src1ProjectPath = Path.Combine(solutionPath, "src1", ambiguousName); var src2ProjectPath = Path.Combine(solutionPath, "src2", ambiguousName); var expectedMessage = $@"The project name '{ambiguousName}' is ambiguous between the following projects: {src1ProjectPath} {src2ProjectPath}"; Runtime.Project project = null; var resolver1 = new ProjectResolver(src1ProjectPath); var exception = Assert.Throws <InvalidOperationException>(() => resolver1.TryResolveProject(ambiguousName, out project)); Assert.Contains(expectedMessage, exception.Message); Assert.Null(project); var resolver2 = new ProjectResolver(src2ProjectPath); exception = Assert.Throws <InvalidOperationException>(() => resolver2.TryResolveProject(ambiguousName, out project)); Assert.Contains(expectedMessage, exception.Message); Assert.Null(project); } }
public void ProjectResolverThrowsWhenResolvingAmbiguousName() { const string ambiguousName = "ProjectA"; var solutionStructure = @"{ 'global.json': '', 'src1': { 'ProjectA': { 'project.json': '{}' } }, 'src2': { 'ProjectA': { 'project.json': '{}' } } }"; using (var solutionPath = new DisposableDir()) { DirTree.CreateFromJson(solutionStructure) .WithFileContents("global.json", @"{ ""projects"": [""src1"", ""src2""] }") .WriteTo(solutionPath); var src1ProjectPath = Path.Combine(solutionPath, "src1", ambiguousName); var src2ProjectPath = Path.Combine(solutionPath, "src2", ambiguousName); var expectedMessage = $@"The project name '{ambiguousName}' is ambiguous between the following projects: {src1ProjectPath} {src2ProjectPath}"; Runtime.Project project = null; var resolver1 = new ProjectResolver(src1ProjectPath); var exception = Assert.Throws<InvalidOperationException>(() => resolver1.TryResolveProject(ambiguousName, out project)); Assert.Contains(expectedMessage, exception.Message); Assert.Null(project); var resolver2 = new ProjectResolver(src2ProjectPath); exception = Assert.Throws<InvalidOperationException>(() => resolver2.TryResolveProject(ambiguousName, out project)); Assert.Contains(expectedMessage, exception.Message); Assert.Null(project); } }
private void WriteGlobalJson() { var rootDirectory = ProjectResolver.ResolveRootDirectory(_project.ProjectDirectory); var projectResolver = new ProjectResolver(_project.ProjectDirectory, rootDirectory); var packagesDir = NuGetDependencyResolver.ResolveRepositoryPath(rootDirectory); var pathResolver = new DefaultPackagePathResolver(packagesDir); var dependenciesObj = new JObject(); // Generate SHAs for all package dependencies foreach (var deploymentPackage in Packages) { var library = deploymentPackage.Library; var shaFilePath = pathResolver.GetHashPath(library.Name, library.Version); if (!File.Exists(shaFilePath)) { throw new FileNotFoundException("Expected SHA file doesn't exist", shaFilePath); } var sha = File.ReadAllText(shaFilePath); var shaObj = new JObject(); shaObj["version"] = library.Version.ToString(); shaObj["sha"] = sha; dependenciesObj[library.Name] = shaObj; } // If "--no-source" is specified, project dependencies are packed to packages // So we also generate SHAs for them in this case foreach (var deploymentProject in Projects) { Runtime.Project project; if (!projectResolver.TryResolveProject(deploymentProject.Name, out project)) { throw new Exception("TODO: unable to resolve project named " + deploymentProject.Name); } var shaFilePath = pathResolver.GetHashPath(project.Name, project.Version); if (!File.Exists(shaFilePath)) { // This project is not packed to a package continue; } var sha = File.ReadAllText(shaFilePath); var shaObj = new JObject(); shaObj.Add(new JProperty("version", project.Version.ToString())); shaObj.Add(new JProperty("sha", sha)); dependenciesObj.Add(new JProperty(project.Name, shaObj)); } var rootObject = default(JObject); if (GlobalSettings.HasGlobalFile(rootDirectory)) { rootObject = JObject.Parse(File.ReadAllText(Path.Combine( rootDirectory, GlobalSettings.GlobalFileName))); } else { rootObject = new JObject(); } var applicationRoot = Path.Combine(OutputPath, BundleRoot.AppRootName); rootObject["dependencies"] = dependenciesObj; rootObject["packages"] = PathUtility.GetRelativePath( PathUtility.EnsureTrailingForwardSlash(applicationRoot), TargetPackagesPath, separator: '/'); File.WriteAllText(Path.Combine(applicationRoot, GlobalSettings.GlobalFileName), rootObject.ToString()); }
private async Task <bool> RestoreForProject(string projectJsonPath, string rootDirectory, string packagesDirectory) { var success = true; Reports.Information.WriteLine(string.Format("Restoring packages for {0}", projectJsonPath.Bold())); var sw = new Stopwatch(); sw.Start(); var projectFolder = Path.GetDirectoryName(projectJsonPath); var projectLockFilePath = Path.Combine(projectFolder, LockFileFormat.LockFileName); Runtime.Project project; if (!Runtime.Project.TryGetProject(projectJsonPath, out project)) { throw new Exception("TODO: project.json parse error"); } var lockFile = await ReadLockFile(projectLockFilePath); var useLockFile = false; if (Lock == false && Unlock == false && lockFile != null && lockFile.Islocked) { useLockFile = true; } if (useLockFile && !lockFile.IsValidForProject(project)) { // Exhibit the same behavior as if it has been run with "dnu restore --lock" Reports.Information.WriteLine("Updating the invalid lock file with {0}", "dnu restore --lock".Yellow().Bold()); useLockFile = false; Lock = true; } Func <string, string> getVariable = key => { return(null); }; if (!ScriptExecutor.Execute(project, "prerestore", getVariable)) { ErrorMessages.GetOrAdd("prerestore", _ => new List <string>()).Add(ScriptExecutor.ErrorMessage); Reports.Error.WriteLine(ScriptExecutor.ErrorMessage); return(false); } var projectDirectory = project.ProjectDirectory; var projectResolver = new ProjectResolver(projectDirectory, rootDirectory); var packageRepository = new PackageRepository(packagesDirectory); var restoreOperations = new RestoreOperations(Reports.Verbose); var projectProviders = new List <IWalkProvider>(); var localProviders = new List <IWalkProvider>(); var remoteProviders = new List <IWalkProvider>(); var contexts = new List <RestoreContext>(); projectProviders.Add( new LocalWalkProvider( new ProjectReferenceDependencyProvider( projectResolver))); localProviders.Add( new LocalWalkProvider( new NuGetDependencyResolver(packageRepository))); var effectiveSources = PackageSourceUtils.GetEffectivePackageSources( SourceProvider, FeedOptions.Sources, FeedOptions.FallbackSources); AddRemoteProvidersFromSources(remoteProviders, effectiveSources); var tasks = new List <Task <GraphNode> >(); if (useLockFile) { Reports.Information.WriteLine(string.Format("Following lock file {0}", projectLockFilePath.White().Bold())); var context = new RestoreContext { FrameworkName = ApplicationEnvironment.RuntimeFramework, ProjectLibraryProviders = projectProviders, LocalLibraryProviders = localProviders, RemoteLibraryProviders = remoteProviders, }; contexts.Add(context); foreach (var lockFileLibrary in lockFile.Libraries) { var projectLibrary = new LibraryRange { Name = lockFileLibrary.Name, VersionRange = new SemanticVersionRange { MinVersion = lockFileLibrary.Version, MaxVersion = lockFileLibrary.Version, IsMaxInclusive = true, VersionFloatBehavior = SemanticVersionFloatBehavior.None, } }; tasks.Add(restoreOperations.CreateGraphNode(context, projectLibrary, _ => false)); } } else { foreach (var configuration in project.GetTargetFrameworks()) { var context = new RestoreContext { FrameworkName = configuration.FrameworkName, ProjectLibraryProviders = projectProviders, LocalLibraryProviders = localProviders, RemoteLibraryProviders = remoteProviders, }; contexts.Add(context); } if (!contexts.Any()) { contexts.Add(new RestoreContext { FrameworkName = ApplicationEnvironment.RuntimeFramework, ProjectLibraryProviders = projectProviders, LocalLibraryProviders = localProviders, RemoteLibraryProviders = remoteProviders, }); } foreach (var context in contexts) { var projectLibrary = new LibraryRange { Name = project.Name, VersionRange = new SemanticVersionRange(project.Version) }; tasks.Add(restoreOperations.CreateGraphNode(context, projectLibrary, _ => true)); } } var graphs = await Task.WhenAll(tasks); foreach (var graph in graphs) { Reduce(graph); } if (!useLockFile) { var runtimeFormatter = new RuntimeFileFormatter(); var projectRuntimeFile = runtimeFormatter.ReadRuntimeFile(projectJsonPath); if (projectRuntimeFile.Runtimes.Any()) { var runtimeTasks = new List <Task <GraphNode> >(); foreach (var pair in contexts.Zip(graphs, (context, graph) => new { context, graph })) { var runtimeFileTasks = new List <Task <RuntimeFile> >(); ForEach(pair.graph, node => { var match = node?.Item?.Match; if (match == null) { return; } runtimeFileTasks.Add(match.Provider.GetRuntimes(node.Item.Match, pair.context.FrameworkName)); }); var libraryRuntimeFiles = await Task.WhenAll(runtimeFileTasks); var runtimeFiles = new List <RuntimeFile> { projectRuntimeFile }; runtimeFiles.AddRange(libraryRuntimeFiles.Where(file => file != null)); foreach (var runtimeName in projectRuntimeFile.Runtimes.Keys) { var runtimeSpecs = new List <RuntimeSpec>(); FindRuntimeSpecs( runtimeName, runtimeFiles, runtimeSpecs, _ => false); var runtimeContext = new RestoreContext { FrameworkName = pair.context.FrameworkName, ProjectLibraryProviders = pair.context.ProjectLibraryProviders, LocalLibraryProviders = pair.context.LocalLibraryProviders, RemoteLibraryProviders = pair.context.RemoteLibraryProviders, RuntimeName = runtimeName, RuntimeSpecs = runtimeSpecs }; var projectLibrary = new LibraryRange { Name = project.Name, VersionRange = new SemanticVersionRange(project.Version) }; Reports.Information.WriteLine(string.Format("Graph for {0} on {1}", runtimeContext.FrameworkName, runtimeContext.RuntimeName)); runtimeTasks.Add(restoreOperations.CreateGraphNode(runtimeContext, projectLibrary, _ => true)); } } var runtimeGraphs = await Task.WhenAll(runtimeTasks); foreach (var runtimeGraph in runtimeGraphs) { Reduce(runtimeGraph); } graphs = graphs.Concat(runtimeGraphs).ToArray(); } } var graphItems = new List <GraphItem>(); var installItems = new List <GraphItem>(); var missingItems = new HashSet <LibraryRange>(); ForEach(graphs, node => { if (node == null || node.LibraryRange == null || node.Disposition == GraphNode.DispositionType.Rejected) { return; } if (node.Item == null || node.Item.Match == null) { if (!node.LibraryRange.IsGacOrFrameworkReference && node.LibraryRange.VersionRange != null && missingItems.Add(node.LibraryRange)) { var errorMessage = string.Format("Unable to locate {0} {1}", node.LibraryRange.Name.Red().Bold(), node.LibraryRange.VersionRange); ErrorMessages.GetOrAdd(projectJsonPath, _ => new List <string>()).Add(errorMessage); Reports.Error.WriteLine(errorMessage); success = false; } return; } if (!string.Equals(node.Item.Match.Library.Name, node.LibraryRange.Name, StringComparison.Ordinal)) { // Fix casing of the library name to be installed node.Item.Match.Library.Name = node.LibraryRange.Name; } var isRemote = remoteProviders.Contains(node.Item.Match.Provider); var isInstallItem = installItems.Any(item => item.Match.Library == node.Item.Match.Library); if (!isInstallItem && isRemote) { installItems.Add(node.Item); } var isGraphItem = graphItems.Any(item => item.Match.Library == node.Item.Match.Library); if (!isGraphItem) { graphItems.Add(node.Item); } }); await InstallPackages(installItems, packagesDirectory, packageFilter : (library, nupkgSHA) => true); if (!useLockFile) { Reports.Information.WriteLine(string.Format("Writing lock file {0}", projectLockFilePath.White().Bold())); // Collect target frameworks var frameworks = new HashSet <FrameworkName>(); foreach (var item in graphItems) { Runtime.Project dependencyProject; if (projectProviders.Contains(item.Match.Provider) && projectResolver.TryResolveProject(item.Match.Library.Name, out dependencyProject)) { frameworks.AddRange(dependencyProject.GetTargetFrameworks().Select(t => t.FrameworkName)); } } WriteLockFile(projectLockFilePath, project, graphItems, new PackageRepository(packagesDirectory), frameworks); } if (!ScriptExecutor.Execute(project, "postrestore", getVariable)) { ErrorMessages.GetOrAdd("postrestore", _ => new List <string>()).Add(ScriptExecutor.ErrorMessage); Reports.Error.WriteLine(ScriptExecutor.ErrorMessage); return(false); } if (!ScriptExecutor.Execute(project, "prepare", getVariable)) { ErrorMessages.GetOrAdd("prepare", _ => new List <string>()).Add(ScriptExecutor.ErrorMessage); Reports.Error.WriteLine(ScriptExecutor.ErrorMessage); return(false); } Reports.Information.WriteLine(string.Format("{0}, {1}ms elapsed", "Restore complete".Green().Bold(), sw.ElapsedMilliseconds)); return(success); }
private void WriteGlobalJson() { var rootDirectory = ProjectResolver.ResolveRootDirectory(_project.ProjectDirectory); var projectResolver = new ProjectResolver(_project.ProjectDirectory, rootDirectory); var packagesDir = NuGetDependencyResolver.ResolveRepositoryPath(rootDirectory); var nugetDependencyResolver = new NuGetDependencyResolver(packagesDir, new EmptyFrameworkResolver()); var pathResolver = new DefaultPackagePathResolver(PackagesPath); var dependenciesObj = new JObject(); // Generate SHAs for all package dependencies foreach (var deploymentPackage in Packages) { // Use the exactly same approach in PackPackage.Emit() to // find the package actually in use var package = nugetDependencyResolver.FindCandidate( deploymentPackage.Library.Name, deploymentPackage.Library.Version); var shaFilePath = pathResolver.GetHashPath(package.Id, package.Version); var sha = File.ReadAllText(shaFilePath); var shaObj = new JObject(); shaObj.Add(new JProperty("version", package.Version.ToString())); shaObj.Add(new JProperty("sha", sha)); dependenciesObj.Add(new JProperty(package.Id, shaObj)); } // If "--no-source" is specified, project dependencies are packed to packages // So we also generate SHAs for them in this case foreach (var deploymentProject in Projects) { Runtime.Project project; if (!projectResolver.TryResolveProject(deploymentProject.Name, out project)) { throw new Exception("TODO: unable to resolve project named " + deploymentProject.Name); } var shaFilePath = pathResolver.GetHashPath(project.Name, project.Version); if (!File.Exists(shaFilePath)) { // This project is not packed to a package continue; } var sha = File.ReadAllText(shaFilePath); var shaObj = new JObject(); shaObj.Add(new JProperty("version", project.Version.ToString())); shaObj.Add(new JProperty("sha", sha)); dependenciesObj.Add(new JProperty(project.Name, shaObj)); } var rootObject = default(JObject); if (GlobalSettings.HasGlobalFile(rootDirectory)) { rootObject = JObject.Parse(File.ReadAllText(Path.Combine( rootDirectory, GlobalSettings.GlobalFileName))); } else { rootObject = new JObject(); } var applicationRoot = Path.Combine(OutputPath, PackRoot.AppRootName); rootObject["dependencies"] = dependenciesObj; rootObject["packages"] = PathUtility.GetRelativePath(PathUtility.EnsureTrailingSlash(applicationRoot), PackagesPath); File.WriteAllText(Path.Combine(applicationRoot, GlobalSettings.GlobalFileName), rootObject.ToString()); }