예제 #1
0
파일: Program.cs 프로젝트: yane3628/bicep
        private void BuildManyFilesToStdOut(IDiagnosticLogger logger, string[] bicepPaths)
        {
            using var writer = new JsonTextWriter(this.outputWriter)
                  {
                      Formatting = Formatting.Indented
                  };

            if (bicepPaths.Length > 1)
            {
                writer.WriteStartArray();
            }
            foreach (var bicepPath in bicepPaths)
            {
                var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepPath));
                var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

                var success = LogDiagnosticsAndCheckSuccess(logger, compilation);
                if (success)
                {
                    var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel());

                    emitter.Emit(writer);
                }
            }
            if (bicepPaths.Length > 1)
            {
                writer.WriteEndArray();
            }
        }
예제 #2
0
        public void ExampleIsValid(ExampleData example)
        {
            var compilation = new Compilation(new AzResourceTypeProvider(), SyntaxFactory.CreateFromText(example.BicepContents));
            var emitter     = new TemplateEmitter(compilation.GetSemanticModel());

            using var stream = new MemoryStream();
            var result = emitter.Emit(stream);

            // allow 'type not available' warnings for examples
            var diagnostics = result.Diagnostics.Where(x => !(IsPermittedMissingTypeDiagnostic(x)));

            diagnostics.Should().BeEmpty();
            result.Status.Should().Be(EmitStatus.Succeeded);

            stream.Position = 0;
            var generated = new StreamReader(stream).ReadToEnd();

            var actual = JToken.Parse(generated);

            FileHelper.SaveResultFile(this.TestContext !, $"{example.BicepFileName}_Compiled_Actual.json", actual.ToString(Formatting.Indented));

            var expected = JToken.Parse(example.JsonContents !);

            FileHelper.SaveResultFile(this.TestContext !, $"{example.BicepFileName}_Compiled_Expected.json", expected.ToString(Formatting.Indented));

            JsonAssert.AreEqual(expected, actual, this.TestContext !, $"{example.BicepFileName}_Compiled_Delta.json");
        }
예제 #3
0
        private void BuildManyFilesToStdOut(IDiagnosticLogger logger, string[] bicepPaths)
        {
            using var writer = new JsonTextWriter(this.outputWriter)
                  {
                      Formatting = Formatting.Indented
                  };

            if (bicepPaths.Length > 1)
            {
                writer.WriteStartArray();
            }
            foreach (var bicepPath in bicepPaths)
            {
                string text       = File.ReadAllText(bicepPath);
                var    lineStarts = TextCoordinateConverter.GetLineStarts(text);

                var compilation = new Compilation(SyntaxFactory.CreateFromText(text));

                var emitter = new TemplateEmitter(compilation.GetSemanticModel());

                var result = emitter.Emit(writer);

                foreach (var diagnostic in result.Diagnostics)
                {
                    logger.LogDiagnostic(bicepPath, diagnostic, lineStarts);
                }
            }
            if (bicepPaths.Length > 1)
            {
                writer.WriteEndArray();
            }
        }
예제 #4
0
파일: Interop.cs 프로젝트: husains/bicep
        private static (string, IEnumerable <object>) CompileInternal(string content)
        {
            try
            {
                var lineStarts      = TextCoordinateConverter.GetLineStarts(content);
                var compilation     = GetCompilation(content);
                var emitterSettings = new EmitterSettings(features);
                var emitter         = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), emitterSettings);

                // memory stream is not ideal for frequent large allocations
                using var stream = new MemoryStream();
                var emitResult = emitter.Emit(stream);

                if (emitResult.Status != EmitStatus.Failed)
                {
                    // compilation was successful or had warnings - return the compiled template
                    stream.Position = 0;
                    return(ReadStreamToEnd(stream), emitResult.Diagnostics.Select(d => ToMonacoDiagnostic(d, lineStarts)));
                }

                // compilation failed
                return("Compilation failed!", emitResult.Diagnostics.Select(d => ToMonacoDiagnostic(d, lineStarts)));
            }
            catch (Exception exception)
            {
                return(exception.ToString(), Enumerable.Empty <object>());
            }
        }
예제 #5
0
        private EmitResult EmitTemplate(string text, string filePath)
        {
            var compilation = new Compilation(SyntaxFactory.CreateFromText(text));
            var emitter     = new TemplateEmitter(compilation.GetSemanticModel());

            return(emitter.Emit(filePath));
        }
예제 #6
0
        private EmitResult EmitTemplate(SourceFileGrouping sourceFileGrouping, string filePath, string assemblyFileVersion)
        {
            var compilation = new Compilation(TestTypeHelper.CreateEmptyProvider(), sourceFileGrouping);
            var emitter     = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), assemblyFileVersion);

            using var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
            return(emitter.Emit(stream));
        }
예제 #7
0
        private EmitResult EmitTemplate(SourceFileGrouping sourceFileGrouping, EmitterSettings emitterSettings, string filePath)
        {
            var compilation = new Compilation(BicepTestConstants.Features, TestTypeHelper.CreateEmptyProvider(), sourceFileGrouping, BicepTestConstants.BuiltInConfiguration, BicepTestConstants.LinterAnalyzer);
            var emitter     = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), emitterSettings);

            using var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
            return(emitter.Emit(stream));
        }
