Exemplo n.º 1
0
        /// <summary>
        /// Extract the package contents to the specified directory. Standard metadata will be deleted, e.g. _rels folder, .nuspec file, etc.
        /// </summary>
        /// <param name="destinationDirectory">The directory where the package will be extracted.</param>
        public void Extract(string destinationDirectory, IEnumerable <string> exclusionPatterns)
        {
            if (Directory.Exists(destinationDirectory))
            {
                Directory.Delete(destinationDirectory, recursive: true);
            }
            Directory.CreateDirectory(destinationDirectory);
            ZipFile.ExtractToDirectory(PackagePath, destinationDirectory);

            // Remove unnecessary files and directories
            Utils.DeleteDirectory(Path.Combine(destinationDirectory, "_rels"));
            Utils.DeleteDirectory(Path.Combine(destinationDirectory, "package"));

            Utils.DeleteFile(Path.Combine(destinationDirectory, ".signature.p7s"));
            Utils.DeleteFile(Path.Combine(destinationDirectory, "[Content_Types].xml"));
            Utils.DeleteFile(Path.Combine(destinationDirectory, $"{Id}.nuspec"));

            if (exclusionPatterns.Count() > 0)
            {
                IEnumerable <string> allFiles      = Directory.EnumerateFiles(destinationDirectory, "*.*", SearchOption.AllDirectories);
                IEnumerable <string> filesToDelete = allFiles.Where(f => exclusionPatterns.Any(p => Regex.IsMatch(f, p)));

                Log?.LogMessage(MessageImportance.High, $"Found {filesToDelete.Count()} files matching exclusion patterns.");

                foreach (string file in filesToDelete)
                {
                    Log?.LogMessage(MessageImportance.High, $"Deleting '{file}'.");
                    File.Delete(file);
                }
            }
        }
