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
6 changes: 3 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ jobs:
- { os: ubuntu-latest, ghc: 9.4.3, cabal: 3.8.1.0 }
# TODO: Unpin cabal from 3.12.10 after https://github.com/haskell/cabal/issues/10718 is fixed.
- { os: ubuntu-latest, ghc: latest, cabal: 3.12.1.0, cabal-package-flags: +os-string, ghc-flags: -Werror=deprecations }
- { os: windows-latest, stack: lts-15.3, stack-extra-deps: "bytestring-0.11.3.0, file-io-0.1.4, filepath-1.4.100.0, time-1.9.3, Win32-2.13.3.0", overrides: "before_prepare() { sed -i.bak -e /CreateSymbolicLinkW/d -e /GetFinalPathNameByHandleW/d configure.ac; }" }
- { os: windows-latest, stack: lts-17.5, stack-extra-deps: "bytestring-0.11.3.0, file-io-0.1.4, filepath-1.4.100.0, time-1.9.3, Win32-2.13.3.0" }
- { os: windows-latest, stack: lts-22.7, stack-extra-deps: "bytestring-0.11.5.3, file-io-0.1.4, filepath-1.5.2.0, os-string-2.0.2, time-1.14, Win32-2.14.0.0", stack-package-flags: "{directory: {os-string: true}, file-io: {os-string: true}, Win32: {os-string: true}}", ghc-flags: -Werror=deprecations }
- { os: windows-latest, stack: lts-15.3, stack-extra-deps: "bytestring-0.11.3.0, file-io-0.1.4, filepath-1.4.100.0, time-1.9.3, Win32-2.14.1.0", overrides: "before_prepare() { sed -i.bak -e /CreateSymbolicLinkW/d -e /GetFinalPathNameByHandleW/d configure.ac; }" }
- { os: windows-latest, stack: lts-17.5, stack-extra-deps: "bytestring-0.11.3.0, file-io-0.1.4, filepath-1.4.100.0, time-1.9.3, Win32-2.14.1.0" }
- { os: windows-latest, stack: lts-22.7, stack-extra-deps: "bytestring-0.11.5.3, file-io-0.1.4, filepath-1.5.2.0, os-string-2.0.2, time-1.14, Win32-2.14.1.0", stack-package-flags: "{directory: {os-string: true}, file-io: {os-string: true}, Win32: {os-string: true}}", ghc-flags: -Werror=deprecations }
runs-on: ${{ matrix.os }}
env:
CABAL_PACKAGE_FLAGS: ${{ matrix.cabal-package-flags }}
Expand Down
7 changes: 7 additions & 0 deletions System/Directory.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ module System.Directory
, getUserDocumentsDirectory
, getTemporaryDirectory

-- * PATH
, System.Directory.getPath

-- * Actions on files
, removeFile
, renameFile
Expand Down Expand Up @@ -1337,3 +1340,7 @@ The function doesn\'t verify whether the path exists.
-}
getTemporaryDirectory :: IO FilePath
getTemporaryDirectory = D.getTemporaryDirectory >>= decodeFS

-- | Get the contents of the @PATH@ environment variable.
getPath :: IO [FilePath]
getPath = D.getPath >>= (`for` decodeFS)
8 changes: 4 additions & 4 deletions System/Directory/Internal/Posix.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ findExecutablesLazyInternal findExecutablesInDirectoriesLazy binary =
path <- getPath
pure (findExecutablesInDirectoriesLazy path binary)

-- | Get the contents of the @PATH@ environment variable.
getPath :: IO [OsPath]
getPath = splitSearchPath <$> getEnvOs (os "PATH")

exeExtensionInternal :: OsString
exeExtensionInternal = exeExtension

Expand Down Expand Up @@ -391,10 +395,6 @@ getEnvOs name = do
Nothing
Just value -> pure value

-- | Get the contents of the @PATH@ environment variable.
getPath :: IO [OsPath]
getPath = splitSearchPath <$> getEnvOs (os "PATH")

