-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
... when configured with the NIX_STORE_DIR and NIX_REMOTE environment variables.
- Loading branch information
Showing
7 changed files
with
140 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
{-# LANGUAGE DeriveDataTypeable #-} | ||
{-# LANGUAGE DerivingStrategies #-} | ||
{-# LANGUAGE GeneralisedNewtypeDeriving #-} | ||
{-# LANGUAGE UndecidableInstances #-} | ||
{-# LANGUAGE NoImportQualifiedPost #-} | ||
|
||
-- | A crude implementation of the Nix store concept. | ||
-- | ||
-- For anything fancier than this, it would be best to use FFI bindings instead, | ||
-- such as hercules-ci-cnix-store. | ||
module Nix.Diff.Store | ||
( StorePath (..), | ||
toPhysicalPath, | ||
toText, | ||
doesFileExist, | ||
readFileUtf8Lenient, | ||
) | ||
where | ||
|
||
import Control.Monad ((<=<)) | ||
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey) | ||
import qualified Data.ByteString | ||
import Data.Data (Data) | ||
import Data.Functor ((<&>)) | ||
import qualified Data.List as L | ||
import Data.Text (Text) | ||
import qualified Data.Text | ||
import qualified Data.Text.Encoding | ||
import qualified Data.Text.Encoding.Error | ||
import qualified System.Directory as Directory | ||
import System.Environment (lookupEnv) | ||
import Test.QuickCheck (Arbitrary) | ||
|
||
-- | A file path that may not exist on the true file system; | ||
-- needs to be looked up in a store, which may be relocated. | ||
-- | ||
-- Unlike the (C++) Nix StorePath type, subpaths are allowed. | ||
newtype StorePath = StorePath | ||
{ -- | If the store is relocated, its physical location is elsewhere, and this 'FilePath' won't resolve. | ||
-- Use 'toPhysicalPath'. | ||
unsafeStorePathFile :: FilePath | ||
} | ||
deriving (Data) | ||
deriving newtype (Show, Eq, Ord, ToJSON, FromJSON, ToJSONKey, FromJSONKey, Arbitrary) | ||
|
||
doesFileExist :: StorePath -> IO Bool | ||
doesFileExist = | ||
Directory.doesFileExist <=< toPhysicalPath | ||
|
||
readFileUtf8Lenient :: StorePath -> IO Text | ||
readFileUtf8Lenient sp = do | ||
file <- toPhysicalPath sp | ||
Data.Text.Encoding.decodeUtf8With Data.Text.Encoding.Error.lenientDecode | ||
<$> Data.ByteString.readFile file | ||
|
||
toPhysicalPath :: StorePath -> IO FilePath | ||
toPhysicalPath (StorePath p) = do | ||
nixStoreDir <- lookupEnv "NIX_STORE_DIR" <&> maybe "/nix/store" stripSlash | ||
nixRemoteMaybe <- lookupEnv "NIX_REMOTE" <&> fmap stripSlash | ||
case nixRemoteMaybe of | ||
Just nixRemote@('/':_) -> | ||
pure $ replaceStart nixStoreDir (nixRemote <> "/" <> nixStoreDir) p | ||
_ -> pure p | ||
|
||
-- | Convert a 'StorePath' to a 'Text' for display purposes. The path may not exist at this physical location. | ||
toText :: StorePath -> Text | ||
toText (StorePath p) = Data.Text.pack p | ||
|
||
stripSlash :: FilePath -> FilePath | ||
stripSlash = reverse . dropWhile (== '/') . reverse | ||
|
||
replaceStart :: String -> String -> String -> String | ||
replaceStart pattern replacement text = | ||
case L.stripPrefix pattern text of | ||
Just rest -> replacement <> rest | ||
Nothing -> text |
Oops, something went wrong.