Example #1
0
        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);
            }
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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());
        }
Example #4
0
        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);
        }
Example #5
0
        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());
        }