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
15 changes: 12 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,24 @@

### Added

- `FileDownload` is now supported on all platforms (`windows`, `core`, `macos`, `linux`); there was no Windows-only code blocking this (#98).
- `FileDownload` relative `Target` paths are now rooted against `$PWD` before resolution, matching the intuitive expectation of callers (#49).
- `FileDownload` is now supported on all platforms (`windows`, `core`,
`macos`, `linux`); there was no Windows-only code blocking this (#98).
- `FileDownload` relative `Target` paths are now rooted against `$PWD`
before resolution, matching the intuitive expectation of callers (#49).

### Fixed

- `Get-Dependency -InputObject` no longer mutates the caller's hashtable:
`PSDependOptions` is now preserved after the call, so a second invocation
with the same object still honors global options such as `Target` (#35).
- `FileDownload` no longer misidentifies a directory-like `Target` (no file extension, or trailing slash) as a full file path when its parent happens to exist; the handler now uses a file-extension heuristic to distinguish file targets from container targets and creates the directory when it does not yet exist (#49).
- `FileDownload` no longer misidentifies a directory-like `Target` (no
file extension, or trailing slash) as a full file path when its parent
happens to exist; the handler now uses a file-extension heuristic to
distinguish file targets from container targets and creates the directory
when it does not yet exist (#49).
- `Git` handler no longer silently ignores a pre-existing directory at
the clone target that is not a valid git repository; it now emits a
`Write-Warning` so the user knows why the install was skipped (#86).

## [0.4.1] - 2026-06-12

Expand Down Expand Up @@ -137,7 +146,7 @@
### Fixed

- `Get-Dependency` operator-precedence bug when `DependencyType` is
set inside `PSDependOptions`: parenthesization was incorrect, so the

Check warning on line 149 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (parenthesization)
global default failed to apply to dependencies without an explicit
type (#131, #173).
- `Find-PSDependLocally` now consults *all* installed versions of a
Expand All @@ -148,7 +157,7 @@
passing it to `Import-Module`, preventing failures when prerelease
segments or `vX.Y.Z` tags appear in the resolved version (#140).
- `Chocolatey` install path now passes `--yes` to `choco install`
(previously the script contained the typo `--yess`), so installs

Check warning on line 160 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (yess) Suggestions: (yes, yeas, yens, yeps, yest)
no longer hang waiting on confirmation, and the surrounding code
was tidied for readability (#174).
- `Git` handler now uses the full `Dependency.Target` path when the
Expand Down
9 changes: 8 additions & 1 deletion PSDepend/PSDependScripts/Git.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

.EXAMPLE
@{
'buildhelpers' = @{

Check warning on line 34 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (buildhelpers)
Name = 'https://github.com/RamblingCookieMonster/BuildHelpers.git'
Version = 'd32a9495c39046c851ceccfb7b1a85b17d5be051'
Target = 'C:\git'
Expand All @@ -39,7 +39,7 @@
}

# Full syntax
# DependencyName (key) uses (unique) name 'buildhelpers'

Check warning on line 42 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (buildhelpers)
# Override DependencyName as URL the name https://github.com/RamblingCookieMonster/BuildHelpers.git
# Specify a commit to checkout (version)
# Clone in C:\git
Expand All @@ -52,15 +52,15 @@
}

# Simple syntax
# First example shows cloning PSDeploy from ramblingcookiemonster's GitHub repo

Check warning on line 55 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (ramblingcookiemonster's)
# Second example shows clonging BuildHelpers from jdoe's internal GitLab account and checking out a specific commit

Check warning on line 56 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (jdoe's) Suggestions: (joe's, Joe's, doe's, Doe's, jodi's)

Check warning on line 56 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (clonging) Suggestions: (cloning, clanging, clinging, clogging, clonking)
# Both are cloned to the current path (e.g. .\<repo name>)
# This syntax assumes git as a source. The right hand side is the version (branch, commit, tags/<tag name>, etc.)
#>
[cmdletbinding()]

Check warning on line 60 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (cmdletbinding)
param(
[PSTypeName('PSDepend.Dependency')]
[psobject[]]$Dependency,

Check warning on line 63 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (psobject) Suggestions: (isobject, isObject, project, object, subject)

[switch]$Force,

Expand All @@ -84,7 +84,7 @@
if ($Name -match "^[a-zA-Z0-9]+/[a-zA-Z0-9_-]+$") {
$Name = "https://github.com/$Name.git"
}
$GitName = $Name.trimend('/').split('/')[-1] -replace "\.git$", ''

Check warning on line 87 in PSDepend/PSDependScripts/Git.ps1

View workflow job for this annotation

GitHub Actions / Continuous Integration / Run Linters

Unknown word (trimend) Suggestions: (trined, timed, trend, tried, triced)
if ($Dependency.Target -and ($Target = (Get-Item $Dependency.Target -ErrorAction SilentlyContinue).FullName)) {
Write-Debug "Target resolved to $Target"
}
Expand Down Expand Up @@ -132,7 +132,14 @@
$Branch = Invoke-ExternalCommand git -Arguments (Write-Output rev-parse --abbrev-ref HEAD) -Passthru
$Commit = Invoke-ExternalCommand git -Arguments (Write-Output rev-parse HEAD) -Passthru
Pop-Location
if ($Version -eq $Branch -or $Version -eq $Commit) {
if (-not $Branch) {
Write-Warning "[$RepoPath] exists but does not appear to be a valid git repository. Skipping [$DependencyName]."
if ($PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) {
return $false
}
$GottaInstall = $False
}
elseif ($Version -eq $Branch -or $Version -eq $Commit) {
Write-Verbose "[$RepoPath] exists and is already at version [$Version]"
if ($PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) {
return $true
Expand Down
42 changes: 42 additions & 0 deletions Tests/Git.Type.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,46 @@ Describe 'Git script' {
$result | Should -Be $false
Should -Invoke -CommandName Invoke-ExternalCommand -ModuleName PSDepend -Times 0
}

It 'Does not clone again when repo already exists at the correct version (idempotency)' {
$targetDir = (New-Item 'TestDrive:/git-idempotent' -ItemType Directory -Force).FullName
# Pre-create the repo directory as if a prior run cloned it
$null = New-Item (Join-Path $targetDir 'repo') -ItemType Directory -Force
$dep = New-PSDependFixture -DependencyName 'https://example.com/user/repo.git' -DependencyType 'Git' -Version 'main' -Target $targetDir

InModuleScope PSDepend -Parameters @{ Dep = $dep; ScriptPath = $script:ScriptPath } {
# rev-parse returns the branch name matching Version
Mock Invoke-ExternalCommand {
if ($Arguments -contains '--abbrev-ref') { return 'main' }
if ($Arguments -notcontains 'clone' -and $Arguments -notcontains '--abbrev-ref') { return 'abc1234' }
}
& $ScriptPath -Dependency $Dep
}
Should -Invoke -CommandName Invoke-ExternalCommand -ModuleName PSDepend -Times 0 -ParameterFilter {
$Arguments -contains 'clone'
}
Should -Invoke -CommandName Invoke-ExternalCommand -ModuleName PSDepend -Times 0 -ParameterFilter {
$Arguments -contains 'checkout'
}
}

It 'Emits a warning and skips install when the repo path exists but is not a git repository' {
$targetDir = (New-Item 'TestDrive:/git-nongit' -ItemType Directory -Force).FullName
# Pre-create the directory but leave it empty (not a git repo)
$null = New-Item (Join-Path $targetDir 'repo') -ItemType Directory -Force
$dep = New-PSDependFixture -DependencyName 'https://example.com/user/repo.git' -DependencyType 'Git' -Version 'main' -Target $targetDir

InModuleScope PSDepend -Parameters @{ Dep = $dep; ScriptPath = $script:ScriptPath } {
# rev-parse returns nothing (non-git directory)
Mock Invoke-ExternalCommand { }
Mock Write-Warning { }
& $ScriptPath -Dependency $Dep
}
Should -Invoke -CommandName Write-Warning -ModuleName PSDepend -Times 1 -ParameterFilter {
$Message -like '*does not appear to be a valid git repository*'
}
Should -Invoke -CommandName Invoke-ExternalCommand -ModuleName PSDepend -Times 0 -ParameterFilter {
$Arguments -contains 'clone'
}
}
}
Loading