예제 #8
0
        private EmitResult EmitTemplate(SyntaxTreeGrouping syntaxTreeGrouping, string filePath)
        {
            var compilation = new Compilation(TestResourceTypeProvider.Create(), syntaxTreeGrouping);
            var emitter     = new TemplateEmitter(compilation.GetEntrypointSemanticModel());

            using var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
            return(emitter.Emit(stream));
        }
예제 #9
0
        private EmitResult EmitTemplate(string text, string filePath)
        {
            var compilation = new Compilation(SyntaxFactory.CreateFromText(text));
            var emitter     = new TemplateEmitter(compilation.GetSemanticModel());

            using var stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
            return(emitter.Emit(stream));
        }
예제 #10
0
        private EmitResult EmitTemplate(string text, MemoryStream memoryStream)
        {
            var compilation = new Compilation(SyntaxFactory.CreateFromText(text));
            var emitter     = new TemplateEmitter(compilation.GetSemanticModel());

            TextWriter tw = new StreamWriter(memoryStream);

            return(emitter.Emit(tw));
        }
예제 #11
0
        private EmitResult EmitTemplate(SourceFileGrouping sourceFileGrouping, MemoryStream memoryStream, string assemblyFileVersion)
        {
            var compilation = new Compilation(TestTypeHelper.CreateEmptyProvider(), sourceFileGrouping);
            var emitter     = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), assemblyFileVersion);

            TextWriter tw = new StreamWriter(memoryStream);

            return(emitter.Emit(tw));
        }
예제 #12
0
        private EmitResult EmitTemplate(SourceFileGrouping sourceFileGrouping, EmitterSettings emitterSettings, MemoryStream memoryStream)
        {
            var compilation = new Compilation(BicepTestConstants.Features, TestTypeHelper.CreateEmptyProvider(), sourceFileGrouping, BicepTestConstants.BuiltInConfiguration, BicepTestConstants.LinterAnalyzer);
            var emitter     = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), emitterSettings);

            TextWriter tw = new StreamWriter(memoryStream);

            return(emitter.Emit(tw));
        }
예제 #13
0
        private EmitResult EmitTemplate(SyntaxTreeGrouping syntaxTreeGrouping, MemoryStream memoryStream)
        {
            var compilation = new Compilation(TestResourceTypeProvider.Create(), syntaxTreeGrouping);
            var emitter     = new TemplateEmitter(compilation.GetEntrypointSemanticModel());

            TextWriter tw = new StreamWriter(memoryStream);

            return(emitter.Emit(tw));
        }
예제 #14
0
        private string GenerateCompiledParametersFileAndReturnOutputMessage(string bicepFilePath, DocumentUri documentUri)
        {
            string compiledFilePath = PathHelper.ResolveParametersFileOutputPath(bicepFilePath);
            string compiledFile     = Path.GetFileName(compiledFilePath);

            // If the template exists and contains bicep generator metadata, we can go ahead and replace the file.
            // If not, we'll fail the generate params.
            if (File.Exists(compiledFilePath) && !TemplateIsParametersFile(File.ReadAllText(compiledFilePath)))
            {
                return("Generating parameters file failed. The file \"" + compiledFile + "\" already exists but does not contain the schema for a parameters file. If overwriting the file is intended, delete it manually and retry the Generate Parameters command.");
            }

            var fileUri = documentUri.ToUri();
            RootConfiguration?configuration = null;

            try
            {
                configuration = this.configurationManager.GetConfiguration(fileUri);
            }
            catch (ConfigurationException exception)
            {
                // Fail the generate params if there's configuration errors.
                return(exception.Message);
            }

            CompilationContext?context = compilationManager.GetCompilation(fileUri);
            Compilation        compilation;

            if (context is null)
            {
                SourceFileGrouping sourceFileGrouping = SourceFileGroupingBuilder.Build(this.fileResolver, this.moduleDispatcher, new Workspace(), fileUri, configuration);
                compilation = new Compilation(features, namespaceProvider, sourceFileGrouping, configuration, new LinterAnalyzer(configuration));
            }
            else
            {
                compilation = context.Compilation;
            }

            KeyValuePair <BicepFile, IEnumerable <IDiagnostic> > diagnosticsByFile = compilation.GetAllDiagnosticsByBicepFile()
                                                                                     .FirstOrDefault(x => x.Key.FileUri == fileUri);

            if (diagnosticsByFile.Value.Any(x => x.Level == DiagnosticLevel.Error))
            {
                return("Generating parameters file failed. Please fix below errors:\n" + DiagnosticsHelper.GetDiagnosticsMessage(diagnosticsByFile));
            }

            var existingContent = File.Exists(compiledFilePath) ? File.ReadAllText(compiledFilePath) : string.Empty;

            var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), emitterSettings);

            using var fileStream = new FileStream(compiledFilePath, FileMode.Create, FileAccess.Write);
            var result = emitter.EmitParametersFile(fileStream, existingContent);

            return("Generating parameters file succeeded. Processed file " + compiledFile);
        }
