dotnet-combine
is .NET global tool that allows you to:
- Merge multiple C# source files (
.cs
) into a single one. - Generate a
.zip
with the specified files within a directory.
.NET 6 SDK is required to use this tool. You can download it from here.
The tool can be installed globally by running:
dotnet tool install -g dotnet-combine
More info about installing dotnet tools can be found here.
Once installed, dotnet-combine --help
should show you the general options:
single-file Combines multiple source code files (.cs) into a single one.
zip Zips multiple files.
help Display more information on a specific command.
version Display version information.
dotnet-combine single-file
combines multiple C# source files (.cs
) into a single, valid one.
This tool, originally inspired by TomKirby/CGCompactor, is handy if you need to submit a single source file somewhere; but you prefer to develop your solution locally using your preferred IDE and structuring it in multiple files.
Some examples are competitive programming contests such as Google Code Jam, CodeChef, CodingGame, etc.
Help for dotnet-combine single-file
can be accessed by running:
dotnet-combine single-file --help
Usage: dotnet-combine single-file <INPUT> [options]
input (pos. 0) Required.
Input path.
-o, --output Output path (file or dir).
If no dir path is provided (i.e. --output file.cs), the file will be created in the input dir.
If no filename is provided (i.e. --output dir/), a unique name will be used.
-f, --overwrite (Default: false)
Overwrites the output file (if it exists).
--exclude (Default: bin/ obj/)
Excluded files and directories, separated by semicolons (;).
-p, --prefix Prefix for the output file.
-s, --suffix Suffix for the output file
-v, --verbose (Default: false)
Verbose output. Shows combined files, progress, etc.
--format (Default: false)
Formats output file. Enabling it slows down file generation process.
--help Display this help screen.
--version Display version information.
If you want to merge the source code of MyAmazingProject.csproj
, located in C:/MyAmazingProject
, you can simply do:
dotnet-combine single-file C:/MyAmazingProject
That will generated a file under C:/MyAmazingProject/
. Since having that file there may conflict with your project compilation, you probably want it to be created somewhere else, let's say, under C:/tmp/
. You can use --output
for that:
dotnet-combine single-file C:/MyAmazingProject --output C:/tmp/
If you want that output file to have a specific name, you can also provide it:
dotnet-combine single-file C:/MyAmazingProject --output C:/tmp/amazing.cs
The option --override
can be used in subsequent runs to replace that file:
dotnet-combine single-file C:/MyAmazingProject --override --output C:/tmp/amazing.cs
If you prefer to keep different versions of your output file, but would still like to identify them, you can use --prefix
and/or --suffix
together with your output dir in --output
:
dotnet-combine single-file C:/MyAmazingProject --output C:/tmp/ --prefix amazing_
dotnet-combine single-file C:/MyAmazingProject --output C:/tmp/ --suffix _amazing
By default, bin/
and obj/
directories are excluded. That can be modified using --exclude
:
dotnet-combine single-file C:/MyAmazingProject --output C:/tmp/ --prefix amazing_ --exclude "bin/;obj/;AutogeneratedDir/;AssemblyInfo.cs"
If you want your MyAmazingProject.csproj
files to be combined every time you build the project in release mode, you can integrate dotnet-combine single-file
as a MsBuild target in your .csproj file:
<Target Name="dotnet-combine single-file" AfterTargets="Build" DependsOnTargets="Build" Condition="'$(Configuration)' == 'Release' ">
<Message Importance="high" Text="Running dotnet-combine tool"/>
<Message Importance="high" Text="dotnet-combine single-file $(MSBuildProjectDirectory) --overwrite --output $(MSBuildProjectDirectory)/bin/ --prefix amazing_ --exclude "bin/;obj/;AutogeneratedDir/;AssemblyInfo.cs""/>
<Exec Command="dotnet-combine single-file $(MSBuildProjectDirectory) --overwrite --output $(MSBuildProjectDirectory)/bin/ --prefix amazing_ --exclude "bin/;obj/;AutogeneratedDir/;AssemblyInfo.cs""/>
</Target>
dotnet-combine zip
generates a .zip
with the specified files within a given directory.
Currently it supports filtering files by extension and excluding both files and directories.
This tool can be used for more general purposes than the previous one. Some of them can be:
-
Extracting all
.pdf
files from a folder in your hard drive with complex hierarchies that has them mixed up with other files (.docx
,.pptx
,.jpg
, etc.). -
Extracting all
.mp3
files from your mirrored cloud's folder. -
Extracting all
.css
files from a web development project. -
Extracting all the relevant source code files (
.sln
,.csproj
,.cs
,.json
,.razor
,.xaml
, etc.) from your .NET project in a GitHub Action step, to be able to make them available as an artifact. -
...
Help for dotnet-combine zip
can be accessed by running:
dotnet-combine zip --help
Usage: dotnet-combine zip <INPUT> [options]
input (pos. 0) Required.
Input path (file or dir).
-o, --output Output path (file or dir).
If no dir path is provided (i.e. --output file.cs), the file will be created in the input
directory.
If no filename is provided (i.e. --output dir/), a unique name will be used.
--extensions (Default: .sln .csproj .cs .json)
File extensions to include, separated by semicolons (;).
-f, --overwrite (Default: false)
Overwrites the output file (if it exists).
--exclude (Default: bin/ obj/)
Excluded files and directories, separated by semicolons (;).
-p, --prefix Prefix for the output file.
-s, --suffix Suffix for the output file.
-v, --verbose (Default: false)
Verbose output. Shows compressed files, progress, etc.
--help Display this help screen.
--version Display version information.
If you want to create a .zip
with all the C++ source code in your MyGeekyProject
project, located in /home/ed/GeekyProject/
, you can simply do:
dotnet-combine zip /home/ed/GeekyProject --extensions ".cpp;cxx:cc;.h;.hpp"
That will generated a file under /home/ed/GeekyProject
. If you plan to create .zip
files regularly, you may want to place them somewhere else, such as /home/ed/GeekyProject/artifacts/
. You can use --output
for that:
dotnet-combine zip /home/ed/GeekyProject --extensions ".cpp;cxx:cc;.h;.hpp;" --output /home/ed/GeekyProject/artifacts/
If you want that output file to have a specific name, you can also provide it using --output
:
dotnet-combine zip /home/ed/GeekyProject --extensions ".cpp;cxx:cc;.h;.hpp" --output /home/ed/GeekyProject/artifacts/src_v1`
The tool will prevent you from generating another file with the same name unless you use --override
(also abbreviated as -f
):
dotnet-combine zip /home/ed/GeekyProject -f --extensions ".cpp;cxx:cc;.h;.hpp" --output /home/ed/GeekyProject/artifacts/src_v1
However, you may prefer to keep different versions of your output file without having to worry about specifying different version numbers in the name. You can achieve that by only including a dir path in --output
, and making use of --prefix
and/or --suffix
:
dotnet-combine zip /home/ed/GeekyProject --extensions ".cpp;cxx:cc;.h;.hpp" --prefix geeky- --output /home/ed/GeekyProject/artifacts/
By default, bin/
and obj/
directories are excluded. That can be modified by using --exclude
:
dotnet-combine zip /home/ed/GeekyProject --extensions ".cpp;cxx:cc;.h;.hpp;.vcxproj;" --prefix geeky- --output /home/ed/GeekyProject/artifacts/ --exclude "build/;UnwantedFile.h"
If you want to pack your MyGeekyProject
source files as part of your GitHub Actions CI pipeline, you can do it like this:
steps:
- uses: actions/[email protected]
- name: Install dotnet-combine locally.
run: |
dotnet new tool-manifest
dotnet tool install dotnet-combine
- name: Create source code artifact using dotnet-combine.
run: dotnet dotnet-combine zip . --extensions ".cpp;cxx:cc;.h;.hpp;.vcxproj;" --prefix geeky- --output ./artifacts/ --exclude "build/;UnwantedFile.h"
- name: Upload source code artifact.
uses: actions/upload-artifact@v2
with:
name: source-code-ci-${{ github.run_number }}
path: artifacts/
if-no-files-found: error
-
Although
dotnet-combine
does support\
path separators in Windows, bear in mind that using them will prevent your commands/targets from being cross-platform. -
If you want use a suffix that starts with a dash (
-
), you can do that by using 'double-dash' (--
) to indicate the end of options (i.e.dotnet-combine single-file ./MyDir --suffix -- -my-suffix
).
If you experience difficulties using dotnet-combine
, please open an issue detailing what you want to achieve and the command you've tried.
Feature requests are welcome.
PRs are also more than welcome, but feel free to open an issue before carrying out any major changes to avoid any misalignments.