Skip to content

Instantly share code, notes, and snippets.

@anthony-c-martin
Last active June 7, 2024 15:03
Show Gist options
  • Save anthony-c-martin/917660b367b998685ea8805abe3a8298 to your computer and use it in GitHub Desktop.
Save anthony-c-martin/917660b367b998685ea8805abe3a8298 to your computer and use it in GitHub Desktop.
Compile Bicep
using System;
using System.IO;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.IO.Abstractions;
using Bicep.Core;
using Bicep.Core.Analyzers.Interfaces;
using Bicep.Core.Analyzers.Linter;
using Bicep.Core.Configuration;
using Bicep.Core.Emit;
using Bicep.Core.Features;
using Bicep.Core.FileSystem;
using Bicep.Core.Registry;
using Bicep.Core.Text;
using Bicep.Core.Registry.Auth;
using Bicep.Core.Semantics.Namespaces;
using Bicep.Core.TypeSystem.Providers;
using Bicep.Core.Utils;
using Microsoft.Extensions.DependencyInjection;
using System.IO.Abstractions.TestingHelpers;
using Environment = Bicep.Core.Utils.Environment;
public class Program
{
public static async Task Main()
{
var files = new Dictionary<string, MockFileData>
{
["/main.bicep"] = """
module mod 'module.bicep' = {
name: 'module'
params: {
foo: 'foo'
}
}
""",
["/module.bicep"] = """
param foo string
output foo string = foo
""",
};
var services = new ServiceCollection()
.AddBicepCore(new MockFileSystem(files))
.BuildServiceProvider();
var template = await Compile(services, new Uri("file:///main.bicep"));
Console.Write(template);
}
private static async Task<string> Compile(IServiceProvider services, Uri bicepUri)
{
var compiler = services.GetRequiredService<BicepCompiler>();
var compilation = await compiler.CreateCompilation(bicepUri);
var model = compilation.GetEntrypointSemanticModel();
using var stream = new MemoryStream();
var emitter = new TemplateEmitter(model);
var emitResult = emitter.Emit(stream);
foreach (var (file, diagnostics) in compilation.GetAllDiagnosticsByBicepFile())
foreach (var diagnostic in diagnostics)
{
(var line, var character) = TextCoordinateConverter.GetPosition(file.LineStarts, diagnostic.Span.Position);
Console.WriteLine($"{file.FileUri.LocalPath}({line + 1},{character + 1}) : {diagnostic.Level} {diagnostic.Code}: {diagnostic.Message}");
}
if (emitResult.Status == EmitStatus.Failed)
{
throw new InvalidOperationException("Compilation failed!");
}
stream.Position = 0;
return new StreamReader(stream).ReadToEnd();
}
}
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddBicepCore(this IServiceCollection services, IFileSystem fileSystem) => services
.AddSingleton<INamespaceProvider, NamespaceProvider>()
.AddSingleton<IResourceTypeProviderFactory, ResourceTypeProviderFactory>()
.AddSingleton<IContainerRegistryClientFactory, ContainerRegistryClientFactory>()
.AddSingleton<ITemplateSpecRepositoryFactory, TemplateSpecRepositoryFactory>()
.AddSingleton<IModuleDispatcher, ModuleDispatcher>()
.AddSingleton<IArtifactRegistryProvider, DefaultArtifactRegistryProvider>()
.AddSingleton<ITokenCredentialFactory, TokenCredentialFactory>()
.AddSingleton<IFileResolver, FileResolver>()
.AddSingleton<IEnvironment, Environment>()
.AddSingleton<IFileSystem>(fileSystem)
.AddSingleton<IConfigurationManager, ConfigurationManager>()
.AddSingleton<IBicepAnalyzer, LinterAnalyzer>()
.AddSingleton<IFeatureProviderFactory, FeatureProviderFactory>()
.AddSingleton<ILinterRulesProvider, LinterRulesProvider>()
.AddSingleton<BicepCompiler>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment