hash-addressed-cli 2.0.0.0 → 2.1.0.0
raw patch · 8 files changed
+46/−32 lines, 8 filesdep +pipesdep ~hash-addressedPVP ok
version bump matches the API change (PVP)
Dependencies added: pipes
Dependency ranges changed: hash-addressed
API changes (from Hackage documentation)
+ HashAddressed.App.HashFunction: SHA_256 :: HashFunctionName
+ HashAddressed.App.HashFunction: data HashFunctionName
+ HashAddressed.App.HashFunction: resolveHashFunction :: HashFunctionName -> HashFunction
+ HashAddressed.App.HashFunction.Naming: SHA_256 :: HashFunctionName
+ HashAddressed.App.HashFunction.Naming: data HashFunctionName
+ HashAddressed.App.HashFunction.Naming: instance GHC.Classes.Eq HashAddressed.App.HashFunction.Naming.HashFunctionName
+ HashAddressed.App.HashFunction.Naming: resolveHashFunction :: HashFunctionName -> HashFunction
- HashAddressed.App.HashFunction: hashFunctionRead :: ReadM HashFunction
+ HashAddressed.App.HashFunction: hashFunctionRead :: ReadM HashFunctionName
- HashAddressed.App.HashFunction: readHashFunctionString :: String -> Maybe HashFunction
+ HashAddressed.App.HashFunction: readHashFunctionString :: String -> Maybe HashFunctionName
- HashAddressed.App.HashFunction: readHashFunctionText :: Text -> Maybe HashFunction
+ HashAddressed.App.HashFunction: readHashFunctionText :: Text -> Maybe HashFunctionName
- HashAddressed.App.HashFunction: showHashFunction :: HashFunction -> String
+ HashAddressed.App.HashFunction: showHashFunction :: HashFunctionName -> String
- HashAddressed.App.HashFunction.Naming: hashFunctions :: [(String, HashFunction)]
+ HashAddressed.App.HashFunction.Naming: hashFunctions :: [(String, HashFunctionName)]
- HashAddressed.App.HashFunction.Naming: readHashFunctionString :: String -> Maybe HashFunction
+ HashAddressed.App.HashFunction.Naming: readHashFunctionString :: String -> Maybe HashFunctionName
- HashAddressed.App.HashFunction.Naming: readHashFunctionText :: Text -> Maybe HashFunction
+ HashAddressed.App.HashFunction.Naming: readHashFunctionText :: Text -> Maybe HashFunctionName
- HashAddressed.App.HashFunction.Naming: showHashFunction :: HashFunction -> String
+ HashAddressed.App.HashFunction.Naming: showHashFunction :: HashFunctionName -> String
- HashAddressed.App.HashFunction.Options: hashFunctionRead :: ReadM HashFunction
+ HashAddressed.App.HashFunction.Options: hashFunctionRead :: ReadM HashFunctionName
- HashAddressed.App.Meta: defaultConfigINI :: HashFunction -> Ini
+ HashAddressed.App.Meta: defaultConfigINI :: HashFunctionName -> Ini
- HashAddressed.App.Meta: initializeStore :: HashFunction -> FilePath -> CommandAction ()
+ HashAddressed.App.Meta: initializeStore :: HashFunctionName -> FilePath -> CommandAction ()
- HashAddressed.App.Meta: readHashFunctionFromConfig :: FilePath -> CommandAction HashFunction
+ HashAddressed.App.Meta: readHashFunctionFromConfig :: FilePath -> CommandAction HashFunctionName
- HashAddressed.App.Meta: tryInitializeStore :: InitializationType -> Verbosity -> HashFunction -> FilePath -> CommandAction ()
+ HashAddressed.App.Meta: tryInitializeStore :: InitializationType -> Verbosity -> HashFunctionName -> FilePath -> CommandAction ()
- HashAddressed.App.Meta.Initialization: defaultConfigINI :: HashFunction -> Ini
+ HashAddressed.App.Meta.Initialization: defaultConfigINI :: HashFunctionName -> Ini
- HashAddressed.App.Meta.Initialization: initializeStore :: HashFunction -> FilePath -> CommandAction ()
+ HashAddressed.App.Meta.Initialization: initializeStore :: HashFunctionName -> FilePath -> CommandAction ()
- HashAddressed.App.Meta.Initialization: tryInitializeStore :: InitializationType -> Verbosity -> HashFunction -> FilePath -> CommandAction ()
+ HashAddressed.App.Meta.Initialization: tryInitializeStore :: InitializationType -> Verbosity -> HashFunctionName -> FilePath -> CommandAction ()
- HashAddressed.App.Meta.Reading: readHashFunctionFromConfig :: FilePath -> CommandAction HashFunction
+ HashAddressed.App.Meta.Reading: readHashFunctionFromConfig :: FilePath -> CommandAction HashFunctionName
Files
- changelog.md +10/−0
- hash-addressed-cli.cabal +3/−2
- library/HashAddressed/App/Command/Examples/Write.hs +11/−15
- library/HashAddressed/App/HashFunction.hs +2/−2
- library/HashAddressed/App/HashFunction/Naming.hs +15/−5
- library/HashAddressed/App/HashFunction/Options.hs +1/−2
- library/HashAddressed/App/Meta/Initialization.hs +3/−4
- library/HashAddressed/App/Meta/Reading.hs +1/−2
changelog.md view
@@ -1,3 +1,13 @@+Version format `A.B.C.D`:++- Raise `A` for any changes that affect the executable behavior+- Raise `B` for breaking changes to the library+- Raise `C` for reverse-compatible changes to the library++## 2.1.0.0 (2023-01-31)++Raise `hash-addressed` version to `0.1`+ ## 2.0.0.0 (2023-01-28) Added a `--link` option to the `write` command
hash-addressed-cli.cabal view
@@ -1,7 +1,7 @@ cabal-version: 3.0 name: hash-addressed-cli-version: 2.0.0.0+version: 2.1.0.0 synopsis: Hash-addressed file storage app category: Hash, Filesystem @@ -42,9 +42,10 @@ , cryptohash-sha256 ^>= 0.11.102 , directory ^>= 1.3.6 , filepath ^>= 1.4.2- , hash-addressed ^>= 0.0.0+ , hash-addressed ^>= 0.1.0 , ini ^>= 0.4.2 , optparse-applicative ^>= 0.16.1 || ^>= 0.17.0+ , pipes ^>= 4.3.16 , quaalude ^>= 0.0.0 , resourcet ^>= 1.2.6 || ^>= 1.3.0 , safe-exceptions ^>= 0.1.7
library/HashAddressed/App/Command/Examples/Write.hs view
@@ -14,7 +14,6 @@ import HashAddressed.App.Verbosity.Options import HashAddressed.App.Verbosity.Printing import HashAddressed.App.Verbosity.Type-import HashAddressed.HashFunction import Control.Monad.IO.Class (liftIO) import HashAddressed.Directory (WriteResult (..), WriteType (..))@@ -24,7 +23,6 @@ import qualified Control.Monad as Monad import qualified Control.Monad.Trans.Except as Except import qualified Control.Monad.Trans.Resource as Resource-import qualified Data.ByteString as Strict import qualified Data.ByteString as Strict.ByteString import qualified HashAddressed.Directory import qualified Options.Applicative as Options@@ -33,6 +31,7 @@ import qualified Control.Exception.Safe as Exception import qualified Data.Either as Either import qualified System.Directory as Directory+import qualified Pipes writeCommand :: Command writeCommand = Options.info (parser <**> Options.helper) $ Options.progDesc@@ -64,7 +63,7 @@ Options.help "Set up a hash-addressed store if one does not already exist. \ \If this option is given, --hash-function is required." - optHashFunction :: Maybe HashFunction <- Options.optional $+ optHashFunction :: Maybe HashFunctionName <- Options.optional $ Options.option hashFunctionRead $ Options.long "hash-function" <> Options.help ("If --initialize is given, use this flag to specify the hash \ \function. If a store exists, fail unless it used this hash function. "@@ -94,9 +93,9 @@ putVerboseLn optVerbosity $ "The hash function is " <> showHashFunction hashFunction - let store = HashAddressed.Directory.init hashFunction optStoreDirectory+ let store = HashAddressed.Directory.Directory optStoreDirectory (resolveHashFunction hashFunction) - WriteResult{ contentAddressedFile, writeType } <- liftIO $ Resource.runResourceT @IO do+ ((), WriteResult{ hashAddressedFile, writeType }) <- liftIO $ Resource.runResourceT @IO do input <- case optSourceFile of Nothing -> pure IO.stdin@@ -104,25 +103,22 @@ (_, h) <- Resource.allocate (IO.openBinaryFile inputFile IO.ReadMode) IO.hClose pure h - liftIO $ HashAddressed.Directory.writeStreaming store- \(writeChunk :: Strict.ByteString -> m ()) -> do- let- loop :: m ()- loop = do+ liftIO $ HashAddressed.Directory.writeStream store $+ let+ loop = do x <- liftIO $ Strict.ByteString.hGetSome input 4096- case Strict.ByteString.null x of- False -> writeChunk x *> loop- True -> pure ()+ Monad.unless (Strict.ByteString.null x) (Pipes.yield x *> loop)+ in loop - putNormalLn optVerbosity contentAddressedFile+ putNormalLn optVerbosity hashAddressedFile putVerboseLn optVerbosity case writeType of AlreadyPresent -> "The file was already present in the store; no change was made." NewContent -> "One new file was added to the store." linkFailures <- fmap fold $ liftIO $ optLinks & traverse \linkToBeCreated ->- Exception.tryIO (Directory.createFileLink contentAddressedFile linkToBeCreated) <&> \case+ Exception.tryIO (Directory.createFileLink hashAddressedFile linkToBeCreated) <&> \case Either.Left _ -> Seq.singleton $ "Failed to create link " <> linkToBeCreated Either.Right () -> Seq.empty
library/HashAddressed/App/HashFunction.hs view
@@ -1,7 +1,7 @@ module HashAddressed.App.HashFunction (- {- * Naming -} readHashFunctionText, readHashFunctionString,- showHashFunction, normalizeHashFunction,+ {- * Naming -} HashFunctionName (..), readHashFunctionText, readHashFunctionString,+ showHashFunction, normalizeHashFunction, resolveHashFunction, {- * Options -} hashFunctionRead, hashFunctionInstructions, ) where
library/HashAddressed/App/HashFunction/Naming.hs view
@@ -1,34 +1,44 @@ module HashAddressed.App.HashFunction.Naming (+ HashFunctionName (..), readHashFunctionText, readHashFunctionString, showHashFunction, normalizeHashFunction, hashFunctions,+ resolveHashFunction, ) where import Essentials import Data.Bool (not)-import HashAddressed.HashFunction (HashFunction (SHA_256))+import HashAddressed.HashFunction (HashFunction) import Prelude (String) import qualified Data.Char as Char import qualified Data.List as List import qualified Data.Text as Strict import qualified Data.Text as Strict.Text+import qualified HashAddressed.HashFunction as Hash -hashFunctions :: [(String, HashFunction)]+data HashFunctionName = SHA_256+ deriving Eq++resolveHashFunction :: HashFunctionName -> HashFunction+resolveHashFunction = \case+ SHA_256 -> Hash.sha256++hashFunctions :: [(String, HashFunctionName)] hashFunctions = [(showHashFunction SHA_256, SHA_256)] -readHashFunctionText :: Strict.Text -> Maybe HashFunction+readHashFunctionText :: Strict.Text -> Maybe HashFunctionName readHashFunctionText = Strict.Text.unpack >>> readHashFunctionString -readHashFunctionString :: String -> Maybe HashFunction+readHashFunctionString :: String -> Maybe HashFunctionName readHashFunctionString x = List.lookup x hashFunctions -showHashFunction :: HashFunction -> String+showHashFunction :: HashFunctionName -> String showHashFunction = \case SHA_256 -> "sha256"
library/HashAddressed/App/HashFunction/Options.hs view
@@ -8,14 +8,13 @@ import Essentials import HashAddressed.App.HashFunction.Naming -import HashAddressed.HashFunction (HashFunction) import Prelude (String) import qualified Control.Monad as Monad import qualified Data.List as List import qualified Options.Applicative as Options -hashFunctionRead :: Options.ReadM HashFunction+hashFunctionRead :: Options.ReadM HashFunctionName hashFunctionRead = do string <- Options.str case List.lookup (normalizeHashFunction string) hashFunctions of
library/HashAddressed/App/Meta/Initialization.hs view
@@ -13,7 +13,6 @@ import HashAddressed.App.Command.Type import Control.Monad.IO.Class (liftIO)-import HashAddressed.HashFunction (HashFunction) import Prelude (FilePath) import qualified Data.ByteString as Strict.ByteString@@ -22,13 +21,13 @@ import qualified Data.Text.Encoding as Strict.Text import qualified System.Directory as Directory -defaultConfigINI :: HashFunction -> INI.Ini+defaultConfigINI :: HashFunctionName -> INI.Ini defaultConfigINI optHashFunction = INI.Ini mempty [ (Strict.Text.pack "version", Strict.Text.pack "1") , (Strict.Text.pack "hash function", Strict.Text.pack (showHashFunction optHashFunction))] -tryInitializeStore :: InitializationType -> Verbosity -> HashFunction -> FilePath -> CommandAction ()+tryInitializeStore :: InitializationType -> Verbosity -> HashFunctionName -> FilePath -> CommandAction () tryInitializeStore initializationType optVerbosity optHashFunction optStoreDirectory = do liftIO (Directory.doesPathExist (metaDirectory optStoreDirectory)) >>= \case False -> initializeStore optHashFunction optStoreDirectory@@ -40,7 +39,7 @@ data InitializationType = CreateNew | CreateIfNotPresent {-| Assumes a store does not already exist -}-initializeStore :: HashFunction -> FilePath -> CommandAction ()+initializeStore :: HashFunctionName -> FilePath -> CommandAction () initializeStore optHashFunction optStoreDirectory = do liftIO $ Directory.createDirectoryIfMissing True (metaDirectory optStoreDirectory) liftIO $ Strict.ByteString.writeFile (configFile optStoreDirectory) $
library/HashAddressed/App/Meta/Reading.hs view
@@ -11,7 +11,6 @@ import HashAddressed.App.Command.Type import Control.Monad.IO.Class (liftIO)-import HashAddressed.HashFunction (HashFunction) import Prelude (FilePath) import qualified Data.Sequence as Seq@@ -23,7 +22,7 @@ import qualified Data.Text as Strict.Text import qualified Data.Text.Encoding as Strict.Text -readHashFunctionFromConfig :: FilePath -> CommandAction HashFunction+readHashFunctionFromConfig :: FilePath -> CommandAction HashFunctionName readHashFunctionFromConfig storeDirectory = do bs <- liftIO $ Strict.ByteString.readFile (configFile storeDirectory)