Skip to content

Commit 57085b3

Browse files
authored
Merge branch 'main' into RSATDependencies
2 parents cf31ed4 + b9891c8 commit 57085b3

79 files changed

Lines changed: 5088 additions & 1907 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/FUNDING.yml

Lines changed: 0 additions & 1 deletion
This file was deleted.

.github/workflows/ci.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: CI
2+
on:
3+
push:
4+
branches: [main]
5+
paths:
6+
- "PSDepend/**"
7+
- "Tests/**"
8+
- "build.ps1"
9+
- "psakeFile.ps1"
10+
- "requirements.psd1"
11+
pull_request:
12+
paths:
13+
- "PSDepend/**"
14+
- "Tests/**"
15+
- "build.ps1"
16+
- "psakeFile.ps1"
17+
- "requirements.psd1"
18+
workflow_dispatch:
19+
20+
jobs:
21+
test_pwsh:
22+
name: Test (${{ matrix.os }})
23+
runs-on: ${{ matrix.os }}
24+
permissions:
25+
contents: read
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
os: [ubuntu-latest, windows-latest, macOS-latest]
30+
steps:
31+
- uses: actions/checkout@v6
32+
- name: Bootstrap
33+
shell: pwsh
34+
run: ./build.ps1 -Bootstrap -Task Init
35+
- name: Test
36+
shell: pwsh
37+
run: ./build.ps1 -Task Test
38+
- name: Upload Test Results
39+
if: always()
40+
uses: actions/upload-artifact@v7
41+
with:
42+
name: testResults-${{ matrix.os }}
43+
path: ./Tests/out/testResults.xml
44+
45+
test_ps51:
46+
name: Test (Windows PowerShell 5.1)
47+
runs-on: windows-latest
48+
permissions:
49+
contents: read
50+
steps:
51+
- uses: actions/checkout@v6
52+
- name: Bootstrap
53+
shell: powershell
54+
run: ./build.ps1 -Bootstrap -Task Init
55+
- name: Test
56+
shell: powershell
57+
run: ./build.ps1 -Task Test
58+
- name: Upload Test Results
59+
if: always()
60+
uses: actions/upload-artifact@v7
61+
with:
62+
name: testResults-ps51
63+
path: ./Tests/out/testResults.xml
64+
publish-test-results:
65+
name: Publish Test Results
66+
needs:
67+
- test_pwsh
68+
- test_ps51
69+
runs-on: ubuntu-latest
70+
permissions:
71+
checks: write
72+
pull-requests: write
73+
if: ${{ !cancelled() }}
74+
steps:
75+
- uses: actions/download-artifact@v8
76+
with:
77+
path: artifacts
78+
- uses: EnricoMi/publish-unit-test-result-action@v2
79+
with:
80+
files: artifacts/**/*.xml

