Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/hfd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import qualified Streamly.Data.Stream.Prelude as Stream
import qualified Streamly.FileSystem.Handle as Handle
import qualified Streamly.FileSystem.Path as Path

import Streamly.Coreutils.Find
import Coreutils.Find
( FindOptions
, findByteChunked
, maxResults
Expand Down Expand Up @@ -114,7 +114,7 @@ parserInfo =
(configParser <**> helper)
(fullDesc
<> briefDesc
<> progDesc "A basic fd-like driver for Streamly.Coreutils.Find."
<> progDesc "A basic fd-like driver for Coreutils.Find."
<> header "hfd")

main :: IO ()
Expand Down
2 changes: 1 addition & 1 deletion benchmark/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Control.Monad.IO.Class (MonadIO)
import Gauge
import Streamly.Data.Stream (Stream)
import System.Random
import Streamly.Coreutils.Uniq
import Coreutils.Uniq

import qualified Streamly.Data.Stream as S
import qualified Streamly.Data.Fold as Fold
Expand Down
22 changes: 0 additions & 22 deletions design/design-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,6 @@ sugegsted above.
We can basically wrap the Haskell functions in CLI parser and an output
renderer to make a Unix like utility.

## Module Naming

We can either keep each utility in its own module or bundle them into a smaller
set of modules. The latter would help reduce the imports. But it may be easier
to remember the module names if they are based on the utility name.

We should keep the naming non-conflicting such that if some wants to bundle
them in a single module and re-export it should be possible. In fact we can
provide a single coreutils module exporting everything.

Each command must have its own module e.g. Coreutils.Cp for the cp command.

The command options could be called "Options" in each module but then
we may not be able to export all commands from a single module which is
desirable. So we can choose to call the options of a command by the same
name as the command itself e.g. "CpOptions". We would not expose the
CpOptions record outside the module but we would still need to export
the type. Using a unique type for each command would help us use it
unqualified.

The command runner would be called "cp" so it would be "cp :: CpOptions -> IO ()".

## API for utilities

There are two ways of writing the API, (1) use separate functions
Expand Down
53 changes: 53 additions & 0 deletions design/naming.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
## Module Naming

## Problem

Multiple Haskell modules (`touch`, `mv`, `rm`) expose option setters with the
same names (e.g., `force`, `recursive`), causing name conflicts when
aggregating them into a single module.

## Options considered

1. Import modules separately (qualified)
2. Rename functions to be unique (`mvForce`, `rmForce`, etc.)
3. Use typeclasses to overload names
4. Provide an aggregated module with aliases

## Decision

Use separate modules with qualified imports. Each command can have its own
module e.g. Coreutils.Cp for the cp command. It may be easy to remember the
module names if they are based on the utility name.

## Rationale

This avoids naming conflicts without renaming functions, keeps the API
intuitive and avoids unnecessary complexity.

The downside is too many imports. But users get to choose what they
import them as, that gives the flexibility of choosing the prefix
rather than hardocding it in the function name itself. Imports can be
automatically managed.

Things that do not conflict can still be imported as a single import i.e.
as Coreutils.

## Best Effort

Let users bundle it if they want to. We can try to keep the naming
non-conflicting as much as we can such that if someone wants to bundle them in
a single module and re-export it should be possible with least effort.

To avoid conflicts, the options for Cp could be called "CpOptions" and
similarly for each module. Otherwise, we may not be able to export all
commands from a single module which is desirable. Using a unique type
for each command would help us use it unqualified.

The command runner would be called "cp" so it would be "cp :: CpOptions -> IO
()".

## Example usage

`Touch.touch (Touch.create False . Touch.followLinks False) path`
`Mv.mv (Mv.force True) old new`
`Rm.rm (Rm.withForce Rm.Force . Rm.recursive True) path`
2 changes: 1 addition & 1 deletion hie.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ cradle:
- path: "./src"
component: "lib:streamly-coreutils"
- path: "./test"
component: "test:Streamly.Coreutils.Rm"
component: "test:Coreutils.Rm"
dependencies:
- streamly-coreutils.cabal
- hie.yaml
16 changes: 16 additions & 0 deletions src/Coreutils.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- |
-- Module : Coreutils
-- Copyright : (c) 2020 Composewell Technologies
-- License : Apache-2.0
-- Maintainer : streamly@composewell.com
-- Stability : experimental
-- Portability : GHC
--
module Coreutils
( module Coreutils.Cp
, module Coreutils.FileTest
)
where

import Coreutils.Cp
import Coreutils.FileTest
6 changes: 3 additions & 3 deletions src/Streamly/Coreutils/Chmod.hs → src/Coreutils/Chmod.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- |
-- Module : Streamly.Coreutils.Chmod
-- Module : Coreutils.Chmod
-- Copyright : (c) 2026 Composewell Technologies
-- License : Apache-2.0
-- Maintainer : streamly@composewell.com
Expand All @@ -17,7 +17,7 @@
-- >>> _ = chmod (additive True) (groupWrite False) -- chmod g-w FILE
-- >>> _ = chmod (modeFrom file) (groupWrite True) -- chmod --reference=ref FILE

module Streamly.Coreutils.Chmod
module Coreutils.Chmod
( -- * Runner
chmod

Expand Down Expand Up @@ -60,7 +60,7 @@ import qualified Streamly.FileSystem.Path as Path

-- $setup
-- >>> :set -XQuasiQuotes
-- >>> import Streamly.Coreutils.Chmod
-- >>> import Coreutils.Chmod
-- >>> import Streamly.FileSystem.Path (path)
-- >>> file = [path|a.txt|]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{-# LANGUAGE PatternSynonyms #-}

-- | This module is deprecated. Use 'Data.Bool' and 'Bool' instead.
module Streamly.Coreutils.Common
module Coreutils.Common
{-# DEPRECATED "This module is deprecated. Please use 'Bool' from 'Data.Bool' instead." #-}
( Switch
#if __GLASGOW_HASKELL__ >= 914
Expand Down
6 changes: 3 additions & 3 deletions src/Streamly/Coreutils/Cp.hs → src/Coreutils/Cp.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- |
-- Module : Streamly.Coreutils.Cp
-- Module : Coreutils.Cp
-- Copyright : (c) 2022 Composewell Technologies
-- License : Apache-2.0
-- Maintainer : streamly@composewell.com
Expand All @@ -8,7 +8,7 @@
--
-- Copy a file or directory.

module Streamly.Coreutils.Cp
module Coreutils.Cp
( cp

-- * Cp options
Expand All @@ -28,7 +28,7 @@ import qualified Streamly.Internal.FileSystem.FileIO as File
import Streamly.FileSystem.Path (Path)
import qualified Streamly.FileSystem.Path as Path

import Streamly.Coreutils.FileTest
import Coreutils.FileTest

-- Note: Recursive copy can be done using find.
--
Expand Down
4 changes: 2 additions & 2 deletions src/Streamly/Coreutils/Cut.hs → src/Coreutils/Cut.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- |
-- Module : Streamly.Coreutils.Cut
-- Module : Coreutils.Cut
-- Copyright : (c) 2025 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
Expand All @@ -8,7 +8,7 @@
--
-- Functionality equivalent to the @cut@ command.

module Streamly.Coreutils.Cut
module Coreutils.Cut
( foldIndicesBy -- XXX rename to cut

-- * Deprecated
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- |
-- Module : Streamly.Coreutils.Directory
-- Module : Coreutils.Directory
-- Copyright : (c) 2022 Composewell Technologies
-- License : Apache-2.0
-- Maintainer : streamly@composewell.com
Expand All @@ -8,7 +8,7 @@
--
-- Perform directory related operations.

module Streamly.Coreutils.Directory
module Coreutils.Directory
( home
, pwd
, cd
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- |
-- Module : Streamly.Coreutils.Dirname
-- Module : Coreutils.Dirname
-- Copyright : (c) 2022 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
Expand All @@ -8,7 +8,7 @@
--
-- Strip the last component from file name.

module Streamly.Coreutils.Dirname
module Coreutils.Dirname
(dirname)
where

Expand Down
10 changes: 5 additions & 5 deletions src/Streamly/Coreutils/FileTest.hs → src/Coreutils/FileTest.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-- |
-- Module : Streamly.Coreutils.FileTest
-- Module : Coreutils.FileTest
-- Copyright : (c) 2021 Composewell Technologies
-- License : Apache-2.0
-- Maintainer : streamly@composewell.com
Expand Down Expand Up @@ -72,7 +72,7 @@
-- >>> _ <- test [path|/usr/bin/ls|] (isReadable `and_` size (> 4096))
-- >>> _ <- test [path|/usr/bin/ls|] (modifyTimeComparedTo [path|reference.txt|] (>))

module Streamly.Coreutils.FileTest
module Coreutils.FileTest
(
-- * File Test Predicate Type
FileTest
Expand Down Expand Up @@ -249,13 +249,13 @@ import System.Posix.Types (Fd, FileMode)
import qualified System.PosixCompat.Files as Files

#if !defined(CABAL_OS_WINDOWS)
import qualified Streamly.Coreutils.FileTest.Posix as FileTest
import qualified Coreutils.FileTest.Posix as FileTest
#else
import qualified Streamly.Coreutils.FileTest.Windows as FileTest
import qualified Coreutils.FileTest.Windows as FileTest
#endif

import Streamly.FileSystem.Path (Path)
import Streamly.Coreutils.FileTest.Common
import Coreutils.FileTest.Common
import Prelude hiding (and, or)

-- $setup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
{-# LANGUAGE ScopedTypeVariables #-}

-- |
-- Module : Streamly.Coreutils.FileTest.Common
-- Module : Coreutils.FileTest.Common
-- Copyright : (c) 2021 Composewell Technologies
-- License : Apache-2.0
-- Maintainer : streamly@composewell.com
-- Stability : experimental
-- Portability : GHC
--
-- See "Streamly.Coreutils.FileTest" module for general module level
-- See "Coreutils.FileTest" module for general module level
-- documentation. This module provides both posix and windows implementations.
--
-- Design Notes:
Expand Down Expand Up @@ -68,7 +68,7 @@
-- XXX Need tests for Windows. Especially for file access permissions. How do
-- ACLs affect it? Also file times.

module Streamly.Coreutils.FileTest.Common
module Coreutils.FileTest.Common
(
-- * File Test Predicate Type
Predicate (..)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
-- |
-- Module : Streamly.Coreutils.FileTest.Posix
-- Module : Coreutils.FileTest.Posix
-- Copyright : (c) 2021 Composewell Technologies
-- License : Apache-2.0
-- Maintainer : streamly@composewell.com
-- Stability : experimental
-- Portability : GHC
--
-- See "Streamly.Coreutils.FileTest" module for general module level
-- See "Coreutils.FileTest" module for general module level
-- documentation. This is a posix specific version of
-- "Streamly.Coreutils.FileTest" with some additional posix specific functions.
-- "Coreutils.FileTest" with some additional posix specific functions.

module Streamly.Coreutils.FileTest.Posix
module Coreutils.FileTest.Posix
( testFd
, testHandle
, sameFileAs
Expand All @@ -36,7 +36,7 @@ import qualified System.Posix.Terminal as Terminal

import Streamly.FileSystem.Path (Path)
import qualified Streamly.FileSystem.Path as Path
import Streamly.Coreutils.FileTest.Common
import Coreutils.FileTest.Common

-- XXX 'getFdStatus' is not implemented for Windows in unix-compat.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Streamly.Coreutils.FileTest.Windows
module Coreutils.FileTest.Windows
( sameFileAs
, isTerminalFd
{-
Expand Down Expand Up @@ -83,7 +83,7 @@ import qualified System.Win32.Types as Win32
import Foreign
import Streamly.FileSystem.Path (Path)
import qualified Streamly.FileSystem.Path as Path
import Streamly.Coreutils.FileTest.Common
import Coreutils.FileTest.Common

-------------------------------------------------------------------------------
-- Types
Expand Down
4 changes: 2 additions & 2 deletions src/Streamly/Coreutils/Find.hs → src/Coreutils/Find.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{-# OPTIONS_GHC -Wno-unused-binds #-}
{-# OPTIONS_GHC -Wno-unused-imports #-}
-- |
-- Module : Streamly.Coreutils.Find
-- Module : Coreutils.Find
-- Copyright : (c) 2026 Composewell Technologies
-- License : BSD-3-Clause
-- Maintainer : streamly@composewell.com
Expand Down Expand Up @@ -61,7 +61,7 @@
-- time hfind > /dev/null # This, Haskell implementation
-- @

module Streamly.Coreutils.Find
module Coreutils.Find
(
find
, findChunked
Expand Down
Loading
Loading