Generate feature.cs file in a different location than the feature file - SpecFlow.xUnit 3.6.23 - xunit

I'm trying to achieve the following:-
My feature files are in a separate repo. I include the external repo into my dotnet repo using git subrepo. When i build my dotnet sln, the feature.cs file gets generated at the same location as the .feature file. Basically in the tracked git subrepo folder. I would like my feature.cs file to be generated in a location different from the .feature file location. Can that be done? I'm on .net5.0 and using SpecFlow 3.6.23 (via Specflow.xUnit 3.6.3) and xUnit Test Runner

Feature.cs files will always be generated in the project where the feature file is.
The only option you have is to copy the feature files into the location where you want to have the feature.cs files at the end.
We are doing this in SpecFlow itself, as we copy some feature files from cucumber for testing.
We are doing this with a custom MSBuild Target:
<Target Name="IncludeCucumberMessagesSpecs" BeforeTargets="BeforeUpdateFeatureFilesInProject" Condition="$(DesignTimeBuild) != 'true' OR '$(BuildingProject)' == 'true'">
<Copy SourceFiles="#(CucumberMessagesSpecFlowFeatureFiles)" DestinationFolder="Features/CucumberMessages" />
<ItemGroup>
<_CucumberMessagesSpecFlowFeatureFiles Include="Features/CucumberMessages/*.feature" />
<_CucumberMessagesSpecFlowFeatureFiles>
<CodeBehindFile>Features/CucumberMessages/%(Filename).feature$(DefaultLanguageSourceExtension)</CodeBehindFile>
<Visible>$(UsingMicrosoftNETSdk)</Visible>
</_CucumberMessagesSpecFlowFeatureFiles>
<SpecFlowFeatureFiles Include="#(_CucumberMessagesSpecFlowFeatureFiles)" Exclude="#(SpecFlowFeatureFiles)" />
</ItemGroup>
</Target>
From https://github.com/SpecFlowOSS/SpecFlow/blob/master/Tests/TechTalk.SpecFlow.Specs/TechTalk.SpecFlow.Specs.csproj#L78

Related

Restore nuget package in different folder

We have some projects (Plugins) which use in several projects, the output of these projects will copy to the specific folder in the target projects (Plugins folder).
We pack project with Visual studio 2019 Pack option and after that, we push npkg files to our local NuGet server for further use.
The problem is when we want to get these packages, Package Manager should put lib files in the Plugins folder, but unfortunately, the package manager extracts these in the root folder (bin).
My question is: How can I config nuspec file to force package manager to extract to the right folder, and can I do it with visual studio or I have to create nuspec file manually.
You should use a <packages_id>.props file to realize it.
create a file called <packages_id>.props under the build folder of your lib project.
You should note that if your nupkg file is called Plugins.1.0.0.nupkg, you should name this file as Plugins.props so that it will work.
add these on Plugins.props file:
<Project>
<Target Name="CopyFiles" BeforeTargets="Build">
<ItemGroup>
<File Include="$(MSBuildThisFileDirectory)..\Plugins\*.*"></File>
</ItemGroup>
<!--It will copy the plugins output files into the Plugins folder of the goal project-->
<Copy SourceFiles="#(File)" DestinationFolder="$(ProjectDir)Plugins"></Copy>
</Target>
</Project>
add these on Plugins.csproj file:
<ItemGroup>
<None Include="bin\Debug\netstandard2.0\Plugins.dll" Pack="true" PackagePath="Plugins"></None>
//add any output files from Plugins project which you want them to be packed
<None Include="build\Plugins.props" Pack="true" PackagePath="build"></None>
</ItemGroup>
use Pack Button to create the new release version of your nuget pakckage.
Also, when you install this new version of nuget package, please clean your nuget caches or delete all files under C:\Users\xxx(current user)\.nuget\packages.
When you finish the installing process, please click Build button and the files will generated under Plugins folder.
There is also a similar issue about this.

Visual Studio 2019 not picking up CS generated files

