Begin Razor build command

This commit is contained in:
Steve Sanderson 2018-01-11 10:31:49 +00:00
parent 863826ab9d
commit 8d4491d4b8
5 changed files with 152 additions and 4 deletions

View File

@ -0,0 +1,80 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.Blazor.Build.Core.RazorCompilation;
using Microsoft.Extensions.CommandLineUtils;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Microsoft.Blazor.Build.Cli.Commands
{
internal class BuildRazorCommand
{
public static void Command(CommandLineApplication command)
{
// Later, we might want to have the complete list of inputs passed in from MSBuild
// so developers can include/exclude whatever they want. The MVC Razor view precompiler
// does this by writing the list to a temporary 'response' file then passing the path
// to that file into its build executable (see: https://github.com/aspnet/MvcPrecompilation/blob/dev/src/Microsoft.AspNetCore.Mvc.Razor.ViewCompilation/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.targets)
// For now it's sufficient to assume we want to include '<sourcedir>**\*.cshtml'
var sourceDirPath = command.Option("--source",
"The path to the directory containing Razor files",
CommandOptionType.SingleValue);
var outputFilePath = command.Option("--output",
"The location where the resulting C# source file should be written",
CommandOptionType.SingleValue);
var verboseFlag = command.Option("--verbose",
"Indicates that verbose console output should written",
CommandOptionType.NoValue);
command.OnExecute(() =>
{
if (!VerifyRequiredOptionsProvided(sourceDirPath, outputFilePath))
{
return 1;
}
var sourceDirPathValue = sourceDirPath.Value();
if (!Directory.Exists(sourceDirPathValue))
{
Console.WriteLine($"ERROR: Directory not found: {sourceDirPathValue}");
return 1;
}
var inputRazorFilePaths = FindRazorFiles(sourceDirPathValue).ToList();
using (var outputWriter = new StreamWriter(outputFilePath.Value()))
{
var diagnostics = new RazorCompiler().CompileFiles(
inputRazorFilePaths,
"Blazor", // TODO: Add required option for namespace
outputWriter,
verboseFlag.HasValue() ? Console.Out : null);
foreach (var diagnostic in diagnostics)
{
Console.WriteLine(diagnostic.FormatForConsole());
}
var hasError = diagnostics.Any(item => item.Type == RazorCompilerDiagnostic.DiagnosticType.Error);
return hasError ? 1 : 0;
}
});
}
private static IEnumerable<string> FindRazorFiles(string rootDirPath)
=> Directory.GetFiles(rootDirPath, "*.cshtml", SearchOption.AllDirectories);
private static bool VerifyRequiredOptionsProvided(params CommandOption[] options)
{
var violations = options.Where(o => !o.HasValue()).ToList();
foreach (var violation in violations)
{
Console.WriteLine($"ERROR: No value specified for required option '{violation.LongName}'.");
}
return !violations.Any();
}
}
}

View File

@ -17,6 +17,7 @@ namespace Microsoft.Blazor.Build
app.HelpOption("-?|-h|--help");
app.Command("build", BuildCommand.Command);
app.Command("buildrazor", BuildRazorCommand.Command);
if (args.Length > 0)
{

View File

@ -0,0 +1,30 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.IO;
namespace Microsoft.Blazor.Build.Core.RazorCompilation
{
public class RazorCompiler
{
public ICollection<RazorCompilerDiagnostic> CompileFiles(IEnumerable<string> inputPaths, string outputNamespace, TextWriter resultOutput, TextWriter verboseOutput)
{
var diagnostics = new List<RazorCompilerDiagnostic>();
foreach (var inputFilePath in inputPaths)
{
verboseOutput?.WriteLine($"Compiling {inputFilePath}...");
resultOutput.WriteLine($"// TODO: Compile {inputFilePath}");
diagnostics.Add(new RazorCompilerDiagnostic(
RazorCompilerDiagnostic.DiagnosticType.Warning,
inputFilePath,
1,
1,
"Compiler not implemented"));
}
return diagnostics;
}
}
}

View File

@ -0,0 +1,40 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.Blazor.Build.Core.RazorCompilation
{
public class RazorCompilerDiagnostic
{
public DiagnosticType Type { get; }
public string SourceFilePath { get; }
public int Line { get; }
public int Column { get; }
public string Message { get; }
internal RazorCompilerDiagnostic(
DiagnosticType type,
string sourceFilePath,
int line,
int column,
string message)
{
Type = type;
SourceFilePath = sourceFilePath;
Line = line;
Column = column;
Message = message;
}
public enum DiagnosticType
{
Warning,
Error
}
public string FormatForConsole()
=> $"{SourceFilePath}({Line},{Column}): {FormatTypeAndCodeForConsole()}: {Message}";
private string FormatTypeAndCodeForConsole()
=> $"{Type.ToString().ToLowerInvariant()} Blazor";
}
}

View File

@ -5,15 +5,12 @@
that the Razor components can be referenced with intellisense from .cs files. -->
<Target Name="BlazorCompileRazorComponents" BeforeTargets="CoreCompile">
<ItemGroup>
<BlazorRazorComponents Include="**\*.cshtml" />
</ItemGroup>
<PropertyGroup>
<BlazorComponentsNamespace>BlazorComponents</BlazorComponentsNamespace>
<IsDesignTimeBuild Condition="'$(DesignTimeBuild)' == 'true' OR '$(BuildingProject)' != 'true'">true</IsDesignTimeBuild>
<GeneratedFilePath>$(IntermediateOutputPath)BlazorRazorComponents.g.cs</GeneratedFilePath>
</PropertyGroup>
<WriteLinesToFile File="$(GeneratedFilePath)" Overwrite="true" Lines="namespace $(BlazorComponentsNamespace) {;@(BlazorRazorComponents->'public class %(Filename) {}');}" />
<Exec Command="$(BlazorBuildExe) buildrazor --source $(ProjectDir) --output $(GeneratedFilePath)" />
<ItemGroup>
<Compile Include="$(GeneratedFilePath)" />
</ItemGroup>