예제 #15
0
        public EmitResult ToStdout(Compilation compilation)
        {
            using var writer = new JsonTextWriter(invocationContext.OutputWriter)
                  {
                      Formatting = Formatting.Indented
                  };

            var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), invocationContext.AssemblyFileVersion);

            return(emitter.Emit(writer));
        }
예제 #16
0
        public override void Emit(XPathNavigator patternNavigator)
        {
            if (patternNavigator != null)
            {
                string firstOrLast = patternNavigator.SelectSingleNode("@FirstOrLast").Value;
                string status      = patternNavigator.SelectSingleNode("@Status").Value;
                string notes       = patternNavigator.SelectSingleNode("@Notes").Value;

                Connection tableConnection =
                    Connection.GetExistingConnection(VulcanPackage, LogtainerPattern.CurrentLog.TableConnectionName);

                string          execSqlTaskName = LogtainerPattern.CurrentLog.LogName + Resources.Seperator + firstOrLast + Guid.NewGuid();
                TemplateEmitter te = new TemplateEmitter(VulcanPackage.TemplateManager["LogSelectQuery"]);
                if (
                    LogtainerPattern.CurrentLog.SourceColumn == null ||
                    LogtainerPattern.CurrentLog.DestinationColumn == null ||
                    LogtainerPattern.CurrentLog.TableConnectionName == null ||
                    LogtainerPattern.CurrentLog.Table == null)
                {
                    Message.Trace(Severity.Error,
                                  "Could not perform LogUpdate (On Log: {0}), Parent Logtainer does not contain all of the necessary information.  Needs SourceColumn, DestinationColumn, TableConnectionName, and Table attributes.", LogtainerPattern.CurrentLog.LogName);
                    return;
                }

                te.SetNamedParameter("Source", LogtainerPattern.CurrentLog.SourceColumn);
                te.SetNamedParameter("Destination", LogtainerPattern.CurrentLog.DestinationColumn);
                te.SetNamedParameter("Table", LogtainerPattern.CurrentLog.Table);
                te.SetNamedParameter("Status", status);
                te.SetNamedParameter("Notes", notes);
                te.SetNamedParameter("SourceConvertStyle", "21");
                te.SetNamedParameter("DestinationConvertStyle", "21");

                string query;
                te.Emit(out query);

                SQLTask readForLogTask = new SQLTask(VulcanPackage, execSqlTaskName, execSqlTaskName, ParentContainer, tableConnection);
                readForLogTask.TransmuteToExpressionTask(String.Format("\"{0}\"", query));
                readForLogTask.ExecuteSQLTask.ResultSetType = Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ResultSetType.ResultSetType_SingleRow;

                DTS.Variable sourceVar = LogtainerPattern.CurrentLog[firstOrLast + "SourceRecord"];
                DTS.Variable destVar   = LogtainerPattern.CurrentLog[firstOrLast + "DestinationRecord"];
                DTS.Variable statusVar = LogtainerPattern.CurrentLog["Status"];
                DTS.Variable notesVar  = LogtainerPattern.CurrentLog["Notes"];

                readForLogTask.BindResult("0", sourceVar.QualifiedName);
                readForLogTask.BindResult("1", destVar.QualifiedName);
                readForLogTask.BindResult("2", statusVar.QualifiedName);
                readForLogTask.BindResult("3", notesVar.QualifiedName);

                this.FirstExecutableGeneratedByPattern = readForLogTask.SQLTaskHost;
                this.LastExecutableGeneratedByPattern  = this.FirstExecutableGeneratedByPattern;
            }
        }
예제 #17
0
        private string GenerateCompiledFileAndReturnBuildOutputMessage(string bicepFilePath, DocumentUri documentUri)
        {
            string compiledFilePath = PathHelper.GetDefaultBuildOutputPath(bicepFilePath);
            string compiledFile     = Path.GetFileName(compiledFilePath);

            // If the template exists and contains bicep generator metadata, we can go ahead and replace the file.
            // If not, we'll fail the build.
            if (File.Exists(compiledFilePath) && !TemplateContainsBicepGeneratorMetadata(File.ReadAllText(compiledFilePath)))
            {
                return("Build failed. The file \"" + compiledFile + "\" already exists and was not generated by Bicep. If overwriting the file is intended, delete it manually and retry the Build command.");
            }

            var fileUri = documentUri.ToUri();
            RootConfiguration?configuration = null;

            try
            {
                configuration = this.configurationManager.GetConfiguration(fileUri);
            }
            catch (ConfigurationException exception)
            {
                // Fail the build if there's configuration errors.
                return(exception.Message);
            }

            CompilationContext?context = compilationManager.GetCompilation(fileUri);
            Compilation        compilation;

            if (context is null)
            {
                SourceFileGrouping sourceFileGrouping = SourceFileGroupingBuilder.Build(this.fileResolver, this.moduleDispatcher, new Workspace(), fileUri, configuration);
                compilation = new Compilation(namespaceProvider, sourceFileGrouping, configuration);
            }
            else
            {
                compilation = context.Compilation;
            }

            KeyValuePair <BicepFile, IEnumerable <IDiagnostic> > diagnosticsByFile = compilation.GetAllDiagnosticsByBicepFile()
                                                                                     .FirstOrDefault(x => x.Key.FileUri == fileUri);

            if (diagnosticsByFile.Value.Any(x => x.Level == DiagnosticLevel.Error))
            {
                return(GetDiagnosticsMessage(diagnosticsByFile));
            }

            using var fileStream = new FileStream(compiledFilePath, FileMode.Create, FileAccess.ReadWrite);
            var        emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), emitterSettings);
            EmitResult result  = emitter.Emit(fileStream);

            return("Build succeeded. Created file " + compiledFile);
        }
예제 #18
0
        public void TemplateEmitter_should_not_dispose_text_writer()
        {
            var(_, _, compilation) = CompilationHelper.Compile(string.Empty);

            var stringBuilder = new StringBuilder();
            var stringWriter  = new StringWriter(stringBuilder);

            var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), BicepTestConstants.EmitterSettings);

            emitter.Emit(stringWriter);

            // second write should succeed if stringWriter wasn't closed
            emitter.Emit(stringWriter);
        }
예제 #19
0
        private void BuildToFile(IDiagnosticLogger logger, string bicepPath, string outputPath)
        {
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepPath));
            var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

            var success = LogDiagnosticsAndCheckSuccess(logger, compilation);

            if (success)
            {
                var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), this.assemblyFileVersion);

                using var outputStream = CreateFileStream(outputPath);
                emitter.Emit(outputStream);
            }
        }
예제 #20
0
        private static void BuildSingleFile(IDiagnosticLogger logger, string bicepPath, string outputPath)
        {
            string text       = File.ReadAllText(bicepPath);
            var    lineStarts = TextCoordinateConverter.GetLineStarts(text);

            var compilation = new Compilation(SyntaxFactory.CreateFromText(text));

            var emitter = new TemplateEmitter(compilation.GetSemanticModel());

            var result = emitter.Emit(outputPath);

            foreach (var diagnostic in result.Diagnostics)
            {
                logger.LogDiagnostic(bicepPath, diagnostic, lineStarts);
            }
        }
예제 #21
0
        private void BuildSingleFile(IDiagnosticLogger logger, string bicepPath, string outputPath)
        {
            string text       = ReadFile(bicepPath);
            var    lineStarts = TextCoordinateConverter.GetLineStarts(text);

            var compilation = new Compilation(resourceTypeProvider, SyntaxFactory.CreateFromText(text));

            var emitter = new TemplateEmitter(compilation.GetSemanticModel());

            using var outputStream = CreateFileStream(outputPath);
            var result = emitter.Emit(outputStream);

            foreach (var diagnostic in result.Diagnostics)
            {
                logger.LogDiagnostic(bicepPath, diagnostic, lineStarts);
            }
        }
예제 #22
0
        public void ExampleIsValid(ExampleData example)
        {
            // save all the files in the containing directory to disk so that we can test module resolution
            var parentStream    = Path.GetDirectoryName(example.BicepStreamName) !.Replace('\\', '/');
            var outputDirectory = FileHelper.SaveEmbeddedResourcesWithPathPrefix(TestContext, typeof(ExamplesTests).Assembly, example.OutputFolderName, parentStream);
            var bicepFileName   = Path.Combine(outputDirectory, Path.GetFileName(example.BicepStreamName));
            var jsonFileName    = Path.Combine(outputDirectory, Path.GetFileName(example.JsonStreamName));

            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepFileName));
            var compilation        = new Compilation(new AzResourceTypeProvider(), syntaxTreeGrouping);
            var emitter            = new TemplateEmitter(compilation.GetEntrypointSemanticModel());

            // group assertion failures using AssertionScope, rather than reporting the first failure
            using (new AssertionScope())
            {
                foreach (var(syntaxTree, diagnostics) in compilation.GetAllDiagnosticsBySyntaxTree())
                {
                    var nonPermittedDiagnostics = diagnostics.Where(x => !IsPermittedMissingTypeDiagnostic(x));

                    nonPermittedDiagnostics.Should().BeEmpty($"\"{syntaxTree.FileUri.LocalPath}\" should not have warnings or errors");
                }

                var exampleExists = File.Exists(jsonFileName);
                exampleExists.Should().BeTrue($"Generated example \"{jsonFileName}\" should be checked in");

                using var stream = new MemoryStream();
                var result = emitter.Emit(stream);

                result.Status.Should().Be(EmitStatus.Succeeded);

                if (result.Status == EmitStatus.Succeeded)
                {
                    stream.Position = 0;
                    var generated = new StreamReader(stream).ReadToEnd();

                    var actual = JToken.Parse(generated);
                    File.WriteAllText(jsonFileName + ".actual", generated);

                    actual.Should().EqualWithJsonDiffOutput(
                        TestContext,
                        exampleExists ? JToken.Parse(File.ReadAllText(jsonFileName)) : new JObject(),
                        example.JsonStreamName,
                        jsonFileName + ".actual");
                }
            }
        }