I have created dot net core dll project. CS files for this project will be files generated by tool (Apache Thrift compiler) but output dll is not picking up generated file. I have added the pre build set to generate the file.
Repro Steps:
Build solution
Open the ThriftSample.dll with object brower. (Delete the generated cs files and bin, com and obj folder.)
Actual: Nothing is there in ThriftSample.dll
Expected: Generated CS code should be there.
Note: I have checked CS file is generated. Attached is the sample project.(
https://onedrive.live.com/?cid=aef000afffca3540&id=AEF000AFFFCA3540%21144&authkey=!AAlMaW2IqIt6l1k
)
Refer: Is there a .NET Core CLI pre before build task?
The "default items" as the .NET SDK calls it are part of the static evaluation of the project file - before any target is run. So you'll need a target that is run before the #(Compile) items are needed.
The trick is to include files added to the filesystem after the custom tool is run. This can be done by re-scanning all files and excluding those already part of the project inside a target that is run before the build:
<Target Name="GenerateSomeFiles" BeforeTargets="BeforeBuild">
<Exec Command="dotnet my-tool" />
<ItemGroup>
<Compile Include="**/*$(DefaultLanguageSourceExtension)"
Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(BaseIntermediateOutputPath)**;$(BaseOutputPath)**;#(Compile)" />
</ItemGroup>
</Target>

Adding umbraco folders to build with MsBuild

If I use msbuild to build my project, all the folders not included in my solution are not deployed. Is there a way of deploying the umbraco and umbraco_client folders using msbuild?
I have tried using Targets like:
https://gist.github.com/aaronpowell/6695293
How can we include the files created by ajaxmin in the msdeploy package created by MSBuild
https://blog.samstephens.co.nz/2010/10/18/msbuild-including-extra-files-multiple-builds/
But hey are not being copied to the output folder. Am I missing anything?
You can use a msbuild target(run after the build ends) in which it calls the msbuild copy task to copy necessary files or folders to output folder. Use AfterTargets="build" to let the target run after the build.
A target script which works in my machine looks like this:
<Target Name="Copyumbraco" AfterTargets="build">
<ItemGroup>
<UmbracoFiles Include="$(ProjectDir)**\umbraco\**\*" />
<Umbraco_ClientFiles Include="$(ProjectDir)**\umbraco_client\**\*" />
</ItemGroup>
<Copy SourceFiles="#(UmbracoFiles)" DestinationFolder="$(OutputPath)\%(RecursiveDir)"/>
<Copy SourceFiles="#(Umbraco_ClientFiles)" DestinationFolder="$(OutputPath)\%(RecursiveDir)"/>
</Target>
Using $(ProjectDir) property to define the path, so Msbuild can find those two folders if they are in project folder as you mentioned in comment.
The \%(RecursiveDir) set the msbuild copy task to copy the files to destination path with original folder structure. If what you want to just copy all files to Output folder, you don't need to set it, then the script should be:
<Target Name="Copyumbraco" AfterTargets="build">
<ItemGroup>
<UmbracoFiles Include="$(ProjectDir)**\umbraco\**\*" />
<Umbraco_ClientFiles Include="$(ProjectDir)**\umbraco_client\**\*" />
</ItemGroup>
<Copy SourceFiles="#(UmbracoFiles)" DestinationFolder="$(OutputPath)"/>
<Copy SourceFiles="#(Umbraco_ClientFiles)" DestinationFolder="$(OutputPath)"/>
</Target>
Add the target script into the your project's project file(xx.csproj), make sure you place the script in the format below, then it can work when you use msbuild to build the project.
<Project Sdk="Microsoft.NET.Sdk.Web">
...
<Target Name="Copyumbraco" AfterTargets="build">
...
</Target>
</Project>
In addition:
For normal projects like console app, class library, the $(OutputPath) represents the output path. But for web site project, we can use $(WebProjectOutputDir) , hint from Mario!

How do I include webjob files while debugging locally but exclude when publishing a web package?

