HamidMolareza / QueraLens

A static site generator showcasing organized solutions to Quera problems with clarity and insights.
https://hamidmolareza.github.io/Quera
GNU General Public License v3.0
0 stars 0 forks source link

dev: add PowerShell script for git hooks and pre-commit #13

Closed HamidMolareza closed 2 days ago

HamidMolareza commented 3 days ago

scripts/setup-hooks.ps1 file:

#!/usr/bin/env pwsh
# Usage:
#   .\scripts\setup-hooks.ps1 (execute script)

# Function to enable a specific Git hook by copying its sample file
function Enable-Hook {
    param (
        [Parameter(Mandatory)][string]$HooksDir,
        [Parameter(Mandatory)][string]$HookName
    )

    $TargetHook = Join-Path $HooksDir $HookName
    $TemplateFile = Join-Path $HooksDir "$HookName.sample"

    if (Test-Path $TargetHook) {
        Write-Host "The '$HookName' hook is already enabled. ($TargetHook)" -ForegroundColor Yellow
    } elseif (Test-Path $TemplateFile) {
        Write-Host "Enabling '$HookName' hook..." -ForegroundColor Green
        Move-Item -Path $TemplateFile -Destination $TargetHook -Force
        Write-Host "Template hook copied to $TargetHook." -ForegroundColor Green
    } else {
        Write-Warning "Template for '$HookName' hook not found."
    }
}

# Function to get the Git hooks path
function Get-HooksPath {
    try {
        $GitRoot = git rev-parse --show-toplevel 2>$null
        $HooksPath = git rev-parse --git-path hooks 2>$null

        if ($GitRoot -and $HooksPath) {
            return Join-Path $GitRoot $HooksPath
        }
    } catch {
        Write-Warning "Unable to determine Git hooks path. Ensure this script is run inside a Git repository."
    }

    return ""
}

# Function to check if a command exists
function Command-Exists {
    param ([Parameter(Mandatory)][string]$Command)

    return $null -ne (Get-Command $Command -ErrorAction SilentlyContinue)
}

# Function to install pre-commit hooks
function Install-PreCommitHooks {
    param ([Parameter(Mandatory)][string[]]$HookTypes)

    foreach ($HookType in $HookTypes) {
        Write-Host "Installing '$HookType' pre-commit hook..." -ForegroundColor Cyan
        pre-commit install --hook-type $HookType
    }
}

# Function to install npm dependencies
function Install-NpmDependencies {
    if (Test-Path "package.json") {
        Write-Host "Installing npm dependencies..." -ForegroundColor Cyan
        npm install
    } else {
        Write-Host "No package.json found. Skipping npm dependency installation." -ForegroundColor Yellow
    }
}

# Main Script Execution
Write-Host "Starting setup-hooks script..." -ForegroundColor Cyan

# Check for required commands
if (-not (Command-Exists "pre-commit")) {
    Write-Error "pre-commit is not installed. Please install it first."
    exit 1
}

if ((-not (Command-Exists "npm")) -and (Test-Path "package.json")) {
    Write-Error "npm is not installed. Please install it first."
    exit 1
}

# Install pre-commit hooks
$PreCommitHooks = @("commit-msg", "prepare-commit-msg", "pre-merge-commit", "pre-push")
Install-PreCommitHooks -HookTypes $PreCommitHooks

# Enable additional Git hooks if hook path exists
$HooksDir = Get-HooksPath
if ($HooksDir) {
    Enable-Hook -HooksDir $HooksDir -HookName "pre-rebase"
} else {
    Write-Warning "Git hooks directory not found. Skipping additional hook setup."
}

# Install npm dependencies
Install-NpmDependencies

Write-Host "Setup-hooks script completed successfully." -ForegroundColor Green
HamidMolareza commented 3 days ago

@ARiYaNSEp0-0

If possible, please read about Git hooks and pre-commit. These tools help streamline the development process, keeping the project clean and organized by catching and fixing errors before the code is committed or pushed. For example, they can:

This is especially valuable in projects where multiple developers are collaborating.
It’s optional, and every developer needs to manually enable it after cloning the repository.

I use a setup-hooks.sh bash script for this, which is suitable for Linux systems.
I’ve also created an initial PowerShell script, but since I don’t use Windows, I can’t test it easily.
If you’re interested, you could test this script, and if everything works well, I’ll add it to this project and the Payadel/README project as well.

This script ensures that pre-commit, a Python module that can be installed via pip, is installed. Then, it installs the necessary npm packages. Finally, it activates pre-commit and the required Git hooks.

HamidMolareza commented 3 days ago

