aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/test.yml37
-rw-r--r--action.yml58
2 files changed, 86 insertions, 9 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 4cb74e7..5866f16 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -13,19 +13,20 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [windows-2019]
platform: [x86, x64]
env: ['', 'winsymlinks:nativestrict']
+ hardlinks: [0, 1]
include:
- - {os: windows-2019, name: 'Windows 2019'}
+ - {env: '', env_descr: 'nativestrict: 0'}
+ - {env: 'winsymlinks:nativestrict', env_descr: 'nativestrict: 1'}
- - {env: '', env_descr: 'Empty %CYGWIN%'}
- - {env: 'winsymlinks:nativestrict', env_descr: 'Custom %CYGWIN%'}
+ - {hardlinks: 0, hardlinks_descr: 'Hardlinks: 0'}
+ - {hardlinks: 1, hardlinks_descr: 'Hardlinks: 1'}
- runs-on: '${{ matrix.os }}'
+ runs-on: windows-2019
- name: '${{ matrix.name }} / ${{ matrix.platform }} / ${{ matrix.env_descr }}'
+ name: '${{ matrix.platform }} / ${{ matrix.env_descr }} / ${{ matrix.hardlinks_descr }}'
defaults:
run:
@@ -35,25 +36,43 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
+ - name: Clean up PATH
+ uses: egor-tensin/cleanup-path@v1
+ if: runner.os == 'Windows'
+
- name: Set up Cygwin
id: setup
uses: ./
with:
platform: '${{ matrix.platform }}'
install-dir: C:\cg
- packages: cmake gcc
+ packages: cmake gcc python3
env: '${{ matrix.env }}'
+ symlinks-to-hardlinks: '${{ matrix.hardlinks }}'
- name: Run bash
run: |
- $output = C:\cg\bin\bash.exe --login -c 'echo foobar'
+ $((Get-Command bash.exe).Path -eq 'C:\cg\bin\bash.exe') -or $(throw (Get-Command bash.exe))
+ $output = bash.exe --login -c 'echo foobar'
$($output -eq 'foobar') -or $(throw $output)
- name: Run cmake
run: |
- C:\cg\bin\cmake.exe --version
+ $((Get-Command cmake.exe).Path -eq 'C:\cg\bin\cmake.exe') -or $(throw (Get-Command cmake.exe))
+ cmake.exe --version
- name: Check CYGWIN environment variable
run: |
$(Test-Path env:CYGWIN) -or $(throw '%CYGWIN% is not set!')
$($env:CYGWIN -eq '${{ matrix.env }}') -or $(throw "Unexpected %CYGWIN% value: $env:CYGWIN")
+
+ - name: python3 is a symlink
+ run: |
+ $(Get-Command python3.exe -ErrorAction SilentlyContinue) -and $(throw (Get-Command python3.exe))
+ if: '!matrix.hardlinks'
+
+ - name: python3 is a hardlink
+ run: |
+ $((Get-Command python3.exe).Path -eq 'C:\cg\bin\python3.exe') -or $(throw (Get-Command python3.exe))
+ python3.exe --version
+ if: matrix.hardlinks
diff --git a/action.yml b/action.yml
index 9de9583..62d021a 100644
--- a/action.yml
+++ b/action.yml
@@ -16,6 +16,10 @@ inputs:
env:
description: Value to set as the CYGWIN environment variable
required: false
+ symlinks-to-hardlinks:
+ description: Convert symlinks in /usr/bin to hardlinks
+ required: false
+ default: 0
runs:
using: composite
@@ -28,6 +32,14 @@ runs:
New-Variable x64 -Value ('${{ inputs.platform }}' -eq 'x64') -Option Constant
New-Variable install_dir -Value '${{ inputs.install-dir }}' -Option Constant
New-Variable packages -Value '${{ inputs.packages }}' -Option Constant
+ New-Variable symlinks_to_hardlinks -Value ('${{ inputs.symlinks-to-hardlinks }}' -eq '1') -Option Constant
+
+ New-Variable bin_dir -Value (Join-Path $install_dir bin) -Option Constant
+ New-Variable realpath -Value (Join-Path $bin_dir realpath.exe) -Option Constant
+ New-Variable readlink -Value (Join-Path $bin_dir readlink.exe) -Option Constant
+ New-Variable dirname -Value (Join-Path $bin_dir dirname.exe) -Option Constant
+ New-Variable cygpath -Value (Join-Path $bin_dir cygpath.exe) -Option Constant
+ New-Variable find -Value (Join-Path $bin_dir find.exe) -Option Constant
function Locate-Choco {
$path = Get-Command 'choco' -ErrorAction SilentlyContinue
@@ -38,6 +50,48 @@ runs:
}
}
+ function Convert-CygwinPath {
+ # Like cygpath -wa, but don't resolve symlinks.
+ param(
+ [Parameter(Mandatory=$true)]
+ [string] $Path
+ )
+
+ $realpath = & $script:realpath --no-symlinks -- $Path
+ $dirname = & $script:dirname -- $realpath
+ $dirname = & $script:cygpath -wa $dirname
+ Join-Path $dirname (Split-Path $realpath -Leaf)
+ }
+
+ function Fix-CygwinLink {
+ # Replace a Cygwin symlink with a hardlink.
+ param(
+ [Parameter(Mandatory=$true)]
+ [string] $Path
+ )
+
+ $link_path = $Path
+ $link_winpath = Convert-CygwinPath $link_path
+ $link_ext = [System.IO.Path]::GetExtension($link_path)
+
+ $dest_path = & $script:readlink --canonicalize-existing -- $link_path
+ $dest_winpath = Convert-CygwinPath $dest_path
+ $dest_ext = [System.IO.Path]::GetExtension($dest_path)
+
+ echo "Removing symlink: $link_winpath"
+ Remove-Item $link_winpath -Force
+
+ # If target is an executable (i.e. its name contains one of the
+ # PATHEXT extensions), make sure the hardlink has the same
+ # extension.
+ $exe_exts = $env:PATHEXT.ToLower().Split(';', [System.StringSplitOptions]::RemoveEmptyEntries)
+ if ($exe_exts -contains $dest_ext.ToLower() -and $dest_ext.ToLower() -ne $link_ext.ToLower()) {
+ $link_winpath += $dest_ext
+ }
+ echo "Creating hardlink '$link_winpath', pointing to '$dest_winpath'"
+ New-Item -ItemType HardLink -Path $link_winpath -Value $dest_winpath | Out-Null
+ }
+
if ($windows_host) {
echo 'CYGWIN=${{ inputs.env }}' >> $env:GITHUB_ENV
@@ -66,6 +120,10 @@ runs:
if ($pkg_list.Count -gt 0) {
& $choco install -y --no-progress --source=cygwin $pkg_list
}
+
+ if ($symlinks_to_hardlinks) {
+ & $find /usr/bin -type l | %{ Fix-CygwinLink $_ }
+ }
} else {
throw "Sorry, installing Cygwin is unsupported on $os"
}