예제 #23
0
        private void BuildToStdout(IDiagnosticLogger logger, string bicepPath)
        {
            using var writer = new JsonTextWriter(this.outputWriter)
                  {
                      Formatting = Formatting.Indented
                  };

            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepPath));
            var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

            var success = LogDiagnosticsAndCheckSuccess(logger, compilation);

            if (success)
            {
                var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), this.assemblyFileVersion);

                emitter.Emit(writer);
            }
        }
예제 #24
0
        public static DerivedColumns CreateIsNullPatcherFromXml(Packages.VulcanPackage vulcanPackage, IDTSComponentMetaData90 parentComponent, MainPipe dataFlowTask, XPathNavigator nullNav)
        {
            if (nullNav == null || nullNav.Name.ToUpperInvariant() != "IsNullPatcher".ToUpperInvariant())
            {
                return(null);
            }

            string componentName = nullNav.SelectSingleNode("@Name", vulcanPackage.VulcanConfig.NamespaceManager).Value;

            Message.Trace(Severity.Debug, "Begin: IsNullPatcher variant DerivedColumns Transformation {0}", componentName);
            DerivedColumns dc = new DerivedColumns(vulcanPackage, dataFlowTask, parentComponent, componentName, componentName);

            IDTSVirtualInput90 vi = dc.Component.InputCollection[0].GetVirtualInput();

            TemplateEmitter te = new TemplateEmitter("NullPatcherIsnullTemplate", vulcanPackage, null);

            foreach (XPathNavigator nav in nullNav.Select("rc:Column", vulcanPackage.VulcanConfig.NamespaceManager))
            {
                string name         = nav.SelectSingleNode("@Name").Value;
                string defaultValue = nav.SelectSingleNode("@DefaultValue").Value;

                dc.SetInputUsageType(vi, vi.VirtualInputColumnCollection[name], DTSUsageType.UT_READWRITE);
                IDTSInputColumn90 inputCol = dc.Component.InputCollection[0].InputColumnCollection[name];

                string expression;
                te.SetParameters("#" + vi.VirtualInputColumnCollection[name].LineageID.ToString(), defaultValue);
                te.Emit(out expression);

                string friendlyExpression;
                te.SetParameters(name, defaultValue);
                te.Emit(out friendlyExpression);

                inputCol.CustomPropertyCollection["Expression"].Value         = expression;
                inputCol.CustomPropertyCollection["FriendlyExpression"].Value = friendlyExpression;
            }
            return(dc);
        }
예제 #25
0
        private string GenerateCompiledFileAndReturnBuildOutputMessage(string bicepFilePath, DocumentUri documentUri)
        {
            string compiledFilePath = PathHelper.GetDefaultBuildOutputPath(bicepFilePath);
            string compiledFile     = Path.GetFileName(compiledFilePath);

            // If the template exists and contains bicep generator metadata, we can go ahead and replace the file.
            // If not, we'll fail the build.
            if (File.Exists(compiledFilePath) && !TemplateContainsBicepGeneratorMetadata(File.ReadAllText(compiledFilePath)))
            {
                return("Build failed. The file \"" + compiledFile + "\" already exists and was not generated by Bicep. If overwriting the file is intended, delete it manually and retry the Build command.");
            }

            CompilationContext?context = CompilationManager.GetCompilation(documentUri);

            if (context is null)
            {
                throw new InvalidOperationException($"Unable to get compilation context");
            }

            SemanticModel semanticModel = context.Compilation.GetEntrypointSemanticModel();
            KeyValuePair <BicepFile, IEnumerable <IDiagnostic> > diagnosticsByFile = context.Compilation.GetAllDiagnosticsByBicepFile()
                                                                                     .FirstOrDefault(x => x.Key.FileUri == documentUri.ToUri());

            if (diagnosticsByFile.Value.Any(x => x.Level == DiagnosticLevel.Error))
            {
                return(GetDiagnosticsMessage(diagnosticsByFile));
            }

            using (FileStream fileStream = new FileStream(compiledFilePath, FileMode.Create, FileAccess.ReadWrite))
            {
                TemplateEmitter emitter = new TemplateEmitter(semanticModel, ThisAssembly.AssemblyFileVersion);
                EmitResult      result  = emitter.Emit(fileStream);

                return("Build succeeded. Created file " + compiledFile);
            }
        }
예제 #26
0
        private static (string?jsonOutput, IEnumerable <Diagnostic> diagnostics) Compile(string bicepContents)
        {
            var syntaxTreeGrouping = SyntaxFactory.CreateFromText(bicepContents);
            var compilation        = new Compilation(new AzResourceTypeProvider(), syntaxTreeGrouping);
            var emitter            = new TemplateEmitter(compilation.GetEntrypointSemanticModel());

            var diagnostics = compilation.GetEntrypointSemanticModel().GetAllDiagnostics();

            string?jsonOutput = null;

            if (!compilation.GetEntrypointSemanticModel().HasErrors())
            {
                using var stream = new MemoryStream();
                var emitResult = emitter.Emit(stream);

                if (emitResult.Status != EmitStatus.Failed)
                {
                    stream.Position = 0;
                    jsonOutput      = new StreamReader(stream).ReadToEnd();
                }
            }

            return(jsonOutput, diagnostics);
        }
예제 #27
0
        public void NestedResources_valid_resource_references()
        {
            var program = @"
resource parent 'My.RP/parentType@2020-01-01' = {
  name: 'parent'
  properties: {
    size: 'large'
  }

  resource child 'childType' = {
    name: 'child'
    properties: {
      style: 'very cool'
    }

    resource grandchild 'grandchildType' = {
      name: 'grandchild'
      properties: {
        temperature: 'ice-cold'
      }
    }
  }

  resource sibling 'childType@2020-01-02' = {
    name: 'sibling'
    properties: {
      style: parent::child.properties.style
      size: parent.properties.size
      temperatureC: child::grandchild.properties.temperature
      temperatureF: parent::child::grandchild.properties.temperature
    }
  }
}

output fromChild string = parent::child.properties.style
output fromGrandchild string = parent::child::grandchild.properties.style
";

            var compilation = new Compilation(BicepTestConstants.Features, TestTypeHelper.CreateEmptyProvider(), SourceFileGroupingFactory.CreateFromText(program, BicepTestConstants.FileResolver), BicepTestConstants.BuiltInConfiguration, BicepTestConstants.LinterAnalyzer);
            var model       = compilation.GetEntrypointSemanticModel();

            model.GetAllDiagnostics().ExcludingLinterDiagnostics().ExcludingMissingTypes().Should().BeEmpty();

            var parent     = model.DeclaredResources.Select(x => x.Symbol).Single(r => r.Name == "parent");
            var references = model.FindReferences(parent);

            references.Should().HaveCount(6);

            var child = model.DeclaredResources.Select(x => x.Symbol).Single(r => r.Name == "child");

            references = model.FindReferences(child);
            references.Should().HaveCount(6);

            var grandchild = model.DeclaredResources.Select(x => x.Symbol).Single(r => r.Name == "grandchild");

            references = model.FindReferences(grandchild);
            references.Should().HaveCount(4);

            var sibling = model.DeclaredResources.Select(x => x.Symbol).Single(r => r.Name == "sibling");

            references = model.FindReferences(sibling);
            references.Should().HaveCount(1);

            var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), BicepTestConstants.EmitterSettings);

            using var outputStream = new MemoryStream();
            emitter.Emit(outputStream);

            outputStream.Seek(0L, SeekOrigin.Begin);
            var text = Encoding.UTF8.GetString(outputStream.GetBuffer());
        }
예제 #28
0
        public void NestedResources_valid_resource_references()
        {
            var program = @"
resource parent 'My.RP/parentType@2020-01-01' = {
  name: 'parent'
  properties: {
    size: 'large'
  }

  resource child 'childType' = {
    name: 'child'
    properties: {
      style: 'very cool'
    }

    resource grandchild 'grandchildType' = {
      name: 'grandchild'
      properties: {
        temperature: 'ice-cold'
      }
    }
  }

  resource sibling 'childType@2020-01-02' = {
    name: 'sibling'
    properties: {
      style: parent::child.properties.style
      size: parent.properties.size
      temperatureC: child::grandchild.properties.temperature
      temperatureF: parent::child::grandchild.properties.temperature
    }
  }
}

output fromChild string = parent::child.properties.style
output fromGrandchild string = parent::child::grandchild.properties.style
";

            var compilation = new Compilation(TestResourceTypeProvider.Create(), SyntaxTreeGroupingFactory.CreateFromText(program));
            var model       = compilation.GetEntrypointSemanticModel();

            model.GetAllDiagnostics().Should().BeEmpty();

            var parent     = model.Root.GetAllResourceDeclarations().Single(r => r.Name == "parent");
            var references = model.FindReferences(parent);

            references.Should().HaveCount(6);

            var child = model.Root.GetAllResourceDeclarations().Single(r => r.Name == "child");

            references = model.FindReferences(child);
            references.Should().HaveCount(6);

            var grandchild = model.Root.GetAllResourceDeclarations().Single(r => r.Name == "grandchild");

            references = model.FindReferences(grandchild);
            references.Should().HaveCount(4);

            var sibling = model.Root.GetAllResourceDeclarations().Single(r => r.Name == "sibling");

            references = model.FindReferences(sibling);
            references.Should().HaveCount(1);

            var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), BicepTestConstants.DevAssemblyFileVersion);

            using var outputStream = new MemoryStream();
            emitter.Emit(outputStream);

            outputStream.Seek(0L, SeekOrigin.Begin);
            var text = Encoding.UTF8.GetString(outputStream.GetBuffer());
        }
