private void EnsureToolJsonDepsFileExists(
     LockFile toolLockFile,
     NuGetFramework framework,
     string depsPath,
     SingleProjectInfo toolLibrary,
     string toolDepsJsonGeneratorProject)
 {
     if (!File.Exists(depsPath))
     {
         GenerateDepsJsonFile(toolLockFile, framework, depsPath, toolLibrary, toolDepsJsonGeneratorProject);
     }
 }
        private string GetToolLockFilePath(
            SingleProjectInfo toolLibrary,
            NuGetFramework framework,
            string nugetPackagesRoot)
        {
            var toolPathCalculator = new ToolPathCalculator(nugetPackagesRoot);

            return(toolPathCalculator.GetBestLockFilePath(
                       toolLibrary.Name,
                       VersionRange.Parse(toolLibrary.Version),
                       framework));
        }
        private LockFile GetToolLockFile(
            SingleProjectInfo toolLibrary,
            NuGetFramework framework,
            IEnumerable <string> possibleNugetPackagesRoot)
        {
            foreach (var packagesRoot in possibleNugetPackagesRoot)
            {
                if (TryGetToolLockFile(toolLibrary, framework, packagesRoot, out LockFile lockFile))
                {
                    return(lockFile);
                }
            }

            return(null);
        }
        private string GetToolDepsFilePath(
            SingleProjectInfo toolLibrary,
            NuGetFramework framework,
            LockFile toolLockFile,
            string depsPathRoot,
            string toolDepsJsonGeneratorProject)
        {
            var depsJsonPath = Path.Combine(
                depsPathRoot,
                toolLibrary.Name + FileNameSuffixes.DepsJson);

            Reporter.Verbose.WriteLine(string.Format(
                                           LocalizableStrings.ExpectDepsJsonAt,
                                           ProjectToolsCommandResolverName,
                                           depsJsonPath));

            EnsureToolJsonDepsFileExists(toolLockFile, framework, depsJsonPath, toolLibrary, toolDepsJsonGeneratorProject);

            return(depsJsonPath);
        }
        internal void GenerateDepsJsonFile(
            LockFile toolLockFile,
            NuGetFramework framework,
            string depsPath,
            SingleProjectInfo toolLibrary,
            string toolDepsJsonGeneratorProject)
        {
            if (string.IsNullOrEmpty(toolDepsJsonGeneratorProject) ||
                !File.Exists(toolDepsJsonGeneratorProject))
            {
                throw new GracefulException(LocalizableStrings.DepsJsonGeneratorProjectNotSet);
            }

            Reporter.Verbose.WriteLine(string.Format(
                                           LocalizableStrings.GeneratingDepsJson,
                                           depsPath));

            var tempDepsFile = Path.GetTempFileName();

            var args = new List <string>();

            args.Add(toolDepsJsonGeneratorProject);
            args.Add($"-property:ProjectAssetsFile=\"{toolLockFile.Path}\"");
            args.Add($"-property:ToolName={toolLibrary.Name}");
            args.Add($"-property:ProjectDepsFilePath={tempDepsFile}");

            var toolTargetFramework = toolLockFile.Targets.First().TargetFramework.GetShortFolderName();

            args.Add($"-property:TargetFramework={toolTargetFramework}");


            //  Look for the .props file in the Microsoft.NETCore.App package, until NuGet
            //  generates .props and .targets files for tool restores (https://github.com/NuGet/Home/issues/5037)
            var platformLibrary = toolLockFile.Targets
                                  .FirstOrDefault(t => framework == t.TargetFramework)
                                  ?.GetPlatformLibrary();

            if (platformLibrary != null)
            {
                string buildRelativePath = platformLibrary.Build.FirstOrDefault()?.Path;

                var platformLibraryPath = toolLockFile.GetPackageDirectory(platformLibrary);

                if (platformLibraryPath != null && buildRelativePath != null)
                {
                    //  Get rid of "_._" filename
                    buildRelativePath = Path.GetDirectoryName(buildRelativePath);

                    string platformLibraryBuildFolderPath = Path.Combine(platformLibraryPath, buildRelativePath);
                    var    platformLibraryPropsFile       = Directory.GetFiles(platformLibraryBuildFolderPath, "*.props").FirstOrDefault();

                    if (platformLibraryPropsFile != null)
                    {
                        args.Add($"-property:AdditionalImport={platformLibraryPropsFile}");
                    }
                }
            }

            //  Delete temporary file created by Path.GetTempFileName(), otherwise the GenerateBuildDependencyFile target
            //  will think the deps file is up-to-date and skip executing
            File.Delete(tempDepsFile);

            var msBuildExePath = _environment.GetEnvironmentVariable(Constants.MSBUILD_EXE_PATH);

            msBuildExePath = string.IsNullOrEmpty(msBuildExePath) ?
                             Path.Combine(AppContext.BaseDirectory, "MSBuild.dll") :
                             msBuildExePath;

            Reporter.Verbose.WriteLine(string.Format(LocalizableStrings.MSBuildArgs,
                                                     ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(args)));

            var result = new MSBuildForwardingAppWithoutLogging(args, msBuildExePath)
                         .GetProcessStartInfo()
                         .ExecuteAndCaptureOutput(out string stdOut, out string stdErr);

            if (result != 0)
            {
                Reporter.Verbose.WriteLine(string.Format(
                                               LocalizableStrings.UnableToGenerateDepsJson,
                                               stdOut + Environment.NewLine + stdErr));

                throw new GracefulException(string.Format(LocalizableStrings.UnableToGenerateDepsJson, toolDepsJsonGeneratorProject));
            }

            try
            {
                File.Move(tempDepsFile, depsPath);
            }
            catch (Exception e)
            {
                Reporter.Verbose.WriteLine(string.Format(
                                               LocalizableStrings.UnableToGenerateDepsJson,
                                               e.Message));

                try
                {
                    File.Delete(tempDepsFile);
                }
                catch (Exception e2)
                {
                    Reporter.Verbose.WriteLine(string.Format(
                                                   LocalizableStrings.UnableToDeleteTemporaryDepsJson,
                                                   e2.Message));
                }
            }
        }
        private CommandSpec ResolveCommandSpecFromToolLibrary(
            SingleProjectInfo toolLibraryRange,
            string commandName,
            IEnumerable <string> args,
            IProject project)
        {
            Reporter.Verbose.WriteLine(string.Format(
                                           LocalizableStrings.AttemptingToResolveCommandSpec,
                                           ProjectToolsCommandResolverName,
                                           toolLibraryRange.Name));

            var possiblePackageRoots = GetPossiblePackageRoots(project).ToList();

            Reporter.Verbose.WriteLine(string.Format(
                                           LocalizableStrings.NuGetPackagesRoot,
                                           ProjectToolsCommandResolverName,
                                           string.Join(Environment.NewLine, possiblePackageRoots.Select((p) => $"- {p}"))));

            List <NuGetFramework> toolFrameworksToCheck = new List <NuGetFramework>();

            toolFrameworksToCheck.Add(project.DotnetCliToolTargetFramework);

            //  NuGet restore in Visual Studio may restore for netcoreapp1.0.  So if that happens, fall back to
            //  looking for a netcoreapp1.0 or netcoreapp1.1 tool restore.
            if (project.DotnetCliToolTargetFramework.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp &&
                project.DotnetCliToolTargetFramework.Version >= new Version(2, 0, 0))
            {
                toolFrameworksToCheck.Add(NuGetFramework.Parse("netcoreapp1.1"));
                toolFrameworksToCheck.Add(NuGetFramework.Parse("netcoreapp1.0"));
            }


            LockFile       toolLockFile        = null;
            NuGetFramework toolTargetFramework = null;;

            foreach (var toolFramework in toolFrameworksToCheck)
            {
                toolLockFile = GetToolLockFile(
                    toolLibraryRange,
                    toolFramework,
                    possiblePackageRoots);

                if (toolLockFile != null)
                {
                    toolTargetFramework = toolFramework;
                    break;
                }
            }

            if (toolLockFile == null)
            {
                return(null);
            }

            Reporter.Verbose.WriteLine(string.Format(
                                           LocalizableStrings.FoundToolLockFile,
                                           ProjectToolsCommandResolverName,
                                           toolLockFile.Path));

            var toolLibrary = toolLockFile.Targets
                              .FirstOrDefault(t => toolTargetFramework == t.TargetFramework)
                              ?.Libraries.FirstOrDefault(
                l => StringComparer.OrdinalIgnoreCase.Equals(l.Name, toolLibraryRange.Name));

            if (toolLibrary == null)
            {
                Reporter.Verbose.WriteLine(string.Format(
                                               LocalizableStrings.LibraryNotFoundInLockFile,
                                               ProjectToolsCommandResolverName));

                return(null);
            }

            var depsFileRoot = Path.GetDirectoryName(toolLockFile.Path);

            var depsFilePath = GetToolDepsFilePath(
                toolLibraryRange,
                toolTargetFramework,
                toolLockFile,
                depsFileRoot,
                project.ToolDepsJsonGeneratorProject);

            Reporter.Verbose.WriteLine(string.Format(
                                           LocalizableStrings.AttemptingToCreateCommandSpec,
                                           ProjectToolsCommandResolverName));

            var commandSpec = _packagedCommandSpecFactory.CreateCommandSpecFromLibrary(
                toolLibrary,
                commandName,
                args,
                _allowedCommandExtensions,
                toolLockFile,
                depsFilePath,
                null);

            if (commandSpec == null)
            {
                Reporter.Verbose.WriteLine(string.Format(
                                               LocalizableStrings.CommandSpecIsNull,
                                               ProjectToolsCommandResolverName));
            }

            commandSpec?.AddEnvironmentVariablesFromProject(project);

            return(commandSpec);
        }