Example #1
0
        private async Task <Tuple <string, string> > ResolvePackageIdAndVersion(string packageId, string packageVersion)
        {
            if (string.IsNullOrEmpty(packageId))
            {
                return(null);
            }

            // For nupkgs, get the id and version from the package
            if (packageId.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase))
            {
                if (!File.Exists(packageId))
                {
                    WriteError(string.Format("Could not find the file {0}.", packageId));
                    return(null);
                }

                var packagePath      = Path.GetFullPath(packageId);
                var packageDirectory = Path.GetDirectoryName(packagePath);
                var zipPackage       = new NuGet.ZipPackage(packagePath);
                FeedOptions.FallbackSources.Add(packageDirectory);

                return(new Tuple <string, string>(
                           zipPackage.Id,
                           zipPackage.Version.ToString()));
            }

            // If the version is missing, try to find the latest version
            if (string.IsNullOrEmpty(packageVersion))
            {
                var rootDirectory = ProjectResolver.ResolveRootDirectory(_commandsRepository.Root.Root);
                var config        = NuGetConfig.ForSolution(rootDirectory, RestoreCommand.FileSystem);

                var packageFeeds = new List <IPackageFeed>();

                var effectiveSources = PackageSourceUtils.GetEffectivePackageSources(
                    config.Sources,
                    FeedOptions.Sources,
                    FeedOptions.FallbackSources);

                foreach (var source in effectiveSources)
                {
                    var feed = PackageSourceUtils.CreatePackageFeed(
                        source,
                        FeedOptions.NoCache,
                        FeedOptions.IgnoreFailedSources,
                        Reports);
                    if (feed != null)
                    {
                        packageFeeds.Add(feed);
                    }
                }

                var package = await PackageSourceUtils.FindLatestPackage(packageFeeds, packageId);

                if (package == null)
                {
                    Reports.Error.WriteLine("Unable to locate the package {0}".Red(), packageId);
                    return(null);
                }

                return(new Tuple <string, string>(
                           packageId,
                           package.Version.ToString()));
            }

            // Otherwise, just assume that what you got is correct
            return(new Tuple <string, string>(packageId, packageVersion));
        }
