summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md21
-rw-r--r--build/smapi.targets107
-rw-r--r--package.nuspec10
3 files changed, 111 insertions, 27 deletions
diff --git a/README.md b/README.md
index c5e01c91..c261e705 100644
--- a/README.md
+++ b/README.md
@@ -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>