Skip to content

eduherminio/dotnet-combine

Repository files navigation

dotnet-combine

GitHub Actions

NuGet

Code coverage Sonar vulnerabilities Sonar bugs Sonar code smells

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.

Installing dotnet-combine

.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

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.

dotnet-combine single-file usage examples

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 &quot;bin/;obj/;AutogeneratedDir/;AssemblyInfo.cs&quot;"/>
    <Exec Command="dotnet-combine single-file $(MSBuildProjectDirectory) --overwrite --output $(MSBuildProjectDirectory)/bin/ --prefix amazing_ --exclude &quot;bin/;obj/;AutogeneratedDir/;AssemblyInfo.cs&quot;"/>
  </Target>

dotnet-combine zip

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.

dotnet-combine zip usage examples

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/checkout@v2.3.3

    - 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

Additional notes

  • 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).

Contributing

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.

About

.NET global tool that allows you to combine multiple C# source files into a single one, create a .zip with multiple files, etc.

Topics

Resources

License

Stars

Watchers

Forks