Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ The `templates/` folder contains ready-to-copy starter files for new repos:

The package also ships bundled agent content under `.agents/**`. During build, the SDK mirrors it into the consuming repository's `.agents/` folder by default so compatible coding agents can discover repository-aware guidance automatically. The SDK also injects a `.gitignore` file into each second-level agent folder with the content `# Ignore all files\n*\n\n# Don't ignore directories, so Git can traverse them\n!*/\n\n# Keep this file\n!.gitignore`, so the copied folder is ignored by Git while keeping the folder structure discoverable.

Repository metadata can also be defined before the SDK import: the package recognizes `PurviewHomepage`, `PurviewProjectUrl`, and `PurviewDocsUrl` for repo/site metadata, which is useful when a package or generated metadata needs to point at a public docs site or project page without hard-coding repo-specific values in each project file.

The mirror is change-aware: file fingerprints and content hashes are recorded in
`.purview/agent-sync.cache` at the repository root, so unchanged content is skipped and repeat builds
touch no files. Every write is staged into a temporary file and renamed into place, and because all
Expand Down Expand Up @@ -481,9 +483,10 @@ Define `PURVIEW_SDK_EXCLUDE_EMBEDDED` only when your build already provides `Mic

## Namespace stripping

Certain suffixes are automatically stripped from `RootNamespace` to avoid awkward namespace names like `Acme.MyProject.Core.Something`:
Certain suffixes are automatically stripped from `RootNamespace` to avoid awkward namespace names like `Acme.MyProject.Core.Something`.

Stripped suffixes: `Core`, `EF`, `Shared`, `ClientShared`, `ServiceDefaults`, and all shared testing project names.
The current built-in stripping set is intentionally broader than the common examples and includes:
`SourceGeneration`, `SourceGenerators`, `SourceGenerator`, `ServiceDefaults`, `Infrastructure`, `Abstractions`, `ClientShared`, `Persistence`, `CodeFixers`, `DataAccess`, `Extensions`, `Generators`, `Analyzers`, `Contracts`, `Framework`, `Utilities`, `AppHost`, `Helpers`, `Library`, `Common`, `Shared`, `Infra`, `Utils`, `Core`, `Data`, `Host`, `Util`, `Lib`, `EF`, plus the known shared and shared-testing project names (`Shared*`, `SharedTesting*`).

### Extensions namespace rule (`PDS0002`)

Expand Down
8 changes: 6 additions & 2 deletions docs/wiki/Assembly-Name-Generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ are evaluated later and win.
Certain suffixes are automatically stripped from `RootNamespace` to avoid awkward namespace names like
`Acme.MyProject.Core.Something`.

Stripped suffixes: `Core`, `EF`, `Shared`, `ClientShared`, `ServiceDefaults`, and all shared and
shared-testing project names.
The built-in stripping set is broader than the common examples and includes:
`SourceGeneration`, `SourceGenerators`, `SourceGenerator`, `ServiceDefaults`, `Infrastructure`,
`Abstractions`, `ClientShared`, `Persistence`, `CodeFixers`, `DataAccess`, `Extensions`,
`Generators`, `Analyzers`, `Contracts`, `Framework`, `Utilities`, `AppHost`, `Helpers`, `Library`,
`Common`, `Shared`, `Infra`, `Utils`, `Core`, `Data`, `Host`, `Util`, `Lib`, `EF`, plus the known
shared and shared-testing project names (`Shared*`, `SharedTesting*`).

See [Project Naming Conventions](Project-Naming-Conventions.md) and
[InternalsVisibleTo](InternalsVisibleTo.md) for related naming behaviour.
15 changes: 15 additions & 0 deletions docs/wiki/Configuration-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ See [Version Detection](Version-Detection.md) for the full resolution rules.
| `DisableGenerateAssemblyInfoClass` | `false` | Set to `true` to disable the generated `AssemblyInfo` helper source. |
| `AutoIncludeUsings` | `true` | Controls SDK-added global usings for `NamespacePrefix` and `RootNamespace`. |

## Repository metadata

The SDK also supports repo/site metadata properties for generated package metadata and docs links. These
values are consumed before the import and are useful when a repository wants a single shared project URL
or docs base URL instead of repeating it per project:

| Property | Default | Description |
| -- | -- | -- |
| `PurviewHomepage` | *(repo-specific)* | Base site URL for the repository or product docs. In this repo it is set to `https://purview.dev/`. |
| `PurviewProjectUrl` | *(repo-specific)* | Public project page URL; usually derived from `PurviewHomepage` plus a project path. |
| `PurviewDocsUrl` | *(repo-specific)* | Public docs URL; often derived from `PurviewHomepage` plus a docs path. |