How to execute powershell script?

1. Save the Script

Save the script file as setup-hooks.ps1 in the scripts folder.

2. Set Execution Policy

By default, PowerShell may restrict script execution. To allow it, you need to set an appropriate execution policy.

  1. Open PowerShell as Administrator.

  2. Run the following command to set the execution policy for the current user:

    Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
    • RemoteSigned: Allows locally created scripts to run, but requires signed scripts if downloaded from the internet.
    • Scope CurrentUser: Ensures the policy change only applies to your user account (safe for non-admin users).
  3. Verify the policy:

    Get-ExecutionPolicy -Scope CurrentUser

    It should return RemoteSigned.

3. Navigate to the Script Location

Use the cd command in PowerShell to navigate to the directory containing the script.

4. Execute the Script

Run the script by typing:

.\setup-hooks.ps1
ARiYaNSEp0-0 commented 3 days ago

Thank you sir. I was a little bit familiar with git hooks and their use case but this explanation and links helped a lot.

ARiYaNSEp0-0 commented 3 days ago

I have two systems a windows 10 which is my main dev pc and linux mint xfce on another, for linux setup-hooks.sh is good ?

HamidMolareza commented 3 days ago

I have two systems a windows 10 which is my main dev pc and linux mint xfce on another, for linux setup-hooks.sh is good ?

This script should likely be suitable for any system that supports bash.

ARiYaNSEp0-0 commented 3 days ago

Fixed : I hadn't run npm install in the root directory until now to install commitlint. Sorry, that was my mistake! 😁

I ran the script, and when I try to commit after closing the COMMIT_MSG tab, I get this error:

Error: Cannot find module "@commitlint/config-conventional" from "C:\Users\lenovo\Desktop\QueraLens\.configs"
    at resolveId (file:///C:/Users/lenovo/.cache/pre-commit/repohdbe0zem/node_env-default/Scripts/node_modules/commitlint-pre-commit-hook/node_modules/@commitlint/resolve-extends/lib/index.js:148:17)
    at resolveConfig (file:///C:/Users/lenovo/.cache/pre-commit/repohdbe0zem/node_env-default/Scripts/node_modules/commitlint-pre-commit-hook/node_modules/@commitlint/resolve-extends/lib/index.js:132:20)
    at file:///C:/Users/lenovo/.cache/pre-commit/repohdbe0zem/node_env-default/Scripts/node_modules/commitlint-pre-commit-hook/node_modules/@commitlint/resolve-extends/lib/index.js:93:26
    at Array.reduce (<anonymous>)
    at loadExtends (file:///C:/Users/lenovo/.cache/pre-commit/repohdbe0zem/node_env-default/Scripts/node_modules/commitlint-pre-commit-hook/node_modules/@commitlint/resolve-extends/lib/index.js:92:22)
    at resolveExtends (file:///C:/Users/lenovo/.cache/pre-commit/repohdbe0zem/node_env-default/Scripts/node_modules/commitlint-pre-commit-hook/node_modules/@commitlint/resolve-extends/lib/index.js:76:28)
    at load (file:///C:/Users/lenovo/.cache/pre-commit/repohdbe0zem/node_env-default/Scripts/node_modules/commitlint-pre-commit-hook/node_modules/@commitlint/load/lib/load.js:47:28)
    at async main (file:///C:/Users/lenovo/.cache/pre-commit/repohdbe0zem/node_env-default/Scripts/node_modules/commitlint-pre-commit-hook/node_modules/@commitlint/cli/lib/cli.js:200:20) {
  code: 'MODULE_NOT_FOUND'
}

Edit : also this is the output of setup-hooks.ps1

Starting setup-hooks script...
Installing 'commit-msg' pre-commit hook...
pre-commit installed at .git\hooks\commit-msg
Installing 'prepare-commit-msg' pre-commit hook...
pre-commit installed at .git\hooks\prepare-commit-msg
Installing 'pre-merge-commit' pre-commit hook...
pre-commit installed at .git\hooks\pre-merge-commit
Installing 'pre-push' pre-commit hook...
pre-commit installed at .git\hooks\pre-push
WARNING: Template for 'pre-rebase' hook not found.
No package.json found. Skipping npm dependency installation.
Setup-hooks script completed successfully.

Edit 2 : But I thought this script should install the dependencies listed in the root package.json, am I correct?

HamidMolareza commented 3 days ago

If everything is set up correctly, these hooks should run as follows:

You can modify this file whenever needed. For example, you can remove the document-oriented hook.

In exceptional cases, you can also skip the execution of these hooks if necessary.