Exemplo n.º 2
0
        SolutionNode AddProject(
            string projectPath,
            string solutionFolder = null,
            Guid projectGuid      = default)
        {
            if (projectPath == null)
            {
                throw new ArgumentNullException(nameof(projectPath));
            }

            var solutionDirectory = Path.GetDirectoryName(FileName);

            if (string.IsNullOrEmpty(solutionDirectory))
            {
                solutionDirectory = ".";
            }

            var relativePath = MakeRelativePath(solutionDirectory, projectPath);

            if (projectGuid == default)
            {
                // for the GUID, force path separators so Win vs Mac produces the same
                projectGuid = GuidV5(solutionGuid, relativePath.Replace('\\', '/'));
            }

            var parentNode = solution;

            if (!string.IsNullOrEmpty(solutionFolder))
            {
                foreach (var name in solutionFolder.Split('\\', '/'))
                {
                    var folderAddOperation = parentNode.AddFolder(name);
                    parentNode = folderAddOperation.node;
                    if (folderAddOperation.added)
                    {
                        log?.LogMessage(MessageImportance.Normal, $"Added solution folder: {solutionFolder}");
                    }
                }
            }

            log?.LogMessage(MessageImportance.Normal, $"Adding project: {relativePath}");

            var(projectNode, addedProject) = parentNode.AddProject(
                projectGuid,
                relativePath);

            if (addedProject && log != null)
            {
                log.LogMessage(MessageImportance.Normal, $"Added project: {relativePath} ({projectGuid})");
                log.LogMessage(MessageImportance.Low, $"  solutionDirectory: {solutionDirectory}");
                log.LogMessage(MessageImportance.Low, $"  projectPath: {projectPath}");
            }

            return(projectNode);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a <see cref="VisualStudioComponent"/> using a workload definition.
        /// </summary>
        /// <param name="manifest"></param>
        /// <param name="workload"></param>
        /// <param name="componentVersions"></param>
        /// <param name="shortNames"></param>
        /// <param name="shortNameMetadata"></param>
        /// <param name="componentResources"></param>
        /// <returns></returns>
        public static VisualStudioComponent Create(TaskLoggingHelper log, WorkloadManifest manifest, WorkloadDefinition workload, ITaskItem[] componentVersions,
                                                   ITaskItem[] shortNames, ITaskItem[] componentResources, ITaskItem[] missingPacks)
        {
            log?.LogMessage("Creating Visual Studio component");
            string workloadId = $"{workload.Id}";

            // If there's an explicit version mapping we use that, otherwise we fall back to the manifest version
            // and normalize it since it can have semantic information and Visual Studio components do not support that.
            ITaskItem versionItem = componentVersions?.Where(v => string.Equals(v.ItemSpec, workloadId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
            Version   version     = (versionItem != null) && !string.IsNullOrWhiteSpace(versionItem.GetMetadata(Metadata.Version))
                ? new Version(versionItem.GetMetadata(Metadata.Version))
                : (new NuGetVersion(manifest.Version)).Version;

            ITaskItem resourceItem = componentResources?.Where(
                r => string.Equals(r.ItemSpec, workloadId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

            // Workload definitions do not have separate title/description fields so the only option
            // is to default to the workload description for both.
            string title       = resourceItem?.GetMetadata(Metadata.Title) ?? workload.Description;
            string description = resourceItem?.GetMetadata(Metadata.Description) ?? workload.Description;
            string category    = resourceItem?.GetMetadata(Metadata.Category) ?? ".NET";
            string isUiGroup   = workload.IsAbstract ? "yes" : "no";

            VisualStudioComponent component = new(Utils.ToSafeId(workloadId), description,
                                                  title, version, isUiGroup, shortNames, category);

            IEnumerable <string> missingPackIds = missingPacks.Select(p => p.ItemSpec);

            log?.LogMessage(MessageImportance.Low, $"Missing packs: {string.Join(", ", missingPackIds)}");

            // If the work extends other workloads, we add those as component dependencies before
            // processing direct pack dependencies
            if (workload.Extends?.Count() > 0)
            {
                foreach (WorkloadDefinitionId dependency in workload.Extends)
                {
                    // Component dependencies, aka. workload extensions only have minimum version dependencies.
                    component.AddDependency($"{Utils.ToSafeId(dependency.ToString())}", new Version("1.0.0.0"), maxVersion: null);
                }
            }

            // Visual Studio is case-insensitive.
            IEnumerable <WorkloadPackId> packIds = workload.Packs.Where(p => !missingPackIds.Contains($"{p}", StringComparer.OrdinalIgnoreCase));

            log?.LogMessage(MessageImportance.Low, $"Packs: {string.Join(", ", packIds.Select(p=>$"{p}"))}");

            foreach (WorkloadPackId packId in packIds)
            {
                log?.LogMessage(MessageImportance.Low, $"Adding component dependency for {packId} ");
                component.AddDependency(manifest.Packs[packId]);
            }

            return(component);
        }
Exemplo n.º 4
0
        private static Assembly AssemblyResolve(object sender, ResolveEventArgs args)
        {
            var name = new AssemblyName(args.Name);

            if (!name.Name.Equals("System.Collections.Immutable", StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }

            var fullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "System.Collections.Immutable.dll");

            Assembly sci;

            try
            {
                sci = Assembly.LoadFile(fullPath);
            }
            catch (Exception e)
            {
                Log?.LogWarning($"AssemblyResolve: exception while loading '{fullPath}': {e.Message}");
                return(null);
            }

            if (name.Version <= sci.GetName().Version)
            {
                Log?.LogMessage(MessageImportance.Low, $"AssemblyResolve: loaded '{fullPath}' to {AppDomain.CurrentDomain.FriendlyName}");
                return(sci);
            }

            return(null);
        }
Exemplo n.º 5
0
        public void Log <TState>(Microsoft.Extensions.Logging.LogLevel logLevel, Microsoft.Extensions.Logging.EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter)
        {
            if (formatter == null)
            {
                throw new ArgumentNullException(nameof(formatter));
            }

            var message = formatter(state, exception);

            if (string.IsNullOrEmpty(message))
            {
                return;
            }

            switch (logLevel)
            {
            case Microsoft.Extensions.Logging.LogLevel.Error:
                _taskLog?.LogError(message);
                break;

            case Microsoft.Extensions.Logging.LogLevel.Warning:
                _taskLog?.LogWarning(message);
                break;

            case Microsoft.Extensions.Logging.LogLevel.Information:
                _taskLog?.LogMessage(MessageImportance.Normal, message);
                break;

            case Microsoft.Extensions.Logging.LogLevel.Debug:
                _taskLog?.LogMessage(MessageImportance.Low, message);
                break;

            default:
                _taskLog?.LogMessage(message);
                break;
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Creates a <see cref="VisualStudioComponent"/> using a workload definition.
        /// </summary>
        /// <param name="manifest"></param>
        /// <param name="workload"></param>
        /// <param name="componentVersion"></param>
        /// <param name="shortNames"></param>
        /// <param name="shortNameMetadata"></param>
        /// <param name="componentResources"></param>
        /// <returns></returns>
        public static VisualStudioComponent Create(TaskLoggingHelper log, WorkloadManifest manifest, WorkloadDefinition workload, string componentVersion,
                                                   ITaskItem[] shortNames, ITaskItem[] componentResources, ITaskItem[] missingPacks)
        {
            log?.LogMessage("Creating Visual Studio component");
            Version version = string.IsNullOrWhiteSpace(componentVersion) ? new Version($"{manifest.Version}.0") :
                              new Version(componentVersion);

            ITaskItem resourceItem = componentResources?.Where(
                r => string.Equals(r.ItemSpec, workload.Id.ToString(), StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

            // Workload definitions do not have separate title/description fields so the only option
            // is to default to the workload description for both.
            string title       = resourceItem?.GetMetadata(Metadata.Title) ?? workload.Description;
            string description = resourceItem?.GetMetadata(Metadata.Description) ?? workload.Description;
            string category    = resourceItem?.GetMetadata(Metadata.Category) ?? ".NET";

            VisualStudioComponent component = new(Utils.ToSafeId(workload.Id.ToString()), description,
                                                  title, version, shortNames, category);

            IEnumerable <string> missingPackIds = missingPacks.Select(p => p.ItemSpec);

            log?.LogMessage(MessageImportance.Low, $"Missing packs: {string.Join(", ", missingPackIds)}");

            // Visual Studio is case-insensitive.
            IEnumerable <WorkloadPackId> packIds = workload.Packs.Where(p => !missingPackIds.Contains($"{p}", StringComparer.OrdinalIgnoreCase));

            log?.LogMessage(MessageImportance.Low, $"Packs: {string.Join(", ", packIds.Select(p=>$"{p}"))}");

            foreach (WorkloadPackId packId in packIds)
            {
                log?.LogMessage(MessageImportance.Low, $"Adding component dependency for {packId} ");
                component.AddDependency(manifest.Packs[packId]);
            }

            return(component);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Store a POString in the dictionary, unless another string with the same msgid already exists.
        /// </summary>
        public static void StoreString(Dictionary <string, POString> dictTrans, POString poStr, TaskLoggingHelper log)
        {
            if (poStr.IsObsolete)
            {
                return;
            }
            var msgid = poStr.MsgIdAsString();

            if (dictTrans.ContainsKey(msgid))
            {
                log?.LogMessage("The message id '{0}' already exists.  Ignoring this occurrence around line {1}.", msgid, POString.InputLineNumber);
            }
            else
            {
                dictTrans.Add(msgid, poStr);
            }
        }
Exemplo n.º 8
0
 public void LogMessage(MessageImportance importance, string message, params object[] messageArgs)
 {
     _log.LogMessage(importance, message, messageArgs);
 }
Exemplo n.º 9
0
 public static void LogTaskProperty(this TaskLoggingHelper log, string propertyName, int value)
 {
     log.LogMessage(TaskPropertyImportance, "  {0}: {1}", propertyName, value);
 }
Exemplo n.º 10
0
        public static async Task <HttpResponseMessage> RequestWithRetry(TaskLoggingHelper loggingHelper, HttpClient client,
                                                                        Func <HttpRequestMessage> createRequest, Func <HttpResponseMessage, bool> validationCallback = null, int retryCount = 5,
                                                                        int retryDelaySeconds = 5)
        {
            if (loggingHelper == null)
            {
                throw new ArgumentNullException(nameof(loggingHelper));
            }
            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }
            if (createRequest == null)
            {
                throw new ArgumentNullException(nameof(createRequest));
            }
            if (retryCount < 1)
            {
                throw new ArgumentException(nameof(retryCount));
            }
            if (retryDelaySeconds < 1)
            {
                throw new ArgumentException(nameof(retryDelaySeconds));
            }

            int retries = 0;
            HttpResponseMessage response = null;

            // add a bit of randomness to the retry delay
            var rng = new Random();

            while (retries < retryCount)
            {
                if (retries > 0)
                {
                    if (response != null)
                    {
                        response.Dispose();
                        response = null;
                    }

                    int delay = retryDelaySeconds * retries * rng.Next(1, 5);
                    loggingHelper.LogMessage(MessageImportance.Low, "Waiting {0} seconds before retry", delay);
                    await System.Threading.Tasks.Task.Delay(delay * 1000);
                }

                try
                {
                    using (var request = createRequest())
                        response = await client.SendAsync(request);
                }
                catch (Exception e)
                {
                    loggingHelper.LogWarningFromException(e, true);

                    // if this is the final iteration let the exception bubble up
                    if (retries + 1 == retryCount)
                    {
                        throw;
                    }
                }

                // response can be null if we fail to send the request
                if (response != null)
                {
                    if (validationCallback == null)
                    {
                        // check if the response code is within the range of failures
                        if (IsWithinRetryRange(response.StatusCode))
                        {
                            loggingHelper.LogWarning("Request failed with status code {0}", response.StatusCode);
                        }
                        else
                        {
                            loggingHelper.LogMessage(MessageImportance.Low, "Response completed with status code {0}", response.StatusCode);
                            return(response);
                        }
                    }
                    else
                    {
                        bool isSuccess = validationCallback(response);
                        if (!isSuccess)
                        {
                            loggingHelper.LogMessage("Validation callback returned retry for status code {0}", response.StatusCode);
                        }
                        else
                        {
                            loggingHelper.LogMessage("Validation callback returned success for status code {0}", response.StatusCode);
                            return(response);
                        }
                    }
                }

                ++retries;
            }

            // retry count exceeded
            loggingHelper.LogWarning("Retry count {0} exceeded", retryCount);

            // set some default values in case response is null
            var statusCode = "None";
            var contentStr = "Null";

            if (response != null)
            {
                statusCode = response.StatusCode.ToString();
                contentStr = await response.Content.ReadAsStringAsync();

                response.Dispose();
            }

            throw new HttpRequestException(string.Format("Request failed with status {0} response {1}", statusCode, contentStr));
        }
Exemplo n.º 11
0
 public void WriteLine()
 {
     taskLog.LogMessage("\n");
 }
 public static void LogDebugMessage(this TaskLoggingHelper log, string message, params object[] messageArgs)
 {
     log.LogMessage(MessageImportance.Low, message, messageArgs);
 }
Exemplo n.º 13
0
        /// <summary>
        /// Creates a new <see cref="SolutionBuilder"/> from an MSBuild traversal project.
        /// </summary>
        /// <param name="projectPath">
        /// The path to the traversal project from which to populate the returned <see cref="SolutionBuilder"/>.
        /// </param>
        /// <param name="solutionOutputPath">
        /// The path to the solution that the returned <see cref="SolutionBuilder"/> should
        /// represent. This path is used to compute the relative path to projects.
        /// </param>
        /// <param name="addTransitiveProjectReferences">
        /// Whether or not to add transitive `&lt;ProjectReference&gt;` projects to the solution.
        /// </param>
        /// <param name="log">
        /// An optional logger.
        /// </param>
        public static SolutionBuilder FromTraversalProject(
            string projectPath,
            string solutionOutputPath           = null,
            bool addTransitiveProjectReferences = true,
            TaskLoggingHelper log = null)
        {
            if (projectPath == null)
            {
                throw new ArgumentNullException(nameof(projectPath));
            }

            if (!File.Exists(projectPath))
            {
                throw new FileNotFoundException($"project does not exist: {projectPath}");
            }

            projectPath = ResolveFullPath(projectPath);

            if (string.IsNullOrEmpty(solutionOutputPath))
            {
                solutionOutputPath = Path.ChangeExtension(projectPath, ".sln");
            }

            log?.LogMessage(MessageImportance.High, "Generating solution from traversal project");
            log?.LogMessage(MessageImportance.Normal, $"  projectPath: {projectPath}");
            log?.LogMessage(MessageImportance.Normal, $"  solutionOutputPath: {solutionOutputPath}");
            log?.LogMessage(MessageImportance.Normal, $"  addTransitiveProjectReferences: {addTransitiveProjectReferences}");

            var solution         = new SolutionBuilder(solutionOutputPath, log);
            var traversalProject = new ProjectCollection().LoadProject(projectPath);

            // Add the explicit solution configurations
            foreach (var item in traversalProject.GetItems("SolutionConfiguration"))
            {
                solution.AddSolutionConfiguration(ConfigurationPlatform.Parse(item.EvaluatedInclude));
            }

            // For each solution configuration, re-evaluate the whole project collection
            // with the mapped solution -> project configurations. This can result in
            // different project references (e.g. cross platform projects that might build
            // on windows and not mac, etc.).
            foreach (var item in traversalProject.GetItems("SolutionConfiguration"))
            {
                var solutionConfigurationPlatform = ConfigurationPlatform.Parse(item.EvaluatedInclude);
                var projectConfigurationPlatform  = new ConfigurationPlatform(
                    item.GetMetadataValue("Configuration") ?? solutionConfigurationPlatform.Configuration,
                    item.GetMetadataValue("Platform") ?? solutionConfigurationPlatform.Platform);

                var globalProperties = new List <(string, string)> {
                    ("IsGeneratingSolution", "true"),
                    ("Configuration", projectConfigurationPlatform.Configuration),
                    ("Platform", projectConfigurationPlatform.Platform)
                };
                globalProperties.AddRange(item.Metadata.Select(m => (m.Name, m.EvaluatedValue)));

                var graph = DependencyGraph
                            .Create(projectPath, globalProperties)
                            .LoadGraph();

                // Add each project. Projects may fail to load in MSBuild, for example, if an SDK
                // is not available via the running MSBuild toolchain. If this is the case, we
                // still need to handle adding the project to the solution, we just can't infer
                // anything therein.
                foreach (var node in graph.TopologicallySortedProjects)
                {
                    // Don't add the root traversal project to the solution
                    if (node.Parents.Count == 0)
                    {
                        continue;
                    }

                    // Prefer an explicit project GUID if one exists (old style projects)
                    Guid projectGuid         = default;
                    var  explicitProjectGuid = node.Project == null
                        ? XDocument
                                               .Load(node.ProjectPath)
                                               .Root
                                               .Elements()
                                               .FirstOrDefault(e => !e.HasAttributes && string.Equals(
                                                                   e.Name.LocalName,
                                                                   "PropertyGroup",
                                                                   StringComparison.OrdinalIgnoreCase))
                                               ?.Elements()
                                               .FirstOrDefault(e => string.Equals(
                                                                   e.Name.LocalName,
                                                                   "ProjectGuid",
                                                                   StringComparison.OrdinalIgnoreCase))
                                               ?.Value
                        : node.Project.GetPropertyValue("ProjectGuid");

                    if (!string.IsNullOrEmpty(explicitProjectGuid))
                    {
                        Guid.TryParse(explicitProjectGuid, out projectGuid);
                    }

                    string solutionFolder    = null;
                    var    includeInSolution = true;

                    foreach (var projectReference in node.ProjectReferenceItems)
                    {
                        if (string.Equals(
                                projectReference.GetMetadataValue("IncludeInSolution"),
                                "false",
                                StringComparison.OrdinalIgnoreCase))
                        {
                            includeInSolution = false;
                            break;
                        }

                        projectConfigurationPlatform = projectConfigurationPlatform
                                                       .WithConfiguration(projectReference.GetMetadataValue("Configuration"))
                                                       .WithPlatform(projectReference.GetMetadataValue("Platform"));

                        var _solutionFolder = projectReference.GetMetadataValue("SolutionFolder");
                        if (!string.IsNullOrEmpty(_solutionFolder))
                        {
                            solutionFolder = _solutionFolder;
                        }
                    }

                    if (!includeInSolution)
                    {
                        continue;
                    }

                    var solutionNode = solution.AddProject(
                        node.ProjectPath,
                        solutionFolder,
                        projectGuid);

                    solutionNode.AddConfigurationMap(new SolutionConfigurationPlatformMap(
                                                         solutionConfigurationPlatform,
                                                         projectConfigurationPlatform));
                }
            }

            return(solution);
        }
Exemplo n.º 14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="descriptors"></param>
        /// <param name="filePaths"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        internal bool TryExecuteAssemblyInfoBumpVersion(IEnumerable <IBumpVersionDescriptor> descriptors
                                                        , IEnumerable <string> filePaths, TaskLoggingHelper log = null)
        {
            /* ProjectFilename should be based on ProjectFullPath,
             * which should be relayed to us as the $(ProjectPath). */
            var projectFilename = ProjectFilename;

            // TODO: TBD: should consider logging the descriptors we do have here...
            // TODO: TBD: or possibly as a function of the targets themselves, if possible...

            // Ensure that we are dealing only with the Descriptors we can.
            descriptors = descriptors.Where(descriptor => descriptor.Kind.ContainedBy(AssemblyVersion
                                                                                      , AssemblyFileVersion, AssemblyInformationalVersion)).ToArray();

            if (!descriptors.Any())
            {
                return(false);
            }

            var services = descriptors.Select(d => d.MakeAssemblyInfoBumpVersionService(log))
                           .Where(x => x != null).ToArray();

            // ReSharper disable once CollectionNeverQueried.Local
            var results = new List <bool>();

            void OnUsingStatementAdded(object sender, UsingStatementAddedEventArgs e)
            {
                log?.LogMessage(High, $"'{projectFilename}': Adding statement '{e.UsingStatement}'");
            }

            void OnBumpResultFound(object sender, BumpResultEventArgs e)
            {
                // ReSharper disable once InvertIf
                if (e.Result is IAssemblyInfoBumpResult assyInfoResult)
                {
                    (assyInfoResult.DidBump ? log : null)?.LogMessage(High, GetMessage());

                    string GetMessage()
                    => $"'{projectFilename}': Bumped '{assyInfoResult.AttributeType.FullName}'"
                    + $" from '{e.Result.OldVersionAndSemanticString}'"
                    + $" to '{e.Result.VersionAndSemanticString}'";
                }
            }

            services.ToList().ForEach(service =>
            {
                service.UsingStatementAdded += OnUsingStatementAdded;
                service.BumpResultFound     += OnBumpResultFound;
            });

            foreach (var fullPath in filePaths.Where(Exists))
            {
                var bumped = false;

                // ReSharper disable once InvertIf
                if (TryReadingFileLines(fullPath, out var givenLines))
                {
#if TASK_LOGGING_HELPER_DIAGNOSTICS
                    log?.LogWarning($"Lines read from '{fullPath}'.");
#endif

                    foreach (var service in services)
                    {
                        service.Log = log;

#if TASK_LOGGING_HELPER_DIAGNOSTICS
                        log?.LogWarning($"Trying to bump lines from '{fullPath}'.");
#endif

                        // ReSharper disable once PossibleMultipleEnumeration
                        if (service.TryBumpVersion(givenLines, out var bumpedLines))
                        {
#if TASK_LOGGING_HELPER_DIAGNOSTICS
                            log?.LogWarning($"Lines bumped for '{fullPath}'.");
#endif

                            // ReSharper disable once PossibleMultipleEnumeration
                            bumped = bumped || !bumpedLines
                                     // ReSharper disable once PossibleMultipleEnumeration
                                     .SequenceEqual(givenLines);

                            if (!bumped)
                            {
                                continue;
                            }

                            // ReSharper disable once PossibleMultipleEnumeration
                            givenLines = bumpedLines.ToArray();
                        }
                    }

                    if (!bumped)
                    {
                        continue;
                    }

#if TASK_LOGGING_HELPER_DIAGNOSTICS
                    log?.LogWarning($"Writing lines to file '{fullPath}' ...");
#endif

                    // ReSharper disable once PossibleMultipleEnumeration
                    results.Add(TryWritingFileLines(fullPath, givenLines.ToArray()));
                }
                else
                {
#if TASK_LOGGING_HELPER_DIAGNOSTICS
                    log?.LogWarning($"Lines not read from '{fullPath}'.");
#endif

                    results.Add(false);
                }
            }

            services.ToList().ForEach(service =>
            {
                service.UsingStatementAdded -= OnUsingStatementAdded;
                service.BumpResultFound     -= OnBumpResultFound;
            });

            return(true);
        }
Exemplo n.º 15
0
        internal void Go(bool doStrongNameCheck)
        {
            VerifyCertificates(_log);

            if (_log.HasLoggedErrors)
            {
                return;
            }

            // Next remove public signing from all of the assemblies; it can interfere with the signing process.
            RemovePublicSign();

            // Next sign all of the files
            if (!SignFiles())
            {
                _log.LogError("Error during execution of signing process.");
                return;
            }

            if (!CopyFiles())
            {
                return;
            }

            // Check that all files have a strong name signature
            if (doStrongNameCheck)
            {
                VerifyStrongNameSigning();
            }

            // Validate the signing worked and produced actual signed binaries in all locations.
            // This is a recursive process since we process nested containers.
            foreach (var file in _batchData.FilesToSign)
            {
                VerifyAfterSign(file);
            }

            if (_log.HasLoggedErrors)
            {
                return;
            }

            _log.LogMessage(MessageImportance.High, "Build artifacts signed and validated.");
        }
Exemplo n.º 16
0
        /// <summary>
        ///     Determine whether a local package is the same as a package on an AzDO feed.
        /// </summary>
        /// <param name="localPackageFullPath"></param>
        /// <param name="packageContentUrl"></param>
        /// <param name="client"></param>
        /// <param name="log"></param>
        /// <param name="retryHandler"></param>
        /// <returns></returns>
        /// <remarks>
        ///     Open a stream to the local file and an http request to the package. There are a couple possibilities:
        ///     - The returned headers include a content MD5 header, in which case we can
        ///       hash the local file and just compare those.
        ///     - No content MD5 hash, and the streams must be compared in blocks. This is a bit trickier to do efficiently,
        ///       since we do not necessarily want to read all bytes if we can help it. Thus, we should compare in blocks.  However,
        ///       the streams make no guarantee that they will return a full block each time when read operations are performed, so we
        ///       must be sure to only compare the minimum number of bytes returned.
        /// </remarks>
        public static async Task <PackageFeedStatus> CompareLocalPackageToFeedPackage(
            string localPackageFullPath,
            string packageContentUrl,
            HttpClient client,
            TaskLoggingHelper log,
            IRetryHandler retryHandler)
        {
            log.LogMessage($"Getting package content from {packageContentUrl} and comparing to {localPackageFullPath}");

            PackageFeedStatus result = PackageFeedStatus.Unknown;

            bool success = await retryHandler.RunAsync(async attempt =>
            {
                try
                {
                    using (Stream localFileStream = File.OpenRead(localPackageFullPath))
                        using (HttpResponseMessage response = await client.GetAsync(packageContentUrl))
                        {
                            response.EnsureSuccessStatusCode();

                            // Check the headers for content length and md5
                            bool md5HeaderAvailable    = response.Headers.TryGetValues("Content-MD5", out var md5);
                            bool lengthHeaderAvailable = response.Headers.TryGetValues("Content-Length", out var contentLength);

                            if (lengthHeaderAvailable && long.Parse(contentLength.Single()) != localFileStream.Length)
                            {
                                log.LogMessage(MessageImportance.Low, $"Package '{localPackageFullPath}' has different length than remote package '{packageContentUrl}'.");
                                result = PackageFeedStatus.ExistsAndDifferent;
                                return(true);
                            }

                            if (md5HeaderAvailable)
                            {
                                var localMD5 = AzureStorageUtils.CalculateMD5(localPackageFullPath);
                                if (!localMD5.Equals(md5.Single(), StringComparison.OrdinalIgnoreCase))
                                {
                                    log.LogMessage(MessageImportance.Low, $"Package '{localPackageFullPath}' has different MD5 hash than remote package '{packageContentUrl}'.");
                                }

                                result = PackageFeedStatus.ExistsAndDifferent;
                                return(true);
                            }

                            const int BufferSize = 64 * 1024;

                            // Otherwise, compare the streams
                            var remoteStream = await response.Content.ReadAsStreamAsync();
                            var streamsMatch = await GeneralUtils.CompareStreamsAsync(localFileStream, remoteStream, BufferSize);
                            result           = streamsMatch ? PackageFeedStatus.ExistsAndIdenticalToLocal : PackageFeedStatus.ExistsAndDifferent;
                            return(true);
                        }
                }
                // String based comparison because the status code isn't exposed in HttpRequestException
                // see here: https://github.com/dotnet/runtime/issues/23648
                catch (HttpRequestException e)
                {
                    if (e.Message.Contains("404 (Not Found)"))
                    {
                        result = PackageFeedStatus.DoesNotExist;
                        return(true);
                    }

                    // Retry this. Could be an http client timeout, 500, etc.
                    return(false);
                }
            });

            return(result);
        }
Exemplo n.º 17
0
 private void ImportantMessage(string msg, params object[] msgParams)
 {
     m_log.LogMessage(MessageImportance.High, msg, msgParams);
 }
Exemplo n.º 18
0
        /// <summary>See <see cref="Task.Execute"/>.</summary>
        public override bool Execute()
        {
            const string VsSdkInstallDirEnvironmentVariable = "VsSDKInstall";
            const string VsSdkVersionsRegistryPath          = @"SOFTWARE\Microsoft\VisualStudio\VSIP";
            const string VsSdkInstallDirRegistryValue       = "InstallDir";
            const string VsSdkIncludeFilesSubdirectory      = @"VisualStudioIntegration\Common\Inc";
            const string VsSdkToolsSubdirectory             = @"VisualStudioIntegration\Tools\Bin";
            const string VsSdkRedistributablesSubdirectory  = @"VisualStudioIntegration\Redistributables";

            TaskLoggingHelper log = base.Log;

            // Try to find the VsSDK installation directory by first checking the environment variable, and then by checking the specified version listed in the registry.
            string installDir = Environment.GetEnvironmentVariable(VsSdkInstallDirEnvironmentVariable);

            if (!string.IsNullOrEmpty(installDir))
            {
                log.LogMessage(MessageImportance.Low, "Using Visual Studio SDK installation directory from \"" + VsSdkInstallDirEnvironmentVariable + "\" environment variable: \"{0}\"", installDir);
            }
            else
            {
                using (RegistryKey vsipRegistryKey = Registry.LocalMachine.OpenSubKey(VsSdkVersionsRegistryPath, RegistryKeyPermissionCheck.ReadSubTree))
                {
                    if (vsipRegistryKey != null)
                    {
                        string requestedVersionSubKeyName = this.RequestedVersion;
                        using (RegistryKey requestedVersionRegistryKey = vsipRegistryKey.OpenSubKey(requestedVersionSubKeyName, RegistryKeyPermissionCheck.ReadSubTree))
                        {
                            if (requestedVersionRegistryKey != null)
                            {
                                installDir = requestedVersionRegistryKey.GetValue(VsSdkInstallDirRegistryValue, null) as string;
                                log.LogMessage(MessageImportance.Low, "Using Visual Studio SDK installation directory from registry for version \"{0}\": \"{1}\"", requestedVersionSubKeyName, installDir);
                            }
                            else if (requestedVersionSubKeyName == "8.0")
                            {
                                // Fallback on the 9.0 SDK, enabling a VS2005 build with a 2008SDK install
                                // and minimal additional files.
                                requestedVersionSubKeyName = "9.0";
                                using (RegistryKey requestedVersionRegistryKeyFallback = vsipRegistryKey.OpenSubKey(requestedVersionSubKeyName, RegistryKeyPermissionCheck.ReadSubTree))
                                {
                                    if (requestedVersionRegistryKeyFallback != null)
                                    {
                                        installDir = requestedVersionRegistryKeyFallback.GetValue(VsSdkInstallDirRegistryValue, null) as string;
                                        log.LogMessage(MessageImportance.Low, "Using Visual Studio SDK installation directory from registry for version \"{0}\": \"{1}\"", requestedVersionSubKeyName, installDir);
                                    }
                                }
                            }
                        }
                    }
                }

                if (string.IsNullOrEmpty(installDir))
                {
                    // if the install has not been found try vswhere
                    // according to https://github.com/Microsoft/vswhere/wiki the install path will be maintained
                    string vsWherePath = Environment.ExpandEnvironmentVariables(@"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe");

                    if (!File.Exists(vsWherePath))
                    {
                        vsWherePath = Environment.ExpandEnvironmentVariables(@"%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe");
                        if (!File.Exists(vsWherePath))
                        {
                            vsWherePath = null;
                        }
                    }

                    if (string.IsNullOrEmpty(vsWherePath))
                    {
                        log.LogError("Unable to find vswhere.");
                    }
                    else
                    {
#if VISUALSTUDIO_16_0
                        string versionParameter = "-version [16.0,17.0)";
#elif VISUALSTUDIO_15_0
                        string versionParameter = "-version [15.0,16.0)";
#else
                        string versionParameter = "-latest";
#endif
                        System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(vsWherePath, versionParameter + " -property installationPath");
                        startInfo.RedirectStandardOutput = true;
                        startInfo.UseShellExecute        = false;
                        startInfo.WindowStyle            = System.Diagnostics.ProcessWindowStyle.Hidden;
                        using (System.Diagnostics.Process p = System.Diagnostics.Process.Start(startInfo))
                        {
                            string paths = p.StandardOutput.ReadToEnd();
                            p.WaitForExit();
                            string[] pathArray = paths.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
                            if (pathArray.Length > 0)
                            {
                                installDir = Path.Combine(pathArray[pathArray.Length - 1], "VSSDK");
                            }
                        }
                    }
                }
            }

            if (string.IsNullOrEmpty(installDir))
            {
                log.LogError("Unable to find Visual Studio SDK installation directory.");
                return(false);
            }

            DirectoryInfo installDirInfo = new DirectoryInfo(installDir);
            if (!installDirInfo.Exists)
            {
                log.LogError("Visual Studio SDK installation directory \"{0}\" does not exist.", installDir);
                return(false);
            }
            installDir = this._installationDirectory = installDirInfo.FullName;

            // Get the include files directory
            DirectoryInfo includesDirInfo = new DirectoryInfo(Path.Combine(installDir, VsSdkIncludeFilesSubdirectory));
            if (includesDirInfo.Exists)
            {
                string includesDir = this._includesDirectory = includesDirInfo.FullName;
                log.LogMessage(MessageImportance.Low, "Visual Studio SDK include files directory found at \"{0}\".", includesDir);
            }
            else
            {
                log.LogWarning("Visual Studio SDK include files directory \"{0}\" does not exist.", includesDirInfo.FullName);
            }

            // Get the tools directory
            DirectoryInfo toolsDirInfo = new DirectoryInfo(Path.Combine(installDir, VsSdkToolsSubdirectory));
            if (toolsDirInfo.Exists)
            {
                string toolsDir = this._toolsDirectory = toolsDirInfo.FullName;
                log.LogMessage(MessageImportance.Low, "Visual Studio SDK tools directory found at \"{0}\".", toolsDir);
            }
            else
            {
                log.LogWarning("Visual Studio SDK tools directory \"{0}\" does not exist.", toolsDirInfo.FullName);
            }

            // Get the redistributables directory
            DirectoryInfo redistributablesDirInfo = new DirectoryInfo(Path.Combine(installDir, VsSdkRedistributablesSubdirectory));
            if (redistributablesDirInfo.Exists)
            {
                string redistributablesDir = this._redistributablesDirectory = redistributablesDirInfo.FullName;
                log.LogMessage(MessageImportance.Low, "Visual Studio SDK redistributables directory found at \"{0}\".", redistributablesDir);
            }
            else
            {
                log.LogWarning("Visual Studio SDK redistributables directory \"{0}\" does not exist.", redistributablesDirInfo.FullName);
            }

            return(true);
        }
        public void LogMessage(string message)
        {
            string messageWithNameTag = GetMessageWithNameTag(message);

            _taskLoggingHelper.LogMessage(messageWithNameTag);
        }
Exemplo n.º 20
0
 /// <summary>
 ///   Logs an informational message.
 /// </summary>
 /// <param name="message">The non-empty message that should be logged.</param>
 /// <param name="arguments">The arguments that should be used to format <paramref name="message" />.</param>
 public override void Info(string message, params object[] arguments)
 {
     _logger.LogMessage(String.Format(message, arguments));
 }
Exemplo n.º 21
0
            public bool IsUpToDate(string assemblyPath, out bool containsFrameworkResources, out List <ResWInfo> reswInfoList)
            {
                reswInfoList = null;
                containsFrameworkResources = false;

                if (PortableLibraryStatesLookup == null)
                {
                    PortableLibraryStatesLookup = new Dictionary <string, PortableLibraryResourceStateInfo>();
                    return(false);
                }
                if (PortableLibraryStatesLookup.Count == 0)
                {
                    return(false);
                }

                try
                {
                    if (assemblyPath == null || !File.Exists(assemblyPath))
                    {
                        return(false);
                    }
                    PortableLibraryResourceStateInfo info;
                    if (!PortableLibraryStatesLookup.TryGetValue(assemblyPath, out info))
                    {
                        return(false);
                    }
                    FileInfo fiPlib = new FileInfo(assemblyPath);
                    if (!fiPlib.LastWriteTimeUtc.Equals(info.PLibTimeUtc))
                    {
                        _logger.LogMessage(MessageImportance.Low, Resources.Message_CachedReswNotUpToDateAssemblyNewer, assemblyPath);
                        return(false);
                    }
                    if (info.ResWInfoList == null)
                    {
                        return(false);
                    }
                    else
                    {
                        foreach (ResWInfo reswInfo in info.ResWInfoList)
                        {
                            if (reswInfo.ResWPath == null || !File.Exists(reswInfo.ResWPath))
                            {
                                _logger.LogMessage(MessageImportance.Low, Resources.Message_CachedReswNotExists, assemblyPath, reswInfo.ResWPath);
                                return(false);
                            }

                            FileInfo fiResW = new FileInfo(reswInfo.ResWPath);
                            if (!fiResW.LastWriteTimeUtc.Equals(reswInfo.ResWTimeUtc))
                            {
                                _logger.LogMessage(MessageImportance.Low, Resources.Message_CachedReswNotUpToDate, reswInfo.ResWPath);
                                return(false);
                            }
                        }
                    }

                    foreach (ResWInfo reswInfo in info.ResWInfoList)
                    {
                        _logger.LogMessage(MessageImportance.Low, Resources.Message_UsingCachedResw, reswInfo.ResWPath, assemblyPath);
                    }

                    reswInfoList = info.ResWInfoList;
                    containsFrameworkResources = info.ContainsFrameworkResources;
                    return(true);
                }
                catch (Exception e)
                {
                    _logger.LogMessage(MessageImportance.Low, Resources.Error_UnspecifiedCheckUpToDate, assemblyPath, e.Message);
                    return(false);
                }
            }
Exemplo n.º 22
0
 public void Log(string fmt, params object[] args)
 {
     Logger.LogMessage(fmt, args);
 }
Exemplo n.º 23
0
 /// <summary>
 /// Outputs messages based on whether the task is initiated within visual studio IDE or not
 /// </summary>
 internal void LogMessage(string message, params object[] args)
 {
     m_logHelper.LogMessage(MessageImportance.High, Prefix + message, args);
 }
Exemplo n.º 24
0
 public void WriteLine(string output)
 {
     _loggingHelper.LogMessage(output);
 }
Exemplo n.º 25
0
 public void LogDebug(string data)
 {
     _taskLogging.LogMessage(MessageImportance.Low, data);
 }
Exemplo n.º 26
0
 public void Info(string message)
 {
     _underlying.LogMessage(message);
 }
Exemplo n.º 27
0
        private static RegexCompilationInfo LoadRegexCompilationInfo(TaskLoggingHelper log, string regexFilePath)
        {
            log.LogMessage("Loading RegexCompilationInfo from \"{0}\".", regexFilePath);
            bool         isPublic     = false;
            string       name         = null;
            string       @namespace   = null;
            string       pattern      = null;
            RegexOptions regexOptions = RegexOptions.Compiled;

            FileInfo fileInfo = new FileInfo(regexFilePath);

            using (FileStream fileStream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete, (int)fileInfo.Length, FileOptions.SequentialScan))
            {
                using (XmlReader xmlReader = XmlReader.Create(fileStream, XmlReaderSettings))
                {
                    while (xmlReader.MoveToNextAttribute() || xmlReader.Read())
                    {
                        switch (xmlReader.NodeType)
                        {
                        case XmlNodeType.Element:
                        case XmlNodeType.Attribute:
                            switch (xmlReader.LocalName)
                            {
                            case "IsPublic":
                                isPublic = xmlReader.ReadContentAsBoolean();
                                break;

                            case "Name":
                                name = xmlReader.ReadContentAsString();
                                break;

                            case "Namespace":
                                @namespace = xmlReader.ReadContentAsString();
                                break;

                            case "CultureInvariant":
                                regexOptions |= RegexOptions.CultureInvariant;
                                break;

                            case "ECMAScript":
                                regexOptions |= RegexOptions.ECMAScript;
                                break;

                            case "ExplicitCapture":
                                regexOptions |= RegexOptions.ExplicitCapture;
                                break;

                            case "IgnoreCase":
                                regexOptions |= RegexOptions.IgnoreCase;
                                break;

                            case "IgnorePatternWhitespace":
                                regexOptions |= RegexOptions.IgnorePatternWhitespace;
                                break;

                            case "Multiline":
                                regexOptions |= RegexOptions.Multiline;
                                break;

                            case "RightToLeft":
                                regexOptions |= RegexOptions.RightToLeft;
                                break;

                            case "Singleline":
                                regexOptions |= RegexOptions.Singleline;
                                break;

                            case "Pattern":
                                pattern = xmlReader.ReadElementContentAsString();
                                break;
                            }
                            break;
                        }
                    }
                }
            }

            RegexCompilationInfo regexCompilationInfo = new RegexCompilationInfo(pattern, regexOptions, name, @namespace, isPublic);

            log.LogMessage("RegexCompilationInfo loaded with settings:", null);
            log.LogMessage("\tNamespace:\t\t{0}", regexCompilationInfo.Namespace);
            log.LogMessage("\tName:\t\t\t{0}", regexCompilationInfo.Name);
            log.LogMessage("\tIsPublic:\t\t{0}", regexCompilationInfo.IsPublic);
            log.LogMessage("\tRegexOptions:\t{0}", regexCompilationInfo.Options);
            return(regexCompilationInfo);
        }
Exemplo n.º 28
0
 public void LogMessage(string message)
 {
     logger.LogMessage(message);
 }
Exemplo n.º 29
0
        /// <summary>
        /// Resolves a single reference item by searcheing for referenced items using the specified SearchPaths.
        /// This method is made public so the resolution logic can be reused by other tasks.
        /// </summary>
        /// <param name="reference">The referenced item.</param>
        /// <param name="searchPaths">The paths to search.</param>
        /// <param name="searchFilenameExtensions">Filename extensions to check.</param>
        /// <param name="log">Logging helper.</param>
        /// <returns>The resolved reference item, or the original reference if it could not be resolved.</returns>
        public static ITaskItem ResolveReference(ITaskItem reference, string[] searchPaths, string[] searchFilenameExtensions, TaskLoggingHelper log)
        {
            if (reference == null)
            {
                throw new ArgumentNullException("reference");
            }

            if (searchPaths == null)
            {
                // Nothing to search, so just return the original reference item.
                return(reference);
            }

            if (searchFilenameExtensions == null)
            {
                searchFilenameExtensions = new string[] { };
            }

            // Copy all the metadata from the source
            TaskItem resolvedReference = new TaskItem(reference);

            log.LogMessage(MessageImportance.Low, "WixReference: {0}", reference.ItemSpec);

            // Now find the resolved path based on our order of precedence
            foreach (string searchPath in searchPaths)
            {
                log.LogMessage(MessageImportance.Low, "Trying {0}", searchPath);
                if (searchPath.Equals(HintPathToken, StringComparison.Ordinal))
                {
                    string path = reference.GetMetadata("HintPath");
                    log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
                    if (File.Exists(path))
                    {
                        resolvedReference.ItemSpec = path;
                        break;
                    }
                }
                else if (searchPath.Equals(RawFileNameToken, StringComparison.Ordinal))
                {
                    log.LogMessage(MessageImportance.Low, "Trying path {0}", resolvedReference.ItemSpec);
                    if (File.Exists(resolvedReference.ItemSpec))
                    {
                        break;
                    }

                    if (ResolveWixReferences.ResolveFilenameExtensions(resolvedReference,
                                                                       resolvedReference.ItemSpec, searchFilenameExtensions, log))
                    {
                        break;
                    }
                }
                else
                {
                    string path = Path.Combine(searchPath, Path.GetFileName(reference.ItemSpec));
                    log.LogMessage(MessageImportance.Low, "Trying path {0}", path);
                    if (File.Exists(path))
                    {
                        resolvedReference.ItemSpec = path;
                        break;
                    }

                    if (ResolveWixReferences.ResolveFilenameExtensions(resolvedReference,
                                                                       path, searchFilenameExtensions, log))
                    {
                        break;
                    }
                }
            }

            // Normalize the item path
            resolvedReference.ItemSpec = resolvedReference.GetMetadata("FullPath");

            return(resolvedReference);
        }
Exemplo n.º 30
0
 public void WriteInfo(string message)
 {
     _logHelper.LogMessage(message);
 }