I'm using Visual Studio 2017 and have a solution with several web projects and webjob projects.
There are some files that I want to include when running locally in the development environment that I want to exclude from being deployed as part of a web publishing package.
I'm attempting to use the process described here http://sedodream.com/2010/05/01/WebDeploymentToolMSDeployBuildPackageIncludingExtraFilesOrExcludingSpecificFiles.aspx and elsewhere, which is:
<ItemGroup>
<ExcludeFromPackageFiles Include="connectionstrings.config">
<FromTarget>Project</FromTarget>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</ExcludeFromPackageFiles>
</ItemGroup>
This works perfectly for my web projects - meaning that when building the connectionstrings.config file is copied to my bin\ directory and not included as part of the web deployment package - whereas when implemented in my webjob projects the file is copied to my bin\ directory but also included in the deployment package.
In the msbuild output I see:
Copying file from "C:\Users\me\Documents\Projects\myapp\myapp\webjob1\connectionstrings.config" to "bin\ProdBuildCfg\connectionstrings.config".
which is what I want because it allows me to run/debug locally, and also:
Copying C:\Users\me\Documents\Projects\myapp\myapp\webjob1\bin\ProdBuildCfg\connectionstrings.config to obj\ProdBuildCfg\Package\PackageTmp\app_data\jobs\continuous\webjob1\connectionstrings.config.
which demonstrates the problem - connectionstrings.config is still being copied to the package directory for subsequent publishing/deployment.
The process described in the above article and others applies to web projects, and they indicate you should place the <ItemGroup> under the
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
line of the project file. Webjob projects don't include that line but rather have something resembling:
<Import Project="..\packages\Microsoft.Web.WebJobs.Publish.1.0.13\tools\webjobs.targets" Condition="Exists('..\packages\Microsoft.Web.WebJobs.Publish.1.0.13\tools\webjobs.targets')" />
I suspect the problem relates to targets - either my project file doesn't include the proper <Import Project="...*.targets')" /> line or I'm not at the right spot in the file.
Next I tried the method mentioned here How do I include webjob files while debugging locally but exclude when publishing a web package?:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<ExcludeFilesFromDeployment>connectionstrings.config</ExcludeFilesFromDeployment>
</PropertyGroup>
I have the connectionstrings.config Build Action set to None and Copy to output directory set to Always (my understanding is that action that results from the Copy to output directory setting is distinctly different from the actions associated with packaging/deployment). Same result. (I've ensured I'm in the right <PropertyGroup> for my build configuration.
Note: I'm deploying either by right-clicking the project in VS and selecting "Publish as Azure webjob" or using an msbuild command to publish like msbuild myproj.csproj /p:DeployOnBuild=true /p:Configuration=Release /p:PublishProfile="Prod" /p:VisualStudioVersion=15.0 /p:Password=
How do I include webjob files while debugging locally but exclude when publishing a web package?
To my knowledge, if you do not want to publish any file, you just need to set the file property to "copy to output directory as DO NOT COPY". This way when you will package the application that particular file will not be part of package and will never be on Azure.
Update:
Unfortunately that setting prevents the file from being copied to the
output directory which means I can’t run or debug locally.
When you debugging the project, you can set the "copy to output directory" as "Copy always". When you want to deploy the project, you can manually clean the build and change the value to DO NOT COPY.
If you do not want to do all those manually, I would like provide you a workaround, hope this can help you.
To accomplish this, unload your project. Then at the very end of the project , just before the end-tag, place below scripts:
<Target Name="ExcludeFileFromPackage" BeforeTargets="PipelineCopyAllFilesToOneFolderForMsdeploy">
<Message Text="Delete the connectionstrings.config from Obj folder to exculde this file in the package directory" />
<Delete Files="$(ProjectDir)obj\Release\Package\PackageTmp\connectionstrings.config" />
</Target>
With this target, VS/MSBuild will delete the connectionstrings.config from the obj folder before publish the project as package.

Ignore file from delete during WebDeploy

I'm using TeamCity to build and deploy a collection of MVC Applications via msbuild and WebDeploy.
In a step previous to my solution build/deploy, I copy an app_offline.htm to the deploy directory so that I can perform SQL updates and other web/solution management steps including the build.
One of the setting in the WebDeploy is to delete files that aren't included in the project, or not needed to run the site. This deletes my app_offline.htm file each time. While I understand this is kind of the desired result, is there a way to exclude this file from being deleted from the deployment directory upon the deploy?
I've tried adding an ItemGroup with the ExcludeFromPackageFiles option, with no results.
I had a similar problem, wanting to keep minified javascript files in the deployment package even though they're not part of the project.
I added a custom MSBuild target for this, that works for me:
<!-- ====== Package the minify files ===== -->
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles1;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
<PropertyGroup>
<AfterAddIisSettingAndFileContentsToSourceManifest>
MakeEmptyFolders
</AfterAddIisSettingAndFileContentsToSourceManifest>
</PropertyGroup>
<Target Name="CustomCollectFiles1">
<ItemGroup>
<!-- =====Controls\Javascript folder ==== -->
<_CustomFilesForRootFolder Include=".\Controls\Javascript\*.min.js">
<DestinationRelativePath>%(RecursiveDir)%(Filename)%(Extension) </DestinationRelativePath>
</_CustomFilesForRootFolder>
<FilesForPackagingFromProject Include="%(_CustomFilesForRootFolder.Identity)">
<DestinationRelativePath>.\Controls\Javascript\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
This other question " Custom app_offline.htm file during publish " suggests one possible way for the final result you describe:
I use my own
app_offline.htm_
file in the solution, which gets
published. My deployment script then
renames it (removing the trailing _)
to make it active.
I can then run my db scripts/do
whatever then rename the file bringing
the site back.

Resources