Skip to content

Commit 4881a45

Browse files
committed
feat(#194): enhance Nova scaffolding with .gitignore management
- create or update default .gitignore in generated project root when Git is enabled - append missing Nova-managed artifact entries without overwriting existing rules - update documentation to reflect .gitignore functionality in scaffold flows
1 parent 90fb0c3 commit 4881a45

14 files changed

Lines changed: 388 additions & 36 deletions

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
1717
- The generated guidance now expresses PowerShell source/helper-script maintainability rules through `code-quality-matrix.instructions.md` and keeps test-specific design guidance in the testing instruction/skill files.
1818
- The generated guidance now requires `docs/<ProjectName>/en-US/*.md` to stay valid PlatyPS help with YAML metadata and build-compatible structure, tells agents to use the documented `New-MarkdownCommandHelp` / `Update-MarkdownCommandHelp` / `Test-MarkdownCommandHelp` workflow instead of replacing command help with plain Markdown that breaks `nova build`, and requires a matching help file for every new public entry point in the same change.
1919
- The generated PowerShell guidance now requires agents to review every changed or generated text file before handoff and normalize the file ending to exactly one trailing newline with no extra blank lines at the bottom.
20+
- When Git is enabled during either scaffold flow, Nova now creates or updates a default `.gitignore` in the generated project root and appends only the missing Nova-managed artifact entries instead of overwriting existing ignore rules.
2021

2122

2223
### Changed

RELEASE_NOTE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This file summarizes public cmdlet, CLI, configuration, and migration changes fo
1515
- Generated guidance now expresses PowerShell source/helper-script maintainability rules through `code-quality-matrix.instructions.md` and keeps test-specific design guidance in the testing instruction/skill files.
1616
- Generated guidance now requires `docs/<ProjectName>/en-US/*.md` to stay valid PlatyPS help with YAML metadata and build-compatible structure, points agents to the `New-MarkdownCommandHelp` / `Update-MarkdownCommandHelp` / `Test-MarkdownCommandHelp` workflow, and requires a matching help file for every new public entry point in the same change so command help stays build-compatible from the start.
1717
- Generated PowerShell guidance now requires agents to review every changed or generated text file before handoff and normalize the file ending to exactly one trailing newline with no extra blank lines at the bottom.
18+
- When Git is enabled during either scaffold flow, Nova now creates or updates a default `.gitignore` in the generated project root and appends only the missing Nova-managed artifact entries instead of overwriting existing ignore rules.
1819

1920

2021
### Changed

docs/NovaModuleTools/en-US/Initialize-NovaModule.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ PS> Initialize-NovaModule [-Path <string>] [-Example] [-WhatIf] [-Confirm] [<Com
2727

2828
`Initialize-NovaModule` creates a new project folder, the standard `src/` layout, and a starter `project.json` file.
2929

30-
The command collects project details interactively, including the module name, description, version, author, minimum PowerShell version, Git initialization, and an optional Agentic Copilot starter package. When you enable the Agentic package, Nova also asks for a project short name used in generated guidance placeholders such as `Invoke-<ShortName>*`; for NovaModuleTools the short name is `Nova`, but it could also have been `NMT`. The Agentic package follows Nova's maintained agentic guidance through a filtered starter mirror, including Nova build/test/package expectations, `project.json` `Manifest.PowerShellHostVersion` compatibility guidance, strict ScriptAnalyzer guidance without excluded rules, generated `dist` module files, command-help ownership, source-mirrored test guidance, guidance that ScriptAnalyzer findings reported by
30+
The command collects project details interactively, including the module name, description, version, author, minimum PowerShell version, Git initialization, and an optional Agentic Copilot starter package. When Git initialization is enabled, Nova also creates or updates a default `.gitignore` in the generated project root so common local and CI artifact paths such as `artifacts/`, `dist/`, `run.ps1`, and `reload.ps1` are ignored from the start. Existing `.gitignore` files are preserved and only receive the missing Nova-managed entries. When you enable the Agentic package, Nova also asks for a project short name used in generated guidance placeholders such as `Invoke-<ShortName>*`; for NovaModuleTools the short name is `Nova`, but it could also have been `NMT`. The Agentic package follows Nova's maintained agentic guidance through a filtered starter mirror, including Nova build/test/package expectations, `project.json`
31+
`Manifest.PowerShellHostVersion` compatibility guidance, strict ScriptAnalyzer guidance without excluded rules, generated `dist` module files, command-help ownership, source-mirrored test guidance, guidance that ScriptAnalyzer findings reported by
3132
`run.ps1` must be fixed before handoff, explicit PSScriptAnalyzer workflow guidance for `./scripts/build/Invoke-ScriptAnalyzerCI.ps1`, `./run.ps1`, and focused `Invoke-ScriptAnalyzer` usage, explicit public/private PowerShell file ownership rules, best-effort source/helper-script maintainability guidance plus separate test-design guidance delivered through Agentic Copilot files, explicit valid-PlatyPS help guidance for `docs/<ProjectName>/en-US/*.md` that uses `New-MarkdownCommandHelp`, `Update-MarkdownCommandHelp`, and `Test-MarkdownCommandHelp`, and a strict file-ending rule for changed or generated text files. For the standard scaffold, the interactive flow also includes optional basic Pester support.
3233

3334
If you enter an invalid answer during the interactive flow, `Initialize-NovaModule` reports the validation problem immediately and retries that prompt before it continues to the next question.
@@ -36,7 +37,7 @@ Use this command when you want to start a new module in the NovaModuleTools stru
3637

3738
Use `-Path` when you want to create the project under a specific base directory. Positional path syntax is no longer supported.
3839

39-
Use `-Example` when you want the scaffold to start from the packaged example project instead of the minimal default layout. The example flow keeps the example source, resource, and test files, skips the Pester enable/disable question, and applies the interactive metadata values to the copied `project.json`. The standard and example flows share the same inline validation and retry behavior for interactive answers, including the optional Agentic Copilot setup prompt after the Git question. When you answer `Yes`, Nova asks for the short project name, adds the same starter package to either scaffold style, and merges the example README instead of replacing it with the generic starter README outright.
40+
Use `-Example` when you want the scaffold to start from the packaged example project instead of the minimal default layout. The example flow keeps the example source, resource, and test files, skips the Pester enable/disable question, and applies the interactive metadata values to the copied `project.json`. The standard and example flows share the same inline validation and retry behavior for interactive answers, including the optional Agentic Copilot setup prompt after the Git question. When Git is enabled in either flow, Nova also ensures the generated project root has the default `.gitignore` entries for local and CI artifacts without overwriting any existing `.gitignore` content. When you answer `Yes`, Nova asks for the short project name, adds the same starter package to either scaffold style, and merges the example README instead of replacing it with the generic starter README outright.
4041

4142
This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the scaffold target after the interactive answers have been collected, without creating folders, writing `project.json`, or initializing Git.
4243

@@ -137,7 +138,7 @@ This cmdlet does not emit an output object.
137138
138139
## NOTES
139140
140-
Generated projects start with NovaModuleTools defaults for recursive discovery, source markers, and duplicate-function validation. The packaged example scaffold keeps its bundled example source and tests, while still updating prompt-driven metadata such as project name, description, version, author, and PowerShell host version. The optional Agentic Copilot starter package adds repository-local Copilot workflow files under the project root and `.github/` that tell agents to keep build/test/package workflows on Nova, treat `project.json` `Manifest.PowerShellHostVersion` as the PowerShell compatibility target, run ScriptAnalyzer before build/test through the repo-standard `Invoke-ScriptAnalyzerCI.ps1` / `run.ps1` workflow, fix any ScriptAnalyzer findings before handoff, run project tests through `Test-NovaBuild` instead of direct `Invoke-Pester`, leave `.psm1` / `.psd1` files to generated
141+
Generated projects start with NovaModuleTools defaults for recursive discovery, source markers, duplicate-function validation, and—when Git is enabled—a default `.gitignore` for common local and CI artifact paths. The packaged example scaffold keeps its bundled example source and tests, while still updating prompt-driven metadata such as project name, description, version, author, and PowerShell host version. The optional Agentic Copilot starter package adds repository-local Copilot workflow files under the project root and `.github/` that tell agents to keep build/test/package workflows on Nova, treat `project.json` `Manifest.PowerShellHostVersion` as the PowerShell compatibility target, run ScriptAnalyzer before build/test through the repo-standard `Invoke-ScriptAnalyzerCI.ps1` / `run.ps1` workflow, fix any ScriptAnalyzer findings before handoff, run project tests through `Test-NovaBuild` instead of direct `Invoke-Pester`, leave `.psm1` / `.psd1` files to generated
141142
`dist` output, generate and validate command help with the Microsoft.PowerShell.PlatyPS cmdlets instead of hand-written Markdown structure, require a matching help file for every new public entry point in the same change, and mirror new tests to source files.
142143

143144
`Initialize-NovaModule` uses `SupportsShouldProcess`, so `Get-Help Initialize-NovaModule -Full` surfaces native

docs/commands.html

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ <h3>Install the <code>nova</code> launcher</h3>
162162
</ul>
163163
<pre><code>PS&gt; Install-NovaCli
164164
PS&gt; Install-NovaCli -DestinationDirectory ~/bin -Force</code></pre>
165-
<p><a class="text-link" href="./getting-started.html#install-and-update">See setup details</a>
165+
<p><a class="text-link" href="./getting-started.html#install-module">See setup details</a>
166166
</p>
167167
</article>
168168

@@ -174,9 +174,11 @@ <h3>Start a new project</h3>
174174
<div class="surface-note" data-command-visibility="powershell">
175175
<p><strong>Cmdlet:</strong> <code>Initialize-NovaModule</code></p>
176176
</div>
177-
<p>Create the minimal scaffold or the example scaffold for a new module project. Both interactive
178-
flows can also add the optional Agentic Copilot starter package, which follows Nova's
179-
maintained agentic guidance through a filtered starter mirror, including Nova build/test
177+
<p>Create the minimal scaffold or the example scaffold for a new module project. When Git is
178+
enabled, Nova also creates or updates a default <code>.gitignore</code> in the generated
179+
project root so common local and CI artifact paths are ignored without overwriting existing
180+
rules. Both interactive flows can also add the optional Agentic Copilot starter package,
181+
which follows Nova's maintained agentic guidance through a filtered starter mirror, including Nova build/test
180182
expectations, <code>project.json</code> <code>Manifest.PowerShellHostVersion</code>
181183
compatibility guidance, strict ScriptAnalyzer guidance without excluded rules, generated
182184
<code>dist</code> module files, command-help ownership, source-mirrored test guidance,

docs/core-workflows.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,11 @@ <h2>Create the project</h2>
124124
path syntax such as <code>% nova init ~/Work</code>.</p>
125125
</div>
126126
<p>Both scaffold styles ask the same core project questions, and both now offer an optional Agentic
127-
Copilot starter package after the Git prompt. The Agentic prompt defaults to <code>No</code>, and
128-
the package follows Nova's maintained agentic guidance through a filtered starter mirror, including
127+
Copilot starter package after the Git prompt. When you enable Git in either scaffold style, Nova
128+
also creates or updates a default <code>.gitignore</code> in the generated project root so common
129+
local and CI artifact paths are ignored without overwriting existing rules. The Agentic prompt
130+
defaults to <code>No</code>, and the package follows Nova's maintained agentic guidance through a
131+
filtered starter mirror, including
129132
Nova build/test/package expectations, <code>project.json</code>
130133
<code>Manifest.PowerShellHostVersion</code> compatibility guidance, strict ScriptAnalyzer guidance
131134
without excluded rules, generated <code>dist</code> module files, command-help ownership,

docs/getting-started.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ <h2>4. Scaffold the packaged example</h2>
195195
</div>
196196
<p>Nova asks for the project name, description, version, author, minimum PowerShell version, whether
197197
Git should be initialized, and whether Nova should add the optional Agentic Copilot starter package.
198+
When you enable Git, Nova also creates or updates a default <code>.gitignore</code> in the new
199+
project root so common local and CI artifact paths start ignored without overwriting existing ignore
200+
rules.
198201
The Agentic package follows Nova's maintained agentic guidance through a filtered starter mirror,
199202
including Nova build/test/package expectations, <code>project.json</code>
200203
<code>Manifest.PowerShellHostVersion</code> compatibility guidance, strict ScriptAnalyzer guidance

scripts/build/Sync-AgenticCopilotScaffold.ps1

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,32 +64,55 @@ function Test-AgenticPathExcluded {
6464
return $false
6565
}
6666

67-
function Get-AgenticMirrorSourceFile {
67+
function Get-AgenticSourceFileListForPath {
6868
param(
6969
[Parameter(Mandatory)][string]$RootPath,
70-
[Parameter(Mandatory)][string[]]$SourcePathList,
70+
[Parameter(Mandatory)][string]$SourcePath
71+
)
72+
73+
$resolvedSourcePath = Resolve-AgenticRepositoryPath -RootPath $RootPath -RelativePath $SourcePath
74+
if (-not (Test-Path -LiteralPath $resolvedSourcePath)) {
75+
throw "Agentic scaffold source path does not exist: $SourcePath"
76+
}
77+
78+
if (Test-Path -LiteralPath $resolvedSourcePath -PathType Leaf) {
79+
return @(Get-Item -LiteralPath $resolvedSourcePath)
80+
}
81+
82+
return @(Get-ChildItem -LiteralPath $resolvedSourcePath -File -Recurse -Force)
83+
}
84+
85+
function ConvertTo-AgenticMirrorSourceFile {
86+
param(
87+
[Parameter(Mandatory)][string]$RootPath,
88+
[Parameter(Mandatory)][System.IO.FileInfo]$SourceFile,
7189
[Parameter(Mandatory)][string[]]$ExcludedPathList
7290
)
7391

74-
$sourceFileList = foreach ($sourcePath in $SourcePathList) {
75-
$resolvedSourcePath = Resolve-AgenticRepositoryPath -RootPath $RootPath -RelativePath $sourcePath
76-
if (-not (Test-Path -LiteralPath $resolvedSourcePath)) {
77-
throw "Agentic scaffold source path does not exist: $sourcePath"
78-
}
92+
$relativePath = Get-AgenticRelativePath -RootPath $RootPath -Path $SourceFile.FullName
93+
if (Test-AgenticPathExcluded -RelativePath $relativePath -ExcludedPathList $ExcludedPathList) {
94+
return $null
95+
}
7996

80-
if (Test-Path -LiteralPath $resolvedSourcePath -PathType Leaf) {
81-
Get-Item -LiteralPath $resolvedSourcePath
82-
} else {
83-
Get-ChildItem -LiteralPath $resolvedSourcePath -File -Recurse -Force
84-
}
97+
return [pscustomobject]@{
98+
SourcePath = $SourceFile.FullName
99+
RelativePath = $relativePath
85100
}
101+
}
102+
103+
function Get-AgenticMirrorSourceFile {
104+
param(
105+
[Parameter(Mandatory)][string]$RootPath,
106+
[Parameter(Mandatory)][string[]]$SourcePathList,
107+
[Parameter(Mandatory)][string[]]$ExcludedPathList
108+
)
86109

87-
foreach ($sourceFile in $sourceFileList) {
88-
$relativePath = Get-AgenticRelativePath -RootPath $RootPath -Path $sourceFile.FullName
89-
if (-not (Test-AgenticPathExcluded -RelativePath $relativePath -ExcludedPathList $ExcludedPathList)) {
90-
[pscustomobject]@{
91-
SourcePath = $sourceFile.FullName
92-
RelativePath = $relativePath
110+
foreach ($sourcePath in $SourcePathList) {
111+
$sourceFileList = @(Get-AgenticSourceFileListForPath -RootPath $RootPath -SourcePath $sourcePath)
112+
foreach ($sourceFile in $sourceFileList) {
113+
$mirrorSourceFile = ConvertTo-AgenticMirrorSourceFile -RootPath $RootPath -SourceFile $sourceFile -ExcludedPathList $ExcludedPathList
114+
if ($null -ne $mirrorSourceFile) {
115+
$mirrorSourceFile
93116
}
94117
}
95118
}

src/private/scaffold/InitializeNovaModuleScaffold.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ function Initialize-NovaModuleScaffold {
2020
}
2121

2222
if ($Answer.EnableGit -eq 'Yes') {
23+
Update-NovaGitIgnore -ProjectRoot $Paths.Project -Confirm:$false
2324
Write-Message 'Initialize Git Repo'
2425
New-InitiateGitRepo -DirectoryPath $Paths.Project
2526
}

0 commit comments

Comments
 (0)