diff options
-rw-r--r-- | README.md | 21 | ||||
-rw-r--r-- | build/smapi.targets | 107 | ||||
-rw-r--r-- | package.nuspec | 10 |
3 files changed, 111 insertions, 27 deletions
@@ -36,12 +36,10 @@ You can copy your mod files into the `Mods` folder automatically each time you b need to do it manually: 1. Edit your mod's `.csproj` file. -2. Add this block under the `<Project` line: +2. Add this block above the first `</PropertyGroup>` line: ```xml - <PropertyGroup> - <DeployModFolderName>$(MSBuildProjectName)</DeployModFolderName> - </PropertyGroup> + <DeployModFolderName>$(MSBuildProjectName)</DeployModFolderName> ``` That's it! Each time you build, the files in `<game path>\Mods\<mod name>` will be updated with @@ -52,7 +50,7 @@ Notes: * To customise the folder name, just replace `$(MSBuildProjectName)` with the folder name you want. * 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). -### Debug into the mod code +### Debug into the mod code (Windows-only) Stepping into your mod code when the game is running is straightforward, since this package injects the configuration automatically. To do it: @@ -62,6 +60,19 @@ the configuration automatically. To do it: This will deploy your mod files into the game folder, launch SMAPI, and attach a debugger automatically. Now you can step through your code, set breakpoints, etc. +### Create release zips automatically (Windows-only) +You can create the mod package automatically when you build: + +1. Edit your mod's `.csproj` file. +2. Add this block above the first `</PropertyGroup>` line: + + ```xml + <DeployModZipTo>$(SolutionDir)\_releases</DeployModZipTo> + ``` + +That's it! Each time you build, the mod files will be zipped into `_releases\<mod name>.zip`. (You +can change the value to save the zips somewhere else.) + ## Troubleshoot ### "Failed to find the game install path" That error means the package couldn't figure out where the game is installed. You need to specify diff --git a/build/smapi.targets b/build/smapi.targets index a544067b..b9f7e98e 100644 --- a/build/smapi.targets +++ b/build/smapi.targets @@ -1,6 +1,68 @@ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <!--********************************************* + ** Define build tasks used below + **********************************************--> <!--###### - ## import global settings + ## create a release zip file for a mod (CodeTaskFactory only available on Windows?) + #######--> + <UsingTask TaskName="CreateModReleaseZip" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" Condition="'$(OS)' == 'Windows_NT'"> + <ParameterGroup> + <ModName ParameterType="System.String" Required="true" /> + <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /> + <OutputFolderPath ParameterType="System.String" Required="true" /> + </ParameterGroup> + <Task> + <Reference Include="System.IO" /> + <Reference Include="System.IO.Compression" /> + <Using Namespace="System.IO" /> + <Using Namespace="System.IO.Compression" /> + <Code Type="Fragment" Language="cs"> + <![CDATA[ + try + { + // create output path if needed + Directory.CreateDirectory(OutputFolderPath); + + // clear old zip file if present + string zipPath = Path.Combine(OutputFolderPath, ModName + ".zip"); + if (File.Exists(zipPath)) + File.Delete(zipPath); + + // create zip file + using (Stream zipStream = new FileStream(zipPath, FileMode.Create, FileAccess.Write)) + using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create)) + { + foreach (ITaskItem file in Files) + { + string filePath = file.ItemSpec; + string entryName = file.GetMetadata("RecursiveDir") + file.GetMetadata("Filename") + file.GetMetadata("Extension"); + + using (Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + using (Stream fileStreamInZip = archive.CreateEntry(entryName).Open()) + { + fileStream.CopyTo(fileStreamInZip); + } + } + } + + return true; + } + catch (Exception ex) + { + Log.LogErrorFromException(ex); + return false; + } + ]]> + </Code> + </Task> + </UsingTask> + + + <!--********************************************* + ** Find the basic mod metadata + **********************************************--> + <!--###### + ## import developer's custom settings (if any) #######--> <Import Condition="$(OS) != 'Windows_NT' AND Exists('$(HOME)\stardewvalley.targets')" Project="$(HOME)\stardewvalley.targets" /> <Import Condition="$(OS) == 'Windows_NT' AND Exists('$(USERPROFILE)\stardewvalley.targets')" Project="$(USERPROFILE)\stardewvalley.targets" /> @@ -30,9 +92,10 @@ </When> </Choose> - <!--###### - ## configure build - #######--> + + <!--********************************************* + ** Inject the assembly references and debugging configuration + **********************************************--> <Choose> <When Condition="$(OS) == 'Windows_NT'"> <!-- references --> @@ -46,6 +109,9 @@ <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86"> <Private>false</Private> </Reference> + <Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86"> + <Private>false</Private> + </Reference> <Reference Include="Stardew Valley"> <HintPath>$(GamePath)\Stardew Valley.exe</HintPath> <Private>false</Private> @@ -92,8 +158,12 @@ </Otherwise> </Choose> + + <!--********************************************* + ** Perform build logic + **********************************************--> <!--###### - ## validate + ## validate metadata before build #######--> <Target Name="BeforeBuild"> <!-- show error for unknown platform --> @@ -107,27 +177,30 @@ </Target> <!--###### - ## deploy mod files on build + ## Deploy files after build #######--> - <Target Name="AfterBuild" Condition="'$(DeployModFolderName)' != ''"> - <!--generate paths--> + <Target Name="AfterBuild" Condition="'$(DeployModFolderName)' != '' OR '$(DeployModZipTo)' != ''"> + <!--collect file paths--> <PropertyGroup> <ModDeployPath>$(GamePath)\Mods\$(DeployModFolderName)</ModDeployPath> - <FallbackManifestPath>$(ProjectDir)\manifest.json</FallbackManifestPath> + <DeployModZipTo Condition="'$(OS)' != 'Windows_NT'"><!--disable on Linux/Mac where CodeTaskFactory doesn't seem to be available--></DeployModZipTo> </PropertyGroup> <ItemGroup> <BuildFiles Include="$(TargetDir)\**\*.*" /> - <FallbackTranslationFiles Include="$(ProjectDir)\i18n\*.json" /> + <BuildFiles Include="$(ProjectDir)\i18n\*.json" Condition="'@(BuildFiles)' != '' AND EXISTS('$(ProjectDir)\i18n')" /> + <BuildFiles Include="$(ProjectDir)\manifest.json" Condition="'@(BuildFiles)' != '' AND EXISTS('$(ProjectDir)\manifest.json')" /> </ItemGroup> - <!--validate--> + <!--validate paths--> <Error Text="Could not deploy mod automatically because no build output was found." Condition="'@(BuildFiles)' == ''" /> - <Error Text="Could not deploy mod automatically because no manifest.json was found in the project or build output." Condition="!Exists('$(TargetDir)\manifest.json') AND !Exists('$(FallbackManifestPath)')" /> + <Error Text="Could not deploy mod automatically because no manifest.json was found in the project or build output." Condition="!Exists('$(TargetDir)\manifest.json') AND !Exists('$(ProjectDir)\manifest.json')" /> + + <!-- copy mod files into mod folder if <DeployModFolderName> property is set --> + <Message Text="Deploying mod to $(ModDeployPath)..." Importance="high" Condition="'$(DeployModFolderName)' != ''" /> + <Copy SourceFiles="@(BuildFiles)" DestinationFolder="$(ModDeployPath)\%(RecursiveDir)" SkipUnchangedFiles="true" Condition="'$(DeployModFolderName)' != ''" /> - <!-- copy mod files --> - <Message Text="Deploying mod to $(ModDeployPath)..." Importance="high" /> - <Copy SourceFiles="@(BuildFiles)" DestinationFolder="$(ModDeployPath)\%(RecursiveDir)" SkipUnchangedFiles="true" /> - <Copy SourceFiles="$(FallbackManifestPath)" DestinationFolder="$(ModDeployPath)" Condition="!Exists('$(TargetDir)\manifest.json')" /> - <Copy SourceFiles="@(FallbackTranslationFiles)" DestinationFolder="$(ModDeployPath)\i18n\%(RecursiveDir)" Condition="!Exists('$(TargetDir)\i18n')" /> + <!-- create release zip if <DeployModZipTo> property is set --> + <Message Text="Generating mod release at $(DeployModZipTo)\$(MSBuildProjectName).zip..." Importance="high" Condition="'$(DeployModZipTo)' != ''" /> + <CreateModReleaseZip ModName="$(MSBuildProjectName)" Files="@(BuildFiles)" OutputFolderPath="$(DeployModZipTo)" Condition="'$(DeployModZipTo)' != ''" /> </Target> </Project> diff --git a/package.nuspec b/package.nuspec index f216803a..9abc7251 100644 --- a/package.nuspec +++ b/package.nuspec @@ -2,19 +2,19 @@ <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"> <metadata> <id>Pathoschild.Stardew.ModBuildConfig</id> - <version>1.6.2</version> + <version>1.7</version> <title>MSBuild config for Stardew Valley mods</title> <authors>Pathoschild</authors> <owners>Pathoschild</owners> <requireLicenseAcceptance>false</requireLicenseAcceptance> - <licenseUrl>https://github.com/Pathoschild/Stardew.ModBuildConfig/blob/1.6.2/LICENSE.txt</licenseUrl> + <licenseUrl>https://github.com/Pathoschild/Stardew.ModBuildConfig/blob/1.7/LICENSE.txt</licenseUrl> <projectUrl>https://github.com/Pathoschild/Stardew.ModBuildConfig#readme</projectUrl> - <iconUrl>https://raw.githubusercontent.com/Pathoschild/Stardew.ModBuildConfig/1.6.2/assets/nuget-icon.png</iconUrl> + <iconUrl>https://raw.githubusercontent.com/Pathoschild/Stardew.ModBuildConfig/1.7/assets/nuget-icon.png</iconUrl> <description>Automates the build configuration for crossplatform Stardew Valley SMAPI mods.</description> - <releaseNotes>Improved OS and game path detection; removed undocumented GamePlatform variable.</releaseNotes> + <releaseNotes>Added option to create release zips on build; added reference to XNA's XACT library for audio-related mods.</releaseNotes> </metadata> <files> <file src="build/smapi.targets" target="build/Pathoschild.Stardew.ModBuildConfig.targets" /> - <file src="readme.md" target="" /> + <file src="readme.md" /> </files> </package> |