-
-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial Support for Handlebars added * Increasing Package Version to force redownload node modules * Adding node directory to .gitignore file * Updating extension manifest file * Source Map file creation support for Handlebars compiler added * Basic Tests for Handlebars added * Temporally map file name changed to prevent unintended overwrites * Handlebars: Spelling mistake fixed
- Loading branch information
1 parent
313198e
commit dc1f553
Showing
27 changed files
with
626 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace WebCompiler | ||
{ | ||
class HandlebarsCompiler : ICompiler | ||
{ | ||
private static Regex _errorRx = new Regex("Error: (?<message>.+) on line (?<line>[0-9]+):", RegexOptions.Compiled); | ||
private string _mapPath; | ||
private string _path; | ||
private string _name = string.Empty; | ||
private string _extension = string.Empty; | ||
private string _output = string.Empty; | ||
private string _error = string.Empty; | ||
private bool _partial = false; | ||
|
||
public HandlebarsCompiler(string path) | ||
{ | ||
_path = path; | ||
} | ||
|
||
public CompilerResult Compile(Config config) | ||
{ | ||
string baseFolder = Path.GetDirectoryName(config.FileName); | ||
string inputFile = Path.Combine(baseFolder, config.InputFile); | ||
|
||
FileInfo info = new FileInfo(inputFile); | ||
string content = File.ReadAllText(info.FullName); | ||
|
||
CompilerResult result = new CompilerResult | ||
{ | ||
FileName = info.FullName, | ||
OriginalContent = content, | ||
}; | ||
|
||
var extension = Path.GetExtension(inputFile); | ||
if (!string.IsNullOrWhiteSpace(extension)) | ||
{ | ||
_extension = extension.Substring(1); | ||
} | ||
|
||
var name = Path.GetFileNameWithoutExtension(inputFile); | ||
if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("_")) | ||
{ | ||
_name = name.Substring(1); | ||
_partial = true; | ||
|
||
// Temporarily Fix | ||
// TODO: Remove after actual fix | ||
var tempFilename = Path.Combine(Path.GetDirectoryName(inputFile), _name + ".handlebarstemp"); | ||
info.CopyTo(tempFilename); | ||
info = new FileInfo(tempFilename); | ||
_extension = "handlebarstemp"; | ||
} | ||
|
||
_mapPath = Path.ChangeExtension(inputFile, ".js.map.tmp"); | ||
|
||
try | ||
{ | ||
RunCompilerProcess(config, info); | ||
|
||
result.CompiledContent = _output; | ||
|
||
var options = HandlebarsOptions.FromConfig(config); | ||
if (options.SourceMap || config.SourceMap) | ||
{ | ||
if (File.Exists(_mapPath)) | ||
result.SourceMap = File.ReadAllText(_mapPath); | ||
} | ||
|
||
if (_error.Length > 0) | ||
{ | ||
CompilerError ce = new CompilerError | ||
{ | ||
FileName = inputFile, | ||
Message = _error.Replace(baseFolder, string.Empty), | ||
IsWarning = !string.IsNullOrEmpty(_output) | ||
}; | ||
|
||
var match = _errorRx.Match(_error); | ||
|
||
if (match.Success) | ||
{ | ||
ce.Message = match.Groups["message"].Value.Replace(baseFolder, string.Empty); | ||
ce.LineNumber = int.Parse(match.Groups["line"].Value); | ||
ce.ColumnNumber = 0; | ||
} | ||
|
||
result.Errors.Add(ce); | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
CompilerError error = new CompilerError | ||
{ | ||
FileName = inputFile, | ||
Message = string.IsNullOrEmpty(_error) ? ex.Message : _error, | ||
LineNumber = 0, | ||
ColumnNumber = 0, | ||
}; | ||
|
||
result.Errors.Add(error); | ||
} | ||
finally | ||
{ | ||
if (File.Exists(_mapPath)) | ||
{ | ||
File.Delete(_mapPath); | ||
} | ||
// Temporarily Fix | ||
// TODO: Remove after actual fix | ||
if (info.Extension == ".handlebarstemp") | ||
{ | ||
info.Delete(); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
private void RunCompilerProcess(Config config, FileInfo info) | ||
{ | ||
string arguments = ConstructArguments(config); | ||
|
||
ProcessStartInfo start = new ProcessStartInfo | ||
{ | ||
WorkingDirectory = info.Directory.FullName, | ||
UseShellExecute = false, | ||
WindowStyle = ProcessWindowStyle.Hidden, | ||
CreateNoWindow = true, | ||
FileName = "cmd.exe", | ||
Arguments = $"/c \"\"{Path.Combine(_path, "node_modules\\.bin\\handlebars.cmd")}\" \"{info.FullName}\" {arguments}\"", | ||
StandardOutputEncoding = Encoding.UTF8, | ||
StandardErrorEncoding = Encoding.UTF8, | ||
RedirectStandardOutput = true, | ||
RedirectStandardError = true, | ||
}; | ||
|
||
start.EnvironmentVariables["PATH"] = _path + ";" + start.EnvironmentVariables["PATH"]; | ||
|
||
using (Process p = Process.Start(start)) | ||
{ | ||
var stdout = p.StandardOutput.ReadToEndAsync(); | ||
var stderr = p.StandardError.ReadToEndAsync(); | ||
p.WaitForExit(); | ||
|
||
_output = stdout.Result.Trim(); | ||
_error = stderr.Result.Trim(); | ||
} | ||
} | ||
|
||
private string ConstructArguments(Config config) | ||
{ | ||
string arguments = ""; | ||
|
||
HandlebarsOptions options = HandlebarsOptions.FromConfig(config); | ||
|
||
if (options.AMD) | ||
arguments += " --amd"; | ||
else if (!string.IsNullOrEmpty(options.CommonJS)) | ||
arguments += $" --commonjs \"{options.CommonJS}\""; | ||
|
||
foreach (var knownHelper in options.KnownHelpers) | ||
{ | ||
arguments += $" --known \"{knownHelper}\""; | ||
} | ||
|
||
if (options.KnownHelpersOnly) | ||
arguments += " --knownOnly"; | ||
|
||
if (options.ForcePartial || _partial) | ||
arguments += " --partial"; | ||
|
||
if (options.NoBOM) | ||
arguments += " --bom"; | ||
|
||
if ((options.SourceMap || config.SourceMap) && !string.IsNullOrWhiteSpace(_mapPath)) | ||
arguments += $" --map \"{_mapPath}\""; | ||
|
||
if (!string.IsNullOrEmpty(options.TemplateNameSpace)) | ||
arguments += $" --namespace \"{options.TemplateNameSpace}\""; | ||
|
||
if (!string.IsNullOrEmpty(options.Root)) | ||
arguments += $" --root \"{options.Root}\""; | ||
|
||
if (!string.IsNullOrEmpty(options.Name)) | ||
arguments += $" --name \"{options.Name}\""; | ||
else if (!string.IsNullOrEmpty(_name)) | ||
arguments += $" --name \"{_name}\""; | ||
|
||
if (!string.IsNullOrEmpty(_extension)) | ||
arguments += $" --extension \"{_extension}\""; | ||
|
||
return arguments; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
using Newtonsoft.Json; | ||
using System.Linq; | ||
|
||
namespace WebCompiler | ||
{ | ||
/// <summary> | ||
/// Give all options for the Handlebars compiler | ||
/// </summary> | ||
public class HandlebarsOptions : BaseOptions<HandlebarsOptions> | ||
{ | ||
private const string trueStr = "true"; | ||
|
||
/// <summary> Creates a new instance of the class.</summary> | ||
public HandlebarsOptions() | ||
{ } | ||
|
||
/// <summary> | ||
/// Load the settings from the config object | ||
/// </summary> | ||
protected override void LoadSettings(Config config) | ||
{ | ||
base.LoadSettings(config); | ||
|
||
var name = GetValue(config, "name"); | ||
if (name != null) | ||
Name = name; | ||
|
||
var @namespace = GetValue(config, "namespace"); | ||
if (@namespace != null) | ||
TemplateNameSpace = @namespace; | ||
|
||
var root = GetValue(config, "root"); | ||
if (root != null) | ||
Root = root; | ||
|
||
var commonjs = GetValue(config, "commonjs"); | ||
if (commonjs != null) | ||
CommonJS = commonjs; | ||
|
||
var amd = GetValue(config, "amd"); | ||
if (amd != null) | ||
AMD = amd.ToLowerInvariant() == trueStr; | ||
|
||
var forcePartial = GetValue(config, "forcePartial"); | ||
if (forcePartial != null) | ||
ForcePartial = forcePartial.ToLowerInvariant() == trueStr; | ||
|
||
var noBOM = GetValue(config, "noBOM"); | ||
if (noBOM != null) | ||
NoBOM = noBOM.ToLowerInvariant() == trueStr; | ||
|
||
var knownHelpersOnly = GetValue(config, "knownHelpersOnly"); | ||
if (knownHelpersOnly != null) | ||
KnownHelpersOnly = knownHelpersOnly.ToLowerInvariant() == trueStr; | ||
|
||
var knownHelpers = GetValue(config, "knownHelpers"); | ||
if (knownHelpers != null) | ||
KnownHelpers = knownHelpers.Split(',').Where(s => !string.IsNullOrWhiteSpace(s)).Select(s => s.Trim()).ToArray(); | ||
} | ||
|
||
/// <summary> | ||
/// The file name should match the compiler name | ||
/// </summary> | ||
protected override string CompilerFileName | ||
{ | ||
get { return "hbs"; } | ||
} | ||
|
||
/// <summary> | ||
/// Template root. Base value that will be stripped from template names. | ||
/// </summary> | ||
[JsonProperty("root")] | ||
public string Root { get; set; } = ""; | ||
|
||
/// <summary> | ||
/// Removes the BOM (Byte Order Mark) from the beginning of the templates. | ||
/// </summary> | ||
[JsonProperty("noBOM")] | ||
public bool NoBOM { get; set; } = false; | ||
|
||
/// <summary> | ||
/// Name of passed string templates. | ||
/// </summary> | ||
[JsonProperty("name")] | ||
public string Name { get; set; } = ""; | ||
|
||
/// <summary> | ||
/// Template namespace | ||
/// </summary> | ||
[JsonProperty("namespace")] | ||
public string TemplateNameSpace { get; set; } = ""; | ||
|
||
/// <summary> | ||
/// Compile with known helpers only | ||
/// </summary> | ||
[JsonProperty("knownHelpersOnly")] | ||
public bool KnownHelpersOnly { get; set; } = false; | ||
|
||
|
||
/// <summary> | ||
/// Forcing a partial template compilation | ||
/// </summary> | ||
[JsonProperty("forcePartial")] | ||
public bool ForcePartial { get; set; } = false; | ||
|
||
/// <summary> | ||
/// List of known helpers for a more optimized output | ||
/// </summary> | ||
[JsonProperty("knownHelpers")] | ||
public string[] KnownHelpers { get; set; } = new string[0]; | ||
|
||
/// <summary> | ||
/// Path to the Handlebars module to export CommonJS style | ||
/// </summary> | ||
[JsonProperty("commonjs")] | ||
public string CommonJS { get; set; } = ""; | ||
|
||
/// <summary> | ||
/// Exports amd style (require.js), this option has priority to commonjs. | ||
/// </summary> | ||
[JsonProperty("amd")] | ||
public bool AMD { get; set; } = false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.