Esempio n. 1
0
        public void Execute(Script script)
        {
            // Generate the script code.
            var generator = new RoslynCodeGenerator();
            var code      = generator.Generate(script);

            // Warn about any code generation excluded namespaces
            foreach (var @namespace in script.ExcludedNamespaces)
            {
                _log.Warning("Namespace {0} excluded by code generation, affected methods:\r\n\t{1}",
                             @namespace.Key, string.Join("\r\n\t", @namespace.Value));
            }

            // Create the script options dynamically.
            var options = Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default
                          .AddImports(Namespaces.Except(script.ExcludedNamespaces.Keys))
                          .AddReferences(References)
                          .AddReferences(ReferencePaths.Select(r => r.FullPath))
                          .WithEmitDebugInformation(_settings.Debug)
                          .WithMetadataResolver(Microsoft.CodeAnalysis.Scripting.ScriptMetadataResolver.Default);

            var roslynScript = CSharpScript.Create(code, options, _host.GetType());

            _log.Verbose("Compiling build script...");
            var compilation = roslynScript.GetCompilation();
            var diagnostics = compilation.GetDiagnostics();

            var errors = new List <Diagnostic>();

            foreach (var diagnostic in diagnostics)
            {
                switch (diagnostic.Severity)
                {
                case DiagnosticSeverity.Info:
                    _log.Information(diagnostic.ToString());
                    break;

                case DiagnosticSeverity.Warning:
                    _log.Warning(diagnostic.ToString());
                    break;

                case DiagnosticSeverity.Error:
                    _log.Error(diagnostic.ToString());
                    errors.Add(diagnostic);
                    break;

                default:
                    break;
                }
            }

            if (errors.Any())
            {
                var errorMessages = string.Join(Environment.NewLine, errors.Select(x => x.ToString()));
                var message       = string.Format(CultureInfo.InvariantCulture, "Error(s) occurred when compiling build script:{0}{1}", Environment.NewLine, errorMessages);
                throw new CakeException(message);
            }

            roslynScript.RunAsync(_host).Wait();
        }
Esempio n. 2
0
        public void Execute(Script script)
        {
            var    scriptName        = _settings.Script.GetFilename();
            var    cacheDLLFileName  = $"{scriptName}.dll";
            var    cacheHashFileName = $"{scriptName}.hash";
            var    cachedAssembly    = _scriptCachePath.CombineWithFilePath(cacheDLLFileName);
            var    hashFile          = _scriptCachePath.CombineWithFilePath(cacheHashFileName);
            string scriptHash        = default;

            if (_scriptCacheEnabled && _fileSystem.Exist(cachedAssembly) && !_regenerateCache)
            {
                _log.Verbose($"Cache enabled: Checking cache build script ({cacheDLLFileName})");
                scriptHash = FastHash.GenerateHash(Encoding.UTF8.GetBytes(string.Concat(script.Lines)));
                var cachedHash = _fileSystem.Exist(hashFile)
                               ? _fileSystem.GetFile(hashFile).ReadLines(Encoding.UTF8).FirstOrDefault()
                               : string.Empty;
                if (scriptHash.Equals(cachedHash, StringComparison.Ordinal))
                {
                    _log.Verbose("Running cached build script...");
                    RunScriptAssembly(cachedAssembly.FullPath);
                    return;
                }
                else
                {
                    _log.Verbose("Cache check failed.");
                }
            }
            // Generate the script code.
            var generator = new RoslynCodeGenerator();
            var code      = generator.Generate(script);

            // Warn about any code generation excluded namespaces
            foreach (var @namespace in script.ExcludedNamespaces)
            {
                _log.Warning("Namespace {0} excluded by code generation, affected methods:\r\n\t{1}",
                             @namespace.Key, string.Join("\r\n\t", @namespace.Value));
            }

            // Create the script options dynamically.
            var options = Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default
                          .AddImports(Namespaces.Except(script.ExcludedNamespaces.Keys))
                          .AddReferences(References)
                          .AddReferences(ReferencePaths.Select(r => r.FullPath))
                          .WithEmitDebugInformation(_settings.Debug)
                          .WithMetadataResolver(Microsoft.CodeAnalysis.Scripting.ScriptMetadataResolver.Default);

            var roslynScript = CSharpScript.Create(code, options, _host.GetType());

            _log.Verbose("Compiling build script...");
            var compilation = roslynScript.GetCompilation();
            var diagnostics = compilation.GetDiagnostics();

            var errors = new List <Diagnostic>();

            foreach (var diagnostic in diagnostics)
            {
                // Suppress some diagnostic information. See https://github.com/cake-build/cake/issues/3337
                switch (diagnostic.Id)
                {
                // CS1701 Compiler Warning (level 2)
                // Assuming assembly reference "Assembly Name #1" matches "Assembly Name #2", you may need to supply runtime policy
                // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs1701
                case "CS1701":
                    continue;

                // CS1702 Compiler Warning (level 3)
                // Assuming assembly reference "Assembly Name #1" matches "Assembly Name #2", you may need to supply runtime policy
                // https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs1702
                case "CS1702":
                    continue;

                // CS1705 Compiler Error
                // Assembly 'AssemblyName1' uses 'TypeName' which has a higher version than referenced assembly 'AssemblyName2'
                case "CS1705":
                    continue;

                default:
                    break;
                }

                switch (diagnostic.Severity)
                {
                case DiagnosticSeverity.Info:
                    _log.Information(diagnostic.ToString());
                    break;

                case DiagnosticSeverity.Warning:
                    _log.Warning(diagnostic.ToString());
                    break;

                case DiagnosticSeverity.Error:
                    _log.Error(diagnostic.ToString());
                    errors.Add(diagnostic);
                    break;

                default:
                    break;
                }
            }

            if (errors.Any())
            {
                var errorMessages = string.Join(Environment.NewLine, errors.Select(x => x.ToString()));
                var message       = string.Format(CultureInfo.InvariantCulture, "Error(s) occurred when compiling build script:{0}{1}", Environment.NewLine, errorMessages);
                throw new CakeException(message);
            }

            if (_scriptCacheEnabled)
            {
                // Verify cache directory exists
                if (!_fileSystem.GetDirectory(_scriptCachePath).Exists)
                {
                    _fileSystem.GetDirectory(_scriptCachePath).Create();
                }
                if (string.IsNullOrWhiteSpace(scriptHash))
                {
                    scriptHash = FastHash.GenerateHash(Encoding.UTF8.GetBytes(string.Concat(script.Lines)));
                }
                var emitResult = compilation.Emit(cachedAssembly.FullPath);

                if (emitResult.Success)
                {
                    using (var stream = _fileSystem.GetFile(hashFile).OpenWrite())
                        using (var writer = new StreamWriter(stream, Encoding.UTF8))
                        {
                            writer.Write(scriptHash);
                        }
                    RunScriptAssembly(cachedAssembly.FullPath);
                }
            }
            else
            {
                roslynScript.RunAsync(_host).GetAwaiter().GetResult();
            }
        }
