116 lines
3.6 KiB
C#
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)));
|
|
}
|
|
}
|
|
}
|