From 59eb3e4ed3548b3e0612c83fb6d4c6a52749eed9 Mon Sep 17 00:00:00 2001 From: sheaf Date: Fri, 5 Apr 2024 14:12:48 +0200 Subject: [PATCH 1/2] Move tests to separate process-tests package This commit moves the process testsuite to a separate package. The rationale is that later commits require the test-suite to use a Custom setup in order to work around Cabal bug #9854. This introduces a setup-depends dependency on the Cabal library, and we would very much like to avoid the dependency cycle: Cabal depends on process process depends on Cabal Instead, splitting up the test-suite, we have: Cabal depends on process process-tests depends on process and on Cabal To run the test-suite, you can use either of the following commands: > cabal run process-tests:test > stack test process-tests There are a few other auxiliary changes, such as: - Using Cabal version >= 2.4 in the .cabal files, and fixing the associated warnings, - Using the CPP mingw32_HOST_OS define to check for Windows; this avoids having to define the same variable twice in two different packages. --- .github/workflows/tests.yml | 4 +++- .gitignore | 13 +++++++------ Setup.hs | 5 +++++ System/Process.hs | 13 ++++++------- System/Process/Common.hs | 6 +++--- System/Process/Internals.hs | 6 +++--- process.cabal | 24 +++++------------------- test/LICENSE | 31 +++++++++++++++++++++++++++++++ test/main.hs | 2 +- test/process-tests.cabal | 32 ++++++++++++++++++++++++++++++++ test/stack.yaml | 9 +++++++++ 11 files changed, 105 insertions(+), 40 deletions(-) create mode 100644 test/LICENSE create mode 100644 test/process-tests.cabal create mode 100644 test/stack.yaml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a6032f30..5c3032ba 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,5 +43,7 @@ jobs: rm -rf C:/ProgramData/Chocolatey/bin/ghc* stack ${{ matrix.args }} exec pacman -- --sync --refresh --noconfirm autoconf fi - stack test --bench --no-run-benchmarks --haddock --no-terminal ${{ matrix.args }} + stack build stack sdist --test-tarball + cd test + stack test --bench --no-run-benchmarks --haddock --no-terminal ${{ matrix.args }} diff --git a/.gitignore b/.gitignore index 44073d05..e71f7167 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,11 @@ -/.cabal-sandbox/ -/cabal.project.local -/cabal.sandbox.config -/dist/ -/dist-newstyle/ -/.stack-work/ +**/.cabal-sandbox/ +**/cabal.project.local +**/cabal.sandbox.config +**/dist/ +**/dist-newstyle/ +**/.stack-work/ *.swp +stack.yaml.lock # Specific generated files GNUmakefile diff --git a/Setup.hs b/Setup.hs index 54f57d6f..3611f30e 100644 --- a/Setup.hs +++ b/Setup.hs @@ -1,6 +1,11 @@ module Main (main) where import Distribution.Simple + ( defaultMainWithHooks + , autoconfUserHooks + ) + +-------------------------------------------------------------------------------- main :: IO () main = defaultMainWithHooks autoconfUserHooks diff --git a/System/Process.hs b/System/Process.hs index 79bfa74d..79bb303a 100644 --- a/System/Process.hs +++ b/System/Process.hs @@ -105,13 +105,12 @@ import System.IO.Error (mkIOError, ioeSetErrorString) #if defined(javascript_HOST_ARCH) import System.Process.JavaScript(getProcessId, getCurrentProcessId) -#elif defined(WINDOWS) +#elif defined(mingw32_HOST_OS) import System.Win32.Process (getProcessId, getCurrentProcessId, ProcessId) #else import System.Posix.Process (getProcessID) import System.Posix.Types (CPid (..)) #endif - import GHC.IO.Exception ( ioException, IOErrorType(..), IOException(..) ) #if defined(wasm32_HOST_ARCH) @@ -126,7 +125,7 @@ import System.IO.Error -- @since 1.6.3.0 #if defined(javascript_HOST_ARCH) type Pid = Int -#elif defined(WINDOWS) +#elif defined(mingw32_HOST_OS) type Pid = ProcessId #else type Pid = CPid @@ -668,7 +667,7 @@ getPid (ProcessHandle mh _ _) = do OpenHandle h -> do pid <- getProcessId h return $ Just pid -#elif defined(WINDOWS) +#elif defined(mingw32_HOST_OS) OpenHandle h -> do pid <- getProcessId h return $ Just pid @@ -691,7 +690,7 @@ getCurrentPid :: IO Pid getCurrentPid = #if defined(javascript_HOST_ARCH) getCurrentProcessId -#elif defined(WINDOWS) +#elif defined(mingw32_HOST_OS) getCurrentProcessId #else getProcessID @@ -743,7 +742,7 @@ waitForProcess ph@(ProcessHandle _ delegating_ctlc _) = lockWaitpid $ do when (was_open && delegating_ctlc) $ endDelegateControlC e return e' -#if defined(WINDOWS) +#if defined(mingw32_HOST_OS) OpenExtHandle h job -> do -- First wait for completion of the job... waitForJobCompletion job @@ -872,7 +871,7 @@ terminateProcess ph = do withProcessHandle ph $ \p_ -> case p_ of ClosedHandle _ -> return () -#if defined(WINDOWS) +#if defined(mingw32_HOST_OS) OpenExtHandle{} -> terminateJobUnsafe p_ 1 >> return () #else OpenExtHandle{} -> error "terminateProcess with OpenExtHandle should not happen on POSIX." diff --git a/System/Process/Common.hs b/System/Process/Common.hs index e2490d85..bac53ee1 100644 --- a/System/Process/Common.hs +++ b/System/Process/Common.hs @@ -21,7 +21,7 @@ module System.Process.Common , pfdToHandle -- Avoid a warning on Windows -#ifdef WINDOWS +#if defined(mingw32_HOST_OS) , CGid (..) #else , CGid @@ -63,7 +63,7 @@ import GHC.JS.Prim (JSVal) -- We do a minimal amount of CPP here to provide uniform data types across -- Windows and POSIX. -#ifdef WINDOWS +#if defined(mingw32_HOST_OS) import Data.Word (Word32) import System.Win32.DebugApi (PHANDLE) #if defined(__IO_MANAGER_WINIO__) @@ -75,7 +75,7 @@ import System.Posix.Types #if defined(javascript_HOST_ARCH) type PHANDLE = JSVal -#elif defined(WINDOWS) +#elif defined(mingw32_HOST_OS) -- Define some missing types for Windows compatibility. Note that these values -- will never actually be used, as the setuid/setgid system calls are not -- applicable on Windows. No value of this type will ever exist. diff --git a/System/Process/Internals.hs b/System/Process/Internals.hs index 97ac6841..4bb735e0 100644 --- a/System/Process/Internals.hs +++ b/System/Process/Internals.hs @@ -22,7 +22,7 @@ module System.Process.Internals ( ProcessHandle(..), ProcessHandle__(..), PHANDLE, closePHANDLE, mkProcessHandle, -#ifdef WINDOWS +#if defined(mingw32_HOST_OS) CGid(..), #else CGid, @@ -39,7 +39,7 @@ module System.Process.Internals ( endDelegateControlC, stopDelegateControlC, unwrapHandles, -#ifdef WINDOWS +#if defined(mingw32_HOST_OS) terminateJob, terminateJobUnsafe, waitForJobCompletion, @@ -68,7 +68,7 @@ import System.Process.Common #if defined(javascript_HOST_ARCH) import System.Process.JavaScript -#elif defined(WINDOWS) +#elif defined(mingw32_HOST_OS) import System.Process.Windows #else import System.Process.Posix diff --git a/process.cabal b/process.cabal index 0b25762f..28565920 100644 --- a/process.cabal +++ b/process.cabal @@ -1,14 +1,14 @@ +cabal-version: 2.4 name: process version: 1.6.19.0 -- NOTE: Don't forget to update ./changelog.md -license: BSD3 +license: BSD-3-Clause license-file: LICENSE maintainer: libraries@haskell.org bug-reports: https://github.com/haskell/process/issues synopsis: Process libraries category: System build-type: Configure -cabal-version: >=1.10 description: This package contains libraries for dealing with system processes. . @@ -18,9 +18,11 @@ description: read more about it at . +extra-doc-files: + changelog.md + extra-source-files: aclocal.m4 - changelog.md configure configure.ac include/HsProcessConfig.h.in @@ -90,19 +92,3 @@ library directory >= 1.1 && < 1.4, filepath >= 1.2 && < 1.6, deepseq >= 1.1 && < 1.6 - -test-suite test - default-language: Haskell2010 - hs-source-dirs: test - main-is: main.hs - type: exitcode-stdio-1.0 - -- Add otherwise redundant bounds on base since GHC's build system runs - -- `cabal check`, which mandates bounds on base. - build-depends: base >= 4 && < 5 - , bytestring - , directory - , process - ghc-options: -threaded - -with-rtsopts "-N" - if os(windows) - cpp-options: -DWINDOWS diff --git a/test/LICENSE b/test/LICENSE new file mode 100644 index 00000000..5343d729 --- /dev/null +++ b/test/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2024, the Haskell process developers. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Isaac Jones nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/test/main.hs b/test/main.hs index b2788264..9624e3f4 100644 --- a/test/main.hs +++ b/test/main.hs @@ -22,7 +22,7 @@ ifWindows action | otherwise = action isWindows :: Bool -#if WINDOWS +#if defined(mingw32_HOST_OS) isWindows = True #else isWindows = False diff --git a/test/process-tests.cabal b/test/process-tests.cabal new file mode 100644 index 00000000..8a9bea93 --- /dev/null +++ b/test/process-tests.cabal @@ -0,0 +1,32 @@ +cabal-version: 2.4 +name: process-tests +version: 1.6.19.0 +license: BSD-3-Clause +license-file: LICENSE +maintainer: libraries@haskell.org +bug-reports: https://github.com/haskell/process/issues +synopsis: Testing package for the process library +category: System +build-type: Simple +description: + This package contains the testing infrastructure for the process library + +source-repository head + type: git + location: https://github.com/haskell/process.git + subdir: test + +test-suite test + default-language: Haskell2010 + hs-source-dirs: . + main-is: main.hs + type: exitcode-stdio-1.0 + -- Add otherwise redundant bounds on base since GHC's build system runs + -- `cabal check`, which mandates bounds on base. + build-depends: base >= 4 && < 5 + , bytestring + , deepseq + , directory + , filepath + , process == 1.6.19.0 + ghc-options: -threaded -rtsopts -with-rtsopts "-N" diff --git a/test/stack.yaml b/test/stack.yaml new file mode 100644 index 00000000..76575cc1 --- /dev/null +++ b/test/stack.yaml @@ -0,0 +1,9 @@ +resolver: ghc-9.2.3 + +extra-deps: + - .. + - Cabal-3.10.2.0 + +allow-newer: True +allow-newer-deps: + - Cabal From 13ede6d48ee895707d605d7f45fb61d4f088f927 Mon Sep 17 00:00:00 2001 From: sheaf Date: Fri, 5 Apr 2024 16:59:51 +0200 Subject: [PATCH 2/2] Update CI to use GitHub Actions --- .github/workflows/tests.yml | 131 +++++++++++++++++++++++++++--------- cabal.project | 1 + stack.yaml | 11 +++ test/process-tests.cabal | 2 - test/stack.yaml | 9 --- 5 files changed, 111 insertions(+), 43 deletions(-) create mode 100644 cabal.project delete mode 100644 test/stack.yaml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5c3032ba..e63f37e2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,47 +3,114 @@ name: Tests on: pull_request: push: - branches: - - master + branches: + - '**' jobs: build: - name: CI + name: GHC ${{ matrix.ghc-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - args: - - "--resolver ghc-9.8.1" - - "--resolver ghc-9.6.3" - - "--resolver ghc-9.4.7" - - "--resolver ghc-9.2.8" - - "--resolver ghc-9.0.1" - - "--resolver ghc-8.10.4" - - "--resolver ghc-8.8.4" - - "--resolver ghc-8.6.5" - - "--resolver ghc-8.4.4" - - "--resolver ghc-8.2.2" + ghc-version: + - 'latest' + - '9.8' + - '9.6' + - '9.4' + - '9.2' + - '9.0' + - '8.10' + - '8.8' + - '8.6' + - '8.4' + - '8.2' + + exclude: + # Exclude GHC 8.2 on Windows (GHC bug: undefined reference to `__stdio_common_vswprintf_s') + - os: windows-latest + ghc-version: '8.2' steps: - - name: Clone project - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + + - name: Set up GHC ${{ matrix.ghc-version }} + uses: haskell-actions/setup@v2 + id: setup + with: + ghc-version: ${{ matrix.ghc-version }} + # Defaults, added for clarity: + cabal-version: 'latest' + cabal-update: true + + - name: Set up autotools (Windows) + if: ${{ runner.os == 'Windows' }} + uses: msys2/setup-msys2@v2 + with: + update: true + install: >- + autotools + + - name: Run autoreconf (Windows) + if: ${{ runner.os == 'Windows' }} + run: autoreconf -i + shell: "msys2 {0}" - - name: Build and run tests - shell: bash + - name: Run autoreconf (Linux & Mac) + if: ${{ runner.os != 'Windows' }} + run: autoreconf -i + + - name: Configure the build run: | - set -ex - stack upgrade - stack --version - if [[ "${{ runner.os }}" = 'Windows' ]] - then - # Looks like a bug in Stack, this shouldn't break things - ls C:/ProgramData/Chocolatey/bin/ - rm -rf C:/ProgramData/Chocolatey/bin/ghc* - stack ${{ matrix.args }} exec pacman -- --sync --refresh --noconfirm autoconf - fi - stack build - stack sdist --test-tarball - cd test - stack test --bench --no-run-benchmarks --haddock --no-terminal ${{ matrix.args }} + cabal configure --enable-tests --enable-benchmarks --disable-documentation + cabal build all --dry-run + # The last step generates dist-newstyle/cache/plan.json for the cache key. + + - name: Restore cached dependencies + uses: actions/cache/restore@v3 + id: cache + env: + key: ${{ runner.os }}-ghc-${{ steps.setup.outputs.ghc-version }}-cabal-${{ steps.setup.outputs.cabal-version }} + with: + path: ${{ steps.setup.outputs.cabal-store }} + key: ${{ env.key }}-plan-${{ hashFiles('**/plan.json') }} + restore-keys: ${{ env.key }}- + + - name: Install dependencies + # If we had an exact cache hit, the dependencies will be up to date. + if: steps.cache.outputs.cache-hit != 'true' + run: cabal build process --only-dependencies + + # Cache dependencies already here, so that we do not have to rebuild them should the subsequent steps fail. + - name: Save cached dependencies + uses: actions/cache/save@v3 + # If we had an exact cache hit, trying to save the cache would error because of key clash. + if: steps.cache.outputs.cache-hit != 'true' + with: + path: ${{ steps.setup.outputs.cabal-store }} + key: ${{ steps.cache.outputs.cache-primary-key }} + + - name: Build + run: cabal build process + + - name: Run tests + run: cabal run process-tests:test + + # On Windows and with GHC >= 9.0, re-run the test-suite using WinIO. + - name: Re-run tests with WinIO (Windows && GHC >= 9.0) + if: ${{ runner.os == 'Windows' && matrix.ghc-version >= '9.0' }} + run: cabal run process-tests:test -- +RTS --io-manager=native -RTS + + - name: Source dist + run: cabal sdist all --ignore-project + + - name: Build documentation + run: cabal haddock process + + - name: Check process.cabal + run: cabal check + + - name: Check process-tests.cabal + working-directory: ./test + run: cabal check diff --git a/cabal.project b/cabal.project new file mode 100644 index 00000000..f99d9fad --- /dev/null +++ b/cabal.project @@ -0,0 +1 @@ +packages: ., test diff --git a/stack.yaml b/stack.yaml index 25614a89..7eca6c60 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1 +1,12 @@ resolver: ghc-9.2.3 + +packages: + - . + - test + +extra-deps: + - Cabal-3.6.3.0 + +allow-newer: True +allow-newer-deps: + - Cabal diff --git a/test/process-tests.cabal b/test/process-tests.cabal index 8a9bea93..e3f702ea 100644 --- a/test/process-tests.cabal +++ b/test/process-tests.cabal @@ -21,8 +21,6 @@ test-suite test hs-source-dirs: . main-is: main.hs type: exitcode-stdio-1.0 - -- Add otherwise redundant bounds on base since GHC's build system runs - -- `cabal check`, which mandates bounds on base. build-depends: base >= 4 && < 5 , bytestring , deepseq diff --git a/test/stack.yaml b/test/stack.yaml deleted file mode 100644 index 76575cc1..00000000 --- a/test/stack.yaml +++ /dev/null @@ -1,9 +0,0 @@ -resolver: ghc-9.2.3 - -extra-deps: - - .. - - Cabal-3.10.2.0 - -allow-newer: True -allow-newer-deps: - - Cabal