These values are not mandatory, but they provide a consistent place to keep package metadata and docs
links aligned with the repo's site structure.

## Packable project defaults

For projects where `IsPackable=true`, the SDK provides these defaults **only when the consuming
Expand Down
10 changes: 10 additions & 0 deletions docs/wiki/Project-Type-Detection.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ wiki.
targets. The detected `TestingType` also becomes the baseline test category, while additional categories
remain available to the test suite.

The SDK recognises the following full `TestType` set, in addition to the standard `Unit` and
`Integration` values:
`Acceptance`, `Accessibility`, `Approval`, `Architecture`, `Benchmark`, `BlackBox`, `Capacity`,
`Chaos`, `Compatibility`, `Compliance`, `Component`, `Concurrency`, `Configuration`, `Contract`,
`Deployment`, `E2E`, `EndToEnd`, `Endurance`, `Environment`, `Failover`, `Functional`, `Fuzz`,
`Globalization`, `GrayBox`, `GreyBox`, `Integration`, `Interactive`, `Interoperability`, `Load`,
`Localization`, `Migration`, `Mutation`, `Penetration`, `Performance`, `Property`, `Recovery`,
`Regression`, `Resilience`, `Sanity`, `Scenario`, `Security`, `Smoke`, `Snapshot`, `Soak`, `Spike`,
`Stress`, `System`, `Threat`, `Unit`, `Upgrade`, `Usability`, `Visual`, and `WhiteBox`.

## What each type gets

