Ejemplo n.º 1
0
        private static Type GetTypeFromAssemblyPath(string pluginAssemblyPath)
        {
            var assembly = LoadAssembly(pluginAssemblyPath);

            var type = GetTypes <ProjectCachePluginBase>(assembly).FirstOrDefault();

            if (type == null)
            {
                ProjectCacheException.ThrowForMSBuildIssueWithTheProjectCache("NoProjectCachePluginFoundInAssembly", pluginAssemblyPath);
            }

            return(type !);

            Assembly LoadAssembly(string resolverPath)
            {
#if !FEATURE_ASSEMBLYLOADCONTEXT
                return(Assembly.LoadFrom(resolverPath));
#else
                return(_loader.LoadFromPath(resolverPath));
#endif
            }

            IEnumerable <Type> GetTypes <T>(Assembly assembly)
            {
                return(assembly.ExportedTypes
                       .Select(type => new { type, info = type.GetTypeInfo() })
                       .Where(
                           t => t.info.IsClass &&
                           t.info.IsPublic &&
                           !t.info.IsAbstract &&
                           typeof(T).IsAssignableFrom(t.type))
                       .Select(t => t.type));
            }
        }
Ejemplo n.º 2
0
        public async Task <CacheResult> GetCacheResultAsync(BuildRequestData buildRequest)
        {
            // TODO: Parent these logs under the project build event so they appear nested under the project in the binlog viewer.
            var queryDescription = $"{buildRequest.ProjectFullPath}" +
                                   $"\n\tTargets:[{string.Join(", ", buildRequest.TargetNames)}]" +
                                   $"\n\tGlobal Properties: {{{string.Join(",", buildRequest.GlobalProperties.Select(kvp => $"{kvp.Name}={kvp.EvaluatedValue}"))}}}";

            var logger = _loggerFactory();

            logger.LogMessage(
                "\n====== Querying project cache for project " + queryDescription,
                MessageImportance.High);

            CacheResult cacheResult = null !;

            try
            {
                cacheResult = await _projectCachePlugin.GetCacheResultAsync(buildRequest, logger, _cancellationToken);
            }
            catch (Exception e)
            {
                HandlePluginException(e, nameof(ProjectCachePluginBase.GetCacheResultAsync));
            }

            if (logger.HasLoggedErrors || cacheResult.ResultType == CacheResultType.None)
            {
                ProjectCacheException.ThrowForErrorLoggedInsideTheProjectCache("ProjectCacheQueryFailed", queryDescription);
            }

            var message = $"Plugin result: {cacheResult.ResultType}.";

            switch (cacheResult.ResultType)
            {
            case CacheResultType.CacheHit:
                message += " Skipping project.";
                break;

            case CacheResultType.CacheMiss:
            case CacheResultType.CacheNotApplicable:
                message += " Building project.";
                break;

            case CacheResultType.None:
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            logger.LogMessage(
                message,
                MessageImportance.High);

            return(cacheResult);
        }
Ejemplo n.º 3
0
        private static void HandlePluginException(Exception e, string apiExceptionWasThrownFrom)
        {
            if (ExceptionHandling.IsCriticalException(e))
            {
                throw e;
            }

            ProjectCacheException.ThrowAsUnhandledException(
                e,
                "ProjectCacheException",
                apiExceptionWasThrownFrom);
        }
Ejemplo n.º 4
0
        public async Task ShutDown()
        {
            var logger = _loggerFactory();

            try
            {
                await _projectCachePlugin.EndBuildAsync(logger, _cancellationToken);
            }
            catch (Exception e)
            {
                HandlePluginException(e, nameof(ProjectCachePluginBase.EndBuildAsync));
            }

            if (logger.HasLoggedErrors)
            {
                ProjectCacheException.ThrowForErrorLoggedInsideTheProjectCache("ProjectCacheShutdownFailed");
            }
        }
Ejemplo n.º 5
0
        public static async Task <ProjectCacheService> FromDescriptorAsync(
            ProjectCacheDescriptor pluginDescriptor,
            BuildManager buildManager,
            ILoggingService loggingService,
            CancellationToken cancellationToken)
        {
            var plugin = await Task.Run(() => GetPluginInstance(pluginDescriptor), cancellationToken)
                         .ConfigureAwait(false);

            // TODO: Detect and use the highest verbosity from all the user defined loggers. That's tricky because right now we can't discern between user set loggers and msbuild's internally added loggers.
            var loggerFactory = new Func <PluginLoggerBase>(() => new LoggingServiceToPluginLoggerAdapter(LoggerVerbosity.Normal, loggingService));

            var logger = loggerFactory();

            try
            {
                await plugin.BeginBuildAsync(
                    new CacheContext(
                        pluginDescriptor.PluginSettings,
                        new IFileSystemAdapter(FileSystems.Default),
                        pluginDescriptor.ProjectGraph,
                        pluginDescriptor.EntryPoints),
                    // TODO: Detect verbosity from logging service.
                    logger,
                    cancellationToken);
            }
            catch (Exception e)
            {
                HandlePluginException(e, nameof(ProjectCachePluginBase.BeginBuildAsync));
            }

            if (logger.HasLoggedErrors)
            {
                ProjectCacheException.ThrowForErrorLoggedInsideTheProjectCache("ProjectCacheInitializationFailed");
            }

            return(new ProjectCacheService(plugin, buildManager, loggerFactory, pluginDescriptor, cancellationToken));
        }