Skip to content

Commit 9cecf7b

Browse files
committed
all nuget package changes
1 parent 08cd5c3 commit 9cecf7b

File tree

5 files changed

+128
-104
lines changed

5 files changed

+128
-104
lines changed

.github/workflows/template-publish.yml

Lines changed: 64 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,45 +53,50 @@ jobs:
5353
- name: Run template preparation script
5454
shell: pwsh
5555
run: |
56-
./CreateTemplate.ps1 -SourceDirectory . -TemplateNamespace Contact -OutputDirectory ./template-output
56+
./template-src/CreateTemplate.ps1 -SourceDirectory . -TemplateNamespace Contact -OutputDirectory ./template-output
5757
58-
- name: Create .nuspec file
59-
shell: pwsh
60-
run: |
61-
$nuspecContent = @"
62-
<?xml version="1.0" encoding="utf-8"?>
63-
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
64-
<metadata>
65-
<id>CleanArchitecture.FullStack.Template</id>
66-
<version>${{ env.TEMPLATE_VERSION }}</version>
67-
<title>Clean Architecture Full-Stack Template</title>
68-
<authors>${{ env.TEMPLATE_AUTHOR }}</authors>
69-
<description>${{ env.TEMPLATE_DESCRIPTION }}</description>
70-
<tags>dotnet-new template cleanarchitecture angular fullstack docker postgresql</tags>
71-
<packageTypes>
72-
<packageType name="Template" />
73-
</packageTypes>
74-
<repository type="git" url="https://github.com/nitin27may/clean-architecture-docker-dotnet-angular" />
75-
<license type="expression">MIT</license>
76-
<projectUrl>https://github.com/nitin27may/clean-architecture-docker-dotnet-angular</projectUrl>
77-
<requireLicenseAcceptance>false</requireLicenseAcceptance>
78-
<copyright>Copyright © ${{ env.TEMPLATE_AUTHOR }} $((Get-Date).Year)</copyright>
79-
<summary>A full-stack template using Clean Architecture principles with .NET 9 API backend and Angular 19 frontend, containerized with Docker.</summary>
80-
</metadata>
81-
</package>
82-
"@
83-
84-
Set-Content -Path "./template-output/CleanArchitecture.FullStack.Template.nuspec" -Value $nuspecContent
85-
86-
- name: Update template.json metadata
58+
- name: Copy template.json file
8759
shell: pwsh
8860
run: |
61+
# Create template config directory
62+
New-Item -Path "./template-output/.template.config" -ItemType Directory -Force
63+
64+
# Copy the existing template.json file
65+
Copy-Item -Path "./template-src/template.json" -Destination "./template-output/.template.config/template.json"
66+
67+
# Update metadata in template.json
8968
$templateJsonPath = "./template-output/.template.config/template.json"
9069
$templateJson = Get-Content -Path $templateJsonPath -Raw | ConvertFrom-Json
9170
9271
$templateJson.author = "${{ env.TEMPLATE_AUTHOR }}"
9372
$templateJson | ConvertTo-Json -Depth 10 | Set-Content -Path $templateJsonPath
9473
74+
- name: Copy README template
75+
shell: pwsh
76+
run: |
77+
# Copy the README template if it exists
78+
if (Test-Path "./template-src/README.template.md") {
79+
Copy-Item -Path "./template-src/README.template.md" -Destination "./template-output/README.md"
80+
}
81+
82+
- name: Copy and update .nuspec file
83+
shell: pwsh
84+
run: |
85+
# Copy the .nuspec file
86+
Copy-Item -Path "./template-src/CleanArchitecture.FullStack.Template.nuspec" -Destination "./template-output/CleanArchitecture.FullStack.Template.nuspec"
87+
88+
# Update metadata in the .nuspec file
89+
$nuspecPath = "./template-output/CleanArchitecture.FullStack.Template.nuspec"
90+
$nuspecContent = Get-Content -Path $nuspecPath -Raw
91+
92+
# Replace version, author, and description with workflow inputs
93+
$nuspecContent = $nuspecContent -replace '<version>.*?</version>', "<version>${{ env.TEMPLATE_VERSION }}</version>"
94+
$nuspecContent = $nuspecContent -replace '<authors>.*?</authors>', "<authors>${{ env.TEMPLATE_AUTHOR }}</authors>"
95+
$nuspecContent = $nuspecContent -replace '<description>.*?</description>', "<description>${{ env.TEMPLATE_DESCRIPTION }}</description>"
96+
$nuspecContent = $nuspecContent -replace '<copyright>.*?</copyright>', "<copyright>Copyright © ${{ env.TEMPLATE_AUTHOR }} $((Get-Date).Year)</copyright>"
97+
98+
Set-Content -Path $nuspecPath -Value $nuspecContent
99+
95100
- name: Verify template structure
96101
shell: pwsh
97102
run: |
@@ -145,10 +150,36 @@ jobs:
145150
cd test-project
146151
147152
# Verify template installed correctly
148-
dotnet new --list | findstr "cleanarch-fullstack"
153+
dotnet new --list | findstr "cleanarch"
154+
155+
# Create project from template with parameters from template.json
156+
dotnet new cleanarch --organization TestCompany --projectName TestProject
157+
158+
# List files to verify creation
159+
dir
160+
161+
- name: Test template package with organization
162+
run: |
163+
dotnet new install ./nupkg/CleanArchitecture.FullStack.Template.${{ env.TEMPLATE_VERSION }}.nupkg
164+
mkdir test-project-with-org
165+
cd test-project-with-org
166+
167+
# Verify template installed correctly
168+
dotnet new --list | findstr "cleanarch"
169+
170+
# Create project from template with organization parameter
171+
dotnet new cleanarch --organization TestCompany --projectName TestProjectWithOrg
172+
173+
# List files to verify creation
174+
dir
175+
176+
- name: Test template package without organization
177+
run: |
178+
mkdir test-project-no-org
179+
cd test-project-no-org
149180
150-
# Create project from template
151-
dotnet new cleanarch-fullstack --Organization TestCompany
181+
# Create project from template without organization parameter
182+
dotnet new cleanarch --projectName TestProjectNoOrg
152183
153184
# List files to verify creation
154185
dir
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
3+
<metadata>
4+
<id>CleanArchitecture.FullStack.Template</id>
5+
<version>1.0.0</version>
6+
<title>Clean Architecture Full-Stack Template</title>
7+
<authors>Nitin Singh</authors>
8+
<description>Full-stack Clean Architecture template with .NET 9 API and Angular 19</description>
9+
<tags>dotnet-new template cleanarchitecture angular fullstack docker postgresql</tags>
10+
<packageTypes>
11+
<packageType name="Template" />
12+
</packageTypes>
13+
<repository type="git" url="https://github.com/nitin27may/clean-architecture-docker-dotnet-angular" />
14+
<license type="expression">MIT</license>
15+
<projectUrl>https://github.com/nitin27may/clean-architecture-docker-dotnet-angular</projectUrl>
16+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
17+
<copyright>Copyright © Nitin Singh 2024</copyright>
18+
<summary>A full-stack template using Clean Architecture principles with .NET 9 API backend and Angular 19 frontend, containerized with Docker.</summary>
19+
</metadata>
20+
</package>