.github/workflows/stale.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Mark stale issues and PRs
2+
3+
on:
4+
schedule:
5+
- cron: '0 8 * * *'
6+
workflow_dispatch:
7+
8+
jobs:
9+
stale:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/stale@v9
13+
with:
14+
stale-issue-message: 'This issue has had no activity for 60 days. It will be closed in 30 days unless there is new activity or a maintainer removes the stale label.'
15+
stale-pr-message: 'This PR has had no activity for 60 days. It will be closed in 30 days unless there is new activity or a maintainer removes the stale label.'
16+
close-issue-message: 'Closing due to inactivity. Please re-open if this is still relevant against the current version.'
17+
days-before-stale: 60
18+
days-before-close: 30
19+
stale-issue-label: 'status: stale'
20+
stale-pr-label: 'status: stale'
21+
exempt-issue-labels: 'priority: high'

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
nuget.exe
1+
nuget.exe
2+
Output/**
3+
Tests/Output/**
4+
Tests/out/**

.vscode/settings.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
"powershell.codeFormatting.ignoreOneLineBlock": false,
44
"powershell.codeFormatting.whitespaceAfterSeparator": false,
55
"powershell.codeFormatting.whitespaceAroundOperator": false,
6-
"powershell.codeFormatting.whitespaceBeforeOpenParen": false
7-
}
6+
"powershell.codeFormatting.whitespaceBeforeOpenParen": false,
7+
"powershell.codeFormatting.preset": "OTBS",
8+
"powershell.codeFormatting.trimWhitespaceAroundPipe": true
9+
}

CLAUDE.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# CLAUDE.md
2+
3+
## Build and Test
4+
5+
Bootstrap: `.\build.ps1 -Bootstrap`
6+
7+
Always run `.\build.ps1 StageFiles` before running tests — tests import from `Output\`, not source.
8+
9+
## Architecture
10+
11+
No compilation; files are staged verbatim to `Output\` — do not edit files under `Output\`.
12+
13+
### Extending with new dependency types
14+
15+
Two files must be updated together:
16+
17+
1. **`PSDepend/PSDependScripts/<Type>.ps1`** — handler script. Must include comment-based help and a `PSDependAction` parameter accepting `Install`, `Test`, and `Import` values.
18+
2. **`PSDepend/PSDependMap.psd1`** — registers the type, maps it to the script, and sets `Supports` to control platform filtering (`windows`, `core`, `macos`, `linux`).
19+
20+
See `Git.ps1` and `PSGalleryModule.ps1` as reference implementations.
21+
22+
`PSDepend/PSDepend.Config` — path variables (`NuGetPath`, etc.) resolved at module load.

CONTEXT.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# PSDepend
2+
3+
A PowerShell dependency handler that resolves, installs, imports, and tests dependencies declared in `.psd1` files using a pluggable set of DependencyScripts.
4+
5+
## Language
6+
7+
**Dependency**:
8+
The unit of work — a named, versioned item to be resolved, with a DependencyType, Target, Tags, and optional Prerequisites.
9+
_Avoid_: package, module, requirement
10+
11+
**DependencyFile**:
12+
A `.psd1` file that declares one or more Dependencies. Filename is arbitrary; `requirements.psd1` is conventional, not canonical.
13+
_Avoid_: requirements file, depend file, manifest
14+
15+
**DependencyType**:
16+
The registered identifier that selects which DependencyScript handles a Dependency (e.g., `PSGalleryModule`, `Git`, `Chocolatey`).
17+
_Avoid_: type, provider, handler type
18+
19+
**DependencyScript**:
20+
A `PSDependScripts/<Type>.ps1` file that implements a DependencyType. Receives a typed Dependency object and a set of PSDependAction flags.
21+
_Avoid_: handler, plugin, provider
22+
23+
**PSDependAction**:
24+
A set of flags (`Install`, `Test`, `Import`) passed to a DependencyScript. Flags are combinable; DependencyScripts must handle each valid combination.
25+
_Avoid_: mode, command, operation
26+
27+
**Target**:
28+
A Dependency field with dual semantics: a scope keyword (`AllUsers`, `CurrentUser`) or a filesystem path. DependencyScripts branch explicitly on which it is.
29+
_Avoid_: destination, scope, path (use Target regardless of which semantic applies)
30+
31+
**PSDependOptions**:
32+
A reserved key in a DependencyFile that sets default field values applied to all Dependencies in that file.
33+
_Avoid_: defaults, global options, file options
34+
35+
**Prerequisite**:
36+
A declared ordering constraint between Dependencies. Expressed via the `DependsOn` field; resolved into topological execution order before dispatch.
37+
_Avoid_: dependency (to avoid confusion with the Dependency concept), requirement
38+
39+
**Tag**:
40+
A label on a Dependency that controls inclusion when `Invoke-PSDepend` is called with `-Tags`.
41+
_Avoid_: filter, category, label
42+
43+
## Relationships
44+
45+
- A **DependencyFile** contains one or more **Dependencies** and at most one **PSDependOptions** block
46+
- A **Dependency** has exactly one **DependencyType**, which selects exactly one **DependencyScript**
47+
- A **Dependency** may declare zero or more **Prerequisites** (other Dependencies that must resolve first)
48+
- A **Dependency** may carry zero or more **Tags**
49+
- A **DependencyScript** receives a **Dependency** and a set of **PSDependAction** flags on each invocation
50+
- **Target** is a field on a **Dependency** interpreted differently by each **DependencyScript**
51+
52+
## Example dialogue
53+
54+
> **Dev:** "Should I add the new module as a dependency or a requirement?"
55+
> **Domain expert:** "It's a **Dependency** — declared in a **DependencyFile** with `DependencyType = 'PSGalleryModule'`."
56+
57+
> **Dev:** "Where does it get installed — do I set the path or the scope?"
58+
> **Domain expert:** "Both are **Target**. If you want `CurrentUser`, set `Target = 'CurrentUser'`. If you want a specific folder, set `Target = 'C:\MyModules'`. The **DependencyScript** branches on which one it sees."
59+
60+
> **Dev:** "I need psake to install before PowerShellBuild. How do I express that?"
61+
> **Domain expert:** "Declare a **Prerequisite** on PowerShellBuild: `DependsOn = 'psake'`. The engine resolves all **Prerequisites** into topological order before dispatching any **DependencyScript**."
62+
63+
## Flagged ambiguities
64+
65+
- "dependency" collides with **Prerequisite** in natural speech ("psake is a dependency of PowerShellBuild") — resolved: use **Prerequisite** for the ordering relationship, **Dependency** only for a declared entry in a DependencyFile.
66+
- "handler" was used in early CLAUDE.md — resolved: canonical term is **DependencyScript**.

Examples/HowDoI.md

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# How Do I
22

3-
Rather than scour the documentation, which may or may not be scenario focused, here is a quick list of common scenarios and recipes.
3+
Common scenarios and recipes for working with PSDepend.
44

55
## Specify global defaults
66

7-
You can use the special PSDependOptions node for default options:
7+
Use the special `PSDependOptions` node to set defaults that apply to all dependencies in the file:
88

99
```powershell
1010
@{
@@ -13,29 +13,29 @@ You can use the special PSDependOptions node for default options:
1313
DependencyType = 'PSGalleryNuget'
1414
}
1515
16-
'PSDeploy' = 'latest'
17-
'BuildHelpers' = 'latest'
18-
'Pester' = 'latest'
19-
'InvokeBuild' = 'latest'
16+
'PSDeploy' = 'latest'
17+
'BuildHelpers' = 'latest'
18+
'Pester' = 'latest'
19+
'InvokeBuild' = 'latest'
2020
}
2121
```
2222

23-
This downloads any dependency without an explicit override to `C:\MyProject`, using PSGalleryNuget
23+
All dependencies without an explicit override will be downloaded to `C:\MyProject` using `PSGalleryNuget`.
2424

25-
You can specify the following in PSDependOptions:
25+
The following properties can be set in `PSDependOptions`:
2626

27-
* Parameters
28-
* Source
29-
* Target
30-
* AddToPath
31-
* Tags
32-
* DependsOn
33-
* PreScripts
34-
* PostScripts
27+
- `Parameters`
28+
- `Source`
29+
- `Target`
30+
- `AddToPath`
31+
- `Tags`
32+
- `DependsOn`
33+
- `PreScripts`
34+
- `PostScripts`
3535

36-
## Specify global defaults, with overrides
36+
## Override a global default for specific dependencies
3737

38-
You can override global defaults:
38+
Individual dependencies can override any value set in `PSDependOptions`:
3939

4040
```powershell
4141
@{
@@ -44,7 +44,7 @@ You can override global defaults:
4444
DependencyType = 'PSGalleryNuget'
4545
}
4646
47-
'PSDeploy' = 'latest'
47+
'PSDeploy' = 'latest'
4848
'BuildHelpers' = 'latest'
4949
'Pester' = @{
5050
Target = 'C:\sc'
@@ -53,43 +53,34 @@ You can override global defaults:
5353
}
5454
```
5555

56-
In this example, all modules are downloaded to `C:\MyProject`, apart from Pester, which has an override.
57-
58-
## Specify one target for all dependencies
56+
All modules install to `C:\MyProject` except `Pester`, which installs to `C:\sc`.
5957

60-
You can certainly set a target on every single dependency, or:
58+
## Set a single target for all dependencies
6159

6260
```powershell
6361
@{
6462
PSDependOptions = @{
65-
Target = 'C:\MyTarget' # <<<<<<<
63+
Target = 'C:\MyTarget'
6664
}
6765
6866
PSDeploy = 'latest'
69-
'darkoperator/ADAudit' = 'dev'
67+
'PowerShellOrg/PSDepend' = 'main'
7068
}
7169
```
7270

73-
Just specify a target under PSDependOptions, this will be used as the default target unless you override it.
74-
75-
## Specify one target for most dependencies
76-
77-
If you want to specify one target for most dependencies, with a few exceptions:
71+
## Set a default target with per-dependency overrides
7872

7973
```powershell
8074
@{
8175
PSDependOptions = @{
82-
Target = 'C:\MyTarget' # <<<<<<<
76+
Target = 'C:\MyTarget'
8377
}
8478
85-
PSDeploy = 'latest'
86-
PSSlack = 'latest'
79+
PSDeploy = 'latest'
80+
PSSlack = 'latest'
8781
PSJira = @{
8882
Target = 'C:\OtherTarget'
8983
}
90-
'darkoperator/ADAudit' = 'dev'
84+
'PowerShellOrg/PSDepend' = 'main'
9185
}
9286
```
93-
94-
95-

0 commit comments

Comments
 (0)