blob: 041b676f600e1e837b2ba8e308cc10849db30cc5 [file] [edit]
#!/usr/bin/env node
/**
*
* Copyright (c) 2020 Silicon Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Generates ~/.config/husky/init.sh so that GUI git clients (Sourcetree,
* Tower, GitHub Desktop, etc.) can find node/npx when running pre-commit
* hooks. Husky v9 sources that file automatically before every hook.
*
* Uses `which node` to locate the stable symlink path of the node binary
* (e.g. /opt/homebrew/opt/node@24/bin) rather than process.execPath, which
* on Homebrew resolves to a versioned Cellar path that breaks on patch
* upgrades. Falls back to process.execPath when `which` is unavailable.
*
* Skips write when the file already exists so manual customisations are
* preserved. Skips entirely in CI environments where hooks do not run.
*/
'use strict'
const fs = require('fs')
const path = require('path')
const os = require('os')
const { execSync } = require('child_process')
// Husky itself skips hooks in CI; skip this script too.
if (process.env.CI) {
process.exit(0)
}
const huskyConfigDir = path.join(os.homedir(), '.config', 'husky')
const initFile = path.join(huskyConfigDir, 'init.sh')
if (fs.existsSync(initFile)) {
console.log(`â„šī¸ ~/.config/husky/init.sh already exists — skipping.`)
process.exit(0)
}
// Prefer `which node` (the symlink / stable PATH entry, e.g.
// /opt/homebrew/opt/node@24/bin) over process.execPath, which on Homebrew
// resolves to a versioned Cellar path that breaks on patch upgrades.
// Fall back to process.execPath for environments where `which` is unavailable.
let nodeDir
try {
const whichNode = execSync('which node', { encoding: 'utf8' }).trim()
nodeDir = path.dirname(whichNode)
} catch (_) {
nodeDir = path.dirname(process.execPath)
}
const content = `# Auto-generated by npm install via src-script/setup-husky-env.js
# Sourced by Husky v9 before every hook to make node/npx available in
# GUI git clients that launch git without a full shell environment.
# Delete this file and re-run "npm install" to regenerate it.
export PATH="${nodeDir}:$PATH"
`
fs.mkdirSync(huskyConfigDir, { recursive: true })
fs.writeFileSync(initFile, content, { mode: 0o644 })
console.log(`✅ Created ~/.config/husky/init.sh (node dir: ${nodeDir})`)