### Test projects (`IsTestProject=true`)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "purview-build-sdk",
"version": "1.0.2.1",
"version": "1.0.2.2",
"homepage": "https://purview.dev/projects/build-sdk/",
"bugs": {
"url": "https://github.com/purview-dev/build-sdk/issues"
Expand Down
5 changes: 5 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
<!-- Dog fooding the Sdk... -->
<Import Project="$(MSBuildThisFileDirectory)src/BuildSdk/Sdk/Sdk.props" />

<ItemGroup>
<NamespaceRemoveSuffix Remove="CodeFixers" />
<NamespaceRemoveSuffix Remove="Analyzers" />
</ItemGroup>

<PropertyGroup Label="Purview site URL metadata">
<PurviewHomepage>https://purview.dev/</PurviewHomepage>
<PurviewProjectUrl>$(PurviewHomepage)projects/build-sdk/</PurviewProjectUrl>
Expand Down
90 changes: 79 additions & 11 deletions src/src/BuildSdk/Sdk/Sdk.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,113 @@
</ItemGroup>

<!-- =====================================================================
NAMESPACE SUFFIXES STRIPPED FROM RootNamespace
===================================================================== -->
NAMESPACE SUFFIXES STRIPPED FROM RootNamespace
Ordered longest-first: overlapping entries (Shared/ClientShared,
Infra/Infrastructure, Data/DataAccess, Lib/Library) must match the
longest candidate, or a single-pass strip mangles them.
===================================================================== -->
<ItemGroup Label="Defining Namespace Suffixes to Remove from RootNamespace">
<NamespaceRemoveSuffix Include="@(SharedProjectName)" />
<NamespaceRemoveSuffix Include="@(SharedTestingProjectName)" />

<!-- 16+ -->
<NamespaceRemoveSuffix Include="SourceGeneration" />
<NamespaceRemoveSuffix Include="SourceGenerators" />
<NamespaceRemoveSuffix Include="SourceGenerator" />
<NamespaceRemoveSuffix Include="ServiceDefaults" />
<NamespaceRemoveSuffix Include="Infrastructure" />

<!-- 10-12 -->
<NamespaceRemoveSuffix Include="Abstractions" />
<NamespaceRemoveSuffix Include="ClientShared" />
<NamespaceRemoveSuffix Include="Persistence" />
<NamespaceRemoveSuffix Include="CodeFixers" />
<NamespaceRemoveSuffix Include="DataAccess" />
<NamespaceRemoveSuffix Include="Extensions" />
<NamespaceRemoveSuffix Include="Generators" />

<!-- 9 -->
<NamespaceRemoveSuffix Include="Analyzers" />
<NamespaceRemoveSuffix Include="Contracts" />
<NamespaceRemoveSuffix Include="Framework" />
<NamespaceRemoveSuffix Include="Utilities" />

<!-- 6-7 -->
<NamespaceRemoveSuffix Include="AppHost" />
<NamespaceRemoveSuffix Include="Helpers" />
<NamespaceRemoveSuffix Include="Library" />
<NamespaceRemoveSuffix Include="Common" />
<NamespaceRemoveSuffix Include="Shared" />

<!-- 2-5 -->
<NamespaceRemoveSuffix Include="Infra" />
<NamespaceRemoveSuffix Include="Utils" />
<NamespaceRemoveSuffix Include="Core" />
<NamespaceRemoveSuffix Include="Data" />
<NamespaceRemoveSuffix Include="Host" />
<NamespaceRemoveSuffix Include="Util" />
<NamespaceRemoveSuffix Include="Lib" />
<NamespaceRemoveSuffix Include="EF" />
<NamespaceRemoveSuffix Include="Shared" />
<NamespaceRemoveSuffix Include="ClientShared" />
<NamespaceRemoveSuffix Include="ServiceDefaults" />
</ItemGroup>

<!-- =====================================================================
TESTING TYPES
Controls InternalsVisibleTo generation and TestingType detection.
===================================================================== -->
TESTING TYPES
Controls InternalsVisibleTo generation and TestingType detection.
Detection must use longest-match, not declaration order.
===================================================================== -->
<ItemGroup Label="Defining Testing Types">
<TestType Include="Accessibility" />
<TestType Include="Acceptance" />
<TestType Include="Accessibility" />
<TestType Include="Approval" />
<TestType Include="Architecture" />
<TestType Include="Benchmark" />
<TestType Include="BlackBox" />
<TestType Include="Capacity" />
<TestType Include="Chaos" />
<TestType Include="Compatibility" />
<TestType Include="Compliance" />
<TestType Include="Component" />
<TestType Include="Concurrency" />
<TestType Include="Configuration" />
<TestType Include="Contract" />
<TestType Include="Deployment" />
<TestType Include="E2E" />
<TestType Include="EndToEnd" />
<TestType Include="Endurance" />
<TestType Include="Environment" />
<TestType Include="Failover" />
<TestType Include="Functional" />
<TestType Include="Interactive" />
<TestType Include="Fuzz" />
<TestType Include="Globalization" />
<TestType Include="GrayBox" />
<TestType Include="GreyBox" />
<TestType Include="Integration" />
<TestType Include="Interactive" />
<TestType Include="Interoperability" />
<TestType Include="Load" />
<TestType Include="Localization" />
<TestType Include="Migration" />
<TestType Include="Mutation" />
<TestType Include="Penetration" />
<TestType Include="Performance" />
<TestType Include="Property" />
<TestType Include="Recovery" />
<TestType Include="Regression" />
<TestType Include="Security" />
<TestType Include="Resilience" />
<TestType Include="Sanity" />
<TestType Include="Scenario" />
<TestType Include="Security" />
<TestType Include="Smoke" />
<TestType Include="Snapshot" />
<TestType Include="Soak" />
<TestType Include="Spike" />
<TestType Include="Stress" />
<TestType Include="System" />
<TestType Include="Threat" />
<TestType Include="Unit" />
<TestType Include="Upgrade" />
<TestType Include="Usability" />
<TestType Include="Visual" />
<TestType Include="WhiteBox" />
</ItemGroup>

Expand Down
Loading