taskwarrior 0.3.1.0 → 0.4.0.0
raw patch · 6 files changed
+33/−30 lines, 6 filesdep −unordered-containersdep ~aesondep ~containers
Dependencies removed: unordered-containers
Dependency ranges changed: aeson, containers
Files
- CHANGELOG.md +7/−2
- README.md +4/−4
- src/Taskwarrior/Task.hs +14/−15
- src/Taskwarrior/UDA.hs +3/−3
- taskwarrior.cabal +3/−4
- test/TaskSpec.hs +2/−2
CHANGELOG.md view
@@ -1,8 +1,13 @@ # Revision history for taskwarrior -## 0.3.1.0+## 0.4.0.0 -* Add support with the JSON Format of taskwarrior 2.6.+### Breaking Change+* Change UDA Type from HashMap to ordered Map.++### Maintenance+* Update to aeson 2.0.+* Improve test.nix ## 0.3.0.0
README.md view
@@ -35,10 +35,10 @@ Also I'd be curious to know what you use this library for. -This project uses brittany in default configuration as code formatter.-The tests on github will check for hlints, missing docs and unapplied formatting.+This project uses fourmolu as code formatter. ## Help & Contact -You can always open an issue on GitHub. You can also ask in `#haskell-taskwarrior` on freenode irc. If you don‘t have an irc client you can log in via [the webchat](https://webchat.freenode.net/#haskell-taskwarrior).-Shooting @maralorn a mail is also an option. But of course that won’t be public and therefore not help anyone else.+You can always open an issue on GitHub. Contacting @maralorn:maralorn.de on+matrix is also an option. But of course that won’t be public and therefore not+help anyone else.
src/Taskwarrior/Task.hs view
@@ -30,12 +30,14 @@ withText, (.:), (.:?),- (.=), withArray+ (.=), ) import qualified Data.Aeson as Aeson+import qualified Data.Aeson.Key as Key+import qualified Data.Aeson.KeyMap as KeyMap import qualified Data.Aeson.Types as Aeson.Types import qualified Data.Foldable as Foldable-import qualified Data.HashMap.Strict as HashMap+import qualified Data.Map.Strict as Map import Data.Maybe (fromMaybe) import qualified Data.Maybe as Maybe import qualified Data.Semigroup as Semigroup@@ -56,14 +58,12 @@ import qualified Taskwarrior.Status as Status import qualified Taskwarrior.Time as Time import Taskwarrior.UDA (UDA)-import Data.Foldable (toList)-import Control.Applicative ((<|>)) {- | A 'Task' represents a task from taskwarrior. The specification demands, that the existence of some fields is dependent on the status of the task. Those fields are therefore bundled in 'Status' as a sum-type. - All fields in an imported task which are not part of the specification will be put in the 'UDA' (user defined attributes) 'Data.HashMap.Strict.HashMap'.+ All fields in an imported task which are not part of the specification will be put in the 'UDA' (user defined attributes) 'Data.Map.Strict.Map Data.Text.Text'. Since the json can have multiple semantically equivalent representations of a task first serializing and then deserializing is not identity. But deserializing and then serializing should be. (Thus making serializing and deserializing idempotent.)@@ -122,7 +122,7 @@ instance FromJSON Task where parseJSON = withObject "Task" $ \object -> do let parseTimeFromFieldMay = parseFromFieldWithMay Time.parse object- uda = HashMap.filterWithKey (\k _ -> k `notElem` reservedKeys) object+ uda = Map.filterWithKey (\k _ -> k `notElem` reservedKeys) . Map.mapKeys Key.toText $ KeyMap.toMap object status <- Status.parseFromObject object recurringChild <- RecurringChild.parseFromObjectMay object uuid <- object .: "uuid"@@ -144,7 +144,7 @@ maybe (pure mempty) parseUuidList- (HashMap.lookup "depends" object)+ (KeyMap.lookup (Key.fromText "depends") object) tags <- Foldable.fold <$> object .:? "tags" urgency <- fromMaybe 0 <$> object .:? "urgency" pure Task{until = until_, ..}@@ -155,15 +155,14 @@ Text -> Aeson.Types.Parser (Maybe a) parseFromFieldWithMay parser object name =- traverse parser (HashMap.lookup name object)+ traverse parser (KeyMap.lookup (Key.fromText name) object) parseUuidList :: Aeson.Value -> Aeson.Types.Parser (Set UUID)-parseUuidList val =- (withArray "Array of uuid strings" $ fmap Set.fromList . mapM parseJSON . toList) val <|>- (withText "Comma separated list of uuids" $+parseUuidList =+ withText "Text" $ fmap Set.fromList . mapM (parseJSON . Aeson.String)- . Text.splitOn ",") val+ . Text.splitOn "," instance ToJSON Task where toJSON Task{until = until_, ..} =@@ -197,7 +196,7 @@ . Set.toList ) <> ifNotNullSet tags ("tags" .=)- <> HashMap.toList uda+ <> Map.toList (Map.mapKeys Key.fromText uda) ifNotNullSet :: (Ord b) => Set b -> (Set b -> a) -> [a] ifNotNullSet set f =@@ -205,7 +204,7 @@ ) [f set] --- | Makes a Task with the given mandatory fields uuid, entry time and description. See createTask for a non-pure version which needs less parameters.+-- | Makes a fresh Task with the given mandatory fields uuid, entry time and description. See createTask for a non-pure version which needs less parameters. makeTask :: UUID -> UTCTime -> Text -> Task makeTask uuid entry description = Task@@ -226,5 +225,5 @@ , depends = mempty , tags = mempty , urgency = 0- , uda = HashMap.empty+ , uda = Map.empty }
src/Taskwarrior/UDA.hs view
@@ -1,11 +1,11 @@--- | User defined attributes are stored in a 'HashMap' from 'Text' to json 'Value's because we have no type information about them.+-- | User defined attributes are stored in a 'Map' from 'Text' to json 'Value's because we have no type information about them. module Taskwarrior.UDA ( UDA, ) where import Data.Aeson (Value)-import Data.HashMap.Strict (HashMap)+import Data.Map.Strict (Map) import Data.Text (Text) -- | A field will in practice only be a number or a string.-type UDA = HashMap Text Value+type UDA = Map Text Value
taskwarrior.cabal view
@@ -4,7 +4,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.3.1.0+version: 0.4.0.0 synopsis: Types and aeson instances for taskwarrior tasks description: Types and aeson instances for the https://taskwarrior.org task import/export feature@@ -45,7 +45,7 @@ StrictData build-depends:- , aeson >=1.4.2.0 && < 1.6+ , aeson >=2.0.0.0 && < 2.1 , base >=4.11 && < 4.16 , bytestring >=0.10.8.2 && < 0.12 , containers >=0.5.0.0 && < 0.7@@ -53,7 +53,6 @@ , random >=1.1 && < 1.3 , text ^>=1.2.3.0 , time >=1.8.0.2 && < 1.13- , unordered-containers ^>=0.2.9.0 , uuid ^>=1.3.13 hs-source-dirs: src@@ -69,13 +68,13 @@ build-depends: , aeson , base+ , containers , hspec >=2.7.1 && < 2.9 , QuickCheck >=2.13.2 && <2.15 , quickcheck-instances ^>=0.3.22 , taskwarrior , text , time- , unordered-containers , uuid default-language: Haskell2010
test/TaskSpec.hs view
@@ -8,7 +8,7 @@ import Prelude hiding (id) import Data.Aeson-import qualified Data.HashMap.Strict as HashMap+import qualified Data.Map.Strict as Map import Data.Time import Taskwarrior.Annotation import Taskwarrior.Mask@@ -91,5 +91,5 @@ depends <- arbitrary tags <- arbitrary urgency <- arbitrary- uda <- HashMap.fromList . fmap (second String) <$> arbitrary+ uda <- Map.fromList . fmap (second String) <$> arbitrary pure Task{until = until_, ..}