-- | $HOME is preferred, because the user has control over it. However, POSIX
-- doesn't define it as a mandatory variable, so fall back to `getpwuid_r`.
getHomeDirectoryInternal :: IO OsPath
Expand Down
40 changes: 22 additions & 18 deletions System/Directory/Internal/Windows.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import System.OsPath
, pack
, pathSeparator
, splitDirectories
, splitSearchPath
, takeExtension
, toChar
, unpack
Expand All @@ -41,6 +42,7 @@ import qualified System.Win32.WindowsString.Info as Win32
import qualified System.Win32.WindowsString.Shell as Win32
import qualified System.Win32.WindowsString.Time as Win32
import qualified System.Win32.WindowsString.Types as Win32
import qualified System.Win32.WindowsString.Console as Win32

type RawHandle = OsPath

Expand All @@ -53,6 +55,26 @@ openRaw _ dir path = pure (pathAt dir path)
closeRaw :: RawHandle -> IO ()
closeRaw _ = pure ()

lookupEnvOs :: OsString -> IO (Maybe OsString)
lookupEnvOs (OsString name) = (OsString <$>) <$> Win32.getEnv name

getEnvOs :: OsString -> IO OsString
getEnvOs name = do
env <- lookupEnvOs name
case env of
Nothing ->
throwIO $
mkIOError
doesNotExistErrorType
("env var " <> show name <> " not found")
Nothing
Nothing
Just value -> pure value

-- | Get the contents of the @PATH@ environment variable.
getPath :: IO [OsPath]
getPath = splitSearchPath <$> getEnvOs (os "PATH")

createDirectoryInternal :: OsPath -> IO ()
createDirectoryInternal path =
(`ioeSetOsPath` path) `modifyIOError` do
Expand Down Expand Up @@ -666,24 +688,6 @@ setAccessPermissions :: OsPath -> Permissions -> IO ()
setAccessPermissions path Permissions{writable = w} = do
setFilePermissions path (setWriteMode w 0)

lookupEnvOs :: OsString -> IO (Maybe OsString)
lookupEnvOs (OsString name) = do
result <-
Win32.withTString name $ \ pName ->
peekTStringWith 256 $ \ pBuffer size ->
c_GetEnvironmentVariable pName pBuffer size
case result of
Left errCode | errCode == win32_eRROR_ENVVAR_NOT_FOUND -> pure Nothing
| otherwise -> Win32.failWith "GetEnvironmentVariable" errCode
Right value -> pure (Just (OsString value))

foreign import WINAPI unsafe "windows.h GetEnvironmentVariableW"
c_GetEnvironmentVariable
:: Win32.LPWSTR
-> Win32.LPWSTR
-> Win32.DWORD
-> IO Win32.DWORD

getFolderPath :: Win32.CSIDL -> IO OsPath
getFolderPath what = OsString <$> Win32.sHGetFolderPath nullPtr what nullPtr 0

Expand Down
4 changes: 4 additions & 0 deletions System/Directory/OsPath.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ module System.Directory.OsPath
, getUserDocumentsDirectory
, getTemporaryDirectory

-- * PATH
, getPath

-- * Actions on files
, removeFile
, renameFile
Expand Down Expand Up @@ -1653,3 +1656,4 @@ The function doesn\'t verify whether the path exists.
-}
getTemporaryDirectory :: IO OsPath
getTemporaryDirectory = getTemporaryDirectoryInternal

4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Changelog for the [`directory`][1] package
==========================================

## 1.3.10.0 (XXX 2025)

* Add `getPath` wrt [#198](https://github.com/haskell/directory/pull/198)

## 1.3.9.0 (Oct 2024)

* Rely on `file-io` for file I/O.
Expand Down
4 changes: 2 additions & 2 deletions directory.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 2.2
name: directory
version: 1.3.9.0
version: 1.3.10.0
license: BSD-3-Clause
license-file: LICENSE
maintainer: libraries@haskell.org
Expand Down Expand Up @@ -63,7 +63,7 @@ Library
file-io >= 0.1.4 && < 0.2,
time >= 1.8.0 && < 1.15,
if os(windows)
build-depends: Win32 >= 2.13.3 && < 2.15
build-depends: Win32 >= 2.14.1.0 && < 2.15
else
build-depends: unix >= 2.8.0 && < 2.9

Expand Down