Development environment for testing remote custom hk hooks. A python script serves pkl packages locally, allowing test package configurations like a remote registry.
.
├── custom-package/ # Custom Pkl package source code
│ ├── Config.pkl
│ └── PklProject
├── scripts/ # Utility scripts
│ └── ggshield.sh
├── server/ # Local HTTPS package server
│ └── server.py
├── target/ # Build output directory
├── hk.pkl # Hook configuration that imports the custom package
└── mise.toml
# Generate certificate + private key in one file
openssl req -x509 -newkey rsa:4096 -keyout server/localhost.pem \
-out server/localhost.pem -days 365 -nodes -subj '/CN=localhost'
# Extract the certificate portion only (without the private key)
openssl x509 -in server/localhost.pem -out server/localhost-cert.pem# Create Pkl CA certificates directory
mkdir -p ~/.pkl/cacerts
# Copy your certificate
cp server/localhost-cert.pem ~/.pkl/cacerts/
# Append system CAs (without this, Pkl can't download public packages)
cat /etc/ssl/certs/ca-certificates.crt >> ~/.pkl/cacerts/localhost-cert.pemcd custom-package/ && pkl project package --output-path ../target --skip-publish-checkNote: Pkl caches packages. You must either:
- Increment the version (in custom-package/PklProject and then hk.pkl)
- Clear the cache:
rm -rf ~/.pkl/cache && rm -rf ~/.cache/hk/
python3 server/server.pymise trust
mise install
hk install$ hk run pre-commit
hk 1.20.0 by @jdx – pre-commit – check [==============] 3/3
✔ files - Fetching modified files (13 files)
✔ ggshield
✔ prettiercustom-config/Config.pkl successfully overrides the default project configuration to provide an evolutive secret detection mechanism to multiple repositories, however :
-
Neither
hknorpklprovides a mechanism to pass authentication tokens when fetching packages from private registries. -
Pkl packages can include script files (like
ggshield.shif moved tocustom-package/), but these scripts cannot be executed because they are trapped in ZIP archives:~/.pkl/cache/package-2/localhost(3a)8443/[email protected]/[email protected]
Obviously we can:
- Call commands directly without wrapper scripts:
check = "ggshield secret scan pre-commit". But we lose configurability. - Commit scripts to each project repository (like here). But it defeats the purpose of centralized configuration.