From 579afc53b931ede1ed992cff1cffed56d665ab86 Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Thu, 16 Apr 2026 23:09:47 +0530 Subject: [PATCH 1/7] Update upper bound of "unix" --- streamly-process.cabal | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/streamly-process.cabal b/streamly-process.cabal index a078e59..5244d43 100644 --- a/streamly-process.cabal +++ b/streamly-process.cabal @@ -107,7 +107,7 @@ library else if !os(windows) build-depends: - unix >= 2.5 && < 2.8 + unix >= 2.5 && < 2.9 ------------------------------------------------------------------------------- -- Benchmarks @@ -130,7 +130,7 @@ benchmark Benchmark.System.Process , directory >= 1.2.2 && < 1.4 -- Uses internal APIs , streamly-core - , tasty-bench >= 0.2.5 && < 0.5 + , tasty-bench >= 0.2.5 && < 0.6 if flag(fusion-plugin) && !impl(ghc < 8.6) build-depends: @@ -150,6 +150,6 @@ test-suite Test.System.Process , directory >= 1.2.2 && < 1.4 , exceptions >= 0.8 && < 0.11 , hspec >= 2.0 && < 3 - , QuickCheck >= 2.10 && < 2.16 + , QuickCheck >= 2.10 && < 2.19 -- Uses internal APIs , streamly-core From 3d23b07a8a190db0aa389f4782bdc3d973d0d914 Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Thu, 16 Apr 2026 23:27:41 +0530 Subject: [PATCH 2/7] Add a nix flake file --- .packcheck.ignore | 2 ++ flake.lock | 88 +++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 19 ++++++++++ 3 files changed, 109 insertions(+) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.packcheck.ignore b/.packcheck.ignore index 7fa4d3f..f6ae9f0 100644 --- a/.packcheck.ignore +++ b/.packcheck.ignore @@ -10,3 +10,5 @@ cabal.project.d/master cabal.project.d/master-Werror cabal.project.d/streamly-0.9.0 cabal.project.d/streamly-0.10.0 +flake.lock +flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..d0a450a --- /dev/null +++ b/flake.lock @@ -0,0 +1,88 @@ +{ + "nodes": { + "basepkgs": { + "inputs": { + "basepkgs": "basepkgs_2", + "nixpkgs": "nixpkgs", + "nixpkgs-darwin": "nixpkgs-darwin" + }, + "locked": { + "lastModified": 1776359956, + "narHash": "sha256-sJ7rbofR7LQIVCHdLhORocWg8dR8u1PnontbgFtKvbU=", + "ref": "refs/heads/master", + "rev": "71f2b6792a9f64be2c4bca5050cb1e08edd625b2", + "revCount": 122, + "type": "git", + "url": "ssh://git@github.com/composewell/streamly-packages" + }, + "original": { + "rev": "71f2b6792a9f64be2c4bca5050cb1e08edd625b2", + "type": "git", + "url": "ssh://git@github.com/composewell/streamly-packages" + } + }, + "basepkgs_2": { + "locked": { + "lastModified": 1776352576, + "narHash": "sha256-/rNYSCE5o+u5ZRfpE+PaDjmp5ttEgSLyiRoDOgguKJw=", + "owner": "composewell", + "repo": "nixpack", + "rev": "8c0e3596f53ae42c43175b7440d9c0f5c462997c", + "type": "github" + }, + "original": { + "owner": "composewell", + "repo": "nixpack", + "rev": "8c0e3596f53ae42c43175b7440d9c0f5c462997c", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1774106199, + "narHash": "sha256-US5Tda2sKmjrg2lNHQL3jRQ6p96cgfWh3J1QBliQ8Ws=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655", + "type": "github" + } + }, + "nixpkgs-darwin": { + "locked": { + "lastModified": 1774106199, + "narHash": "sha256-US5Tda2sKmjrg2lNHQL3jRQ6p96cgfWh3J1QBliQ8Ws=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6c9a78c09ff4d6c21d0319114873508a6ec01655", + "type": "github" + } + }, + "root": { + "inputs": { + "basepkgs": "basepkgs", + "nixpkgs": [ + "basepkgs", + "nixpkgs" + ], + "nixpkgs-darwin": [ + "basepkgs", + "nixpkgs-darwin" + ] + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c426fde --- /dev/null +++ b/flake.nix @@ -0,0 +1,19 @@ +{ + description = "streamly-process"; + + inputs = { + basepkgs.url = "git+ssh://git@github.com/composewell/streamly-packages?rev=71f2b6792a9f64be2c4bca5050cb1e08edd625b2"; + nixpkgs.follows = "basepkgs/nixpkgs"; + nixpkgs-darwin.follows = "basepkgs/nixpkgs-darwin"; + }; + + outputs = { self, nixpkgs, nixpkgs-darwin, basepkgs }: + basepkgs.nixpack.mkOutputs { + inherit nixpkgs nixpkgs-darwin basepkgs; + name = "streamly-process"; + sources = basepkgs.nixpack.lib.localSource "streamly-process" ./.; + packages = basepkgs.nixpack.lib.devPackage "streamly-process"; + #sources = import ./sources.nix; + #packages = import ./packages.nix; + }; +} From 7f841dacf506ef7c9135168a130d7c3bcd9bed37 Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Thu, 16 Apr 2026 23:28:13 +0530 Subject: [PATCH 3/7] Update the package description and some docs --- src/Streamly/System/Command.hs | 12 ++++++------ streamly-process.cabal | 21 ++++++++++++++------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Streamly/System/Command.hs b/src/Streamly/System/Command.hs index 6fbf711..2042b2e 100644 --- a/src/Streamly/System/Command.hs +++ b/src/Streamly/System/Command.hs @@ -49,16 +49,16 @@ -- :} -- HELLO WORLD -- --- Here, system commands are run as independent processes and composed --- directly in Haskell — without invoking a shell. This offers a powerful, --- type-safe, and efficient alternative to shell scripting, using Streamly’s --- streaming APIs for composition. +-- In the example above, system commands are run as independent processes and +-- composed directly in Haskell, without invoking a shell. This offers a +-- powerful, type-safe, and efficient alternative to shell scripting, using +-- Streamly’s streaming APIs for composition. -- -- = Shell Commands as Functions -- -- Prefer running commands directly and composing their output in Haskell (see --- previous example) instead of relying on a shell interpreter. If you want to --- run a command using shell as interpreter, you can invoke it like this: +-- previous example) instead of using shell pipes. But if you really want to +-- run a command using shell as interpreter, you can do that too like this: -- -- >>> :{ -- Command.toBytes [str|sh "-c" "echo 'hello world' | tr [a-z] [A-Z]"|] diff --git a/streamly-process.cabal b/streamly-process.cabal index 5244d43..66245bb 100644 --- a/streamly-process.cabal +++ b/streamly-process.cabal @@ -1,14 +1,21 @@ cabal-version: 2.2 name: streamly-process version: 0.4.0 -synopsis: Use OS processes as stream transformation functions +synopsis: Write shell-like command pipelines in Haskell description: - Use operating system (OS) commands in Haskell programs as if they were - native Haskell functions, by treating their inputs and outputs as - Haskell streams. This allows you to write high-level Haskell scripts - that can perform tasks similar to shell scripts, but with C-like - performance, and with strong safety guarantees, refactorability, and - modularity. + Treat operating system (OS) processes as first-class stream + transformations in Haskell. This package lets you compose external + commands as if they were native Haskell functions, connecting + their inputs and outputs through typed streams and perform tasks + concurrently. It let's you do your scripting tasks in Haskell with + near-native performance. + . + The API is designed to be concise and ergonomic, making it easy + to express complex pipelines with minimal boilerplate. You can + build high-level, declarative workflows similar to shell scripts + while retaining Haskell’s strengths: type safety, composability, + refactorability, and modular design. Moreover, you get the concurrent + compositions and C-like performance of streamly. homepage: https://streamly.composewell.com bug-reports: https://github.com/composewell/streamly-process/issues license: Apache-2.0 From 4d1f494922f7650e381e8f3f47a20410643ee1b6 Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Fri, 17 Apr 2026 00:07:40 +0530 Subject: [PATCH 4/7] Update github CI config, sync with packcheck --- .github/workflows/haskell.yml | 575 ++++++++++++++++---- .packcheck.ignore | 4 +- cabal.project.d/Werror | 4 + cabal.project.d/master-Werror | 15 - cabal.project.d/streamly-0.10.0 | 4 +- cabal.project.d/{master => streamly-master} | 0 stack.yaml | 2 +- streamly-process.cabal | 22 +- 8 files changed, 475 insertions(+), 151 deletions(-) create mode 100644 cabal.project.d/Werror delete mode 100644 cabal.project.d/master-Werror rename cabal.project.d/{master => streamly-master} (100%) diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index 798b536..95f6893 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -1,20 +1,20 @@ -# packcheck-0.7.0 +# packcheck-0.7.1 # You can use any of the options supported by packcheck as environment # variables here. See https://github.com/composewell/packcheck for all # options and their explanation. -name: packcheck +name: TEST #----------------------------------------------------------------------------- # Events on which the build should be triggered #----------------------------------------------------------------------------- on: + workflow_dispatch: + pull_request: push: branches: - master - pull_request: - #----------------------------------------------------------------------------- # Build matrix @@ -22,164 +22,499 @@ on: jobs: build: - name: ${{ matrix.name }} + name: >- + ${{ matrix.runner }} + ${{ matrix.command }} + ${{ matrix.ghc_version }} + ${{ matrix.name }} env: + # ------------------------------------------------------------------------ + # What to build + # ------------------------------------------------------------------------ + # DISABLE_TEST: "y" + # DISABLE_BENCH: "y" + # DISABLE_DOCS: "y" + # DISABLE_SDIST_BUILD: "y" + # DISABLE_SDIST_GIT_CHECK: "y" + # DISABLE_DIST_CHECKS: "y" + + # ------------------------------------------------------------------------ + # Selecting tool versions + # ------------------------------------------------------------------------ + # For updating see: https://downloads.haskell.org/~ghcup/ + #GHCUP_VERSION: 0.1.50.2 + + # ------------------------------------------------------------------------ + # cabal options + # ------------------------------------------------------------------------ + + # CABAL_BUILD_OPTIONS="-j1" + # Enable the above option if you: + # 1. want logs in serial order to be able to correlate them better. + # + # 2. run into memory issues due to Build paralellism. We need to + # have sufficient per CPU memory, if not we can use a lower -j + # option; cabal default is ncpus. + # + # Currently (2026-03-12) from packcheck output we see: + # Linux: 15GB, 4 cpus + # macOS: 7GB, 3 cpus + # Windows: 16GB, 4 cpus + + # ------------------------------------------------------------------------ + # stack options (if using stack builds) + # ------------------------------------------------------------------------ + # Note requiring a specific version of stack using STACKVER may fail due to + # github API limit while checking and upgrading/downgrading to the specific + # version. + #STACKVER: "1.6.5" + #STACK_UPGRADE: "y" + # ------------------------------------------------------------------------ # Common options # ------------------------------------------------------------------------ - # GHC_OPTIONS: "-Werror" - GHCUP_VERSION: 0.1.20.0 - DOCSPEC_URL: https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20210111/cabal-docspec-0.0.0.20210111.xz - DOCSPEC_OPTIONS: "--timeout 60" - CABAL_REINIT_CONFIG: y - LC_ALL: C.UTF-8 - STACK_UPGRADE: "y" + # Subdir + SUBDIR: ${{ matrix.subdir }} - CABAL_CHECK_RELAX: y - CABAL_HACKAGE_MIRROR: hackage.haskell.org:http://hackage.fpcomplete.com + # If this option is enabled packcheck clears out the environment + # and only uses the options explicitly set on the command line, + # implicit environment won't affect the build. if you find this + # annoying comment this. + CHECK_ENV: "y" - PACKCHECK: "./packcheck.sh" + # NOTE: by capturing the options in env variables here quotes + # are presrved, if we expand them directly into the script + # quotes are lost. + # + # WARNING! you cannot use comments in this + COMMON_OPTIONS: >- + LC_ALL=C.UTF-8 + BUILD_PREFETCH=y + GHCUP_VERSION=latest + GHCVER=${{ matrix.ghc_version }} + + # WARNING! you cannot use comments in this + CABAL_OPTIONS: >- + CABAL_REINIT_CONFIG=y + CABAL_CHECK_RELAX=y + + MATRIX_OPTIONS: ${{ matrix.pack_options }} + + # ------------------------------------------------------------------------ + # Location of packcheck.sh (the shell script invoked to perform CI tests ). + # ------------------------------------------------------------------------ + # You can either commit the packcheck.sh script in your repo root or + # you can use it by specifying the PACKCHECK_REPO_URL option. + # If you have not committed packcheck.sh in your repo at PACKCHECK + # then it is automatically pulled from this URL. PACKCHECK_GITHUB_URL: "https://raw.githubusercontent.com/composewell/packcheck" - PACKCHECK_GITHUB_COMMIT: "7c4e1ab7a59b5ed6e92cfd0da67460a6116be4ac" - - BUILD: ${{ matrix.build }} - GHCVER: ${{ matrix.ghc_version }} - #RESOLVER: ${{ matrix.resolver }} - CABAL_BUILD_OPTIONS: ${{ matrix.cabal_build_options }} - CABAL_PROJECT: ${{ matrix.cabal_project }} - DISABLE_DOCS: ${{ matrix.disable_docs }} - #DISABLE_SDIST_BUILD: ${{ matrix.disable_sdist_build }} - #DISABLE_SDIST_BUILD: "y" - HLINT_VERSION: 3.6.1 - HLINT_OPTIONS: ${{ matrix.hlint_options }} - HLINT_TARGETS: ${{ matrix.hlint_targets }} + PACKCHECK_GITHUB_COMMIT: "dd9ba87d2a42c7cd1d96e3946636c07e732587b4" + # ubuntu seems to have better support than debian on CI systems runs-on: ${{ matrix.runner }} + #continue-on-error: ${{ matrix.ignore_error }} strategy: fail-fast: false matrix: + + # The order of jobs is important to optimize fail-fast, if + # fail-fast is set to true. + + # This section is to order the important jobs first especially for + # "fail-fast" so that these are the ones started first. + #name: + # - ci + + # IMPORTANT NOTE: + # If runner, command, ghc version are identical then the name of + # CI is used to distinguish the cache key. + + # The reason we have an explicit "name" field in the following + # entries is to force an additional config instead of adding to + # an existing config while adding additional configs. + # Look at + # for more info about adding matrix elements. + # Adding any element to the list will increase the number of matrix + # elements proportional to the cross product. + include: - - name: 9.10.1-Werror - ghc_version: 9.10.1 - build: cabal - runner: ubuntu-latest - cabal-version: 3.10.2.0 - cabal_project: cabal.project.d/master-Werror - - name: 9.8.1-Werror - ghc_version: 9.8.1 - build: cabal - runner: ubuntu-latest - cabal-version: 3.10.2.0 - cabal_project: cabal.project.d/master-Werror + #- name: ci + # runner: ubuntu-latest + # command: cabal + # ghc_version: head + # # The URL may change, to find a working URL go to https://gitlab.haskell.org/ghc/ghc/-/jobs/ + # # Find a debian10/11/12 job, click on a passed/failed status, at the + # # end of the output you will find the tar.xz name, put that tar + # # name after "raw/", and put the job name after "job=". + # # Also see https://github.com/mpickering/ghc-artefact-nix/blob/master/gitlab-artifact.nix + # # + # # May also use ghcup for installing ghc head version, use the + # # version "LatestNightly", and the following config: + # # ghcup config add-release-channel https://ghc.gitlab.haskell.org/ghcup-metadata/ghcup-nightlies-0.0.7.yaml + # # WARNING! cannot use # comments inside pack_options. + # pack_options: >- + # GHCUP_GHC_OPTIONS="-u https://gitlab.haskell.org/ghc/ghc/-/jobs/artifacts/master/raw/ghc-x86_64-linux-deb10-int_native-validate.tar.xz?job=x86_64-linux-deb10-int_native-validate" + # CABAL_PROJECT=cabal.project.ghc-head + # DISABLE_SDIST_BUILD="y" - - name: 9.8.1-doctest - runner: ubuntu-latest - ghc_version: 9.8.1 - build: cabal - cabal-version: 3.10.2.0 - cabal_project: cabal.project.d/master - disable_test: "y" - disable_bench: "y" - disable_docs: "y" - disable_sdist_build: "y" - enable_docspec: "y" - - - name: hlint - build: hlint - hlint_options: "lint" - hlint_targets: "src test Benchmark" + - name: ci runner: ubuntu-latest - cabal-version: 3.2 - cabal_project: cabal.project.d/master + command: cabal + ghc_version: 9.14.1 + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + DISABLE_SDIST_BUILD=y + ENABLE_DOCSPEC="y" + DOCSPEC_URL=https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20250606/cabal-docspec-0.0.0.20250606-x86_64-linux.xz + DOCSPEC_OPTIONS="--timeout 60" - - name: 9.6.3-macos + - name: ci runner: macos-latest - ghc_version: 9.6.3 - build: cabal - cabal-version: 3.10.1.0 - cabal_project: cabal.project.d/master + command: cabal + ghc_version: 9.12.4 + # autoreconf required by SDIST build when a configure script + # is present, is not available by default on macOS, so + # disable it. + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + CABAL_PROJECT=cabal.project.d/Werror + DISABLE_SDIST_BUILD=y - - name: 9.4.4-streamly-0.9.0 + - name: ci runner: ubuntu-latest - ghc_version: 9.4.4 - build: cabal - cabal-version: 3.8.1.0 - cabal_project: cabal.project.d/streamly-0.9.0 + command: cabal + ghc_version: 9.10.3 + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + CABAL_PROJECT=cabal.project.d/streamly-0.10.0 - - name: 9.4.4-streamly-0.10.0 + - name: ghc-9.10.3 runner: ubuntu-latest - ghc_version: 9.4.4 - build: cabal - cabal-version: 3.8.1.0 - cabal_project: cabal.project.d/streamly-0.10.0 + command: stack + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + STACK_UPGRADE="y" + STACK_YAML="stack.yaml" + DISABLE_SDIST_BUILD="y" - - name: 9.2.7+fusion-plugin + - name: streamly-master runner: ubuntu-latest - ghc_version: 9.2.7 - build: cabal - cabal-version: 3.6 - cabal_project: cabal.project.d/master - cabal-build-options: --flag fusion-plugin + command: cabal + ghc_version: 9.8.4 + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + CABAL_PROJECT=cabal.project.d/streamly-master + CABAL_BUILD_OPTIONS="--flag fusion-plugin --allow-newer" - - name: 8.10.7 + - name: ci runner: ubuntu-latest - ghc_version: 8.10.7 - build: cabal - cabal-version: 3.2 - cabal_project: cabal.project.d/master - disable_docs: y + command: cabal + ghc_version: 9.6.3 + # WARNING! cannot use # comments inside pack_options. + #pack_options: >- + # CABAL_PROJECT=cabal.project - - name: 8.8.4 + # NOTE: ghc-9.4 is the latest compiler possible for streamly-0.9 + - name: streamly-0.9 runner: ubuntu-latest - ghc_version: 8.8.4 - build: cabal - cabal-version: 3.2 - cabal_project: cabal.project.d/master - disable_docs: y + command: cabal + ghc_version: 9.4.8 + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + CABAL_PROJECT=cabal.project.d/streamly-0.9.0 - - name: 8.6.5 + - name: ci runner: ubuntu-latest - ghc_version: 8.6.5 - build: cabal - cabal-version: 3.2 - cabal_project: cabal.project.d/master - disable_docs: y + command: cabal + ghc_version: 8.10.7 + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + DISABLE_DOCS=y + + - name: ci + runner: windows-latest + command: cabal + ghc_version: 9.14.1 + # On Windows, DISABLE_SDIST_BUILD is useful for (1) avoiding + # path length restriction, (2) avoid installing autoreconf + # for configure builds. + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + DISABLE_SDIST_BUILD="y" + + - name: ci + runner: ubuntu-latest + command: hlint + # WARNING! cannot use # comments inside pack_options. + pack_options: >- + HLINT_VERSION=3.6.1 + HLINT_OPTIONS="lint" + HLINT_TARGETS="src" + +#----------------------------------------------------------------------------- +# Usually you do not need to change anything below, this is generic code for +# caching and running packcheck on Linux/Mac/Windows. +#----------------------------------------------------------------------------- steps: - - uses: actions/checkout@v2 - - uses: actions/cache@v4 - name: Restore cache + - name: Enable long paths on Windows + if: runner.os == 'Windows' + shell: powershell + continue-on-error: true + run: | + # Enable long paths. Sometimes failures occur due to path + # length limitation. + Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1 + + # Cache saving is very slow on Windows, it could be due to tar, + # or the compression program or the file system. Changing the + # compression level of zstd does not help. We are also not able to pick + # another tar program by changing the path, tar is picked up by the + # cache action itself. + + # This does not seem to make much difference. + # Disable Windows Defender to speed up IO/Tar operations + #Set-MpPreference -DisableRealtimeMonitoring $true + + - uses: actions/checkout@v4 + + # This should happen before cache restore. + - name: Remove ~/.ghcup symlink (non-Windows) + if: runner.os != 'Windows' + run: | + rm -f ~/.ghcup + + # See the "cabal path" output in the CI logs to tweak the cache + # locations. + + # Shared by all tests, all platforms + - name: Restore hackage package index (non-Windows) + id: restore-hackage + uses: actions/cache/restore@v4 + if: runner.os != 'Windows' with: path: | - ~/.local - ~/.cabal + ~/.cache/cabal/packages + key: cabal-hackage-index-non-windows + + # GHC is not test/options specific + - name: Restore ghcup and ghc (non-Windows) + id: restore-ghcup + uses: actions/cache/restore@v4 + if: runner.os != 'Windows' + with: + path: | + ~/.ghcup + key: ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }} + + # GHC is not test/options specific + #- name: Restore ghcup and ghc (Windows) + # id: restore-ghcup-win + # uses: actions/cache/restore@v4 + # if: runner.os == 'Windows' + # with: + # path: | + # C:/ghcup + # key: ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }} + + # XXX If we want to invalidate the cache on resolver change we + # should use a separate cache for stack as it should be keyed on + # resolver as well. But that requires resolver as a matrix element + # and then copied to pack_options from there, needs some work. It + # should be fine as resolver minor version change can only increase + # the cache size. + # Deps are test/options specific + - name: Restore build dependencies (non-Windows) + id: restore-deps-nonwin + uses: actions/cache/restore@v4 + if: runner.os != 'Windows' + with: + # cabal: ~/.local/bin, ~/.local/state/cabal + # ~/.cache/cabal/packages can be cached, but will increase the + # cache size. But can save the "cabal update" time. + path: | + ~/.local/bin + ~/.local/state/cabal ~/.stack - .stack-work - key: ${{ runner.os }}-${{ matrix.name }} + key: ${{ matrix.command }}-deps-ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}-${{ matrix.name }} + + # Deps are test/options specific + - name: Restore build dependencies, hackage index, local/bin (Windows) + id: restore-deps-win + uses: actions/cache/restore@v4 + if: runner.os == 'Windows' + with: + path: | + C:/cabal + key: ${{ matrix.command }}-deps-ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}-${{ matrix.name }} - name: Download packcheck + # on windows-latest GitHub Actions defaults to PowerShell + shell: bash run: | - # If a custom stack-yaml is specified, replace the default with that - #if test -e "$STACK_YAML"; then rm -f stack.yaml && ln -sv $STACK_YAML stack.yaml; else true; fi - #unset STACK_YAML - - if test ! -e "$PACKCHECK" - then - if test -z "$PACKCHECK_GITHUB_COMMIT" + download_one () { + if test ! -e "$1" then - die "PACKCHECK_GITHUB_COMMIT is not specified." + if test -z "$PACKCHECK_GITHUB_COMMIT" + then + die "Downloading [$1]: PACKCHECK_GITHUB_COMMIT env var is not specified." + fi + PACKCHECK_URL_PREFIX=${PACKCHECK_GITHUB_URL}/${PACKCHECK_GITHUB_COMMIT} + curl --fail -sLO ${PACKCHECK_URL_PREFIX}/$1 || exit 1 + chmod +x "$1" + elif test ! -x "$1" + then + chmod +x $1 fi - PACKCHECK_URL=${PACKCHECK_GITHUB_URL}/${PACKCHECK_GITHUB_COMMIT}/packcheck.sh - curl --fail -sL -o "$PACKCHECK" $PACKCHECK_URL || exit 1 - chmod +x $PACKCHECK - elif test ! -x "$PACKCHECK" - then - chmod +x $PACKCHECK + } + if test -n "$SUBDIR"; then + cd "$SUBDIR" fi + download_one packcheck.sh - - name: Run packcheck + # Store the function in a file so that it can be reused across multiple + # steps. + - name: Setup packcheck + shell: bash run: | - bash -c "$PACKCHECK $BUILD" + if test -n "$SUBDIR"; then + rm -f cabal.project + cd "$SUBDIR" + fi + cat << 'EOF' > packcheck-setup.sh + setup_packcheck_args() { + ARGS="${{ matrix.command }} $COMMON_OPTIONS" + if test "${{ matrix.command }}" = "cabal"; then + ARGS="$ARGS $CABAL_OPTIONS" + fi + + # Caution: do not use matrix.pack_options directly here + # quotes will get stripped. + ARGS="$ARGS $MATRIX_OPTIONS" + PATH_VAR=/bin:/usr/bin:/sbin:/usr/sbin + + case "$(uname)" in + Linux) + export GHCUP_INSTALL_BASE_PREFIX=$HOME + # Access usr/local seems to be much slower on github + #PATH_VAR="$PATH_VAR:/usr/local/.ghcup/bin" + ;; + CYGWIN*|MINGW*|MSYS*) + for var in APPDATA CABAL_DIR; do + val="${!var}" + [ -n "$val" ] && ARGS="$ARGS $var=\"$(cygpath -u "$val")\"" + done + ARGS="$ARGS CABAL_BUILDDIR=\"/c/b\" WINVER=$WINVER" + ARGS="$ARGS NUMBER_OF_PROCESSORS=$NUMBER_OF_PROCESSORS" + ARGS="$ARGS PROCESSOR_IDENTIFIER=\"$PROCESSOR_IDENTIFIER\"" + PATH_VAR="$PATH_VAR:/c/ghcup:/c/Program Files/7-Zip:/mingw64/bin" + ;; + esac + ARGS="$ARGS PATH=\"$PATH_VAR\"" + export ARGS + } + EOF + + - name: Run packcheck (dependencies only) + id: deps-only + # Check the relevant step based on the runner OS + if: | + (runner.os != 'Windows' && steps.restore-deps-nonwin.outputs.cache-hit != 'true') || + (runner.os == 'Windows' && steps.restore-deps-win.outputs.cache-hit != 'true') + shell: bash + run: | + if test -n "$SUBDIR"; then + cd "$SUBDIR" + fi + source packcheck-setup.sh + setup_packcheck_args + eval "./packcheck.sh $ARGS BUILD_DEPS_ONLY=y" + + - name: Save hackage package index (non-Windows) + uses: actions/cache/save@v4 + if: always() && steps.deps-only.outcome == 'success' && runner.os != 'Windows' && steps.restore-hackage.outputs.cache-hit != 'true' + with: + path: ~/.cache/cabal/packages + key: cabal-hackage-index-non-windows + + - name: Save ghcup and ghc (non-Windows) + uses: actions/cache/save@v4 + if: always() && steps.deps-only.outcome == 'success' && runner.os != 'Windows' && steps.restore-ghcup.outputs.cache-hit != 'true' + with: + path: ~/.ghcup + key: ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }} + + # On Windows, ghc restore step takes 2-3 minutes whereas installing + # GHC takes less than 2 minutes. On top of this saving the ghc cache + # takes 7 minutes. So this does not make sense. + #- name: Save ghcup and ghc (Windows) + # uses: actions/cache/save@v4 + # if: always() && steps.deps-only.outcome == 'success' && runner.os == 'Windows' && steps.restore-ghcup-win.outputs.cache-hit != 'true' + # with: + # path: | + # C:/ghcup + # key: ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }} + + # Deps are test/options specific, hence, matrix.name in the key + - name: Save build dependencies (non-Windows) + uses: actions/cache/save@v4 + if: always() && steps.deps-only.outcome == 'success' && runner.os != 'Windows' && steps.restore-deps-nonwin.outputs.cache-hit != 'true' + with: + path: | + ~/.local/bin + ~/.local/state/cabal + ~/.stack + key: ${{ matrix.command }}-deps-ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}-${{ matrix.name }} + + # hackage package index is part of C:/cabal + # Deps are test/options specific, hence, matrix.name in the key + # Add if needed ~/AppData/Roaming/local + - name: Save build dependencies (Windows) + uses: actions/cache/save@v4 + if: always() && steps.deps-only.outcome == 'success' && runner.os == 'Windows' && steps.restore-deps-win.outputs.cache-hit != 'true' + with: + path: | + C:/cabal + key: ${{ matrix.command }}-deps-ghc-${{ matrix.ghc_version }}-v${{ matrix.ghc_salt }}-${{ matrix.runner }}-${{ matrix.name }} + + - name: Run packcheck (final build) + shell: bash + run: | + if test -n "$SUBDIR"; then + cd "$SUBDIR" + fi + source packcheck-setup.sh + setup_packcheck_args + eval "./packcheck.sh $ARGS BUILD_PACKAGE_ONLY=y" + + # Enable for debugging, this itself takes 50 sec on Windows, in packcheck + # build which is tiny. + #- name: Check cache locations + # shell: bash + # run: | + # # We want to see if any cache paths are symlinks; e.g. on github + # # ~/.ghcup is a pre-existing symlink to /usr/local. + # if [ "$RUNNER_OS" == "Windows" ]; then + # # Convert Windows paths to Unix-style for Bash + # APPDATA_UNIX=$(cygpath "$APPDATA") + # list="$APPDATA_UNIX/local C:/ghcup C:/cabal" + # else + # list="$HOME/.local/bin $HOME/.local/state/cabal $HOME/.ghcup $HOME/.stack" + # fi + + # for dir in $list; do + # # macOS does not have --no-dereference option + # if [ -L "$dir" ]; then + # echo "$dir is a symlink -> $(readlink $dir)" + # elif [ -d "$dir" ]; then + # du -sh "$dir" 2>/dev/null || echo "$dir permission denied" + # else + # echo "$dir missing or not a dir" + # fi + # done + # echo + # #ls -ld $list 2>/dev/null || true + # ls -al $list 2>/dev/null || true diff --git a/.packcheck.ignore b/.packcheck.ignore index f6ae9f0..73a958c 100644 --- a/.packcheck.ignore +++ b/.packcheck.ignore @@ -6,8 +6,8 @@ hie.yaml appveyor.yml default.nix stack.yaml -cabal.project.d/master -cabal.project.d/master-Werror +cabal.project.d/streamly-master +cabal.project.d/Werror cabal.project.d/streamly-0.9.0 cabal.project.d/streamly-0.10.0 flake.lock diff --git a/cabal.project.d/Werror b/cabal.project.d/Werror new file mode 100644 index 0000000..4130fcb --- /dev/null +++ b/cabal.project.d/Werror @@ -0,0 +1,4 @@ +packages: streamly-process.cabal + +package streamly-process + ghc-options: -Werror diff --git a/cabal.project.d/master-Werror b/cabal.project.d/master-Werror deleted file mode 100644 index df798f3..0000000 --- a/cabal.project.d/master-Werror +++ /dev/null @@ -1,15 +0,0 @@ -packages: streamly-process.cabal - -package streamly-process - ghc-options: -Werror - -source-repository-package - type: git - location: https://github.com/composewell/streamly.git - tag: master - -source-repository-package - type: git - location: https://github.com/composewell/streamly.git - tag: master - subdir: core diff --git a/cabal.project.d/streamly-0.10.0 b/cabal.project.d/streamly-0.10.0 index 3da1728..4fde714 100644 --- a/cabal.project.d/streamly-0.10.0 +++ b/cabal.project.d/streamly-0.10.0 @@ -1,5 +1,5 @@ packages: streamly-process.cabal constraints: - streamly == 0.10.0.* - , streamly-core == 0.2.0.* + streamly == 0.10.* + , streamly-core == 0.2.* diff --git a/cabal.project.d/master b/cabal.project.d/streamly-master similarity index 100% rename from cabal.project.d/master rename to cabal.project.d/streamly-master diff --git a/stack.yaml b/stack.yaml index bbff110..518f1ff 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,4 +1,4 @@ -resolver: lts-22.0 +resolver: lts-24.37 packages: - '.' extra-deps: diff --git a/streamly-process.cabal b/streamly-process.cabal index 66245bb..b306535 100644 --- a/streamly-process.cabal +++ b/streamly-process.cabal @@ -25,21 +25,21 @@ maintainer: streamly@composewell.com copyright: Composewell Technologies category: Streamly, Streaming, System stability: Experimental -tested-with: GHC==9.10.1 - , GHC==9.8.1 - , GHC==9.6.3 - , GHC==9.4.4 - , GHC==9.2.7 - , GHC==9.0.2 - , GHC==8.10.7 - , GHC==8.8.4 - , GHC==8.6.5 -build-type: Simple -extra-source-files: +tested-with: + GHC==9.14.1 + , GHC==9.12.4 + , GHC==9.10.3 + , GHC==9.8.4 + , GHC==9.6.3 + , GHC==9.4.8 + , GHC==8.10.7 +build-type: Simple +extra-doc-files: CHANGELOG.md NOTICE README.md design/proposal.md +extra-source-files: src/DocTestCommand.hs src/DocTestProcess.hs test/data/failExec.bat From 057962723a87ef3225b09ba36c6b439862fd8d82 Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Fri, 17 Apr 2026 00:10:38 +0530 Subject: [PATCH 5/7] Update appveyor config --- appveyor.yml | 72 +++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f0472ee..dcd742d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,10 +1,11 @@ -# packcheck-0.7.0 +# packcheck-0.7.1 # You can use any of the options supported by packcheck as environment # variables here. See https://github.com/composewell/packcheck for all # options and their explanation. -branches: - only: - - master + +#branches: +# only: +# - master environment: # ------------------------------------------------------------------------ @@ -14,42 +15,37 @@ environment: # ------------------------------------------------------------------------ # Common options # ------------------------------------------------------------------------ - GHC_OPTIONS: "-Werror" CABAL_REINIT_CONFIG: "y" LC_ALL: "C.UTF-8" + # ------------------------------------------------------------------------ + # How to build + # ------------------------------------------------------------------------ + # + GHCUP_VERSION: "0.1.50.2" + GHCVER: "9.12.4" + #CABALVER: "3.10.3.0" + # ------------------------------------------------------------------------ # What to build # ------------------------------------------------------------------------ # DISABLE_TEST: "y" # DISABLE_BENCH: "y" # DISABLE_DOCS: "y" - DISABLE_SDIST_BUILD: "y" # DISABLE_DIST_CHECKS: "y" - - # ------------------------------------------------------------------------ - # stack options - # ------------------------------------------------------------------------ - # Note requiring a specific version of stack using STACKVER may fail due to - # github API limit while checking and upgrading/downgrading to the specific - # version. - #STACKVER: "1.6.5" - STACK_UPGRADE: "y" - RESOLVER: "lts-22.0" - STACK_ROOT: "c:\\sr" - STACK_YAML: "stack.yaml" + # On Windows, DISABLE_SDIST_BUILD is useful for (1) avoiding + # path length restriction, (2) avoid installing autoreconf + # for configure builds. + DISABLE_SDIST_BUILD: "y" + # Note: these require the "diff" utility. + # DISABLE_SDIST_GIT_CHECK: "y" + DISABLE_SDIST_PROJECT_CHECK: "y" # ------------------------------------------------------------------------ # cabal options # ------------------------------------------------------------------------ CABAL_CHECK_RELAX: "y" - CABAL_HACKAGE_MIRROR: "hackage.haskell.org:http://hackage.fpcomplete.com" - - # ------------------------------------------------------------------------ - # Where to find the required tools - # ------------------------------------------------------------------------ - PATH: "%PATH%;%APPDATA%\\local\\bin" - LOCAL_BIN: "%APPDATA%\\local\\bin" + #CABAL_PROJECT: "cabal.project" # ------------------------------------------------------------------------ # Location of packcheck.sh (the shell script invoked to perform CI tests ). @@ -62,31 +58,33 @@ environment: # If you have not committed packcheck.sh in your repo at PACKCHECK_LOCAL_PATH # then it is automatically pulled from this URL. PACKCHECK_GITHUB_URL: "https://raw.githubusercontent.com/composewell/packcheck" - PACKCHECK_GITHUB_COMMIT: "v0.7.0" + PACKCHECK_GITHUB_COMMIT: "dd9ba87d2a42c7cd1d96e3946636c07e732587b4" # Override the temp directory to avoid sed escaping issues # See https://github.com/haskell/cabal/issues/5386 TMP: "c:\\tmp" +# Bump the -> version to clear the cache +# packcheck uses "%APPDATA%\\local" to install tools like hlint etc. +# cabal may use "%APPDATA%\\cabal" or "c:\\cabal" +# ghcup may use "%APPDATA%\\ghcup" or "c:\\ghcup" cache: - - "%STACK_ROOT%" - - "%LOCAL_BIN%" + - "%APPDATA%\\local\\bin -> v1" - "%APPDATA%\\cabal" - - "%APPDATA%\\ghc" -# - "%LOCALAPPDATA%\\Programs\\stack" + - "%LOCALAPPDATA%\\cabal" + - "C:\\ghcup" + - "C:\\cabal" +# Folder where the repository is cloned. clone_folder: "c:\\pkg" build: off before_test: -- if not exist %PACKCHECK_LOCAL_PATH% curl -sSkL -o%PACKCHECK_LOCAL_PATH% %PACKCHECK_GITHUB_URL%/%PACKCHECK_GITHUB_COMMIT%/packcheck.sh -- if not exist %LOCAL_BIN% mkdir %LOCAL_BIN% -- where stack.exe || curl -sSkL -ostack.zip http://www.stackage.org/stack/windows-x86_64 && 7z x stack.zip stack.exe && move stack.exe %LOCAL_BIN% -- if defined STACKVER (stack upgrade --binary-only --binary-version %STACKVER%) else (stack upgrade --binary-only || ver > nul) -- stack --version +- if not exist %PACKCHECK_LOCAL_PATH% curl --fail -sSL -o%PACKCHECK_LOCAL_PATH% %PACKCHECK_GITHUB_URL%/%PACKCHECK_GITHUB_COMMIT%/packcheck.sh test_script: -- stack setup > nul - for /f "usebackq tokens=*" %%i in (`where 7z.exe`) do set PATH7Z=%%i\.. - for /f "usebackq tokens=*" %%i in (`where git.exe`) do set PATHGIT=%%i\.. -- chcp 65001 && stack exec bash -- -c "chmod +x %PACKCHECK_LOCAL_PATH%; %PACKCHECK_LOCAL_PATH% stack PATH=/usr/bin:\"%PATH7Z%\":\"%PATHGIT%\"" +- for /f "usebackq tokens=*" %%i in (`where curl.exe`) do set PATHCURL=%%i\.. +- chcp 65001 +- bash %PACKCHECK_LOCAL_PATH% cabal PATH="/usr/bin:%PATH7Z%:%PATHGIT%:%PATHCURL%" From 649a1f15201268973ed13bae2edc33205340386d Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Fri, 17 Apr 2026 01:06:04 +0530 Subject: [PATCH 6/7] Bump minor version and update changelog --- CHANGELOG.md | 4 ++++ streamly-process.cabal | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c543f00..76a4f3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.4.1 (Apr 2026) + +* Rename quotedWord to shellWord + ## 0.4.0 (Sep 2025) * Remove buffering from the pipe chunked APIs. diff --git a/streamly-process.cabal b/streamly-process.cabal index b306535..c844179 100644 --- a/streamly-process.cabal +++ b/streamly-process.cabal @@ -1,6 +1,6 @@ cabal-version: 2.2 name: streamly-process -version: 0.4.0 +version: 0.4.1 synopsis: Write shell-like command pipelines in Haskell description: Treat operating system (OS) processes as first-class stream From eb1c3e81e22c588a4af43928210ba773032e83db Mon Sep 17 00:00:00 2001 From: Harendra Kumar Date: Fri, 17 Apr 2026 03:24:05 +0530 Subject: [PATCH 7/7] Update nixpack to fetch test/benchmark deps --- flake.lock | 18 +++++++++--------- flake.nix | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/flake.lock b/flake.lock index d0a450a..05f06b6 100644 --- a/flake.lock +++ b/flake.lock @@ -7,33 +7,33 @@ "nixpkgs-darwin": "nixpkgs-darwin" }, "locked": { - "lastModified": 1776359956, - "narHash": "sha256-sJ7rbofR7LQIVCHdLhORocWg8dR8u1PnontbgFtKvbU=", + "lastModified": 1776376313, + "narHash": "sha256-lfL+xfAZVM4nYLEggaRo3nBNxTHKgjdxJTcEHkM8P7Q=", "ref": "refs/heads/master", - "rev": "71f2b6792a9f64be2c4bca5050cb1e08edd625b2", - "revCount": 122, + "rev": "187bde6bd362eced707ed96198ddc193af66ff42", + "revCount": 123, "type": "git", "url": "ssh://git@github.com/composewell/streamly-packages" }, "original": { - "rev": "71f2b6792a9f64be2c4bca5050cb1e08edd625b2", + "rev": "187bde6bd362eced707ed96198ddc193af66ff42", "type": "git", "url": "ssh://git@github.com/composewell/streamly-packages" } }, "basepkgs_2": { "locked": { - "lastModified": 1776352576, - "narHash": "sha256-/rNYSCE5o+u5ZRfpE+PaDjmp5ttEgSLyiRoDOgguKJw=", + "lastModified": 1776376172, + "narHash": "sha256-tVn1PuKG+kJGH2PUnV3weRHDnbtgUDlwwSC0K3A45aM=", "owner": "composewell", "repo": "nixpack", - "rev": "8c0e3596f53ae42c43175b7440d9c0f5c462997c", + "rev": "f50a0b2aaaab434f46847bc171240957b508b901", "type": "github" }, "original": { "owner": "composewell", "repo": "nixpack", - "rev": "8c0e3596f53ae42c43175b7440d9c0f5c462997c", + "rev": "f50a0b2aaaab434f46847bc171240957b508b901", "type": "github" } }, diff --git a/flake.nix b/flake.nix index c426fde..9475b73 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,7 @@ description = "streamly-process"; inputs = { - basepkgs.url = "git+ssh://git@github.com/composewell/streamly-packages?rev=71f2b6792a9f64be2c4bca5050cb1e08edd625b2"; + basepkgs.url = "git+ssh://git@github.com/composewell/streamly-packages?rev=187bde6bd362eced707ed96198ddc193af66ff42"; nixpkgs.follows = "basepkgs/nixpkgs"; nixpkgs-darwin.follows = "basepkgs/nixpkgs-darwin"; };