Skip to content

Commit ec77836

Browse files
committed
Closes #1 & README follow dotfiles repo structure & precommit hooks replaced from dotfiles
1 parent 20b846a commit ec77836

File tree

7 files changed

+136
-10
lines changed

7 files changed

+136
-10
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
.gitignore text eol=lf
1111
.gitattributes text eol=lf
1212
LICENSE text eol=lf
13+
tools/hooks/* text eol=lf

GitAliases.Extras.psm1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,11 @@ function Register-GitAliasCompletion {
400400

401401
# Reconstruct the command line as if 'git <subcommand>' was typed
402402
$line = $commandAst.Extent.Text
403+
# CommandAst extent drops trailing whitespace, but completion context
404+
# depends on it (e.g. "gsw " vs "gsw"). Restore it using cursor offset.
405+
if ($cursorPosition -gt $line.Length) {
406+
$line += (' ' * ($cursorPosition - $line.Length))
407+
}
403408
$gitLine = $line -replace "^$commandName", "git $subCommand"
404409
$offset = ("git $subCommand").Length - $commandName.Length
405410
$gitCursorPosition = $cursorPosition + $offset

README.md

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,66 @@
22

33
Custom PowerShell git aliases and tab completion helpers on top of `posh-git` and `git-aliases`.
44

5-
## Install from PowerShell Gallery
5+
## Module installation
6+
7+
Install from PowerShell Gallery:
68

79
```powershell
810
Install-Module GitAliases.Extras -Scope CurrentUser
911
Import-Module GitAliases.Extras
1012
```
1113

12-
## Install from source
14+
Install from source:
1315

1416
```powershell
1517
git clone https://github.com/PhysShell/GitAliases.Extras.git "$HOME\Documents\PowerShell\Modules\GitAliases.Extras"
1618
Import-Module GitAliases.Extras
1719
```
1820

19-
## Prerequisites
20-
21-
- `git`
22-
- `posh-git`
23-
- `git-aliases`
24-
25-
Example bootstrap:
21+
Install dependencies:
2622

2723
```powershell
2824
Install-Module posh-git -Scope CurrentUser -Force
2925
Install-Module git-aliases -Scope CurrentUser -Force
3026
Install-Module GitAliases.Extras -Scope CurrentUser -Force
3127
```
3228

33-
## Local quality checks
29+
## Quality checks
30+
31+
Run both lint and tests:
3432

3533
```powershell
3634
.\tools\ci.ps1
3735
```
3836

37+
Run only lint:
38+
39+
```powershell
40+
.\tools\ci.ps1 -LintOnly
41+
```
42+
43+
Run only tests:
44+
45+
```powershell
46+
.\tools\ci.ps1 -TestOnly
47+
```
48+
49+
## Commit hooks
50+
51+
Install local git hooks:
52+
53+
```powershell
54+
.\tools\install-hooks.ps1
55+
```
56+
57+
Installed hooks:
58+
- `pre-commit` (lightweight no-op)
59+
- `commit-msg` (runs `tools/ci.ps1`)
60+
61+
Checks are skipped when:
62+
- commit message contains `[skip precommit hook]` or `[skip pch]`
63+
- there are no working tree changes (for example, `git commit --allow-empty ...`)
64+
3965
## Publishing
4066

4167
This repository includes:
@@ -49,6 +75,14 @@ To publish from CI:
4975
2. Bump `ModuleVersion` in `GitAliases.Extras.psd1`.
5076
3. Push a tag `v<ModuleVersion>` (for example, `v0.1.0`) or run the publish workflow manually.
5177

78+
## What CI checks
79+
80+
- `PSScriptAnalyzer` linting with `PSScriptAnalyzerSettings.psd1`
81+
- `Pester` tests in `tests\`
82+
- GitHub Actions matrix on:
83+
- Windows PowerShell
84+
- PowerShell 7
85+
5286
## License
5387

5488
WTFPL. See `LICENSE`.

tests/GitAliases.Extras.Module.Tests.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,11 @@ Describe 'GitAliases.Extras module exports' {
4747
Get-Command Register-GitAliasCompletion -ErrorAction Stop | Should -Not -BeNullOrEmpty
4848
}
4949
}
50+
51+
Describe 'GitAliases.Extras tooling' {
52+
It 'includes install-hooks and hook templates' {
53+
(Test-Path -LiteralPath (Join-Path $script:RepoRoot 'tools\install-hooks.ps1')) | Should -BeTrue
54+
(Test-Path -LiteralPath (Join-Path $script:RepoRoot 'tools\hooks\pre-commit')) | Should -BeTrue
55+
(Test-Path -LiteralPath (Join-Path $script:RepoRoot 'tools\hooks\commit-msg')) | Should -BeTrue
56+
}
57+
}

tools/hooks/commit-msg

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/sh
2+
set -e
3+
4+
message_file="$1"
5+
if [ -z "$message_file" ] || [ ! -f "$message_file" ]; then
6+
echo "commit-msg: missing commit message file"
7+
exit 1
8+
fi
9+
10+
# Allow opt-out tokens in the commit message.
11+
if grep -Eiq '\[skip[[:space:]]+precommit[[:space:]]+hook\]|\[skip[[:space:]]+pch\]' "$message_file"; then
12+
echo "commit-msg: checks skipped by commit message tag"
13+
exit 0
14+
fi
15+
16+
# Skip expensive checks for no-op commits (for example, --allow-empty with no file changes).
17+
if [ -z "$(git status --porcelain)" ]; then
18+
exit 0
19+
fi
20+
21+
# Prevent hook-provided Git env vars from leaking into nested temp-repo tests.
22+
unset GIT_DIR
23+
unset GIT_WORK_TREE
24+
unset GIT_INDEX_FILE
25+
unset GIT_OBJECT_DIRECTORY
26+
unset GIT_ALTERNATE_OBJECT_DIRECTORIES
27+
unset GIT_COMMON_DIR
28+
unset GIT_PREFIX
29+
30+
if command -v pwsh >/dev/null 2>&1; then
31+
pwsh -NoProfile -ExecutionPolicy Bypass -File tools/ci.ps1
32+
elif command -v powershell >/dev/null 2>&1; then
33+
powershell -NoProfile -ExecutionPolicy Bypass -File tools/ci.ps1
34+
else
35+
echo "commit-msg: neither pwsh nor powershell is available"
36+
exit 1
37+
fi

tools/hooks/pre-commit

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/sh
2+
set -e
3+
4+
# Validation runs in commit-msg, where Git provides the commit message file.
5+
# Keep pre-commit lightweight and deterministic.
6+
exit 0

tools/install-hooks.ps1

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[CmdletBinding()]
2+
param()
3+
4+
$ErrorActionPreference = 'Stop'
5+
Set-StrictMode -Version Latest
6+
7+
[string]$root = Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..') |
8+
Select-Object -ExpandProperty Path -First 1
9+
10+
$gitDir = (git -C $root rev-parse --git-dir 2>$null)
11+
if (-not $gitDir) {
12+
throw "Not a git repository: $root"
13+
}
14+
15+
$gitDir = $gitDir.Trim()
16+
$hookDir = if ([IO.Path]::IsPathRooted($gitDir)) {
17+
Join-Path $gitDir 'hooks'
18+
} else {
19+
Join-Path $root $gitDir 'hooks'
20+
}
21+
22+
New-Item -ItemType Directory -Path $hookDir -Force | Out-Null
23+
24+
$hookNames = @('pre-commit', 'commit-msg')
25+
foreach ($hookName in $hookNames) {
26+
$source = Join-Path $root ("tools\hooks\{0}" -f $hookName)
27+
$destination = Join-Path $hookDir $hookName
28+
29+
if (-not (Test-Path -LiteralPath $source)) {
30+
throw "Hook source not found: $source"
31+
}
32+
33+
Copy-Item -Path $source -Destination $destination -Force
34+
Write-Host ("Installed {0} hook: {1}" -f $hookName, $destination)
35+
}

0 commit comments

Comments
 (0)