From b887ecb30b4c41d58c6211ea00423f8259eebef5 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 18 Apr 2019 22:46:00 -0400 Subject: [PATCH] fix not applied to files matched by convention, update readme --- docs/mod-build-config.md | 45 ++++--- .../Framework/ModFileManager.cs | 119 ++++++++++-------- src/SMAPI.ModBuildConfig/package.nuspec | 1 + 3 files changed, 94 insertions(+), 71 deletions(-) diff --git a/docs/mod-build-config.md b/docs/mod-build-config.md index 8bd7b79d..4f46100a 100644 --- a/docs/mod-build-config.md +++ b/docs/mod-build-config.md @@ -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 `` 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 `` 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 `\.txt$, \.pdf$ ``` 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 `` 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). diff --git a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs index 6c11b0fe..e67a18c1 100644 --- a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs +++ b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs @@ -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 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 *********/ + /// Get all files to include in the mod folder, not accounting for ignore patterns. + /// The folder containing the project files. + /// The folder containing the build output. + /// Returns tuples containing the relative path within the mod folder, and the file to copy to it. + private IEnumerable> 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); + } + } + /// Get whether a build output file should be ignored. /// The file to check. /// The file's relative path in the package. diff --git a/src/SMAPI.ModBuildConfig/package.nuspec b/src/SMAPI.ModBuildConfig/package.nuspec index b6ef98f0..79a4f008 100644 --- a/src/SMAPI.ModBuildConfig/package.nuspec +++ b/src/SMAPI.ModBuildConfig/package.nuspec @@ -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 `<IgnoreModFilePatterns>` not working for `i18n` files.