This repository has been archived on 2023-02-02. You can view files and clone it, but cannot push or open issues or pull requests.
mfgames-nitride-cil/src/Nitride.Javascript/RunWebpack.cs
Dylan R. E. Moonfire 78054ee2a7 feat: initial release
2021-09-07 00:15:45 -05:00

116 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Gallium;
using Nitride.IO.Contents;
using Nitride.IO.Paths;
using Serilog;
using Zio;
namespace Nitride.Javascript
{
/// <summary>
/// Runs `webpack` in the directory, writing out whatever files need to be
/// written.
/// </summary>
[WithProperties]
public partial class RunWebpack : INitrideOperation
{
private readonly IFileSystem fileSystem;
private readonly ILogger logger;
private readonly ReadFiles readFiles;
public RunWebpack(
ILogger logger,
IFileSystem fileSystem,
ReadFiles readFiles)
{
this.fileSystem = fileSystem;
this.readFiles = readFiles;
this.logger = logger.ForContext<RunWebpack>();
this.WebpackDirectory = "/";
}
/// <summary>
/// Gets or sets the directory that contains the output from the
/// webpack execution.
/// </summary>
public UPath? OutputDirectory { get; set; }
/// <summary>
/// Gets or sets the directory that the install should be run from. This
/// is typically the same file as the webpack.config.js.
/// </summary>
public UPath? WebpackDirectory { get; set; }
/// <inheritdoc />
public IEnumerable<Entity> Run(IEnumerable<Entity> input)
{
// Make sure we have a sane values.
if (!this.WebpackDirectory.HasValue)
{
throw new InvalidOperationException(
nameof(InstallYarn)
+ ".WebpackDirectory was not set before Run() was called.");
}
if (!this.OutputDirectory.HasValue)
{
throw new InvalidOperationException(
nameof(InstallYarn)
+ ".OutputDirectory was not set before Run() was called.");
}
// Make sure the directory exists in case we are the first.
UPath directory = this.WebpackDirectory.Value;
if (!this.fileSystem.DirectoryExists(directory))
{
this.logger.Information("Creating directory {Path}", directory);
this.fileSystem.CreateDirectory(directory);
}
// Sadly, Yarn doesn't understand virtual file systems, so we need
// the "real" path to the directory for this.
string realPath = this.fileSystem
.ConvertPathToInternal(directory);
// Run the install.
this.logger.Debug("Running Webpack via Yarn");
string command = YarnHelper.GetYarnCommand();
var start = new ProcessStartInfo
{
FileName = command,
Arguments = "run webpack",
WorkingDirectory = realPath,
RedirectStandardOutput = true,
};
Process process = Process.Start(start);
if (process == null)
{
throw new InvalidOperationException(
"Cannot start yarn run webpack");
}
process.WaitForExit();
// We are done and all the output will be written into the
// filesystem, so merge it with our input.
this.logger.Debug("Adding Webpack output to the pipeline");
UPath outputDirectory = this.OutputDirectory.Value;
return input
.Union(
this.readFiles
.Read(outputDirectory)
.Run(new RemovePathPrefix(outputDirectory)));
}
}
}