diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f4427e8..e0d3b51 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,8 +11,15 @@ Please note that this project is released with a [Contributor Code of Conduct][c ## Submitting a pull request 1. [Fork][fork] and clone the repository -2. Configure and install the dependencies: `script/bootstrap` -3. Make sure the tests pass on your machine: `make test` + + + +2. Configure and install the dependencies + - On Unix-like machines: `script/bootstrap` + - On Windows: `script/bootstrap.ps1` (requires PowerShell 7+) +3. Make sure the tests pass on your machine + - On Unix-like machines: `make test` + - On Windows machines: `make -f Makefile.win test` (because there's a different Makefile when building on Windows) 4. Create a new branch: `git checkout -b my-branch-name` 5. Make your change, add tests, and make sure the tests still pass 6. Push to your fork and [submit a pull request][pr] diff --git a/Makefile.win b/Makefile.win new file mode 100644 index 0000000..b772251 --- /dev/null +++ b/Makefile.win @@ -0,0 +1,57 @@ +# Windows-specific Makefile for git-sizer designed for PowerShell + +PACKAGE := github.com/github/git-sizer +GO111MODULES := 1 + +# Use the project's go wrapper script via the -File parameter to avoid loading your profile +GOSCRIPT := $(CURDIR)/script/go.ps1 +GO := pwsh.exe -NoProfile -ExecutionPolicy Bypass -File $(GOSCRIPT) + +# Get the build version from git using try/catch instead of "||" +BUILD_VERSION := $(shell pwsh.exe -NoProfile -ExecutionPolicy Bypass -Command "try { git describe --tags --always --dirty 2>$$null } catch { Write-Output 'unknown' }") +LDFLAGS := -X github.com/github/git-sizer/main.BuildVersion=$(BUILD_VERSION) +GOFLAGS := -mod=readonly + +ifdef USE_ISATTY +GOFLAGS := $(GOFLAGS) --tags isatty +endif + +# Find all Go source files +GO_SRC_FILES := $(shell powershell -NoProfile -ExecutionPolicy Bypass -Command "Get-ChildItem -Path . -Filter *.go -Recurse | Select-Object -ExpandProperty FullName") + +# Define common PowerShell command +PWSH := @powershell -NoProfile -ExecutionPolicy Bypass -Command + +# Default target +all: bin/git-sizer.exe + +# Main binary target - depend on all Go source files +bin/git-sizer.exe: $(GO_SRC_FILES) + $(PWSH) "if (-not (Test-Path bin)) { New-Item -ItemType Directory -Path bin | Out-Null }" + $(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -a -o .\bin\git-sizer.exe . + +# Test target - explicitly run the build first to ensure binary is up to date +test: + @$(MAKE) -f Makefile.win bin/git-sizer.exe + @$(MAKE) -f Makefile.win gotest + +# Run go tests +gotest: + $(GO) test -timeout 60s $(GOFLAGS) -ldflags "$(LDFLAGS)" ./... + +# Clean up builds +clean: + $(PWSH) "if (Test-Path bin) { Remove-Item -Recurse -Force bin }" + +# Help target +help: + $(PWSH) "Write-Host 'Windows Makefile for git-sizer' -ForegroundColor Cyan" + $(PWSH) "Write-Host ''" + $(PWSH) "Write-Host 'Targets:' -ForegroundColor Green" + $(PWSH) "Write-Host ' all - Build git-sizer (default)'" + $(PWSH) "Write-Host ' test - Run tests'" + $(PWSH) "Write-Host ' clean - Clean build artifacts'" + $(PWSH) "Write-Host ''" + $(PWSH) "Write-Host 'Example usage:' -ForegroundColor Green" + $(PWSH) "Write-Host ' make -f Makefile.win'" + $(PWSH) "Write-Host ' make -f Makefile.win test'" diff --git a/script/bootstrap.ps1 b/script/bootstrap.ps1 new file mode 100644 index 0000000..7f0413a --- /dev/null +++ b/script/bootstrap.ps1 @@ -0,0 +1,18 @@ +#!/usr/bin/env pwsh + +# Exit immediately if any command fails +$ErrorActionPreference = "Stop" + +# Change directory to the parent directory of the script +Set-Location -Path (Split-Path -Parent $PSCommandPath | Split-Path -Parent) + +# Set ROOTDIR environment variable to the current directory +$env:ROOTDIR = (Get-Location).Path + +# Check if the operating system is macOS +if ($IsMacOS) { + brew bundle +} + +# Source the ensure-go-installed.ps1 script +. ./script/ensure-go-installed.ps1 \ No newline at end of file diff --git a/script/ensure-go-installed.ps1 b/script/ensure-go-installed.ps1 new file mode 100644 index 0000000..3d653c1 --- /dev/null +++ b/script/ensure-go-installed.ps1 @@ -0,0 +1,64 @@ +# This script is meant to be sourced with ROOTDIR set. + +if (-not $env:ROOTDIR) { + $env:ROOTDIR = (Resolve-Path (Join-Path $scriptDir "..")).Path +} + +# Function to check if Go is installed and at least version 1.21 +function GoOk { + $goVersionOutput = & go version 2>$null + if ($goVersionOutput) { + $goVersion = $goVersionOutput -match 'go(\d+)\.(\d+)' | Out-Null + $majorVersion = [int]$Matches[1] + $minorVersion = [int]$Matches[2] + return ($majorVersion -eq 1 -and $minorVersion -ge 21) + } + return $false +} + +# Function to set up a local Go installation if available +function SetUpVendoredGo { + $GO_VERSION = "go1.23.7" + $VENDORED_GOROOT = Join-Path -Path $env:ROOTDIR -ChildPath "vendor/$GO_VERSION/go" + if (Test-Path -Path "$VENDORED_GOROOT/bin/go") { + $env:GOROOT = $VENDORED_GOROOT + $env:PATH = "$env:GOROOT/bin;$env:PATH" + } +} + +# Function to check if Make is installed and install it if needed +function EnsureMakeInstalled { + $makeInstalled = $null -ne (Get-Command "make" -ErrorAction SilentlyContinue) + if (-not $makeInstalled) { + #Write-Host "Installing Make using winget..." + winget install --no-upgrade --nowarn -e --id GnuWin32.Make + if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne 0x8A150061) { + Write-Error "Failed to install Make. Please install it manually. Exit code: $LASTEXITCODE" + } + # Refresh PATH to include the newly installed Make + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "User") + } + + # Add GnuWin32 bin directory directly to the PATH + $gnuWin32Path = "C:\Program Files (x86)\GnuWin32\bin" + if (Test-Path -Path $gnuWin32Path) { + $env:PATH = "$gnuWin32Path;$env:PATH" + } else { + Write-Host "Couldn't find GnuWin32 bin directory at the expected location." + # Also refresh PATH from environment variables as a fallback + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "User") + } +} + +SetUpVendoredGo + +if (-not (GoOk)) { + & ./script/install-vendored-go >$null + if ($LASTEXITCODE -ne 0) { + exit 1 + } + SetUpVendoredGo +} + +# Ensure Make is installed +EnsureMakeInstalled diff --git a/script/go.ps1 b/script/go.ps1 new file mode 100644 index 0000000..e2314b8 --- /dev/null +++ b/script/go.ps1 @@ -0,0 +1,21 @@ +# Ensure that script errors stop execution +$ErrorActionPreference = "Stop" + +# Determine the root directory of the project. +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ROOTDIR = (Resolve-Path (Join-Path $scriptDir "..")).Path + +# Source the ensure-go-installed functionality. +# (This assumes you have a corresponding PowerShell version of ensure-go-installed. +# If not, you could call the bash version via bash.exe if available.) +$ensureScript = Join-Path $ROOTDIR "script\ensure-go-installed.ps1" +if (Test-Path $ensureScript) { + . $ensureScript +} else { + Write-Error "Unable to locate '$ensureScript'. Please provide a PowerShell version of ensure-go-installed." +} + +# Execute the actual 'go' command with passed arguments. +# This re-invokes the Go tool in PATH. +$goExe = "go" +& $goExe @args \ No newline at end of file