Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,16 @@ Add the following to your csproj file to have the merge tool run after build:
### Creator Modes
There are 3 types of merge options when using Plugin Merge.
`Plugin` - will merge all files into a final Plugin to be used.
`Framework` - Will output a framework file that can be copied into another plugin that isn't a merge framework plugin
`MergeFramework` - Will output a framework file that can be used with a plugin that is a merge framework plugin
`Framework` - Will output a framework file that can be copied into another plugin that isn't a merge framework plugin
`MergeFramework` - Will output a framework file that can be used with a plugin that is a merge framework plugin

#### Region Path Trim Left/Right
These keys control how much of the file path appears in the generated region names.
`Region Path Trim Left` removes directory segments from the start of the relative path (use `-1` to keep only the file name).
`Region Path Trim Right` removes segments from the end of the path. The defaults are `-1` and `0` respectively.
For example, for a file located at `src/Plugins/Foo.cs` relative to the current directory:
* `Region Path Trim Left: 1` results in the region name `Plugins/Foo.cs`.
* `Region Path Trim Right: 1` results in the region name `src/Plugins`.

### YAML Configuration File
```yaml
Expand Down Expand Up @@ -127,6 +135,10 @@ Merge Settings:
# Namespaces to ignore when processing output file
Ignore Namespaces:
- IgnoreThisNameSpace
# Segments to trim from the start of region names (-1 keeps only the file name)
Region Path Trim Left: -1
# Segments to trim from the end of region names
Region Path Trim Right: 0
Code Style:
# Character to use for code indents
Indent Character: ' '
Expand Down Expand Up @@ -181,6 +193,8 @@ Compile Settings:
"Ignore Namespaces": [
"IgnoreThisNameSpace"
],
"Region Path Trim Left": -1,
"Region Path Trim Right": 0,
"Code Style": {
"Indent Character": " ",
"Indent Char Amount": 4,
Expand Down
32 changes: 30 additions & 2 deletions src/PluginMerge/Configuration/MergeConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,38 @@ public class MergeConfig
[JsonPropertyName("Ignore Namespaces")]
[YamlMember(Alias = "Ignore Namespaces", Description = "Namespaces to ignore when processing output file")]
public List<string> IgnoreNameSpaces { get; set; }

[JsonPropertyName("Region Path Trim Left")]
[YamlMember(Alias = "Region Path Trim Left", Description = "Segments to trim from the start of region names (-1 to keep only the file name)")]
public int RegionPathTrimLeft { get; set; } = -1;

[JsonPropertyName("Region Path Trim Right")]
[YamlMember(Alias = "Region Path Trim Right", Description = "Segments to trim from the end of region names")]
public int RegionPathTrimRight { get; set; } = 0;

[JsonPropertyName("Code Style")]
[YamlMember(Alias = "Code Style")]
public CodeStyleConfig CodeStyle { get; set; }

[JsonIgnore]
[YamlIgnore]
public IEnumerable<string> FinalFiles => OutputPaths.Select(p => Path.Combine(p, $"{PluginName}.cs").ToFullPath());
public IEnumerable<string> FinalFiles
{
get
{
if (string.IsNullOrEmpty(PluginName))
{
return Enumerable.Empty<string>();
}

return OutputPaths.Select(p => Path.Combine(p, $"{PluginName}.cs").ToFullPath());
}
}

private bool ShouldSerializeNamespaceOverride() => CreatorMode == CreatorMode.MergeFramework;

public void Initialize()
{
PluginName ??= "MyPluginName";
NamespaceOverride ??= string.Empty;
InputPaths ??= new List<string> { "./" };
OutputPaths ??= new List<string> {"./build"};
Expand All @@ -69,5 +87,15 @@ public void Initialize()
IgnoreNameSpaces ??= new List<string> {"IgnoreThisNameSpace"};
CodeStyle ??= new CodeStyleConfig();
CodeStyle.Initialize();

if (RegionPathTrimLeft < -1)
{
RegionPathTrimLeft = -1;
}

if (RegionPathTrimRight < -1)
{
RegionPathTrimRight = 0;
}
}
}
8 changes: 8 additions & 0 deletions src/PluginMerge/Configuration/PluginMergeConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ public class PluginMergeConfig
[JsonPropertyName("Merge Settings")]
[YamlMember(Alias = "Merge Settings")]
public MergeConfig Merge { get; set; }

[JsonIgnore]
[YamlIgnore]
public int RegionPathTrimLeft => Merge.RegionPathTrimLeft;

[JsonIgnore]
[YamlIgnore]
public int RegionPathTrimRight => Merge.RegionPathTrimRight;

[JsonPropertyName("Preprocessor Directive Settings")]
[YamlMember(Alias = "Preprocessor Directive Settings")]
Expand Down
3 changes: 2 additions & 1 deletion src/PluginMerge/Creator/FileCreator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public bool Create()
}

FilterFiles(_plugin.PluginData);


_settings.Merge.PluginName ??= _plugin.PluginData.ClassName;
_writer = new CodeWriter(_plugin.PluginData, _settings.Merge);

WriteReferences();
Expand Down
22 changes: 20 additions & 2 deletions src/PluginMerge/Merge/FileHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,29 @@ public class FileHandler
/// Sets the file path
/// </summary>
/// <param name="file"></param>
public FileHandler(ScannedFile file)
public FileHandler(ScannedFile file, int trimLeft, int trimRight)
{
_logger = LogBuilder.GetLogger<FileHandler>();
FilePath = file.FileName;
RegionName = FilePath.Replace(file.InputPath, "").TrimStart(Path.DirectorySeparatorChar);

string relative = Path.GetRelativePath(Directory.GetCurrentDirectory(), FilePath);
List<string> parts = relative.Split(Path.DirectorySeparatorChar).ToList();

if (trimLeft == -1)
{
parts = parts.TakeLast(1).ToList();
}
else if (trimLeft > 0)
{
parts = parts.Skip(Math.Min(trimLeft, parts.Count - 1)).ToList();
}

if (trimRight > 0)
{
parts = parts.Take(Math.Max(parts.Count - trimRight, 1)).ToList();
}

RegionName = string.Join(Path.DirectorySeparatorChar, parts);
}

/// <summary>
Expand Down
50 changes: 41 additions & 9 deletions src/PluginMerge/Merge/MergeHandler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp;
using System.IO;

namespace PluginMerge.Merge;

Expand All @@ -22,22 +23,38 @@ public async Task Run()
Stopwatch sw = Stopwatch.StartNew();
_logger.LogInformation("Starting Plugin Merge Version: {Version} Mode: {Mode}", typeof(Program).Assembly.GetName().Version, _merge.CreatorMode);
_logger.LogInformation("Input Paths: {Input}", string.Join(", ", _merge.InputPaths.Select(p => p.ToFullPath())));
foreach (string path in _merge.OutputPaths)

for (int i = 0; i < _merge.OutputPaths.Count; i++)
{
if (!string.IsNullOrEmpty(path) && !Directory.Exists(path))
string path = _merge.OutputPaths[i];
if (string.IsNullOrEmpty(path))
{
continue;
}

if (Path.GetExtension(path).Equals(".cs", StringComparison.OrdinalIgnoreCase))
{
string fileName = Path.GetFileName(path);
if (string.IsNullOrWhiteSpace(_merge.PluginName))
{
_merge.PluginName = Path.GetFileNameWithoutExtension(fileName);
}

path = Path.GetDirectoryName(path) ?? string.Empty;
_merge.OutputPaths[i] = path;
}

if (!Directory.Exists(path))
{
_logger.LogDebug("Output path doesn't exist. Creating output path: {Path}", path);
Directory.CreateDirectory(path);
}
}

List<string> finalFiles = _merge.FinalFiles.ToList();

FileScanner scanner = new(_merge.InputPaths, "*.cs", _merge.IgnorePaths, _merge.IgnoreFiles.Concat(finalFiles));

FileScanner scanner = new(_merge.InputPaths, "*.cs", _merge.IgnorePaths, _merge.IgnoreFiles);
foreach (ScannedFile file in scanner.ScanFiles())
{
_files.Add(new FileHandler(file));
_files.Add(new FileHandler(file, _config.RegionPathTrimLeft, _config.RegionPathTrimRight));
}

CSharpParseOptions options = new(_config.PlatformSettings.Lang);
Expand All @@ -46,6 +63,21 @@ public async Task Run()

_files = _files.Where(f => !f.IsExcludedFile()).OrderBy(f => f.Order).ToList();

if (string.IsNullOrWhiteSpace(_merge.PluginName))
{
FileHandler? pluginFile = _files.FirstOrDefault(f => f.PluginData is { } data &&
!string.IsNullOrWhiteSpace(data.Title) &&
!string.IsNullOrWhiteSpace(data.Description));

if (pluginFile is not null)
{
_merge.PluginName = pluginFile.PluginData.ClassName;
}
}

List<string> finalFiles = _merge.FinalFiles.ToList();
_files = _files.Where(f => !finalFiles.Contains(f.FilePath)).ToList();

FileCreator creator = new(_config, _files);
if (!creator.Create())
{
Expand All @@ -58,7 +90,7 @@ public async Task Run()
// SourceText text = await parsed.NormalizeWhitespace("\n").SyntaxTree.GetTextAsync().ConfigureAwait(false);
//
// code = text.ToString();

await Task.WhenAll(finalFiles.Select(f => File.WriteAllTextAsync(f, code))).ConfigureAwait(false);

sw.Stop();
Expand Down