chromatin (empty) → 0.1.0.0
raw patch · 41 files changed
+1382/−0 lines, 41 filesdep +Globdep +HTFdep +basesetup-changed
Dependencies added: Glob, HTF, base, bytestring, chromatin, conduit, containers, data-default-class, deepseq, directory, filepath, hslogger, lens, messagepack, nvim-hs, parsec, prettyprinter, resourcet, ribosome, split, stm-chans, stm-conduit, transformers, typed-process, unliftio
Files
- LICENSE +30/−0
- README.md +1/−0
- Setup.hs +2/−0
- app/Main.hs +6/−0
- chromatin.cabal +199/−0
- lib/Chromatin/Config.hs +95/−0
- lib/Chromatin/Data/ActiveRplugin.hs +12/−0
- lib/Chromatin/Data/Chromatin.hs +9/−0
- lib/Chromatin/Data/Env.hs +27/−0
- lib/Chromatin/Data/InstallResult.hs +14/−0
- lib/Chromatin/Data/RebuildControl.hs +11/−0
- lib/Chromatin/Data/RebuildTask.hs +10/−0
- lib/Chromatin/Data/Rplugin.hs +13/−0
- lib/Chromatin/Data/RpluginConfig.hs +36/−0
- lib/Chromatin/Data/RpluginName.hs +18/−0
- lib/Chromatin/Data/RpluginSource.hs +27/−0
- lib/Chromatin/Data/RpluginState.hs +11/−0
- lib/Chromatin/Data/Rplugins.hs +20/−0
- lib/Chromatin/Data/RunBuiltResult.hs +21/−0
- lib/Chromatin/Data/RunExistingResult.hs +14/−0
- lib/Chromatin/Diag.hs +17/−0
- lib/Chromatin/Init.hs +26/−0
- lib/Chromatin/Log.hs +22/−0
- lib/Chromatin/Plugin.hs +38/−0
- lib/Chromatin/Rebuild.hs +121/−0
- lib/Chromatin/Rebuild/Build.hs +124/−0
- lib/Chromatin/Rebuild/Existing.hs +56/−0
- lib/Chromatin/Rebuild/Nonexisting.hs +35/−0
- lib/Chromatin/Run.hs +87/−0
- lib/Chromatin/Settings.hs +10/−0
- lib/Chromatin/Test/Config.hs +13/−0
- lib/Chromatin/Test/Unit.hs +32/−0
- lib/Chromatin/Unload.hs +18/−0
- test/f/SpecMain.hs +11/−0
- test/u/BuildSpec.hs +46/−0
- test/u/Config.hs +9/−0
- test/u/ConfigSpec.hs +28/−0
- test/u/DiagSpec.hs +30/−0
- test/u/RebuildSpec.hs +36/−0
- test/u/RunSpec.hs +33/−0
- test/u/SpecMain.hs +14/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2018++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,1 @@+# chromatin
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,6 @@+import Neovim++import Chromatin.Plugin (plugin)++main :: IO ()+main = neovim defaultConfig {plugins = [plugin]}
+ chromatin.cabal view
@@ -0,0 +1,199 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.1.+--+-- see: https://github.com/sol/hpack+--+-- hash: 560b0a26d65a7e63d7c566631d1a3e83822116adb9958225a42bbb595604065f++name: chromatin+version: 0.1.0.0+synopsis: neovim package manager+description: Please see the README on GitHub at <https://github.com/tek/chromatin-hs>+category: Neovim+homepage: https://github.com/tek/chromatin-hs#readme+bug-reports: https://github.com/tek/chromatin-hs/issues+author: Torsten Schmits+maintainer: tek@tryp.io+copyright: 2018 Torsten Schmits+license: MIT+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md++source-repository head+ type: git+ location: https://github.com/tek/chromatin-hs++library+ exposed-modules:+ Chromatin.Config+ Chromatin.Data.ActiveRplugin+ Chromatin.Data.Chromatin+ Chromatin.Data.Env+ Chromatin.Data.InstallResult+ Chromatin.Data.RebuildControl+ Chromatin.Data.RebuildTask+ Chromatin.Data.Rplugin+ Chromatin.Data.RpluginConfig+ Chromatin.Data.RpluginName+ Chromatin.Data.Rplugins+ Chromatin.Data.RpluginSource+ Chromatin.Data.RpluginState+ Chromatin.Data.RunBuiltResult+ Chromatin.Data.RunExistingResult+ Chromatin.Diag+ Chromatin.Init+ Chromatin.Log+ Chromatin.Plugin+ Chromatin.Rebuild+ Chromatin.Rebuild.Build+ Chromatin.Rebuild.Existing+ Chromatin.Rebuild.Nonexisting+ Chromatin.Run+ Chromatin.Settings+ Chromatin.Test.Config+ Chromatin.Test.Unit+ Chromatin.Unload+ other-modules:+ Paths_chromatin+ hs-source-dirs:+ lib+ build-depends:+ Glob+ , base >=4.7 && <5+ , bytestring+ , conduit+ , containers+ , data-default-class+ , deepseq+ , directory+ , filepath+ , hslogger+ , lens+ , messagepack+ , nvim-hs+ , parsec+ , prettyprinter+ , resourcet+ , ribosome+ , split+ , stm-chans+ , stm-conduit+ , transformers+ , typed-process+ , unliftio+ default-language: Haskell2010++executable chromatin+ main-is: Main.hs+ other-modules:+ Paths_chromatin+ hs-source-dirs:+ app+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ Glob+ , base >=4.7 && <5+ , bytestring+ , chromatin+ , conduit+ , containers+ , data-default-class+ , deepseq+ , directory+ , filepath+ , hslogger+ , lens+ , messagepack+ , nvim-hs+ , parsec+ , prettyprinter+ , resourcet+ , ribosome+ , split+ , stm-chans+ , stm-conduit+ , transformers+ , typed-process+ , unliftio+ default-language: Haskell2010++test-suite chromatin-functional+ type: exitcode-stdio-1.0+ main-is: SpecMain.hs+ other-modules:+ Paths_chromatin+ hs-source-dirs:+ test/f+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ Glob+ , HTF+ , base >=4.7 && <5+ , bytestring+ , chromatin+ , conduit+ , containers+ , data-default-class+ , deepseq+ , directory+ , filepath+ , hslogger+ , lens+ , messagepack+ , nvim-hs+ , parsec+ , prettyprinter+ , resourcet+ , ribosome+ , split+ , stm-chans+ , stm-conduit+ , transformers+ , typed-process+ , unliftio+ default-language: Haskell2010++test-suite chromatin-unit+ type: exitcode-stdio-1.0+ main-is: SpecMain.hs+ other-modules:+ BuildSpec+ Config+ ConfigSpec+ DiagSpec+ RebuildSpec+ RunSpec+ Paths_chromatin+ hs-source-dirs:+ test/u+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ Glob+ , HTF+ , base >=4.7 && <5+ , bytestring+ , chromatin+ , conduit+ , containers+ , data-default-class+ , deepseq+ , directory+ , filepath+ , hslogger+ , lens+ , messagepack+ , nvim-hs+ , parsec+ , prettyprinter+ , resourcet+ , ribosome+ , split+ , stm-chans+ , stm-conduit+ , transformers+ , typed-process+ , unliftio+ default-language: Haskell2010
+ lib/Chromatin/Config.hs view
@@ -0,0 +1,95 @@+module Chromatin.Config(+ readConfig,+ analyzeConfig,+ RpluginModification(..),+ analyzeConfigIO,+) where++import Data.Maybe (fromMaybe)+import Data.Foldable (find)+import Text.ParserCombinators.Parsec+import System.FilePath (takeFileName)+import qualified Ribosome.Control.Ribo as Ribo (inspect)+import Ribosome.Config.Setting (setting)+import Chromatin.Data.Chromatin (Chromatin)+import qualified Chromatin.Data.Env as Env (rplugins)+import Chromatin.Data.Rplugin (Rplugin(Rplugin))+import Chromatin.Data.RpluginName (RpluginName(RpluginName))+import Chromatin.Data.RpluginSource (RpluginSource(..), HackageDepspec(HackageDepspec), PypiDepspec(PypiDepspec))+import Chromatin.Data.Rplugins (Rplugins(Rplugins))+import Chromatin.Data.RpluginConfig (RpluginConfig(RpluginConfig))+import qualified Chromatin.Settings as S (rplugins)++readConfig :: Chromatin Rplugins+readConfig = setting S.rplugins++data RpluginModification =+ RpluginNew RpluginName RpluginSource+ |+ RpluginRemove Rplugin+ |+ RpluginUpdate Rplugin RpluginSource+ |+ RpluginKeep Rplugin+ deriving (Eq, Show)++data ParsedSpec =+ PrefixedSpec String String+ |+ PlainSpec String++parsePrefixed :: GenParser Char st ParsedSpec+parsePrefixed = do+ prefix <- many $ noneOf ":"+ _ <- char ':'+ spec <- many anyChar+ return $ PrefixedSpec prefix spec++specParser :: GenParser Char st ParsedSpec+specParser = try parsePrefixed <|> fmap PlainSpec (many anyChar)++parseSpec :: String -> Either ParseError ParsedSpec+parseSpec = parse specParser "none"++sourceFromSpec :: String -> Either String RpluginSource+sourceFromSpec spec =+ case parseSpec spec of+ Right (PrefixedSpec prefix spec') -> case prefix of+ "pip" -> Right $ Pypi (PypiDepspec spec')+ "hackage" -> Right $ Hackage (HackageDepspec spec')+ "stack" -> Right $ Stack spec'+ a -> Left $ "unknown rplugin prefix `" ++ a ++ "` in `" ++ spec ++ "`"+ Right (PlainSpec name') ->+ Right $ Hackage (HackageDepspec name')+ Left _ -> Left $ "failed to parse `" ++ spec ++ "`"++rpluginHasName :: RpluginName -> Rplugin -> Bool+rpluginHasName target (Rplugin name _) = target == name++nameFromSource :: RpluginSource -> RpluginName+nameFromSource (Hackage (HackageDepspec n)) = RpluginName n+nameFromSource (Stack fp) = RpluginName (takeFileName fp)+nameFromSource (Pypi (PypiDepspec n)) = RpluginName n++modifyExisting :: RpluginSource -> Rplugin -> RpluginModification+modifyExisting _ _ = undefined++modification :: [Rplugin] -> RpluginConfig -> Either String RpluginModification+modification current (RpluginConfig spec explicitName) = do+ source <- sourceFromSpec spec+ let name = fromMaybe (nameFromSource source) explicitName+ let sameName = find (rpluginHasName name) current+ return $ maybe (RpluginNew name source) (modifyExisting source) sameName++removals :: [RpluginModification] -> [RpluginModification]+removals _ = []++analyzeConfig :: [Rplugin] -> Rplugins -> Either String [RpluginModification]+analyzeConfig current (Rplugins rplugins) = do+ let mods = traverse (modification current) rplugins+ fmap (\m -> m ++ removals m) mods++analyzeConfigIO :: Rplugins -> Chromatin (Either String [RpluginModification])+analyzeConfigIO rplugins = do+ current <- Ribo.inspect Env.rplugins+ return $ analyzeConfig current rplugins
+ lib/Chromatin/Data/ActiveRplugin.hs view
@@ -0,0 +1,12 @@+module Chromatin.Data.ActiveRplugin(+ ActiveRplugin(..),+) where++import Chromatin.Data.Rplugin (Rplugin)++data ActiveRplugin =+ ActiveRplugin {+ arChannelId :: Int,+ arRplugin :: Rplugin+ }+ deriving (Show, Eq)
+ lib/Chromatin/Data/Chromatin.hs view
@@ -0,0 +1,9 @@+module Chromatin.Data.Chromatin(+ Chromatin,+) where++import UnliftIO.STM (TVar)+import Ribosome.Control.Ribo (Ribo)+import Chromatin.Data.Env (Env)++type Chromatin a = Ribo (TVar Env) a
+ lib/Chromatin/Data/Env.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE TemplateHaskell #-}++module Chromatin.Data.Env(+ Env(..),+ _rplugins,+ _errors,+ _installerChan,+) where++import Control.Concurrent.STM.TBMChan (TBMChan)+import Control.Lens (makeClassy_)+import Data.Default.Class (Default(def))+import Ribosome.Data.Errors (Errors)+import Chromatin.Data.Rplugin (Rplugin)+import Chromatin.Data.RebuildControl (RebuildControl)++data Env =+ Env {+ rplugins :: [Rplugin],+ errors :: Errors,+ installerChan :: Maybe (TBMChan RebuildControl)+ }++makeClassy_ ''Env++instance Default Env where+ def = Env def def def
+ lib/Chromatin/Data/InstallResult.hs view
@@ -0,0 +1,14 @@+module Chromatin.Data.InstallResult(+ InstallResult(..),+) where++import Chromatin.Data.Rplugin (Rplugin)+import Chromatin.Data.RebuildTask (RebuildTask)++data InstallResult =+ Success Rplugin+ |+ Failure RebuildTask+ |+ PreviousFailure String RebuildTask+ deriving Show
+ lib/Chromatin/Data/RebuildControl.hs view
@@ -0,0 +1,11 @@+module Chromatin.Data.RebuildControl(+ RebuildControl(..),+) where++import Chromatin.Data.RebuildTask (RebuildTask)++data RebuildControl =+ Continue RebuildTask+ |+ Stop+ deriving Show
+ lib/Chromatin/Data/RebuildTask.hs view
@@ -0,0 +1,10 @@+module Chromatin.Data.RebuildTask(+ RebuildTask(..),+) where++import Chromatin.Data.RpluginName (RpluginName)+import Chromatin.Data.RpluginSource (RpluginSource)++data RebuildTask =+ RebuildTask RpluginName RpluginSource+ deriving Show
+ lib/Chromatin/Data/Rplugin.hs view
@@ -0,0 +1,13 @@+module Chromatin.Data.Rplugin(+ Rplugin(..),+) where++import Chromatin.Data.RpluginName (RpluginName)+import Chromatin.Data.RpluginSource (RpluginSource)++data Rplugin =+ Rplugin {+ name :: RpluginName,+ source :: RpluginSource+ }+ deriving (Show, Eq)
+ lib/Chromatin/Data/RpluginConfig.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++module Chromatin.Data.RpluginConfig(+ RpluginConfig(..),+) where++import GHC.Generics (Generic)+import qualified Data.Map as Map (fromList)+import Data.Text.Prettyprint.Doc ((<+>), viaShow)+import Control.DeepSeq (NFData)+import Neovim (NvimObject(..), Dictionary, Object(ObjectMap))+import Ribosome.Internal.NvimObject (extractObject)+import Chromatin.Data.RpluginName (RpluginName)++data RpluginConfig =+ RpluginConfig {+ rpluginConfigSpec :: String,+ rpluginConfigName :: Maybe RpluginName+ }+ deriving (Show, Generic, NFData)++instance NvimObject RpluginConfig where+ toObject RpluginConfig {..} =+ (toObject :: Dictionary -> Object) . Map.fromList $+ [+ ("spec", toObject rpluginConfigSpec),+ ("name", toObject rpluginConfigName)+ ]+ fromObject (ObjectMap o) = do+ spec' <- extractObject "spec" o+ name' <- extractObject "name" o+ return $ RpluginConfig spec' name'+ fromObject o = Left ("invalid type for RpluginConfig: " <+> viaShow o)
+ lib/Chromatin/Data/RpluginName.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-}++module Chromatin.Data.RpluginName(+ RpluginName(..),+) where++import GHC.Generics (Generic)+import Control.DeepSeq (NFData)+import Neovim.Classes (NvimObject(..))+import Ribosome.Internal.NvimObject (deriveString)++newtype RpluginName = RpluginName String+ deriving (Eq, Show, Generic, NFData)++instance NvimObject RpluginName where+ toObject (RpluginName s) = toObject s+ fromObject = deriveString RpluginName
+ lib/Chromatin/Data/RpluginSource.hs view
@@ -0,0 +1,27 @@+module Chromatin.Data.RpluginSource(+ HackageDepspec(..),+ PypiDepspec(..),+ RpluginSource(..),+) where++newtype HackageDepspec =+ HackageDepspec String+ deriving (Show, Eq)++newtype PypiDepspec =+ PypiDepspec String+ deriving (Show, Eq)++data RpluginSource =+ Hackage {+ hackageSpec :: HackageDepspec+ }+ |+ Stack {+ stackProject :: FilePath+ }+ |+ Pypi {+ pypiSpec :: PypiDepspec+ }+ deriving (Show, Eq)
+ lib/Chromatin/Data/RpluginState.hs view
@@ -0,0 +1,11 @@+module Chromatin.Data.RpluginState(+ RpluginState(..),+) where++data RpluginState =+ Broken String+ |+ Ready+ |+ Incomplete+ deriving Show
+ lib/Chromatin/Data/Rplugins.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DeriveAnyClass #-}++module Chromatin.Data.Rplugins(+ Rplugins(..),+) where++import GHC.Generics (Generic)+import Data.Default.Class (Default)+import Control.DeepSeq (NFData)+import Neovim.Classes (NvimObject(..))+import Chromatin.Data.RpluginConfig (RpluginConfig)++newtype Rplugins =+ Rplugins [RpluginConfig]+ deriving (Generic, NFData, Default)++instance NvimObject Rplugins where+ toObject (Rplugins cs) = toObject cs+ fromObject o = fmap Rplugins (fromObject o)
+ lib/Chromatin/Data/RunBuiltResult.hs view
@@ -0,0 +1,21 @@+module Chromatin.Data.RunBuiltResult(+ RunBuiltResult(..),+) where++import Chromatin.Data.ActiveRplugin (ActiveRplugin)+import Chromatin.Data.RebuildTask (RebuildTask)++data RunBuiltResult =+ Success ActiveRplugin+ |+ Failure {+ task :: RebuildTask,+ errors :: [String]+ }+ |+ PreviousFailure {+ stage :: String,+ task :: RebuildTask,+ errors :: [String]+ }+ deriving Show
+ lib/Chromatin/Data/RunExistingResult.hs view
@@ -0,0 +1,14 @@+module Chromatin.Data.RunExistingResult(+ RunExistingResult(..),+) where++import Chromatin.Data.ActiveRplugin (ActiveRplugin)+import Chromatin.Data.RebuildTask (RebuildTask)++data RunExistingResult =+ Success ActiveRplugin+ |+ Failure RebuildTask [String]+ |+ NotReady RebuildTask+ deriving Show
+ lib/Chromatin/Diag.hs view
@@ -0,0 +1,17 @@+module Chromatin.Diag(+ crmDiag,+) where++import Data.Functor (void)+import Neovim (CommandArguments)+import Ribosome.Data.ScratchOptions (defaultScratchOptions)+import Ribosome.Scratch (showInScratch)+import Chromatin.Data.Chromatin (Chromatin)++diagnostics :: Chromatin [String]+diagnostics = return ["Diagnostics", ""]++crmDiag :: CommandArguments -> Chromatin ()+crmDiag _ = do+ content <- diagnostics+ void $ showInScratch content (defaultScratchOptions "chromatin-diagnostics")
+ lib/Chromatin/Init.hs view
@@ -0,0 +1,26 @@+module Chromatin.Init(+ initialize,+) where++import Data.Default.Class (Default(def))+import System.Log.Logger (updateGlobalLogger, setLevel, Priority(ERROR))+import Control.Monad.IO.Class (liftIO)+import UnliftIO.STM (TVar)+import Neovim (Neovim)+import Neovim.Context.Internal (Config(customConfig), asks')+import Ribosome.Control.Ribosome (newRibosome, Ribosome)+import Ribosome.Internal.IO (retypeNeovim)+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Data.Env (Env)+import Chromatin.Rebuild (crmRebuild)++initialize' :: Chromatin (Ribosome (TVar Env))+initialize' = do+ crmRebuild def+ asks' customConfig++initialize :: Neovim e (Ribosome (TVar Env))+initialize = do+ liftIO $ updateGlobalLogger "Neovim.Plugin" (setLevel ERROR)+ ribo <- newRibosome "chromatin" def+ retypeNeovim (const ribo) initialize'
+ lib/Chromatin/Log.hs view
@@ -0,0 +1,22 @@+module Chromatin.Log(+ debug,+ info,+ debugS,+ infoS,+ R.p,+) where++import Ribosome.Control.Ribo (Ribo)+import qualified Ribosome.Log as R (debug, info, p)++debug :: String -> Ribo e ()+debug = R.debug "chromatin"++info :: String -> Ribo e ()+info = R.info "chromatin"++debugS :: Show a => a -> Ribo e ()+debugS = R.debug "chromatin"++infoS :: Show a => a -> Ribo e ()+infoS = R.info "chromatin"
+ lib/Chromatin/Plugin.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE OverloadedStrings #-}++module Chromatin.Plugin(+ plugin,+)+where++import UnliftIO.STM (TVar)+import Neovim (+ Plugin(..),+ command',+ Neovim,+ StartupConfig,+ NeovimConfig,+ NeovimPlugin,+ wrapPlugin,+ )+import Ribosome.Control.Ribosome (Ribosome)+import Chromatin.Init (initialize)+import Chromatin.Data.Env (Env)+import Chromatin.Diag (crmDiag)+import Chromatin.Rebuild (crmRebuild)++plugin' :: Ribosome (TVar Env) -> Plugin (Ribosome (TVar Env))+plugin' env =+ Plugin {+ environment = env,+ exports = [+ $(command' 'crmDiag) [],+ $(command' 'crmRebuild) []+ ]+ }++plugin :: Neovim (StartupConfig NeovimConfig) NeovimPlugin+plugin = do+ env <- initialize+ wrapPlugin $ plugin' env
+ lib/Chromatin/Rebuild.hs view
@@ -0,0 +1,121 @@+module Chromatin.Rebuild(+ crmRebuild,+) where++import Conduit (ConduitT, (.|), runConduit, mapMC, sinkList, await, yield)+import Control.Concurrent.STM.TBMChan (TBMChan, newTBMChan, writeTBMChan, closeTBMChan)+import qualified Control.Lens as Lens (set)+import Control.Monad.Trans.Class (lift)+import Data.Conduit.TMChan (sourceTBMChan)+import Data.Foldable (traverse_)+import Data.Functor (void)+import Data.Void (Void)+import UnliftIO (atomically)+import UnliftIO.STM (TVar, STM)+import Neovim (CommandArguments)+import Ribosome.Control.Ribo (Ribo)+import qualified Ribosome.Control.Ribo as Ribo (inspect, modify)+import Ribosome.Data.ScratchOptions (defaultScratchOptions)+import Ribosome.Internal.IO (forkNeovim)+import Ribosome.Scratch (showInScratch)+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Data.Env (Env)+import qualified Chromatin.Data.Env as Env (installerChan, _installerChan)+import Chromatin.Data.RebuildTask (RebuildTask(..))+import Chromatin.Data.RebuildControl (RebuildControl)+import qualified Chromatin.Data.RebuildControl as RebuildControl (RebuildControl(..))+import Chromatin.Data.RunExistingResult (RunExistingResult)+import Chromatin.Data.RunBuiltResult (RunBuiltResult)+import qualified Chromatin.Data.RunBuiltResult as RunBuiltResult (RunBuiltResult(..))+import Chromatin.Data.RpluginName (RpluginName(RpluginName))+import Chromatin.Data.RpluginSource (RpluginSource)+import Chromatin.Config (readConfig, analyzeConfigIO, RpluginModification(RpluginNew))+import Chromatin.Rebuild.Existing (handleExisting)+import Chromatin.Rebuild.Nonexisting (handleNonexisting)+import qualified Chromatin.Log as Log++mapMChan :: Chromatin a -> (TBMChan RebuildControl -> Chromatin a) -> Chromatin a+mapMChan fEmpty f = do+ storedChan <- Ribo.inspect Env.installerChan+ maybe fEmpty f storedChan++stopRebuilder :: Chromatin ()+stopRebuilder =+ mapMChan (return ()) $ \c -> do+ Ribo.modify $ Lens.set Env._installerChan Nothing+ atomically $ closeTBMChan c+ Log.debug "stopped installer conduit"++createChan :: STM (TBMChan RebuildControl)+createChan = newTBMChan 64++extractFailure :: RunBuiltResult -> [String]+extractFailure (RunBuiltResult.Failure (RebuildTask (RpluginName name) _) err) =+ ("error when runnning plugin `" ++ name ++ "`:") : err+extractFailure (RunBuiltResult.Success _) = []+extractFailure (RunBuiltResult.PreviousFailure stage (RebuildTask (RpluginName name) _) err) =+ ("error in stage `" ++ stage ++ "` for plugin `" ++ name ++ "`:") : err++controlC :: ConduitT RebuildControl RebuildTask (Ribo (TVar Env)) ()+controlC = do+ ctrl <- await+ case ctrl of+ Just RebuildControl.Stop -> lift stopRebuilder+ Just (RebuildControl.Continue task) -> yield task >> controlC+ Nothing -> controlC++handleExistingC :: ConduitT RebuildTask RunExistingResult (Ribo (TVar Env)) ()+handleExistingC = mapMC handleExisting++handleNonexistingC :: ConduitT RunExistingResult RunBuiltResult (Ribo (TVar Env)) ()+handleNonexistingC = mapMC handleNonexisting++rebuilder :: TBMChan RebuildControl -> ConduitT () Void (Ribo (TVar Env)) [RunBuiltResult]+rebuilder chan = sourceTBMChan chan+ .| controlC+ .| handleExistingC+ .| handleNonexistingC+ .| sinkList++runRebuilder :: TBMChan RebuildControl -> Chromatin ()+runRebuilder chan = do+ result <- runConduit $ rebuilder chan+ case concatMap extractFailure result of+ err@(_:_) -> void $ showInScratch err (defaultScratchOptions "chromatin-rebuild-error")+ _ -> return ()+ Log.debug $ "installer terminated: " ++ show result++forkRebuilder :: Chromatin (TBMChan RebuildControl)+forkRebuilder = do+ chan <- atomically createChan+ Ribo.modify $ Lens.set Env._installerChan (Just chan)+ forkNeovim $ runRebuilder chan+ return chan++enqueue :: RebuildControl -> TBMChan RebuildControl -> Chromatin ()+enqueue ctrl chan = atomically $ writeTBMChan chan ctrl++executeRpluginNew :: RpluginName -> RpluginSource -> Chromatin ()+executeRpluginNew name source = do+ chan <- mapMChan forkRebuilder return+ enqueue (RebuildControl.Continue (RebuildTask name source)) chan++executeModification :: RpluginModification -> Chromatin ()+executeModification (RpluginNew name source) = executeRpluginNew name source+executeModification _ = return ()++executeModifications :: [RpluginModification] -> Chromatin ()+executeModifications mods = do+ traverse_ executeModification mods+ mapMChan (return ()) (enqueue RebuildControl.Stop)++analysisError :: String -> Chromatin ()+analysisError _ = return ()++crmRebuild :: CommandArguments -> Chromatin ()+crmRebuild _ = do+ config <- readConfig+ analysis <- analyzeConfigIO config+ case analysis of+ Right mods -> executeModifications mods+ Left e -> analysisError e
+ lib/Chromatin/Rebuild/Build.hs view
@@ -0,0 +1,124 @@+module Chromatin.Rebuild.Build(+ installRplugin,+ InstallResult(..),+ venvDir,+) where++import Control.Monad.IO.Class (MonadIO)+import Data.List.Split (linesBy)+import GHC.IO.Exception (ExitCode(ExitFailure))+import GHC.IO.Handle.Types (Handle)+import qualified Data.ByteString.Lazy.Internal as B (unpackChars)+import System.FilePath ((</>))+import System.Process.Typed (ProcessConfig, setStdout, useHandleClose, readProcessStderr, proc, setWorkingDir)+import UnliftIO.Temporary (withSystemTempFile)+import UnliftIO.Directory (+ getXdgDirectory,+ XdgDirectory(XdgData, XdgCache),+ createDirectoryIfMissing,+ removePathForcibly,+ )+import Neovim (Buffer, vim_command', vim_get_current_buffer', vim_command, buffer_get_number')+import Ribosome.Api.Echo (echom)+import Chromatin.Data.Rplugin (Rplugin(Rplugin))+import Chromatin.Data.RpluginName (RpluginName(..))+import Chromatin.Data.RpluginSource (RpluginSource(Hackage, Stack, Pypi), HackageDepspec(..), PypiDepspec(..))+import Chromatin.Data.Chromatin (Chromatin)++data InstallResult =+ Success Rplugin+ |+ Failure [String]+ deriving (Show, Eq)++tailInTerminal :: FilePath -> Chromatin Buffer+tailInTerminal path = do+ vim_command' $ "15split term://tail -f " ++ path+ vim_get_current_buffer'++closeTerminal :: Buffer -> Chromatin ()+closeTerminal buf = do+ num <- buffer_get_number' buf+ _ <- vim_command $ "silent! " ++ show num ++ "bwipeout!"+ return ()++processWithStdoutFile :: MonadIO m => ProcessConfig stdin stdout stderr -> Handle -> m (Either String ())+processWithStdoutFile processConfig logHandle = do+ let pipe = setStdout (useHandleClose logHandle)+ (code, err) <- readProcessStderr $ pipe processConfig+ return $ case code of+ ExitFailure _ -> Left (B.unpackChars err)+ _ -> Right ()++hackageProcess :: FilePath -> HackageDepspec -> ProcessConfig () () ()+hackageProcess bindir (HackageDepspec spec) =+ proc "cabal" ["new-install", "--symlink-bindir", bindir, spec]++stackProcess :: FilePath -> ProcessConfig () () ()+stackProcess path =+ setWorkingDir path $ proc "stack" ["build"]++processWithLog :: RpluginName -> ProcessConfig stdin stdout sderr -> Chromatin (Either String ())+processWithLog (RpluginName name) processConfig =+ withSystemTempFile "test-chromatin" $ \logFile logHandle -> do+ buf <- tailInTerminal logFile+ result <- processWithStdoutFile processConfig logHandle+ case result of+ Right _ -> do+ echom $ "installed `" ++ name ++ "`"+ closeTerminal buf+ Left _ -> echom $ "failed to install `" ++ name ++ "`"+ return result++installHackageProcess :: RpluginName -> FilePath -> HackageDepspec -> Chromatin (Either String ())+installHackageProcess name bindir spec =+ processWithLog name $ hackageProcess bindir spec++installStackProcess :: RpluginName -> FilePath -> Chromatin (Either String ())+installStackProcess name path =+ processWithLog name $ stackProcess path++venvProcess :: FilePath -> ProcessConfig () () ()+venvProcess dir =+ proc "python3" ["-m", "venv", dir, "--upgrade"]++venvDir :: RpluginName -> Chromatin FilePath+venvDir (RpluginName name) = getXdgDirectory XdgCache ("chromatin-hs" </> "venvs" </> name)++createVenvProcess :: RpluginName -> Chromatin (Either String FilePath)+createVenvProcess name = do+ dir <- venvDir name+ removePathForcibly dir+ r <- processWithLog name (venvProcess dir)+ return $ dir <$ r++pipProcess :: PypiDepspec -> FilePath -> ProcessConfig () () ()+pipProcess (PypiDepspec spec) venv =+ proc (venv </> "bin" </> "pip") ["install", "--no-cache", "--upgrade", spec]++installPypiProcess :: RpluginName -> PypiDepspec -> FilePath -> Chromatin (Either String ())+installPypiProcess name spec venv =+ processWithLog name (pipProcess spec venv)++binaryDir :: Chromatin FilePath+binaryDir = getXdgDirectory XdgData ("chromatin" </> "bin")++installRpluginFromSource :: RpluginName -> RpluginSource -> Chromatin (Either String ())+installRpluginFromSource name (Hackage spec) = do+ bindir <- binaryDir+ createDirectoryIfMissing True bindir+ installHackageProcess name bindir spec+installRpluginFromSource name (Stack path) =+ installStackProcess name path+installRpluginFromSource name (Pypi spec) = do+ dir <- createVenvProcess name+ case dir of+ Right d -> installPypiProcess name spec d+ Left e -> return $ Left e++installRplugin :: RpluginName -> RpluginSource -> Chromatin InstallResult+installRplugin name source = do+ result <- installRpluginFromSource name source+ return $ case result of+ Right _ -> Success $ Rplugin name source+ Left err -> Failure $ linesBy (=='\n') err
+ lib/Chromatin/Rebuild/Existing.hs view
@@ -0,0 +1,56 @@+module Chromatin.Rebuild.Existing(+ handleExisting,+) where++import GHC.IO.Exception (IOException)+import qualified Data.ByteString.Lazy.Internal as B (unpackChars)+import Data.List.Split (linesBy)+import System.Process.Typed (readProcessStderr, proc, setWorkingDir)+import UnliftIO (tryIO)+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Data.RebuildTask (RebuildTask(..))+import Chromatin.Data.RunExistingResult (RunExistingResult)+import qualified Chromatin.Data.RunExistingResult as RunExistingResult (RunExistingResult(..))+import Chromatin.Data.Rplugin (Rplugin(Rplugin))+import Chromatin.Data.RpluginName (RpluginName)+import Chromatin.Data.RpluginSource (RpluginSource(Stack, Pypi))+import Chromatin.Data.RpluginState (RpluginState)+import qualified Chromatin.Data.RpluginState as RpluginState (RpluginState(..))+import Chromatin.Run (runRplugin, RunRpluginResult, pypiPluginPackage)+import qualified Chromatin.Run as RunRpluginResult (RunRpluginResult(..))++runPreexistingResult :: RebuildTask -> RunRpluginResult -> RunExistingResult+runPreexistingResult _ (RunRpluginResult.Success active) = RunExistingResult.Success active+runPreexistingResult task (RunRpluginResult.Failure err) = RunExistingResult.Failure task err++unsafeStackDryRun :: FilePath -> Chromatin [String]+unsafeStackDryRun path = do+ (_, output) <- readProcessStderr $ setWorkingDir path $ proc "stack" ["build", "--dry-run"]+ return $ linesBy (=='\n') $ B.unpackChars output++stackDryRun :: FilePath -> Chromatin (Either IOException [String])+stackDryRun path =+ tryIO $ unsafeStackDryRun path++rpluginReady :: RpluginName -> RpluginSource -> Chromatin RpluginState+rpluginReady _ (Stack path) = do+ output <- stackDryRun path+ return $ case output of+ Right lines' -> if "Would build:" `elem` lines' then RpluginState.Incomplete else RpluginState.Ready+ Left err -> RpluginState.Broken $ "could not execute `stack build` in " ++ path ++ ": " ++ show err+rpluginReady name (Pypi _) = do+ package <- pypiPluginPackage name+ return $ maybe RpluginState.Incomplete (const RpluginState.Ready) package+rpluginReady _ _ = return $ RpluginState.Broken "NI"++runPreexisting :: RebuildTask -> Chromatin RunExistingResult+runPreexisting task@(RebuildTask name source) =+ runPreexistingResult task <$> runRplugin (Rplugin name source)++handleExisting :: RebuildTask -> Chromatin RunExistingResult+handleExisting task@(RebuildTask name source) = do+ state <- rpluginReady name source+ case state of+ RpluginState.Ready -> runPreexisting task+ RpluginState.Incomplete -> return $ RunExistingResult.NotReady task+ RpluginState.Broken reason -> return $ RunExistingResult.Failure task [reason]
+ lib/Chromatin/Rebuild/Nonexisting.hs view
@@ -0,0 +1,35 @@+module Chromatin.Rebuild.Nonexisting(+ handleNonexisting,+) where++import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Data.Rplugin (Rplugin)+import Chromatin.Data.RunExistingResult (RunExistingResult)+import qualified Chromatin.Data.RunExistingResult as RunExistingResult (RunExistingResult(..))+import Chromatin.Data.RunBuiltResult (RunBuiltResult)+import qualified Chromatin.Data.RunBuiltResult as RunBuiltResult (RunBuiltResult(..))+import Chromatin.Data.RebuildTask (RebuildTask(..))+import Chromatin.Rebuild.Build (InstallResult, installRplugin)+import qualified Chromatin.Rebuild.Build as InstallResult (InstallResult(Success, Failure))+import Chromatin.Run (runRplugin, RunRpluginResult)+import qualified Chromatin.Run as RunRpluginResult (RunRpluginResult(..))++runBuiltResult :: RebuildTask -> RunRpluginResult -> RunBuiltResult+runBuiltResult _ (RunRpluginResult.Success active) = RunBuiltResult.Success active+runBuiltResult task (RunRpluginResult.Failure err) = RunBuiltResult.Failure task err++installSuccess :: RebuildTask -> Rplugin -> Chromatin RunBuiltResult+installSuccess task rplugin =+ fmap (runBuiltResult task) (runRplugin rplugin)++installResult :: RebuildTask -> InstallResult -> Chromatin RunBuiltResult+installResult task (InstallResult.Success rplugin) = installSuccess task rplugin+installResult task (InstallResult.Failure err) = return $ RunBuiltResult.Failure task err++handleNonexisting :: RunExistingResult -> Chromatin RunBuiltResult+handleNonexisting (RunExistingResult.Success active) = return $ RunBuiltResult.Success active+handleNonexisting (RunExistingResult.Failure task err) =+ return $ RunBuiltResult.PreviousFailure "run-existing" task err+handleNonexisting (RunExistingResult.NotReady task@(RebuildTask name source)) = do+ result <- installRplugin name source+ installResult task result
+ lib/Chromatin/Run.hs view
@@ -0,0 +1,87 @@+module Chromatin.Run(+ runRplugin,+ RunRpluginResult(..),+ pypiPluginPackage,+) where++import Control.Monad.IO.Class (liftIO)+import Data.List.Split (linesBy)+import Data.MessagePack (Object)+import UnliftIO.Exception (catch)+import System.FilePath ((</>))+import qualified System.FilePath.Glob as Glob (globDir1, compile)+import Neovim (NeovimException, toObject, fromObject', vim_call_function')+import qualified Neovim as NeovimException (NeovimException(ErrorMessage, ErrorResult))+import qualified Data.Map as Map (fromList)+import Chromatin.Data.Rplugin (Rplugin(Rplugin))+import Chromatin.Data.RpluginName (RpluginName(RpluginName))+import Chromatin.Data.ActiveRplugin (ActiveRplugin(ActiveRplugin))+import Chromatin.Data.RpluginSource (RpluginSource(Stack, Pypi))+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Rebuild.Build (venvDir)++data RunRpluginResult =+ Success ActiveRplugin+ |+ Failure [String]+ deriving (Show, Eq)++jobstartFailure :: NeovimException -> Either String a+jobstartFailure (NeovimException.ErrorMessage doc) = Left (show doc)+jobstartFailure (NeovimException.ErrorResult obj) = Left (show obj)++unsafeJobstart :: [Object] -> Chromatin Int+unsafeJobstart args = do+ result <- vim_call_function' "jobstart" args+ fromObject' result++jobstart :: [Object] -> Chromatin (Either String Int)+jobstart args =+ catch (Right <$> unsafeJobstart args) (return . jobstartFailure)++runRpluginStack :: RpluginName -> FilePath -> Chromatin (Either String Int)+runRpluginStack (RpluginName name) path = do+ let opts = Map.fromList [("cwd", toObject path), ("rpc", toObject True)]+ jobstart [toObject $ "stack exec " ++ name, toObject opts]++pypiPluginExecutable :: RpluginName -> Chromatin FilePath+pypiPluginExecutable name = do+ dir <- venvDir name+ return $ dir </> "bin" </> "ribosome_start_plugin"++pypiSiteDir :: RpluginName -> Chromatin (Maybe FilePath)+pypiSiteDir name = do+ venv <- venvDir name+ matches <- liftIO $ Glob.globDir1 (Glob.compile "python3.?") (venv </> "lib")+ return $ case matches of+ dir : _ -> Just $ dir </> "site-packages"+ _ -> Nothing++pypiPluginPackage :: RpluginName -> Chromatin (Maybe FilePath)+pypiPluginPackage rpluginName@(RpluginName name) = do+ dir <- pypiSiteDir rpluginName+ return $ fmap (</> name) dir++runRpluginPypi :: RpluginName -> Chromatin (Either String Int)+runRpluginPypi rpluginName@(RpluginName name) = do+ dir <- venvDir rpluginName+ let exe = dir </> "bin" </> "python"+ let opts = Map.fromList [("rpc", toObject True)]+ start <- pypiPluginExecutable rpluginName+ mayPackage <- pypiPluginPackage rpluginName+ case mayPackage of+ Just package ->+ jobstart [toObject [toObject exe, toObject start, toObject package], toObject opts]+ Nothing -> return $ Left $ "no `lib/python` directory in virtualenv for `" ++ name ++ "`"++runRplugin' :: RpluginName -> RpluginSource -> Chromatin (Either String Int)+runRplugin' name (Stack path) = runRpluginStack name path+runRplugin' name (Pypi _) = runRpluginPypi name+runRplugin' _ _ = return (Left "NI")++runRplugin :: Rplugin -> Chromatin RunRpluginResult+runRplugin rplugin@(Rplugin name source) = do+ result <- runRplugin' name source+ return $ case result of+ Right channelId -> Success (ActiveRplugin channelId rplugin)+ Left err -> Failure (linesBy (=='\n') err)
+ lib/Chromatin/Settings.hs view
@@ -0,0 +1,10 @@+module Chromatin.Settings(+ rplugins,+) where++import Data.Default.Class (Default(def))+import Ribosome.Config.Setting+import Chromatin.Data.Rplugins (Rplugins)++rplugins :: Setting Rplugins+rplugins = Setting "rplugins" True (Just def)
+ lib/Chromatin/Test/Config.hs view
@@ -0,0 +1,13 @@+module Chromatin.Test.Config(+ defaultTestConfigWith,+ defaultTestConfig,+) where++import Ribosome.Test.Embed (TestConfig, Vars)+import qualified Ribosome.Test.Embed as E (defaultTestConfig, defaultTestConfigWith)++defaultTestConfigWith :: Vars -> TestConfig+defaultTestConfigWith = E.defaultTestConfigWith "chromatin"++defaultTestConfig :: TestConfig+defaultTestConfig = E.defaultTestConfig "chromatin"
+ lib/Chromatin/Test/Unit.hs view
@@ -0,0 +1,32 @@+module Chromatin.Test.Unit(+ spec,+ specWith,+ specWithDef,+ specConfig,+) where++import Data.Default.Class (def)+import UnliftIO.STM (newTVarIO)+import Ribosome.Test.Embed (Vars, TestConfig)+import Ribosome.Test.Unit (unitSpec)+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Data.Env (Env)+import Chromatin.Test.Config (defaultTestConfig, defaultTestConfigWith)++specConfig :: TestConfig -> Env -> Chromatin () -> IO ()+specConfig conf e s = do+ t <- newTVarIO e+ unitSpec conf t s++spec :: Env -> Chromatin () -> IO ()+spec =+ specConfig defaultTestConfig++specWith :: Env -> Chromatin () -> Vars -> IO ()+specWith e s vars = do+ t <- newTVarIO e+ unitSpec (defaultTestConfigWith vars) t s++specWithDef :: Chromatin () -> Vars -> IO ()+specWithDef =+ specWith def
+ lib/Chromatin/Unload.hs view
@@ -0,0 +1,18 @@+module Chromatin.Unload(+ unloadRplugins,+) where++import Data.Foldable (traverse_)+import qualified Control.Lens as Lens (over)+import qualified Ribosome.Control.Ribo as Ribo (modify)+import Chromatin.Data.Rplugin (Rplugin)+import Chromatin.Data.Chromatin (Chromatin)+import qualified Chromatin.Data.Env as Env (_rplugins)++unloadRplugin :: Rplugin -> Chromatin ()+unloadRplugin rplugin =+ Ribo.modify $ Lens.over Env._rplugins $ filter (rplugin ==)++unloadRplugins :: [Rplugin] -> Chromatin ()+unloadRplugins =+ traverse_ unloadRplugin
+ test/f/SpecMain.hs view
@@ -0,0 +1,11 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-}++module Main where++import Test.Framework+import Test.Framework.BlackBoxTest ()++main :: IO ()+main =+ return ()+ -- htfMain htf_importedTests
+ test/u/BuildSpec.hs view
@@ -0,0 +1,46 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-}++module BuildSpec(+ htf_thisModulesTests+) where++import Control.Monad.IO.Class (liftIO)+import Data.Default.Class (def)+import Test.Framework+import UnliftIO.Directory (getCurrentDirectory)+import Ribosome.Test.Embed (TestConfig(tcTimeout))+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Data.Rplugin (Rplugin(Rplugin))+import Chromatin.Data.RpluginName (RpluginName(RpluginName))+import Chromatin.Data.RpluginSource (RpluginSource(Stack, Pypi), PypiDepspec(..))+import Chromatin.Test.Unit (specWithDef, specConfig)+import Chromatin.Test.Config (defaultTestConfig)+import Chromatin.Rebuild.Build (installRplugin)+import qualified Chromatin.Rebuild.Build as InstallResult (InstallResult(Success))+import Config (vars)++stackSpec :: Chromatin ()+stackSpec = do+ cwd <- getCurrentDirectory+ let name = RpluginName "chromatin"+ let source = Stack cwd+ result <- installRplugin name source+ liftIO $ assertEqual (InstallResult.Success (Rplugin name source)) result++test_stack :: IO ()+test_stack =+ vars >>= specWithDef stackSpec++pypiSpec :: Chromatin ()+pypiSpec = do+ let name = RpluginName "myo"+ let source = Pypi (PypiDepspec "myo~=1.0.0a")+ result <- installRplugin name source+ liftIO $ assertEqual (InstallResult.Success (Rplugin name source)) result++testConfig :: TestConfig+testConfig = defaultTestConfig { tcTimeout = 30 }++test_pypi :: IO ()+test_pypi =+ specConfig testConfig def pypiSpec
+ test/u/Config.hs view
@@ -0,0 +1,9 @@+module Config(+ vars,+) where++import Ribosome.Test.Embed (Vars(..))++vars :: IO Vars+vars =+ return $ Vars []
+ test/u/ConfigSpec.hs view
@@ -0,0 +1,28 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-}++module ConfigSpec(+ htf_thisModulesTests+) where++import Test.Framework+import Chromatin.Data.Rplugins (Rplugins(Rplugins))+import Chromatin.Data.RpluginName (RpluginName(RpluginName))+import Chromatin.Data.RpluginConfig (RpluginConfig(RpluginConfig))+import Chromatin.Data.RpluginSource (RpluginSource(Hackage), HackageDepspec(HackageDepspec))+import Chromatin.Config (analyzeConfig, RpluginModification(RpluginNew))++rplugins :: Rplugins+rplugins = Rplugins [+ RpluginConfig "hackage:proteome-0.1.0.0" (Just (RpluginName "proteome")),+ RpluginConfig "hackage:flagellum" Nothing+ ]++target :: Either String [RpluginModification]+target = Right [+ RpluginNew (RpluginName "proteome") (Hackage (HackageDepspec "proteome-0.1.0.0")),+ RpluginNew (RpluginName "flagellum") (Hackage (HackageDepspec "flagellum"))+ ]++test_analyzeConfig :: IO ()+test_analyzeConfig =+ assertEqual target (analyzeConfig [] rplugins)
+ test/u/DiagSpec.hs view
@@ -0,0 +1,30 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-}++module DiagSpec(+ htf_thisModulesTests+) where++import Control.Monad.IO.Class (liftIO)+import Data.Default.Class (Default(def))+import Test.Framework+import Ribosome.Api.Buffer (currentBufferContent)+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Test.Unit (specWithDef)+import Chromatin.Diag (crmDiag)+import Config (vars)++target :: [String]+target = [+ "Diagnostics",+ ""+ ]++diagSpec :: Chromatin ()+diagSpec = do+ crmDiag def+ content <- currentBufferContent+ liftIO $ assertEqual target content++test_diag :: IO ()+test_diag =+ vars >>= specWithDef diagSpec
+ test/u/RebuildSpec.hs view
@@ -0,0 +1,36 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-}++module RebuildSpec(+ htf_thisModulesTests+) where++import Data.Default.Class (Default(def))+import Control.Monad.IO.Class (liftIO)+import Test.Framework+import Neovim (vim_command')+import Ribosome.Config.Setting (updateSetting)+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Data.Rplugins (Rplugins(Rplugins))+import Chromatin.Data.RpluginName (RpluginName(RpluginName))+import Chromatin.Data.RpluginConfig (RpluginConfig(RpluginConfig))+import Chromatin.Rebuild (crmRebuild)+import Chromatin.Test.Unit (specWithDef)+import qualified Chromatin.Settings as S (rplugins)+import Config (vars)++rplugins :: Rplugins+rplugins = Rplugins [+ RpluginConfig "hackage:proteome-0.1.0.0" (Just (RpluginName "proteome")),+ RpluginConfig "hackage:flagellum" Nothing+ ]++rebuildSpec :: Chromatin ()+rebuildSpec = do+ updateSetting S.rplugins rplugins+ crmRebuild def+ vim_command' "sleep 1"+ liftIO $ assertEqual [""] [""]++test_rebuild :: IO ()+test_rebuild =+ vars >>= specWithDef rebuildSpec
+ test/u/RunSpec.hs view
@@ -0,0 +1,33 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-}++module RunSpec(+ htf_thisModulesTests+) where++import Control.Monad.IO.Class (liftIO)+import Neovim (vim_call_function', toObject, vim_command)+import Test.Framework+import UnliftIO.Directory (getCurrentDirectory)+import Chromatin.Data.Chromatin (Chromatin)+import Chromatin.Data.ActiveRplugin (ActiveRplugin(ActiveRplugin))+import Chromatin.Data.Rplugin (Rplugin(Rplugin))+import Chromatin.Data.RpluginName (RpluginName(RpluginName))+import Chromatin.Data.RpluginSource (RpluginSource(Stack))+import Chromatin.Test.Unit (specWithDef)+import Chromatin.Run (runRplugin)+import qualified Chromatin.Run as RunRpluginResult (RunRpluginResult(Success))+import Config (vars)++runSpec :: Chromatin ()+runSpec = do+ cwd <- getCurrentDirectory+ let rplugin = Rplugin (RpluginName "chromatin") (Stack cwd)+ result <- runRplugin rplugin+ _ <- vim_command "sleep 500m"+ exists <- vim_call_function' "exists" [toObject ":CrmDiag"]+ liftIO $ assertEqual (RunRpluginResult.Success (ActiveRplugin 3 rplugin)) result+ liftIO $ assertEqual (toObject (2 :: Int)) exists++test_run :: IO ()+test_run =+ vars >>= specWithDef runSpec
+ test/u/SpecMain.hs view
@@ -0,0 +1,14 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-}++module Main where++import {-@ HTF_TESTS @-} DiagSpec+import {-@ HTF_TESTS @-} RebuildSpec+import {-@ HTF_TESTS @-} ConfigSpec+import {-@ HTF_TESTS @-} BuildSpec+import {-@ HTF_TESTS @-} RunSpec+import Test.Framework+import Test.Framework.BlackBoxTest ()++main :: IO ()+main = htfMain htf_importedTests