Skip to content
Open
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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@

## [Unreleased]

### Fixed

- `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).

### Tests

- Added idempotency test: a second install run against an already-cloned
repo does not trigger a second `git clone` (#86).
- Added non-git-directory test: confirms a warning is emitted and no
clone is attempted when the target path exists but is not a git repo (#86).

## [0.4.1] - 2026-06-12

### Added
Expand Down Expand Up @@ -127,7 +140,7 @@
### Fixed

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

Check warning on line 143 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 @@ -138,7 +151,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 154 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
6 changes: 5 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,11 @@
$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]."
$GottaInstall = $False
}
elseif ($Version -eq $Branch -or $Version -eq $Commit) {
Comment on lines +135 to +139
Write-Verbose "[$RepoPath] exists and is already at version [$Version]"
if ($PSDependAction -contains 'Test' -and $PSDependAction.count -eq 1) {
return $true
Expand Down
35 changes: 35 additions & 0 deletions Tests/Git.Type.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,39 @@ 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'
}
}
Comment on lines +92 to +95

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 { }
{ & $ScriptPath -Dependency $Dep } | Should -Not -Throw
}
Should -Invoke -CommandName Invoke-ExternalCommand -ModuleName PSDepend -Times 0 -ParameterFilter {
$Arguments -contains 'clone'
}
}
Comment on lines +103 to +111
}
Loading