Esempio n. 3
0
        public void Execute(Script script)
        {
            // Generate the script code.
            var generator = new RoslynCodeGenerator();
            var code      = generator.Generate(script);

            // Warn about any code generation excluded namespaces
            foreach (var @namespace in script.ExcludedNamespaces)
            {
                _log.Warning("Namespace {0} excluded by code generation, affected methods:\r\n\t{1}",
                             @namespace.Key, string.Join("\r\n\t", @namespace.Value));
            }

            // Create the script options dynamically.
            var options = Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default
                          .AddImports(Namespaces.Except(script.ExcludedNamespaces.Keys))
                          .AddReferences(References)
                          .AddReferences(ReferencePaths.Select(r => r.FullPath))
                          .WithEmitDebugInformation(_settings.Debug)
                          .WithMetadataResolver(Microsoft.CodeAnalysis.Scripting.ScriptMetadataResolver.Default);

            var roslynScript = CSharpScript.Create(code, options, _host.GetType());

            _log.Verbose("Compiling build script...");
            var compilation = roslynScript.GetCompilation();
            var diagnostics = compilation.GetDiagnostics();

            var errors = new List <Diagnostic>();

            foreach (var diagnostic in diagnostics)
            {
                // Suppress some diagnostic information. See https://github.com/cake-build/cake/issues/3337
                switch (diagnostic.Id)
                {
                // CS1701 Compiler Warning (level 2)
                // Assuming assembly reference "Assembly Name #1" matches "Assembly Name #2", you may need to supply runtime policy
                // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs1701
                case "CS1701":
                    continue;

                // CS1702 Compiler Warning (level 3)
                // Assuming assembly reference "Assembly Name #1" matches "Assembly Name #2", you may need to supply runtime policy
                // https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs1702
                case "CS1702":
                    continue;

                // CS1705 Compiler Error
                // Assembly 'AssemblyName1' uses 'TypeName' which has a higher version than referenced assembly 'AssemblyName2'
                case "CS1705":
                    continue;

                default:
                    break;
                }

                switch (diagnostic.Severity)
                {
                case DiagnosticSeverity.Info:
                    _log.Information(diagnostic.ToString());
                    break;

                case DiagnosticSeverity.Warning:
                    _log.Warning(diagnostic.ToString());
                    break;

                case DiagnosticSeverity.Error:
                    _log.Error(diagnostic.ToString());
                    errors.Add(diagnostic);
                    break;

                default:
                    break;
                }
            }

            if (errors.Any())
            {
                var errorMessages = string.Join(Environment.NewLine, errors.Select(x => x.ToString()));
                var message       = string.Format(CultureInfo.InvariantCulture, "Error(s) occurred when compiling build script:{0}{1}", Environment.NewLine, errorMessages);
                throw new CakeException(message);
            }

            roslynScript.RunAsync(_host).Wait();
        }