Example #2
0
        private async Task <bool> RestoreForProject(string projectJsonPath, string rootDirectory, string packagesDirectory, IList <IWalkProvider> remoteProviders, SummaryContext summary)
        {
            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;
            var             diagnostics = new List <DiagnosticMessage>();

            if (!Runtime.Project.TryGetProject(projectJsonPath, out project, diagnostics))
            {
                var errorMessages = diagnostics
                                    .Where(x => x.Severity == DiagnosticMessageSeverity.Error)
                                    .Select(x => x.Message);

                throw new InvalidOperationException(errorMessages.Any() ?
                                                    $"Errors occurred when while parsing project.json:{Environment.NewLine}{string.Join(Environment.NewLine, errorMessages)}" :
                                                    "Invalid project.json");
            }

            if (diagnostics.HasErrors())
            {
                var errorMessages = diagnostics
                                    .Where(x => x.Severity == DiagnosticMessageSeverity.Error)
                                    .Select(x => x.Message);
                summary.ErrorMessages.GetOrAdd(projectJsonPath, _ => new List <string>()).AddRange(errorMessages);
            }

            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 (!SkipRestoreEvents)
            {
                if (!ScriptExecutor.Execute(project, "prerestore", getVariable))
                {
                    summary.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)
            {
                CheckHashFile = CheckHashFile
            };
            var restoreOperations = new RestoreOperations(Reports.Verbose);
            var projectProviders  = new List <IWalkProvider>();
            var localProviders    = new List <IWalkProvider>();
            var contexts          = new List <RestoreContext>();
            var cache             = new Dictionary <LibraryRange, Task <WalkProviderMatch> >();

            projectProviders.Add(
                new LocalWalkProvider(
                    new ProjectReferenceDependencyProvider(
                        projectResolver)));

            localProviders.Add(
                new LocalWalkProvider(
                    new NuGetDependencyResolver(packageRepository)));

            var tasks = new List <Task <TargetContext> >();

            if (useLockFile)
            {
                Reports.Information.WriteLine(string.Format("Following lock file {0}", projectLockFilePath.White().Bold()));

                var context = new RestoreContext
                {
                    FrameworkName           = FallbackFramework,
                    ProjectLibraryProviders = projectProviders,
                    LocalLibraryProviders   = localProviders,
                    RemoteLibraryProviders  = remoteProviders,
                    MatchCache = cache
                };

                contexts.Add(context);

                foreach (var lockFileLibrary in lockFile.PackageLibraries)
                {
                    var projectLibrary = new LibraryRange(lockFileLibrary.Name, frameworkReference: false)
                    {
                        VersionRange = new SemanticVersionRange
                        {
                            MinVersion           = lockFileLibrary.Version,
                            MaxVersion           = lockFileLibrary.Version,
                            IsMaxInclusive       = true,
                            VersionFloatBehavior = SemanticVersionFloatBehavior.None,
                        }
                    };

                    tasks.Add(CreateGraphNode(restoreOperations, context, projectLibrary, _ => false));
                }
            }
            else
            {
                var frameworks = TargetFrameworks.Count == 0 ? project.GetTargetFrameworks().Select(f => f.FrameworkName) : TargetFrameworks;

                foreach (var frameworkName in frameworks)
                {
                    var context = new RestoreContext
                    {
                        FrameworkName           = frameworkName,
                        ProjectLibraryProviders = projectProviders,
                        LocalLibraryProviders   = localProviders,
                        RemoteLibraryProviders  = remoteProviders,
                        MatchCache = cache
                    };
                    contexts.Add(context);
                }

                if (!contexts.Any())
                {
                    contexts.Add(new RestoreContext
                    {
                        FrameworkName           = FallbackFramework,
                        ProjectLibraryProviders = projectProviders,
                        LocalLibraryProviders   = localProviders,
                        RemoteLibraryProviders  = remoteProviders,
                        MatchCache = cache
                    });
                }

                foreach (var context in contexts)
                {
                    var projectLibrary = new LibraryRange(project.Name, frameworkReference: false)
                    {
                        VersionRange = new SemanticVersionRange(project.Version)
                    };

                    tasks.Add(CreateGraphNode(restoreOperations, context, projectLibrary, _ => true));
                }
            }

            var targetContexts = await Task.WhenAll(tasks);

            foreach (var targetContext in targetContexts)
            {
                Reduce(targetContext.Root);
            }

            if (!useLockFile)
            {
                var projectRuntimeFile = RuntimeFile.ParseFromProject(project);
                var restoreRuntimes    = GetRestoreRuntimes(projectRuntimeFile.Runtimes.Keys).ToList();
                if (restoreRuntimes.Any())
                {
                    var runtimeTasks = new List <Task <TargetContext> >();

                    foreach (var pair in contexts.Zip(targetContexts, (context, graph) => new { context, graph }))
                    {
                        var runtimeFileTasks = new List <Task <RuntimeFile> >();
                        ForEach(pair.graph.Root, 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 restoreRuntimes)
                        {
                            Reports.WriteVerbose($"Restoring packages for {pair.context.FrameworkName} on {runtimeName}...");
                            var runtimeDependencies = new Dictionary <string, DependencySpec>();
                            var runtimeNames        = new HashSet <string>();
                            var runtimeStopwatch    = Stopwatch.StartNew();
                            FindRuntimeDependencies(
                                runtimeName,
                                runtimeFiles,
                                runtimeDependencies,
                                runtimeNames);
                            runtimeStopwatch.Stop();
                            Reports.WriteVerbose($" Scanned Runtime graph in {runtimeStopwatch.ElapsedMilliseconds:0.00}ms");

                            // If there are no runtime specs in the graph, we still want to restore for the specified runtime, so synthesize one
                            if (!runtimeNames.Any(r => r.Equals(runtimeName)))
                            {
                                runtimeNames.Add(runtimeName);
                            }

                            var runtimeContext = new RestoreContext
                            {
                                FrameworkName           = pair.context.FrameworkName,
                                ProjectLibraryProviders = pair.context.ProjectLibraryProviders,
                                LocalLibraryProviders   = pair.context.LocalLibraryProviders,
                                RemoteLibraryProviders  = pair.context.RemoteLibraryProviders,
                                RuntimeName             = runtimeName,
                                AllRuntimeNames         = runtimeNames,
                                RuntimeDependencies     = runtimeDependencies,
                                MatchCache = cache
                            };
                            var projectLibrary = new LibraryRange(project.Name, frameworkReference: false)
                            {
                                VersionRange = new SemanticVersionRange(project.Version)
                            };

                            runtimeTasks.Add(CreateGraphNode(restoreOperations, runtimeContext, projectLibrary, _ => true));
                        }
                    }

                    var runtimeTragetContexts = await Task.WhenAll(runtimeTasks);

                    foreach (var runtimeTargetContext in runtimeTragetContexts)
                    {
                        Reduce(runtimeTargetContext.Root);
                    }

                    targetContexts = targetContexts.Concat(runtimeTragetContexts).ToArray();
                }
            }

            var graphItems   = new List <GraphItem>();
            var installItems = new List <GraphItem>();
            var missingItems = new HashSet <LibraryRange>();

            foreach (var context in targetContexts)
            {
                ForEach(context.Root, node =>
                {
                    if (node == null || node.LibraryRange == null)
                    {
                        return;
                    }

                    if (node.Item == null || node.Item.Match == null)
                    {
                        // This is a workaround for #1322. Since we use restore to generate the lock file
                        // after publish, it's possible to fail restore after copying the closure
                        if (!IgnoreMissingDependencies)
                        {
                            if (!node.LibraryRange.IsGacOrFrameworkReference &&
                                missingItems.Add(node.LibraryRange))
                            {
                                var versionString = node.LibraryRange.VersionRange == null ?
                                                    string.Empty :
                                                    (" " + node.LibraryRange.VersionRange.ToString());
                                var errorMessage =
                                    $"Unable to locate {DependencyTargets.GetDisplayForTarget(node.LibraryRange.Target)} " +
                                    $"{node.LibraryRange.Name.Red().Bold()}{versionString}";
                                summary.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 = node.Item.Match.Library.ChangeName(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)
                    {
                        // It's ok to download rejected nodes so we avoid downloading them in the future
                        // The trade off is that subsequent restores avoid going to any remotes
                        installItems.Add(node.Item);
                    }

                    // Don't add rejected nodes since we only want to write reduced nodes
                    // to the lock file
                    if (node.Disposition != GraphNode.DispositionType.Rejected)
                    {
                        var isGraphItem = graphItems.Any(item => item.Match.Library == node.Item.Match.Library);

                        if (!isGraphItem)
                        {
                            graphItems.Add(node.Item);
                        }

                        context.Matches.Add(node.Item.Match);
                    }
                });
            }

            if (!SkipInstall)
            {
                await InstallPackages(installItems, packagesDirectory);

                summary.InstallCount += installItems.Count;
            }

            if (!useLockFile)
            {
                Reports.Information.WriteLine(string.Format("Writing lock file {0}", projectLockFilePath.White().Bold()));

                var repository = new PackageRepository(packagesDirectory);

                WriteLockFile(lockFile,
                              projectLockFilePath,
                              project,
                              graphItems,
                              repository,
                              projectResolver,
                              targetContexts);
            }

            if (!SkipRestoreEvents)
            {
                if (!ScriptExecutor.Execute(project, "postrestore", getVariable))
                {
                    summary.ErrorMessages.GetOrAdd("postrestore", _ => new List <string>()).Add(ScriptExecutor.ErrorMessage);
                    Reports.Error.WriteLine(ScriptExecutor.ErrorMessage);
                    return(false);
                }

                if (!ScriptExecutor.Execute(project, "prepare", getVariable))
                {
                    summary.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 #3
0
        private async Task <bool> Execute(string restoreDirectory, PackageFeedCache packageFeeds, SummaryContext summary)
        {
            try
            {
                var sw = Stopwatch.StartNew();

                IEnumerable <string> projectJsonFiles;
                if (!RestoreProjectsCollector.Find(restoreDirectory, out projectJsonFiles))
                {
                    var errorMessage = $"The given root {restoreDirectory.Red().Bold()} is invalid.";
                    summary.ErrorMessages.GetOrAdd(restoreDirectory, _ => new List <string>()).Add(errorMessage);
                    Reports.Error.WriteLine(errorMessage);
                    return(false);
                }

                var rootDirectory = ProjectResolver.ResolveRootDirectory(restoreDirectory);
                ReadSettings(rootDirectory);

                var settings = Config.Settings as Settings;
                if (settings != null)
                {
                    var configFiles = settings.GetConfigFiles();
                    foreach (var file in configFiles)
                    {
                        summary.InformationMessages.GetOrAdd("NuGet Config files used:", _ => new List <string>()).Add(file);
                    }
                }

                string packagesDirectory = FeedOptions.TargetPackagesFolder;

                if (string.IsNullOrEmpty(packagesDirectory))
                {
                    packagesDirectory = NuGetDependencyResolver.ResolveRepositoryPath(rootDirectory);
                }

                var packagesFolderFileSystem = CreateFileSystem(packagesDirectory);
                var pathResolver             = new DefaultPackagePathResolver(packagesDirectory);

                var effectiveSources = PackageSourceUtils.GetEffectivePackageSources(
                    Config.Sources,
                    FeedOptions.Sources,
                    FeedOptions.FallbackSources);

                var remoteProviders = new List <IWalkProvider>();
                AddRemoteProvidersFromSources(remoteProviders, effectiveSources, packageFeeds, summary);

                int restoreCount = 0;
                int successCount = 0;

                Func <string, Task> restorePackage = async projectJsonPath =>
                {
                    Interlocked.Increment(ref restoreCount);
                    var success = await RestoreForProject(projectJsonPath, rootDirectory, packagesDirectory, remoteProviders, summary);

                    if (success)
                    {
                        Interlocked.Increment(ref successCount);
                    }
                };

                if (!RestoringInParallel())
                {
                    // Restoring in parallel on Mono throws native exception
                    foreach (var projectJsonFile in projectJsonFiles)
                    {
                        await restorePackage(projectJsonFile);
                    }
                }
                else
                {
                    await ForEachAsync(
                        projectJsonFiles,
                        MaxDegreesOfConcurrency,
                        restorePackage);
                }

                if (restoreCount > 1)
                {
                    Reports.Information.WriteLine(string.Format("Total time {0}ms", sw.ElapsedMilliseconds));
                }

                if (summary.InstallCount > 0)
                {
                    summary.InformationMessages.GetOrAdd("Installed:", _ => new List <string>()).Add($"{summary.InstallCount} package(s) to {packagesDirectory}");
                }

                return(restoreCount == successCount);
            }
            catch (Exception ex)
            {
                Reports.Information.WriteLine("----------");
                Reports.Information.WriteLine(ex.ToString());
                Reports.Information.WriteLine("----------");
                Reports.Information.WriteLine("Restore failed");
                Reports.Information.WriteLine(ex.Message);
                return(false);
            }
        }
Example #4
0
        public async Task <bool> ExecuteCommand()
        {
            if (string.IsNullOrEmpty(_addCommand.Name))
            {
                Reports.Error.WriteLine("Name of dependency to install is required.".Red());
                return(false);
            }

            SemanticVersion version = null;

            if (!string.IsNullOrEmpty(_addCommand.Version))
            {
                version = SemanticVersion.Parse(_addCommand.Version);
            }

            // Create source provider from solution settings
            _addCommand.ProjectDir = _addCommand.ProjectDir ?? Directory.GetCurrentDirectory();

            var rootDir    = ProjectResolver.ResolveRootDirectory(_addCommand.ProjectDir);
            var fileSystem = new PhysicalFileSystem(Directory.GetCurrentDirectory());
            var settings   = SettingsUtils.ReadSettings(solutionDir: rootDir,
                                                        nugetConfigFile: null,
                                                        fileSystem: fileSystem,
                                                        machineWideSettings: new CommandLineMachineWideSettings());
            var sourceProvider = PackageSourceBuilder.CreateSourceProvider(settings);

            var effectiveSources = PackageSourceUtils.GetEffectivePackageSources(sourceProvider,
                                                                                 _restoreCommand.FeedOptions.Sources, _restoreCommand.FeedOptions.FallbackSources);

            var packageFeeds = new PackageFeedCache();
            var feeds        = new List <IPackageFeed>();

            foreach (var source in effectiveSources)
            {
                var feed = packageFeeds.GetPackageFeed(
                    source,
                    _restoreCommand.FeedOptions.NoCache,
                    _restoreCommand.FeedOptions.IgnoreFailedSources,
                    Reports);
                if (feed != null)
                {
                    feeds.Add(feed);
                }
            }

            PackageInfo result = null;

            if (version == null)
            {
                result = await PackageSourceUtils.FindLatestPackage(feeds, _addCommand.Name);
            }
            else
            {
                result = await PackageSourceUtils.FindBestMatchPackage(feeds, _addCommand.Name, new SemanticVersionRange(version));
            }

            if (result == null)
            {
                Reports.Error.WriteLine("Unable to locate {0} >= {1}",
                                        _addCommand.Name.Red().Bold(), _addCommand.Version);
                return(false);
            }

            if (string.IsNullOrEmpty(_addCommand.Version))
            {
                _addCommand.Version = result.Version.ToString();
            }

            return(_addCommand.ExecuteCommand() && (await _restoreCommand.Execute()));
        }
Example #5
0
        private async Task <bool> Execute(string restoreDirectory, SummaryContext summary)
        {
            try
            {
                var sw = Stopwatch.StartNew();

                var projectJsonFiles = new List <string>();

                if (string.Equals(
                        Runtime.Project.ProjectFileName,
                        Path.GetFileName(restoreDirectory),
                        StringComparison.OrdinalIgnoreCase) && File.Exists(restoreDirectory))
                {
                    // If the path is a project.json file we don't do recursive search in subfolders
                    projectJsonFiles.Add(restoreDirectory);
                }
                else if (Directory.Exists(restoreDirectory))
                {
                    var projectJsonFile = Path.Combine(restoreDirectory, Runtime.Project.ProjectFileName);
                    if (File.Exists(projectJsonFile))
                    {
                        // If the path contains a project.json file we don't do recursive search in subfolders
                        projectJsonFiles.Add(projectJsonFile);
                    }
                    else
                    {
                        projectJsonFiles.AddRange(Directory.EnumerateFiles(
                                                      restoreDirectory,
                                                      Runtime.Project.ProjectFileName,
                                                      SearchOption.AllDirectories));
                    }
                }
                else
                {
                    var errorMessage = $"The given root {restoreDirectory.Red().Bold()} is invalid.";
                    summary.ErrorMessages.GetOrAdd(restoreDirectory, _ => new List <string>()).Add(errorMessage);
                    Reports.Error.WriteLine(errorMessage);
                    return(false);
                }

                var rootDirectory = ProjectResolver.ResolveRootDirectory(restoreDirectory);
                ReadSettings(rootDirectory);

                var settings = Config.Settings as Settings;
                if (settings != null)
                {
                    var configFiles = settings.GetConfigFiles();
                    foreach (var file in configFiles)
                    {
                        summary.InformationMessages.GetOrAdd("NuGet Config files used:", _ => new List <string>()).Add(file);
                    }
                }

                string packagesDirectory = FeedOptions.TargetPackagesFolder;

                if (string.IsNullOrEmpty(packagesDirectory))
                {
                    packagesDirectory = NuGetDependencyResolver.ResolveRepositoryPath(rootDirectory);
                }

                var packagesFolderFileSystem = CreateFileSystem(packagesDirectory);
                var pathResolver             = new DefaultPackagePathResolver(packagesDirectory);

                int restoreCount = 0;
                int successCount = 0;

                Func <string, Task> restorePackage = async projectJsonPath =>
                {
                    Interlocked.Increment(ref restoreCount);
                    var success = await RestoreForProject(projectJsonPath, rootDirectory, packagesDirectory, summary);

                    if (success)
                    {
                        Interlocked.Increment(ref successCount);
                    }
                };

                if (!RestoringInParallel())
                {
                    // Restoring in parallel on Mono throws native exception
                    foreach (var projectJsonFile in projectJsonFiles)
                    {
                        await restorePackage(projectJsonFile);
                    }
                }
                else
                {
                    await ForEachAsync(
                        projectJsonFiles,
                        MaxDegreesOfConcurrency,
                        restorePackage);
                }

                if (restoreCount > 1)
                {
                    Reports.Information.WriteLine(string.Format("Total time {0}ms", sw.ElapsedMilliseconds));
                }

                if (summary.InstallCount > 0)
                {
                    summary.InformationMessages.GetOrAdd("Installed:", _ => new List <string>()).Add($"{summary.InstallCount} package(s) to {packagesDirectory}");
                }

                return(restoreCount == successCount);
            }
            catch (Exception ex)
            {
                Reports.Information.WriteLine("----------");
                Reports.Information.WriteLine(ex.ToString());
                Reports.Information.WriteLine("----------");
                Reports.Information.WriteLine("Restore failed");
                Reports.Information.WriteLine(ex.Message);
                return(false);
            }
        }
Example #6
0
        private void EmitProjectWrapper(XElement projectElement)
        {
            var projectFile = Path.GetFullPath(projectElement.Attribute("projectFile").Value);

            // Name of the wrapper project is output assembly name, instead of .csproj file name
            var outputAssemblyPath = GetOutputAssemblyPath(projectElement);

            outputAssemblyPath = GetConfigAgnosticAssemblyPath(outputAssemblyPath);
            var projectName = Path.GetFileNameWithoutExtension(outputAssemblyPath);

            var projectDir = Path.GetDirectoryName(projectFile);
            var rootDir    = ResolveRootDirectory(projectDir);
            var wrapRoot   = Path.Combine(rootDir, WrapRootName);

            string targetProjectJson;

            if (InPlace)
            {
                targetProjectJson = Path.Combine(projectDir, Runtime.Project.ProjectFileName);
            }
            else
            {
                var projectResolver = new ProjectResolver(projectDir, rootDir);
                targetProjectJson = LocateExistingProject(projectResolver, projectName);
                if (string.IsNullOrEmpty(targetProjectJson))
                {
                    AddWrapFolderToGlobalJson(rootDir);
                    targetProjectJson = Path.Combine(wrapRoot, projectName, Runtime.Project.ProjectFileName);
                }
            }

            var targetFramework = GetTargetFramework(projectElement);

            Reports.Information.WriteLine("Wrapping project '{0}' for '{1}'", projectName, targetFramework);
            Reports.Information.WriteLine("  Source {0}", projectFile.Bold());
            Reports.Information.WriteLine("  Target {0}", targetProjectJson.Bold());

            var projectJson = LoadOrCreateProjectJson(targetProjectJson);

            var relativeCsProjectPath = PathUtility.GetRelativePath(targetProjectJson, projectFile, PathSeparator);

            AddWrappedProjectPath(projectJson, relativeCsProjectPath, targetFramework);

            // Add 'assembly' and 'pdb' to 'bin' section of the target framework
            var relativeAssemblyPath = PathUtility.GetRelativePath(targetProjectJson, outputAssemblyPath, PathSeparator);
            var relativePdbPath      = Path.ChangeExtension(relativeAssemblyPath, ".pdb");

            Reports.Information.WriteLine("  Adding bin paths for '{0}'", targetFramework);
            Reports.Information.WriteLine("    Assembly: {0}", relativeAssemblyPath.Bold());
            Reports.Information.WriteLine("    Pdb: {0}", relativePdbPath.Bold());
            AddFrameworkBinPaths(projectJson, targetFramework, relativeAssemblyPath, relativePdbPath);

            var nugetPackages     = ResolveNuGetPackages(projectDir);
            var nugetPackagePaths = nugetPackages.Select(x => x.Path);

            // Add nuget dependency to 'dependencies' section of the target framework
            foreach (var package in nugetPackages)
            {
                Reports.Information.WriteLine("  Adding package dependency '{0}.{1}'",
                                              package.Identity, package.Version);
                AddNuGetDependency(projectJson, package, targetFramework);
            }

            // Add dependency projects to 'dependencies' section of the target framework
            foreach (var itemElement in GetItemsByType(projectElement, type: "ProjectReference"))
            {
                var referenceProjectName = GetMetadataValue(itemElement, "Name");
                var outputName           = GetReferenceProjectOutputName(projectElement, referenceProjectName);
                Reports.Information.WriteLine("  Adding project dependency '{0}.{1}'",
                                              outputName, WrapperProjectVersion);
                AddProjectDependency(projectJson, outputName, targetFramework);
            }

            // Create wrapper projects for assembly references
            // and add wrapper projects as project references
            foreach (var itemElement in GetItemsByType(projectElement, type: "ReferencePath"))
            {
                if (IsAssemblyFromProjectReference(itemElement) ||
                    IsFrameworkAssembly(itemElement) ||
                    IsAssemblyFromNuGetPackage(itemElement, nugetPackagePaths))
                {
                    continue;
                }

                // This assembly becomes a project reference
                var assemblyPath        = itemElement.Attribute("evaluated").Value;
                var assemblyProjectName = Path.GetFileNameWithoutExtension(assemblyPath);

                EmitAssemblyWrapper(wrapRoot, targetFramework, assemblyPath, isSubProcedure: true);

                Reports.Information.WriteLine("  Adding project dependency '{0}.{1}'",
                                              assemblyProjectName, WrapperProjectVersion);
                AddProjectDependency(projectJson, assemblyProjectName, targetFramework);
                AddWrapFolderToGlobalJson(rootDir);
            }

            PathUtility.EnsureParentDirectory(targetProjectJson);
            File.WriteAllText(targetProjectJson, projectJson.ToString());

            AddToGlobalJsonSources(rootDir, Path.GetDirectoryName(targetProjectJson));

            Reports.Information.WriteLine();
        }