mirror of
https://github.com/Ellpeck/Contentless.git
synced 2024-11-26 00:48:34 +01:00
Compare commits
No commits in common. "05818f1c74e0503072d0bdcfce65ec28b2f7977d" and "6dcaca4e8c5c0990ae94e0ab55d0784feecd86fd" have entirely different histories.
05818f1c74
...
6dcaca4e8c
10 changed files with 530 additions and 526 deletions
|
@ -1,8 +1,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Contentless;
|
namespace Contentless {
|
||||||
|
|
||||||
public class Config {
|
public class Config {
|
||||||
|
|
||||||
[JsonProperty("exclude")]
|
[JsonProperty("exclude")]
|
||||||
|
@ -12,7 +12,7 @@ public class Config {
|
||||||
public bool LogSkipped = true;
|
public bool LogSkipped = true;
|
||||||
|
|
||||||
[JsonProperty("overrides")]
|
[JsonProperty("overrides")]
|
||||||
public Dictionary<string, Override> Overrides = new();
|
public Dictionary<string, Override> Overrides = new Dictionary<string, Override>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,8 +23,9 @@ public class Override {
|
||||||
[JsonProperty("processor")]
|
[JsonProperty("processor")]
|
||||||
public string Processor;
|
public string Processor;
|
||||||
[JsonProperty("processorParams")]
|
[JsonProperty("processorParams")]
|
||||||
public Dictionary<string, string> ProcessorParams = new();
|
public Dictionary<string, string> ProcessorParams = new Dictionary<string, string>();
|
||||||
[JsonProperty("copy")]
|
[JsonProperty("copy")]
|
||||||
public bool Copy;
|
public bool Copy;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<RollForward>Major</RollForward>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
<repository type="git" url="https://github.com/Ellpeck/Contentless"/>
|
<repository type="git" url="https://github.com/Ellpeck/Contentless"/>
|
||||||
<readme>README.md</readme>
|
<readme>README.md</readme>
|
||||||
<icon>Logo.png</icon>
|
<icon>Logo.png</icon>
|
||||||
<version>3.0.7</version>
|
<version>3.0.6</version>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<group targetFramework="net6.0" />
|
<group targetFramework="net5.0" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="_._" target="lib/net6.0/" />
|
<file src="_._" target="lib/net5.0/"/>
|
||||||
<file src="Contentless.targets" target="build/Contentless.targets"/>
|
<file src="Contentless.targets" target="build/Contentless.targets"/>
|
||||||
<file src="bin\Debug\net6.0\**\*" target="tools/" />
|
<file src="bin\Debug\net5.0\**\*" target="tools/"/>
|
||||||
<file src="../README.md" target="" />
|
<file src="../README.md" target="" />
|
||||||
<file src="../Logo.png" target="" />
|
<file src="../Logo.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||||
|
|
||||||
namespace Contentless;
|
namespace Contentless {
|
||||||
|
|
||||||
public class ImporterInfo {
|
public class ImporterInfo {
|
||||||
|
|
||||||
public readonly ContentImporterAttribute Importer;
|
public readonly ContentImporterAttribute Importer;
|
||||||
|
@ -18,3 +17,4 @@ public class ImporterInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Contentless;
|
namespace Contentless {
|
||||||
|
|
||||||
public class OverrideInfo {
|
public class OverrideInfo {
|
||||||
|
|
||||||
public readonly Regex Regex;
|
public readonly Regex Regex;
|
||||||
|
@ -13,3 +12,4 @@ public class OverrideInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -6,9 +6,9 @@ using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Xna.Framework.Content.Pipeline;
|
using Microsoft.Xna.Framework.Content.Pipeline;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Contentless;
|
namespace Contentless {
|
||||||
|
|
||||||
public static class Program {
|
public static class Program {
|
||||||
|
|
||||||
public static void Main(string[] args) {
|
public static void Main(string[] args) {
|
||||||
|
@ -24,24 +24,25 @@ public static class Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"Using content file {contentFile}");
|
Console.WriteLine($"Using content file {contentFile}");
|
||||||
var content = Program.ReadContent(contentFile);
|
var content = ReadContent(contentFile);
|
||||||
|
|
||||||
// load config
|
// load config
|
||||||
var config = new Config();
|
var config = new Config();
|
||||||
var configFile = new FileInfo(Path.Combine(contentFile.DirectoryName!, "Contentless.json"));
|
var configFile = new FileInfo(Path.Combine(contentFile.DirectoryName, "Contentless.json"));
|
||||||
if (configFile.Exists) {
|
if (configFile.Exists) {
|
||||||
using var stream = configFile.OpenText();
|
using (var stream = configFile.OpenText()) {
|
||||||
try {
|
try {
|
||||||
config = JsonConvert.DeserializeObject<Config>(stream.ReadToEnd());
|
config = JsonConvert.DeserializeObject<Config>(stream.ReadToEnd());
|
||||||
Console.WriteLine($"Using config from {configFile}");
|
Console.WriteLine($"Using config from {configFile}");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Console.WriteLine($"Error loading config from {configFile}: {e}");
|
Console.WriteLine($"Error loading config from {configFile}: {e}");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Console.WriteLine("Using default config");
|
Console.WriteLine("Using default config");
|
||||||
}
|
}
|
||||||
var excluded = config.ExcludedFiles.Select(Program.MakeFileRegex).ToArray();
|
var excluded = config.ExcludedFiles.Select(MakeFileRegex).ToArray();
|
||||||
var overrides = Program.GetOverrides(config.Overrides).ToArray();
|
var overrides = GetOverrides(config.Overrides).ToArray();
|
||||||
|
|
||||||
// load any references to be able to include custom content types as well
|
// load any references to be able to include custom content types as well
|
||||||
foreach (var line in content) {
|
foreach (var line in content) {
|
||||||
|
@ -58,7 +59,7 @@ public static class Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
// load content importers
|
// load content importers
|
||||||
var (importers, processors) = Program.GetContentData();
|
var (importers, processors) = GetContentData();
|
||||||
Console.WriteLine($"Found possible importer types {string.Join(", ", importers)}");
|
Console.WriteLine($"Found possible importer types {string.Join(", ", importers)}");
|
||||||
Console.WriteLine($"Found possible processor types {string.Join(", ", processors)}");
|
Console.WriteLine($"Found possible processor types {string.Join(", ", processors)}");
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ public static class Program {
|
||||||
// is the file the content or config file?
|
// is the file the content or config file?
|
||||||
if (file.Name == contentFile.Name || file.Name == configFile.Name)
|
if (file.Name == contentFile.Name || file.Name == configFile.Name)
|
||||||
continue;
|
continue;
|
||||||
var relative = Program.GetRelativePath(contentFile.DirectoryName, file.FullName).Replace("\\", "/");
|
var relative = GetRelativePath(contentFile.DirectoryName, file.FullName).Replace("\\", "/");
|
||||||
|
|
||||||
// is the file in an excluded directory?
|
// is the file in an excluded directory?
|
||||||
if (excluded.Any(e => e.IsMatch(relative))) {
|
if (excluded.Any(e => e.IsMatch(relative))) {
|
||||||
|
@ -77,7 +78,7 @@ public static class Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the file already in the content file?
|
// is the file already in the content file?
|
||||||
if (Program.HasEntry(content, relative)) {
|
if (HasEntry(content, relative)) {
|
||||||
if (config.LogSkipped)
|
if (config.LogSkipped)
|
||||||
Console.WriteLine($"Skipping file {relative} as it is already part of the content file");
|
Console.WriteLine($"Skipping file {relative} as it is already part of the content file");
|
||||||
continue;
|
continue;
|
||||||
|
@ -88,13 +89,13 @@ public static class Program {
|
||||||
Dictionary<string, string> processorParams = null;
|
Dictionary<string, string> processorParams = null;
|
||||||
|
|
||||||
// override importers
|
// override importers
|
||||||
var over = Program.GetOverrideFor(relative, overrides);
|
var over = GetOverrideFor(relative, overrides);
|
||||||
if (over != null) {
|
if (over != null) {
|
||||||
processorParams = over.Override.ProcessorParams;
|
processorParams = over.Override.ProcessorParams;
|
||||||
|
|
||||||
// copy special case
|
// copy special case
|
||||||
if (over.Override.Copy) {
|
if (over.Override.Copy) {
|
||||||
Program.CopyFile(content, relative);
|
CopyFile(content, relative);
|
||||||
changed = true;
|
changed = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,8 @@ public static class Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal importers
|
// normal importers
|
||||||
importer ??= Program.GetImporterFor(relative, importers);
|
if (importer == null)
|
||||||
|
importer = GetImporterFor(relative, importers);
|
||||||
if (importer != null && processor == null)
|
if (importer != null && processor == null)
|
||||||
processor = processors.Find(p => p == importer.Importer.DefaultProcessor);
|
processor = processors.Find(p => p == importer.Importer.DefaultProcessor);
|
||||||
|
|
||||||
|
@ -127,7 +129,7 @@ public static class Program {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Program.AddFile(content, relative, importer.Type.Name, processor, processorParams);
|
AddFile(content, relative, importer.Type.Name, processor, processorParams);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +166,7 @@ public static class Program {
|
||||||
|
|
||||||
private static IEnumerable<OverrideInfo> GetOverrides(Dictionary<string, Override> config) {
|
private static IEnumerable<OverrideInfo> GetOverrides(Dictionary<string, Override> config) {
|
||||||
foreach (var entry in config)
|
foreach (var entry in config)
|
||||||
yield return new OverrideInfo(Program.MakeFileRegex(entry.Key), entry.Value);
|
yield return new OverrideInfo(MakeFileRegex(entry.Key), entry.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OverrideInfo GetOverrideFor(string file, IEnumerable<OverrideInfo> overrides) {
|
private static OverrideInfo GetOverrideFor(string file, IEnumerable<OverrideInfo> overrides) {
|
||||||
|
@ -194,13 +196,16 @@ public static class Program {
|
||||||
|
|
||||||
private static List<string> ReadContent(FileInfo file) {
|
private static List<string> ReadContent(FileInfo file) {
|
||||||
var content = new List<string>();
|
var content = new List<string>();
|
||||||
using var stream = file.OpenText();
|
using (var stream = file.OpenText()) {
|
||||||
while (stream.ReadLine() is {} line)
|
string line;
|
||||||
|
while ((line = stream.ReadLine()) != null) {
|
||||||
content.Add(line);
|
content.Add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddFile(ICollection<string> content, string relative, string importer, string processor, Dictionary<string, string> processorParams) {
|
private static void AddFile(List<string> content, string relative, string importer, string processor, Dictionary<string, string> processorParams) {
|
||||||
content.Add($"#begin {relative}");
|
content.Add($"#begin {relative}");
|
||||||
content.Add($"/importer:{importer}");
|
content.Add($"/importer:{importer}");
|
||||||
content.Add($"/processor:{processor}");
|
content.Add($"/processor:{processor}");
|
||||||
|
@ -213,7 +218,7 @@ public static class Program {
|
||||||
Console.WriteLine($"Adding file {relative} with importer {importer} and processor {processor}");
|
Console.WriteLine($"Adding file {relative} with importer {importer} and processor {processor}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CopyFile(ICollection<string> content, string relative) {
|
private static void CopyFile(List<string> content, string relative) {
|
||||||
content.Add($"#begin {relative}");
|
content.Add($"#begin {relative}");
|
||||||
content.Add($"/copy:{relative}");
|
content.Add($"/copy:{relative}");
|
||||||
content.Add("");
|
content.Add("");
|
||||||
|
@ -231,3 +236,4 @@ public static class Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
10
README.md
10
README.md
|
@ -1,18 +1,16 @@
|
||||||
![The Contentless logo](https://raw.githubusercontent.com/Ellpeck/Contentless/main/Logo.png)
|
![The Contentless logo](https://raw.githubusercontent.com/Ellpeck/Contentless/main/Logo.png)
|
||||||
|
|
||||||
**Contentless** is tool for MonoGame that automatically handles adding assets to the Content Pipeline project, so you don't have to use their interface to add every content file manually.
|
**Contentless** is tool for MonoGame that automatically handles adding assets to the Content Pipeline project so you don't have to use their interface to add every content file manually.
|
||||||
|
|
||||||
# How to use
|
# How to use
|
||||||
To use Contentless, you first have to add it to your project, either through your NuGet package manager or by adding it to your `.csproj` file as follows. Keep in mind to update the `Version` to the most recent one. You can find the package on the [NuGet website](https://www.nuget.org/packages/Contentless/) as well.
|
To use Contentless, you first have to add it to your project, either through your NuGet package manager or by adding it to your `.csproj` file as follows. Keep in mind to update the `Version` to the most recent one. You can find the package on the [NuGet website](https://www.nuget.org/packages/Contentless/) as well.
|
||||||
```xml
|
```xml
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Contentless" Version="VERSION" />
|
<PackageReference Include="Contentless" Version="VERSION" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
```
|
```
|
||||||
Next, you need to find the reference to your `Content.mgcb` file in your `.csproj` file or create one if there isn't already one present. The reference's type should be `MonoGameContentReference` so that Contentless can identify it correctly. If you're using the [MonoGame Content Builder](https://www.nuget.org/packages/MonoGame.Content.Builder.Task) alongside Contentless, this setting should already be applied.
|
Next, you need to find the reference to your `Content.mgcb` file in your `.csproj` file or create one if there isn't already one present. The reference's type should be `MonoGameContentReference` so that Contentless can identify it correctly. If you're using the [MonoGame Content Builder](https://www.nuget.org/packages/MonoGame.Content.Builder.Task) alongside Contentless, this setting should already be applied.
|
||||||
```xml
|
```xml
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<MonoGameContentReference Include="Content\Content.mgcb" />
|
<MonoGameContentReference Include="Content\Content.mgcb" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -21,7 +19,7 @@ Next, you need to find the reference to your `Content.mgcb` file in your `.cspro
|
||||||
Contentless will now automatically add any content files from your `Content` directory and subdirectories to your `Content.mgcb` file if they haven't already been added either manually or by Contentless. No existing items' configurations will be overridden, so you can still use the Content Pipeline tool to modify any settings as well.
|
Contentless will now automatically add any content files from your `Content` directory and subdirectories to your `Content.mgcb` file if they haven't already been added either manually or by Contentless. No existing items' configurations will be overridden, so you can still use the Content Pipeline tool to modify any settings as well.
|
||||||
|
|
||||||
# Configuring
|
# Configuring
|
||||||
If you want to change the way Contentless works, you can use a configuration file. To do so, simply create a file named `Contentless.json` in the same directory as your `Content.mgcb` file. You can use the config to change several options:
|
To add a configuration file to Contentless, simply create a file named `Contentless.json` in the same directory as your `Content.mgcb` file. You can use the config to change several options:
|
||||||
```json5
|
```json5
|
||||||
{
|
{
|
||||||
// The list of files that should be excluded. Can use regex.
|
// The list of files that should be excluded. Can use regex.
|
||||||
|
@ -65,8 +63,8 @@ If you want to change the way Contentless works, you can use a configuration fil
|
||||||
For an example of a config in use, see the [test config](https://github.com/Ellpeck/Contentless/blob/main/Test/Content/Contentless.json).
|
For an example of a config in use, see the [test config](https://github.com/Ellpeck/Contentless/blob/main/Test/Content/Contentless.json).
|
||||||
|
|
||||||
# What it does
|
# What it does
|
||||||
When running Contentless and supplying the location of a MonoGame Content Pipeline project (`Content.mgcb`), it scans all the files in the project's directory as well as its subdirectories. For each file, it checks if the `Content.mgcb` file already contains any references to that file. If no references are found, then a new reference to the file is added.
|
When running Contentless and supplying the location of a MonoGame Content Pipeline project (`Content.mgcb`), it scans all of the files in the project's directory as well as its subdirectories. For each file, it checks if the `Content.mgcb` file already contains any references to that file. If no references are found, then a new reference to the file is added.
|
||||||
|
|
||||||
Contentless figures out which importer and processor to register for any given file by generating a list of all the importers and processors that are available, both inside of MonoGame, and inside of References added to the `Content.mgcb` file. This process is similar to what occurs when adding an existing file through MonoGame's Content Pipeline tool. If Contentless sets the wrong importer or processor for any file, the user can simply open `Content.mgcb` in MonoGame's Content Pipeline tool and edit it manually.
|
Contentless figures out which importer and processor to register for any given file by generating a list of all of the importers and processors that are available, both inside of MonoGame, and inside of References added to the `Content.mgcb` file. This process is similar to what occurs when adding an existing file through MonoGame's Content Pipeline tool. If Contentless sets the wrong importer or processor for any file, the user can simply open `Content.mgcb` in MonoGame's Content Pipeline tool and edit it manually.
|
||||||
|
|
||||||
As Contentless never changes any existing content of a `Content.mgcb` file, all changes that are made to it by hand or using the Content Pipeline tool will not be overridden.
|
As Contentless never changes any existing content of a `Content.mgcb` file, all changes that are made to it by hand or using the Content Pipeline tool will not be overridden.
|
|
@ -1,7 +1,7 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
Loading…
Reference in a new issue