fix <IgnoreModFilePatterns> not applied to files matched by convention, update readme

This commit is contained in:
Jesse Plamondon-Willard 2019-04-18 22:46:00 -04:00
parent aa7e4b9c36
commit b887ecb30b
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
3 changed files with 94 additions and 71 deletions

View File

@ -26,16 +26,9 @@ The package...
## Configure
### Deploy files into the `Mods` folder
Your mod is copied into the game's `Mods` folder (with a subfolder matching your project name)
when you rebuild the code. The package automatically includes...
* any build output;
* your `manifest.json`;
* any [`i18n` files](https://stardewvalleywiki.com/Modding:Translations);
* the `assets` folder if present.
To add custom files to the mod folder, just [add them to the build output](https://stackoverflow.com/a/10828462/262123).
(If your project references another mod, make sure the reference is [_not_ marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).)
Your mod is copied into the game's `Mods` folder when you rebuild the code, with a subfolder
matching the mod's project name. This includes the files set via [_Files included in the release_](#files-included-in-release)
below.
You can change the mod's folder name by adding this above the first `</PropertyGroup>` in your
`.csproj`:
@ -49,9 +42,9 @@ If you don't want to deploy the mod automatically, you can add this:
```
### Create release zip
A zip file is also created in the build output folder when you rebuild the code. This contains the
same files deployed to the `Mods` folder, in the recommended format for uploading to Nexus Mods or
other sites.
A zip file is also created in the build output folder when you rebuild the code. This includes the
files set via [_Files included in the release_](#files-included-in-release) below, in the format
recommended for uploading to Nexus Mods or other sites.
You can change the zipped folder name (and zip name) by adding this above the first
`</PropertyGroup>` in your `.csproj`:
@ -118,15 +111,30 @@ or you have multiple installs, you can specify the path yourself. There's two wa
The configuration will check your custom path first, then fall back to the default paths (so it'll
still compile on a different computer).
### Ignore files
If you don't want to include a file in the mod folder or release zip:
* Make sure it's not copied to the build output. For a DLL, make sure the reference is [not marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).
You access the game path via `$(GamePath)` in MSBuild properties, if you need to reference another
file in the game folder.
### Files included in release
The package automatically considers these files to be part of your mod:
* the `manifest.json` in your project;
* the [`i18n` files](https://stardewvalleywiki.com/Modding:Translations) in your project (if any);
* the `assets` folder in your project (if present);
* and any files in the build output folder.
To add custom files to the release, just [add them to the build output](https://stackoverflow.com/a/10828462/262123).
(If your project references another mod, make sure the reference is [_not_ marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).)
To exclude a file from the release:
* Make sure it's not copied to the build output. (For a DLL, make sure the reference is [not marked 'copy local'](https://msdn.microsoft.com/en-us/library/t1zz5y8c(v=vs.100).aspx).) This doesn't apply to `manifest.json`,
`assets`, or `i18n` which are copied regardless.)
* Or add this to your `.csproj` file under the `<Project` line:
```xml
<IgnoreModFilePatterns>\.txt$, \.pdf$</IgnoreModFilePatterns>
```
This is a comma-delimited list of regular expression patterns. If any pattern matches a file's
relative path in your mod folder, that file won't be included.
relative path in your mod folder, that file won't be included. (This also works for `assets` and
`i18n`.)
### Non-mod projects
You can use the package in non-mod projects too (e.g. unit tests or framework DLLs). You'll need to
@ -216,8 +224,9 @@ _[Game path](#game-path)_ above.
### Upcoming release
* Updated for Stardew Valley 1.4.
* If the project contains an `assets` folder, its contents are now included in the mod automatically.
* Dropped support for very old versions of SMAPI and Visual Studio.
* Fixed `Newtonsoft.Json.pdb` included in release zips when Json.NET is referenced directly.
* Fixed `<IgnoreModFilePatterns>` not working for `i18n` files.
* Dropped support for very old versions of SMAPI and Visual Studio.
### 2.2
* Added support for SMAPI 2.8+ (still compatible with earlier versions).

View File

@ -41,62 +41,14 @@ namespace StardewModdingAPI.ModBuildConfig.Framework
if (!Directory.Exists(targetDir))
throw new UserErrorException("Could not create mod package because no build output was found.");
// project manifest
bool hasProjectManifest = false;
// collect files
foreach (Tuple<string, FileInfo> entry in this.GetPossibleFiles(projectDir, targetDir))
{
FileInfo manifest = new FileInfo(Path.Combine(projectDir, "manifest.json"));
if (manifest.Exists)
{
this.Files[this.ManifestFileName] = manifest;
hasProjectManifest = true;
}
}
string relativePath = entry.Item1;
FileInfo file = entry.Item2;
// project i18n files
bool hasProjectTranslations = false;
DirectoryInfo translationsFolder = new DirectoryInfo(Path.Combine(projectDir, "i18n"));
if (translationsFolder.Exists)
{
foreach (FileInfo file in translationsFolder.EnumerateFiles())
this.Files[Path.Combine("i18n", file.Name)] = file;
hasProjectTranslations = true;
}
// project assets folder
bool hasAssetsFolder = false;
DirectoryInfo assetsFolder = new DirectoryInfo(Path.Combine(projectDir, "assets"));
if (assetsFolder.Exists)
{
foreach (FileInfo file in assetsFolder.EnumerateFiles("*", SearchOption.AllDirectories))
{
string relativePath = PathUtilities.GetRelativePath(projectDir, file.FullName);
if (!this.ShouldIgnore(file, relativePath, ignoreFilePatterns))
this.Files[relativePath] = file;
}
hasAssetsFolder = true;
}
// build output
DirectoryInfo buildFolder = new DirectoryInfo(targetDir);
foreach (FileInfo file in buildFolder.EnumerateFiles("*", SearchOption.AllDirectories))
{
// get path info
string relativePath = PathUtilities.GetRelativePath(buildFolder.FullName, file.FullName);
string[] segments = PathUtilities.GetSegments(relativePath);
// prefer project manifest/i18n/assets files
if (hasProjectManifest && this.EqualsInvariant(relativePath, this.ManifestFileName))
continue;
if (hasProjectTranslations && this.EqualsInvariant(segments[0], "i18n"))
continue;
if (hasAssetsFolder && this.EqualsInvariant(segments[0], "assets"))
continue;
// handle ignored files
if (this.ShouldIgnore(file, relativePath, ignoreFilePatterns))
continue;
// add file
this.Files[relativePath] = file;
}
// check for required files
@ -133,6 +85,67 @@ namespace StardewModdingAPI.ModBuildConfig.Framework
/*********
** Private methods
*********/
/// <summary>Get all files to include in the mod folder, not accounting for ignore patterns.</summary>
/// <param name="projectDir">The folder containing the project files.</param>
/// <param name="targetDir">The folder containing the build output.</param>
/// <returns>Returns tuples containing the relative path within the mod folder, and the file to copy to it.</returns>
private IEnumerable<Tuple<string, FileInfo>> GetPossibleFiles(string projectDir, string targetDir)
{
// project manifest
bool hasProjectManifest = false;
{
FileInfo manifest = new FileInfo(Path.Combine(projectDir, this.ManifestFileName));
if (manifest.Exists)
{
yield return Tuple.Create(this.ManifestFileName, manifest);
hasProjectManifest = true;
}
}
// project i18n files
bool hasProjectTranslations = false;
DirectoryInfo translationsFolder = new DirectoryInfo(Path.Combine(projectDir, "i18n"));
if (translationsFolder.Exists)
{
foreach (FileInfo file in translationsFolder.EnumerateFiles())
yield return Tuple.Create(Path.Combine("i18n", file.Name), file);
hasProjectTranslations = true;
}
// project assets folder
bool hasAssetsFolder = false;
DirectoryInfo assetsFolder = new DirectoryInfo(Path.Combine(projectDir, "assets"));
if (assetsFolder.Exists)
{
foreach (FileInfo file in assetsFolder.EnumerateFiles("*", SearchOption.AllDirectories))
{
string relativePath = PathUtilities.GetRelativePath(projectDir, file.FullName);
yield return Tuple.Create(relativePath, file);
}
hasAssetsFolder = true;
}
// build output
DirectoryInfo buildFolder = new DirectoryInfo(targetDir);
foreach (FileInfo file in buildFolder.EnumerateFiles("*", SearchOption.AllDirectories))
{
// get path info
string relativePath = PathUtilities.GetRelativePath(buildFolder.FullName, file.FullName);
string[] segments = PathUtilities.GetSegments(relativePath);
// prefer project manifest/i18n/assets files
if (hasProjectManifest && this.EqualsInvariant(relativePath, this.ManifestFileName))
continue;
if (hasProjectTranslations && this.EqualsInvariant(segments[0], "i18n"))
continue;
if (hasAssetsFolder && this.EqualsInvariant(segments[0], "assets"))
continue;
// add file
yield return Tuple.Create(relativePath, file);
}
}
/// <summary>Get whether a build output file should be ignored.</summary>
/// <param name="file">The file to check.</param>
/// <param name="relativePath">The file's relative path in the package.</param>

View File

@ -17,6 +17,7 @@
- If the project contains an `assets` folder, its contents are now included in the mod automatically.
- Dropped support for very old versions of SMAPI and Visual Studio.
- Fixed `Newtonsoft.Json.pdb` included in release zips when Json.NET is referenced directly.
- Fixed `&lt;IgnoreModFilePatterns&gt;` not working for `i18n` files.
</releaseNotes>
</metadata>
</package>