template-src/CreateTemplate.ps1

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
.PARAMETER SourceDirectory
1111
The directory containing the source code to templatize. Default is the current directory.
1212
13-
.PARAMETER TemplateNamespace
14-
The current namespace prefix used in the solution that will be tokenized. Default is "Contact".
13+
.PARAMETER OrganizationNamespace
14+
The current organization namespace prefix used in the solution that will be tokenized. Default is "Contact".
1515
1616
.PARAMETER OutputDirectory
1717
The directory where the prepared template will be created. Default is ".\template-output".
1818
#>
1919

2020
param(
2121
[string]$SourceDirectory = ".",
22-
[string]$TemplateNamespace = "Contact",
22+
[string]$OrganizationNamespace = "Contact",
2323
[string]$OutputDirectory = ".\template-output"
2424
)
2525

@@ -95,17 +95,18 @@ foreach ($file in $filesToProcess) {
9595
Write-Host "Processing $($file.FullName)"
9696
$content = Get-Content -Path $file.FullName -Raw
9797

98-
# Replace namespace references
98+
# Replace namespace references with tokenized versions
99+
# Note the trailing dot - when organization is empty, we don't want an extra dot
99100
if ($file.Extension -eq ".cs") {
100-
$content = $content -replace "namespace\s+$TemplateNamespace\.", "namespace ${TemplateNamespace}."
101-
$content = $content -replace "using\s+$TemplateNamespace\.", "using ${TemplateNamespace}."
101+
$content = $content -replace "namespace\s+$OrganizationNamespace\.", "namespace NamespacePrefix."
102+
$content = $content -replace "using\s+$OrganizationNamespace\.", "using NamespacePrefix."
102103
}
103104
elseif ($file.Extension -eq ".csproj") {
104-
$content = $content -replace "<RootNamespace>$TemplateNamespace\.", "<RootNamespace>${TemplateNamespace}."
105-
$content = $content -replace "<AssemblyName>$TemplateNamespace\.", "<AssemblyName>${TemplateNamespace}."
105+
$content = $content -replace "<RootNamespace>$OrganizationNamespace\.", "<RootNamespace>NamespacePrefix."
106+
$content = $content -replace "<AssemblyName>$OrganizationNamespace\.", "<AssemblyName>NamespacePrefix."
106107
}
107108
elseif ($file.Name -eq "*.sln") {
108-
$content = $content -replace "$TemplateNamespace\.", "${TemplateNamespace}."
109+
$content = $content -replace "$OrganizationNamespace\.", "NamespacePrefix."
109110
}
110111

111112
# Write the modified content back to the file
@@ -125,7 +126,7 @@ $templateJson = @{
125126
language = "C#"
126127
type = "project"
127128
}
128-
sourceName = $TemplateNamespace
129+
sourceName = $OrganizationNamespace
129130
preferNameDirectory = $true
130131
symbols = @{
131132
Framework = @{
@@ -145,7 +146,7 @@ $templateJson = @{
145146
datatype = "string"
146147
description = "Organization name to use in the project"
147148
defaultValue = "YourCompany"
148-
replaces = $TemplateNamespace
149+
replaces = $OrganizationNamespace
149150
}
150151
SkipRestore = @{
151152
type = "parameter"

template-src/README.template.md

Lines changed: 16 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@ This template provides a starting point for creating a Clean Architecture soluti
1313
1. **Install the template:**
1414

1515
```bash
16-
dotnet new install <path-to-template>
16+
dotnet new install <path-to-template-package>
17+
# Or from NuGet
18+
dotnet new install CleanArchitecture.FullStack.Template
1719
```
1820

1921
2. **Create a new project using the template:**
2022

2123
```bash
22-
dotnet new cleanarch --projectName MyTestApp --namespacePrefix NitinSoft.
24+
dotnet new cleanarch --organization YourCompany --projectName MyApp
2325
```
2426

2527
3. **Navigate to the project directory:**
2628

2729
```bash
28-
cd MyTestApp
30+
cd MyApp
2931
```
3032

3133
4. **Build and run the project:**
@@ -36,81 +38,38 @@ This template provides a starting point for creating a Clean Architecture soluti
3638

3739
## Template Parameters
3840

41+
- `--organization`: Optional organization or company name to be used in namespaces. If specified, namespaces will be formatted as `YourCompany.MyApp.Feature`. If not specified, namespaces will be formatted as `MyApp.Feature`.
3942
- `--projectName`: The name of the project. Default is `MyApp`.
40-
- `--namespacePrefix`: Optional namespace prefix (e.g., `MyOrg.`). Default is an empty string.
4143

4244
## Directory Structure
4345

4446
The template creates the following directory structure:
4547

4648
```
47-
MyTestApp/
49+
MyApp/
4850
├── backend/
4951
│ ├── src/
52+
│ │ ├── YourCompany.MyApp.Api/
53+
│ │ ├── YourCompany.MyApp.Core/
54+
│ │ ├── YourCompany.MyApp.Infrastructure/
55+
│ │ └── ...
5056
│ ├── tests/
57+
│ │ ├── YourCompany.MyApp.UnitTests/
58+
│ │ ├── YourCompany.MyApp.IntegrationTests/
59+
│ │ └── ...
5160
│ └── ...
5261
├── frontend/
5362
│ ├── src/
5463
│ ├── e2e/
5564
│ └── ...
5665
├── docker-compose.yml
66+
├── .env-example
5767
└── README.md
5868
```
5969

6070
## Customizing the Template
6171

62-
You can customize the template by modifying the `template.json` file located in the `template-src` directory. Refer to the [Microsoft documentation](https://docs.microsoft.com/en-us/dotnet/core/tools/custom-templates) for more information on creating custom templates.
63-
64-
## Contributing
65-
66-
If you would like to contribute to this template, please follow the steps below:
67-
68-
1. **Create a new branch:**
69-
70-
```bash
71-
git checkout -b template-generator
72-
```
73-
74-
2. **Add the folder structure:**
75-
76-
- Add the `template-src/` folder with:
77-
- `CreateTemplate.ps1`
78-
- `template.json`
79-
- `README.template.md`
80-
- `.github/workflows/dotnet-template-publish.yml` (if you’re automating)
81-
82-
3. **Test locally:**
83-
84-
```bash
85-
cd template-src
86-
./CreateTemplate.ps1
87-
```
88-
89-
4. **Install and try the template:**
90-
91-
```bash
92-
dotnet new install ../src/ProjectTemplate
93-
dotnet new cleanarch --projectName MyTestApp --namespacePrefix NitinSoft.
94-
```
95-
96-
5. **Check generated output:**
97-
98-
Validate if:
99-
- Project files are renamed
100-
- Namespaces are updated
101-
- It builds and runs
102-
103-
6. **Commit and push:**
104-
105-
```bash
106-
git add .
107-
git commit -m "Add dynamic template generation"
108-
git push origin template-generator
109-
```
110-
111-
Once you’re happy, you can either:
112-
- Merge into main, or
113-
- Keep it as a separate maintained branch for template packaging
72+
You can customize the template by modifying the source files to meet your specific requirements. The template follows Clean Architecture principles, with proper separation of concerns between API, Core, and Infrastructure layers.
11473

11574
## License
11675

template-src/template.json

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,31 @@
1313
"type": "project"
1414
},
1515
"symbols": {
16-
"namespacePrefix": {
16+
"organization": {
1717
"type": "parameter",
1818
"datatype": "text",
19-
"description": "Optional namespace prefix (e.g., MyOrg.)",
19+
"description": "Optional organization or company name to be used in namespaces (e.g., YourCompany). If not specified, organization name will be omitted.",
2020
"defaultValue": "",
21-
"replaces": "NamespacePrefix"
21+
"replaces": "NamespacePrefix."
2222
},
2323
"projectName": {
2424
"type": "parameter",
2525
"datatype": "text",
2626
"defaultValue": "MyApp",
2727
"replaces": "ProjectNamePlaceholder"
28+
},
29+
"skipOrgPrefix": {
30+
"type": "computed",
31+
"value": "(organization == \"\")"
32+
}
33+
},
34+
"forms": {
35+
"namespace": {
36+
"identifier": "replace",
37+
"pattern": {
38+
"from": "^(.*?)\\.(.*?)$",
39+
"to": "$1.$2"
40+
}
2841
}
2942
}
3043
}

0 commit comments

Comments
 (0)