Skip to content

Latest commit

 

History

History
175 lines (128 loc) · 5.85 KB

CONTRIBUTING.md

File metadata and controls

175 lines (128 loc) · 5.85 KB

Contributing to MTC

Thanks for taking the time. MTC is a small project, so the process is light — the only hard rule is that dotnet build and dotnet test must be clean before a PR.

Getting set up

You need the .NET 10 SDK. Nothing else.

git clone https://github.com/JuansesDev/MTC.git
cd MTC
dotnet build
dotnet test

The build should finish with 0 warnings. If you see warnings that were not there before your change, they count as breakage.

Running your build

dotnet run swallows CLI arguments in confusing ways, so drive the binary directly:

dotnet build
./MTC/bin/Debug/net10.0/MTC list

A good scratch loop is to generate into a throwaway directory and inspect the result:

mkdir -p /tmp/mtc-scratch && cd /tmp/mtc-scratch
/path/to/MTC/MTC/bin/Debug/net10.0/MTC new CleanArch MyShop
/path/to/MTC/MTC/bin/Debug/net10.0/MTC add feature Product --fields "Name:string Price:decimal"
dotnet build MyShop.sln    # generated projects must compile clean too

How the code is laid out

Path What lives there
MTC/Program.cs CLI command definitions and handlers
MTC/Services/ The real logic — one interface + implementation per concern
MTC/Models/ Plain data types (Template, Property, ProjectContext)
Templates/ The templates themselves, copied to the build output
MTC.Tests/ Unit tests
MTC.IntegrationTests/ Tests that run the compiled binary end to end

The services worth knowing:

  • ContextService — walks up from the current directory to find a .sln, then decides whether the solution is Clean Architecture, Vertical Slice or MVC.
  • TemplateService — discovers templates by scanning recursively for manifest.json.
  • ScribanTemplateRenderer — renders template content and file/directory names.
  • ScaffoldingService — walks a template directory and writes the rendered result.
  • FieldParser — turns "Name:string Price:decimal" into Property objects.

Adding or editing a template

A template is just a directory with a manifest.json and the files to render. Both file contents and file/directory names go through Scriban, which is why you see paths like Templates/Common/Dto/{{Name}}.cs.

{
    "Name": "MyTemplate",
    "Description": "What it generates",
    "Version": "1.0.0",
    "Author": "You",
    "Tags": ["Tag"],
    "Variables": { "Name": "string" }
}

Name is what users type (mtc new MyTemplate ...), so it must be unique.

Variables available in templates

Variable Available in Notes
Name everywhere the entity/project name the user typed
ProjectName add feature taken from the .sln file name
Namespace add value-object, add dto resolved from the detected architecture
Properties add * list of { Name, Type, IsValueType }

Member names are case-sensitive: write {{ prop.Name }}, not {{ prop.name }}.

Two conventions that matter

1. Control whitespace, or the output looks generated. Use {{~ and ~}} around loops so the rendered file is indented like hand-written code:

public class {{Name}}
{
{{~ for prop in Properties ~}}
    public {{ prop.Type }} {{ prop.Name }} { get; set; }
{{~ end ~}}
}

2. Emit required for reference types. Generated projects have <Nullable>enable</Nullable>, so a plain public string Name { get; set; } raises CS8618. That is what IsValueType is for:

    public {{ if !prop.IsValueType }}required {{ end }}{{ prop.Type }} {{ prop.Name }} { get; set; }

Anything MTC generates must compile with zero warnings. Always build the generated solution before opening a PR, not just MTC itself.

Tests

  • Put unit tests in MTC.Tests, next to the service they cover.
  • MTC.IntegrationTests runs the compiled binary, so it needs a build first. It locates the executable by searching MTC/bin/Debug/ — don't hardcode a framework folder.
  • New behaviour needs a test. Bug fixes should come with a test that fails without the fix.

Style

Follow the surrounding code; there is no separate style config.

  • 4 spaces, file-scoped namespaces, nullable enabled.
  • Services go behind an interface and get registered in Program.cs.
  • Commands report failures with AnsiConsole.MarkupLine("[red]Error:[/] ...") and set Environment.ExitCode = 1. Silent failures with exit code 0 break scripted use.
  • Prefer a short explanatory comment over a long one. Don't commit commented-out code or notes to yourself.

Pull requests

  1. Branch off main.
  2. Keep the change focused — one concern per PR.
  3. Make sure dotnet build and dotnet test are clean.
  4. Add an entry under ## [Unreleased] in CHANGELOG.md. Describe the effect on users, not the diff.
  5. Say what you changed and why. If it changes CLI behaviour, update the README too.

CI runs build and tests on every push and PR to main.

Releasing (maintainers)

Version numbers live in two places and must match:

  • MTC/MTC.csproj → <Version>
  • publish.sh → VERSION

Rename the ## [Unreleased] heading in CHANGELOG.md to the version and date, then tag and push:

git tag v1.1.0
git push origin v1.1.0

Tags may be written v1.1.0, V1.1.0, V.1.1.0 or 1.1.0 — the workflow strips the prefix either way. Releases up to 1.0.2 used the V. form.

The release workflow builds the cross-platform binaries and the .deb, publishes the GitHub release, and pushes the package to NuGet. AUR is published separately with ./publish_aur.sh.

Reporting bugs

Open an issue with the MTC version, your OS, the exact command, what you expected, and what happened. For anything about architecture detection, include the output of:

mtc debug-context

License

Contributions are accepted under the MIT License.