예제 #29
0
        public override void Emit(XPathNavigator patternNavigator)
        {
            if (patternNavigator != null)
            {
                string taskName       = patternNavigator.SelectSingleNode("@Name").Value;
                string connectionName = patternNavigator.SelectSingleNode("@Connection").Value;
                string varPrefix      = patternNavigator.SelectSingleNode("@PreviousLogEntryVariablePrefix").Value;

                string sourceColumn        = patternNavigator.SelectSingleNode("@SourceColumn") == null ? null : patternNavigator.SelectSingleNode("@SourceColumn").Value;
                string destinationColumn   = patternNavigator.SelectSingleNode("@DestinationColumn") == null ? null : patternNavigator.SelectSingleNode("@DestinationColumn").Value;
                string table               = patternNavigator.SelectSingleNode("@Table") == null ? null : patternNavigator.SelectSingleNode("@Table").Value;
                string tableConnectionName = patternNavigator.SelectSingleNode("@TableConnection") == null ? null : patternNavigator.SelectSingleNode("@TableConnection").Value;

                if (varPrefix.ToUpperInvariant() == "varLog")
                {
                    Message.Trace(Severity.Error, "Name: {0}: Error in PreviousLogEntryVariablePrefix: varLog is a reserved variable name.", taskName);
                    return;
                }

                Connection connection =
                    Connection.GetExistingConnection(VulcanPackage, connectionName);

                LogtainerLog ll = new LogtainerLog(
                    VulcanPackage,
                    Resources.LogVariablePrefix + VulcanPackage.Name + taskName,
                    sourceColumn,
                    destinationColumn,
                    table,
                    tableConnectionName
                    );

                string  execSqlTaskName = Resources.Log + Resources.Seperator + VulcanPackage.Name + Resources.Seperator + taskName + Resources.Seperator;
                SQLTask logStartTask    = new SQLTask(VulcanPackage, execSqlTaskName + Resources.Start, execSqlTaskName + Resources.Start, ParentContainer, connection);


                TemplateEmitter te = new TemplateEmitter(VulcanPackage.TemplateManager["LogStart"]);
                te.SetNamedParameter("ETLName", VulcanPackage.Name);
                te.SetNamedParameter("TaskName", taskName);

                if (_logStack.Count > 0)
                {
                    te.SetNamedParameter("ParentLogID", "?");
                    // Yes you have to hard code the data type as there is no lookup or cross-reference source, and the intger is dependent on the connection you create... bugbug!
                    logStartTask.BindParameter(CurrentLog.LogVariable, Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Input, 3);
                }
                else
                {
                    te.SetNamedParameter("ParentLogID", "NULL");
                }
                logStartTask.BindParameter(ll.LogVariable, Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output, 3);
                logStartTask.BindParameter(ll.LastRecordLogVariable, Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output, 3);
                logStartTask.BindParameter(ll.IsAnotherInstanceCurrentlyRunningLogVariable, Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output, 3);


                string sqlExpression;
                te.Emit(out sqlExpression);
                logStartTask.TransmuteToExpressionTask(sqlExpression);

                te = new TemplateEmitter(VulcanPackage.TemplateManager["LogGetValue"]);
                te.SetNamedParameter("LogID", ll.LastRecordLogVariable.QualifiedName);
                this.FirstExecutableGeneratedByPattern = logStartTask.SQLTaskHost;



                // Push the current log variable onto the stack!
                _logStack.Push(ll);

                //Add a new SQL Task to read the  previous log
                te = new TemplateEmitter("LogGetValue", VulcanPackage, ll.LastRecordLogVariable.QualifiedName);
                string readPreviousLogValuesQuery;
                te.Emit(out readPreviousLogValuesQuery);

                SQLTask readPreviousLogValues = new SQLTask(VulcanPackage, Resources.Log + Resources.LoadInto + varPrefix, Resources.Log + Resources.LoadInto + varPrefix, ParentContainer, connection);
                readPreviousLogValues.TransmuteToExpressionTask(readPreviousLogValuesQuery);
                VulcanPackage.AddPrecedenceConstraint(this.FirstExecutableGeneratedByPattern, readPreviousLogValues.SQLTaskHost, ParentContainer);

                //Bind and create variables for the SQL Task that reads the previous log. This is kinda hacky
                readPreviousLogValues.BindParameter(
                    VulcanPackage.AddVariable(varPrefix + "StartTime", new DateTime(1980, 1, 1)),
                    Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output,
                    (int)System.Data.OleDb.OleDbType.DBTimeStamp,
                    255);
                readPreviousLogValues.BindParameter(
                    VulcanPackage.AddVariable(varPrefix + "EndTime", new DateTime(1980, 1, 1)),
                    Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output,
                    (int)System.Data.OleDb.OleDbType.DBTimeStamp,
                    255);

                readPreviousLogValues.BindParameter(
                    VulcanPackage.AddVariable(varPrefix + "FirstSourceRecord", String.Empty),
                    Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output,
                    (int)System.Data.OleDb.OleDbType.WChar,
                    255);
                readPreviousLogValues.BindParameter(
                    VulcanPackage.AddVariable(varPrefix + "FirstDestinationRecord", String.Empty),
                    Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output,
                    (int)System.Data.OleDb.OleDbType.WChar,
                    255);
                readPreviousLogValues.BindParameter(
                    VulcanPackage.AddVariable(varPrefix + "LastSourceRecord", String.Empty),
                    Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output,
                    (int)System.Data.OleDb.OleDbType.WChar,
                    255);
                readPreviousLogValues.BindParameter(
                    VulcanPackage.AddVariable(varPrefix + "LastDestinationRecord", String.Empty),
                    Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output,
                    (int)System.Data.OleDb.OleDbType.WChar,
                    255);

                readPreviousLogValues.BindParameter(
                    VulcanPackage.AddVariable(varPrefix + "Status", String.Empty),
                    Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output,
                    (int)System.Data.OleDb.OleDbType.WChar,
                    255);

                readPreviousLogValues.BindParameter(
                    VulcanPackage.AddVariable(varPrefix + "Notes", String.Empty),
                    Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Output,
                    (int)System.Data.OleDb.OleDbType.WChar,
                    255);

                // Handle the sub-tasks just like the Container pattern
                DTS.Executable previousExec = readPreviousLogValues.SQLTaskHost;
                Pattern        p            = null;
                foreach (XPathNavigator nav in patternNavigator.SelectChildren(XPathNodeType.Element))
                {
                    p = PatternFactory.ProcessPattern(VulcanPackage, ParentContainer, nav, p);
                    VulcanPackage.AddPrecedenceConstraint(previousExec, p.FirstExecutableGeneratedByPattern, ParentContainer);
                    previousExec = p.LastExecutableGeneratedByPattern;
                }

                this.LastExecutableGeneratedByPattern = previousExec;

                // Pop the current log variable off of the stack and end the log.
                ll = _logStack.Pop();

                te = new TemplateEmitter(VulcanPackage.TemplateManager["LogSetValue"]);
                te.SetNamedParameter("LogID", ll.LogVariable.QualifiedName);
                StringBuilder writeValuesToLogQuery = new StringBuilder();
                foreach (string column in ll.LogColumnDictionary.Keys)
                {
                    string temp;
                    te.SetNamedParameter("Column", column);
                    te.SetNamedParameter("Value", ll.LogColumnDictionary[column].QualifiedName);
                    te.Emit(out temp);
                    writeValuesToLogQuery.Append(temp);
                    writeValuesToLogQuery.AppendFormat(" + \n");
                }

                te = new TemplateEmitter(VulcanPackage.TemplateManager["LogEnd"]);
                te.Emit(out sqlExpression);

                writeValuesToLogQuery.Append(sqlExpression);

                SQLTask logEndTask = new SQLTask(VulcanPackage, execSqlTaskName + Resources.Stop, execSqlTaskName + Resources.Stop, ParentContainer, connection);
                logEndTask.TransmuteToExpressionTask(writeValuesToLogQuery.ToString());
                logEndTask.BindParameter(ll.LogVariable, Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ParameterDirections.Input, 3);
                if (previousExec != null)
                {
                    VulcanPackage.AddPrecedenceConstraint(previousExec, logEndTask.SQLTaskHost, ParentContainer);
                }
                this.LastExecutableGeneratedByPattern = logEndTask.SQLTaskHost;
            }
        }
예제 #30
0
        public VulcanConfig XmlTemplateReplacement(VulcanConfig vulcanConfig)
        {
            List <XPathNavigator> nodeList = new List <XPathNavigator>();
            VulcanConfig          vc       = vulcanConfig;

            foreach (XPathNavigator node in vc.Navigator.SelectDescendants(XPathNodeType.Element, true))
            {
                if (node.XmlType != null && node.XmlType.Name != null)
                {
                    if (node.XmlType.Name.ToUpperInvariant().Contains("TEMPLATEXML"))
                    {
                        nodeList.Add(node);
                    }
                }
            }

            foreach (XPathNavigator node in nodeList)
            {
                XPathNavigator nameNode     = node.SelectSingleNode("@Name");
                string         templateName = nameNode.Value;
                nameNode.DeleteSelf();
                Message.Trace(Severity.Debug, "Replacing Template {0}", node.OuterXml);
                if (this.templateDictionary.ContainsKey(templateName))
                {
                    Template        t  = this[templateName];
                    TemplateEmitter te = new TemplateEmitter(t);

                    int parameterCount = 0;
                    if (node.MoveToFirstAttribute())
                    {
                        do
                        {
                            parameterCount++;
                            Message.Trace(Severity.Debug, "Mapping Parameter {0}={1}", node.Name, node.Value);
                            te.SetNamedParameter(node.Name, node.Value);
                        } while (node.MoveToNextAttribute());
                    }
                    if (parameterCount == t.MapDictionary.Keys.Count)
                    {
                        string newXml;
                        te.Emit(out newXml);
                        if (parameterCount > 0)
                        {
                            node.MoveToParent();
                        }
                        Message.Trace(Severity.Debug, "Old Node: {0}", node.OuterXml);
                        node.OuterXml = newXml;
                        Message.Trace(Severity.Debug, "New Node: {0}", node.OuterXml);
                    }
                    else
                    {
                        Message.Trace(Severity.Error, "Template parameters do not match up.  Contains {0} but the template requires {1}", parameterCount, t.MapDictionary.Keys.Count);
                    }
                }
                else
                {
                    Message.Trace(Severity.Error, "Invalid template {0}", templateName);
                }
            }
            string savePath = vc.Save();

            Message.Trace(Severity.Notification, "Saved new VulcanConfig to {0}", savePath);
            vc = new VulcanConfig(savePath);
            return(vc);
        }