packages feed

ihaskell 0.2.0.3 → 0.2.0.4

raw patch · 8 files changed

+296/−85 lines, 8 filesdep +cmdargsdep −basic-preludedep ~MissingHdep ~aesondep ~bytestring

Dependencies added: cmdargs

Dependencies removed: basic-prelude

Dependency ranges changed: MissingH, aeson, bytestring, classy-prelude, containers, mtl, random, shelly, strict, text, zeromq3-haskell

Files

IHaskell/Eval/Evaluate.hs view
@@ -440,9 +440,16 @@   -- Do not display any output   return [] -evalCommand _ (ParseError loc err) = wrapExecution $ do-  write $ "Parse Error."-  return $ displayError $ formatParseError loc err+evalCommand _ (TypeSignature sig) = wrapExecution $+  -- We purposefully treat this as a "success" because that way execution+  -- continues. Empty type signatures are likely due to a parse error later+  -- on, and we want that to be displayed.+  return $ displayError $ "The type signature " ++ sig +++                          "\nlacks an accompanying binding."++evalCommand _ (ParseError loc err) = do+  write "Parse Error."+  return (Failure, displayError $ formatParseError loc err)  capturedStatement :: (String -> IO ())         -- ^ Function used to publish intermediate output.                   -> String                            -- ^ Statement to evaluate.
IHaskell/Eval/Parser.hs view
@@ -124,7 +124,7 @@     failures (_:rest) = failures rest      bestError :: [(ErrMsg, LineNumber, ColumnNumber)] -> CodeBlock-    bestError errors = ParseError (Loc line col) msg+    bestError errors = ParseError (Loc (line + startLine - 1) col) msg       where         (msg, line, col) = maximumBy compareLoc errors         compareLoc (_, line1, col1) (_, line2, col2) = compare line1 line2 <> compare col1 col2
IHaskell/IPython.hs view
@@ -3,16 +3,17 @@ -- | Description : Shell scripting wrapper using @Shelly@ for the @notebook@, @setup@, and --                 @console@ commands. module IHaskell.IPython (-  runIHaskell,-  setupIPythonProfile,-  ipythonVersion,-  parseVersion,   ipythonInstalled,-  installIPython+  installIPython,+  removeIPython,+  runConsole,+  runNotebook,+  readInitInfo,+  defaultConfFile, ) where  import ClassyPrelude-import Prelude (read, reads)+import Prelude (read, reads, init) import Shelly hiding (find, trace, path) import System.Argv0 import System.Directory@@ -22,20 +23,25 @@ import Text.Printf  import qualified System.IO.Strict as StrictIO- import qualified Paths_ihaskell as Paths import qualified Codec.Archive.Tar as Tar +import IHaskell.Types+ -- | Which commit of IPython we are on. ipythonCommit :: Text ipythonCommit = "1faf2f6e77fa31f4533e3edbe101c38ddf8943d8" +-- | The IPython profile name.+ipythonProfile :: String+ipythonProfile = "haskell"+ -- | Run IPython with any arguments. ipython :: Bool         -- ^ Whether to suppress output.         -> [Text]       -- ^ IPython command line arguments.         -> Sh String    -- ^ IPython output. ipython suppress args = do-  (_, ipythonDir) <- ihaskellDirs+  (_, ipythonDir, _) <- ihaskellDirs   let ipythonPath = fromText $ ipythonDir ++ "/bin/ipython"   sub $ do     setenv "PYTHONPATH" $ ipythonDir ++ "/lib/python2.7/site-packages"@@ -56,21 +62,39 @@     nothing _ _ _ = return ()  -- | Return the data directory for IHaskell and the IPython subdirectory. -ihaskellDirs :: Sh (Text, Text)+ihaskellDirs :: Sh (Text, Text, Text) ihaskellDirs = do   home <- maybe (error "$HOME not defined.") id <$> get_env "HOME" :: Sh Text   let ihaskellDir = home ++ "/.ihaskell"       ipythonDir = ihaskellDir ++ "/ipython"+      notebookDir = ihaskellDir ++ "/notebooks"    -- Make sure the directories exist.   mkdir_p $ fromText ipythonDir+  mkdir_p $ fromText notebookDir -  return (ihaskellDir, ipythonDir)+  return (ihaskellDir, ipythonDir, notebookDir) +defaultConfFile :: IO (Maybe String)+defaultConfFile = shellyNoDir $ do+  (ihaskellDir, _, _) <- ihaskellDirs+  let filename = ihaskellDir ++ "/rc.hs"+  exists <- test_f $ fromText filename+  return $ if exists+           then Just $ unpack filename+           else Nothing++-- | Remove IPython so it can be reinstalled.+removeIPython :: IO ()+removeIPython = void . shellyNoDir $ do+  (ihaskellDir, _, _) <- ihaskellDirs+  cd $ fromText ihaskellDir+  rm_rf "ipython-src"+ -- | Install IPython from source. installIPython :: IO () installIPython = void . shellyNoDir $ do-  (ihaskellDir, ipythonDir) <- ihaskellDirs+  (ihaskellDir, ipythonDir, _) <- ihaskellDirs    -- Install all Python dependencies.   pipPath <- path "pip"@@ -98,7 +122,7 @@ -- | Check whether IPython is properly installed. ipythonInstalled :: IO Bool ipythonInstalled = shellyNoDir $ do-  (_, ipythonDir) <- ihaskellDirs+  (_, ipythonDir, _) <- ihaskellDirs   let ipythonPath = ipythonDir ++ "/bin/ipython"   test_f $ fromText ipythonPath @@ -131,8 +155,8 @@ runIHaskell :: String   -- ^ IHaskell profile name.             -> String    -- ^ IPython app name.            -> [String]  -- ^ Arguments to IPython.-           -> IO ()-runIHaskell profile app args = void . shellyNoDir $ do+           -> Sh ()+runIHaskell profile app args = void $ do   -- Try to locate the profile. Do not die if it doesn't exist.   errExit False $ ipython True ["locate", "profile", pack profile] @@ -145,6 +169,33 @@   -- Run the IHaskell command.   ipython False $ map pack $ [app, "--profile", profile] ++ args +runConsole :: InitInfo -> IO ()+runConsole initInfo = void . shellyNoDir $ do+  writeInitInfo initInfo+  runIHaskell ipythonProfile "console" []++runNotebook :: InitInfo -> Maybe String -> IO ()+runNotebook initInfo maybeServeDir = void . shellyNoDir $ do+  (_, _, notebookDir) <- ihaskellDirs+  let args = case maybeServeDir of +               Nothing -> ["--notebook-dir", unpack notebookDir]+               Just dir -> ["--notebook-dir", dir]++  writeInitInfo initInfo+  runIHaskell ipythonProfile "notebook" args++writeInitInfo :: InitInfo -> Sh ()+writeInitInfo info = do+  (ihaskellDir, _, _) <- ihaskellDirs+  let filename = fromText $ ihaskellDir ++ "/last-arguments"+  liftIO $ writeFile filename $ show info++readInitInfo :: IO InitInfo+readInitInfo = shellyNoDir $ do+  (ihaskellDir, _, _) <- ihaskellDirs+  let filename = fromText $ ihaskellDir ++ "/last-arguments"+  read <$> liftIO (readFile filename)+ -- | Create the IPython profile. setupIPythonProfile :: String -- ^ IHaskell profile name.                     -> IO ()@@ -164,6 +215,17 @@ copyProfile :: Text -> IO () copyProfile profileDir = do   profileTar <- Paths.getDataFileName "profile/profile.tar"+  {-+  -- Load profile from Resources directory of Mac *.app.+  ihaskellPath <- shellyNoDir getIHaskellPath+  profileTar <- if "IHaskell.app/Contents/MacOS" `isInfixOf` ihaskellPath+               then+                let pieces = split "/" ihaskellPath+                    pathPieces = init pieces ++ ["..", "Resources", "profile.tar"] in+                  return $ intercalate "/" pathPieces+               else Paths.getDataFileName "profile/profile.tar"+  -}+  putStrLn $ pack $ "Loading profile from " ++ profileTar    Tar.extract (unpack profileDir) profileTar   -- | Insert the IHaskell path into the IPython configuration.
IHaskell/Types.hs view
@@ -15,6 +15,7 @@   MimeType(..),   DisplayData(..),   ExecuteReplyStatus(..),+  InitInfo(..),   ) where  import ClassyPrelude@@ -64,6 +65,13 @@                     "iopub_port"  .= iopubPort profile,                     "key"         .= key profile                    ]++-- | Initialization information for the kernel.+data InitInfo = InitInfo {+  extensions :: [String],   -- ^ Extensions to enable at start.+  initCells :: [String]     -- ^ Code blocks to run before start.+  }+  deriving (Show, Read)  -- | A message header with some metadata.   data MessageHeader = MessageHeader {
IHaskell/ZeroMQ.hs view
@@ -9,9 +9,9 @@   serveProfile   ) where -import BasicPrelude+import ClassyPrelude hiding (stdin) import Control.Concurrent-import System.ZMQ3+import System.ZMQ3 hiding (stdin) import Data.Aeson (encode)  import qualified Data.ByteString.Lazy as ByteString@@ -71,7 +71,7 @@ serveSocket :: SocketType a => Context -> a -> Port -> (Socket a -> IO b) -> IO () serveSocket context socketType port action = void $   withSocket context socketType $ \socket -> do-    bind socket $ textToString $ "tcp://127.0.0.1:" ++ show port+    bind socket $ unpack $ "tcp://127.0.0.1:" ++ show port     forever $ action socket  -- | Listener on the heartbeat port. Echoes back any data it was sent.
Main.hs view
@@ -5,11 +5,14 @@ --                 Chans to communicate with the ZeroMQ sockets.  module Main where import ClassyPrelude hiding (liftIO)+import Prelude (last) import Control.Concurrent.Chan+import Control.Concurrent (threadDelay) import Data.Aeson import Text.Printf import System.Exit (exitSuccess) import System.Directory+import System.Console.CmdArgs.Explicit hiding (complete)  import qualified Data.Map as Map @@ -22,40 +25,160 @@ import qualified Data.ByteString.Char8 as Chars import IHaskell.IPython -import GHC+import GHC hiding (extensions) import Outputable (showSDoc, ppr) +-- All state stored in the kernel between executions. data KernelState = KernelState   { getExecutionCounter :: Int   } +-- Command line arguments to IHaskell.  A set of aruments is annotated with+-- the mode being invoked.+data Args = Args IHaskellMode [Argument]++data Argument+  = ServeFrom String    -- ^ Which directory to serve notebooks from.+  | Extension String    -- ^ An extension to load at startup.+  | ConfFile String     -- ^ A file with commands to load at startup.+  | Help                -- ^ Display help text.+  deriving (Eq, Show)++-- Which mode IHaskell is being invoked in.+-- `None` means no mode was specified.+data IHaskellMode+  = None+  | Notebook+  | Console+  | UpdateIPython+  | Kernel (Maybe String)+  deriving (Eq, Show)+ main ::  IO () main = do+  stringArgs <- map unpack <$> getArgs+  writeFile "/users/silver/bloop" $ show stringArgs+  case process ihaskellArgs stringArgs of+    Left errmsg -> putStrLn $ pack errmsg+    Right args ->+      ihaskell args++universalFlags :: [Flag Args]+universalFlags = [+  flagReq ["extension","e", "X"] (store Extension) "<ghc-extension>" "Extension to enable at start.",+  flagReq ["conf","c"] (store ConfFile) "<file.hs>" "File with commands to execute at start.",+  flagHelpSimple (add Help)+  ]+  where +    add flag (Args mode flags) = Args mode $ flag : flags++store :: (String -> Argument) -> String -> Args -> Either String Args+store constructor str (Args mode prev) = Right $ Args mode $ constructor str : prev++notebook :: Mode Args+notebook = mode "notebook" (Args Notebook []) "Browser-based notebook interface." noArgs $+  flagReq ["serve","s"] (store ServeFrom) "<dir>" "Directory to serve notebooks from.":+  universalFlags++console :: Mode Args+console = mode "console" (Args Console []) "Console-based interactive repl." noArgs universalFlags++kernel = mode "kernel" (Args (Kernel Nothing) []) "Invoke the IHaskell kernel." kernelArg []+  where+    kernelArg = flagArg update "<json-kernel-file>"+    update filename (Args _ flags) = Right $ Args (Kernel $ Just filename) flags++update :: Mode Args+update = mode "update" (Args UpdateIPython []) "Update IPython frontends." noArgs []++ihaskellArgs :: Mode Args+ihaskellArgs = (modeEmpty $ Args None []) { modeGroupModes = toGroup [console, notebook, update, kernel] }++noArgs = flagArg unexpected ""+  where+    unexpected a = error $ "Unexpected argument: " ++ a++ihaskell :: Args -> IO ()+-- If no mode is specified, print help text.+ihaskell (Args None _) = +  print $ helpText [] HelpFormatAll ihaskellArgs++-- Update IPython: remove then reinstall.+-- This is in case cabal updates IHaskell but the corresponding IPython+-- isn't updated. This is hard to detect since versions of IPython might+-- not change!+ihaskell (Args UpdateIPython _) = do+  removeIPython+  installIPython+  putStrLn "IPython updated."+    +ihaskell (Args Console flags) = showingHelp Console flags $ do   installed <- ipythonInstalled   unless installed installIPython -  args <- map unpack <$> getArgs-  case args of-    -- Create the "haskell" profile.-    ["setup"] -> setupIPythonProfile "haskell"+  flags <- addDefaultConfFile flags+  info <- initInfo flags+  runConsole info -    -- Run the ipython <cmd> --profile haskell <args> command.-    "notebook":ipythonArgs -> runIHaskell "haskell" "notebook" ipythonArgs-    "console":ipythonArgs -> runIHaskell "haskell" "console" ipythonArgs+ihaskell (Args Notebook flags) = showingHelp Notebook flags $ do+  installed <- ipythonInstalled+  unless installed installIPython -    -- Read the profile JSON file from the argument list.-    ["kernel", profileSrc] -> kernel profileSrc+  let server = case mapMaybe serveDir flags of+                 [] -> Nothing+                 xs -> Just $ last xs -    -- Bad arguments.-    [] -> putStrLn $ "Provide command to run ('setup', 'kernel <profile-file.json>', " ++-                                           "'notebook [args]', 'console [args]')."-    cmd:_ -> putStrLn $ "Unknown command: " ++ pack cmd+  flags <- addDefaultConfFile flags+  info <- initInfo flags+  runNotebook info server+  where+    serveDir (ServeFrom dir) = Just dir+    serveDir _ = Nothing +ihaskell (Args (Kernel (Just filename)) _) = do+  initInfo <- readInitInfo+  runKernel filename initInfo +-- | Add a conf file to the arguments if none exists.+addDefaultConfFile :: [Argument] -> IO [Argument]+addDefaultConfFile flags = do+  def <- defaultConfFile+  case (find isConfFile flags, def) of+    (Nothing, Just file) -> return $ ConfFile file : flags+    _ -> return flags+  where+    isConfFile (ConfFile _) = True+    isConfFile _ = False++showingHelp :: IHaskellMode -> [Argument] -> IO () -> IO ()+showingHelp mode flags act =+  case find (==Help) flags of+    Just _ ->+      print $ helpText [] HelpFormatAll $ chooseMode mode+    Nothing ->+      act+  where+    chooseMode Console = console+    chooseMode Notebook = notebook+    chooseMode (Kernel _) = kernel+    chooseMode UpdateIPython = update+ +-- | Parse initialization information from the flags.+initInfo :: [Argument] -> IO InitInfo+initInfo [] = return InitInfo { extensions = [], initCells = []}+initInfo (flag:flags) = do+  info <- initInfo flags+  case flag of+    Extension ext -> return info { extensions = ext:extensions info }+    ConfFile filename -> do+      cell <- readFile (fpFromText $ pack filename)+      return info { initCells = cell:initCells info }+ -- | Run the IHaskell language kernel.-kernel :: String -- ^ Filename of profile JSON file.-       -> IO ()-kernel profileSrc = do+runKernel :: String    -- ^ Filename of profile JSON file.+          -> InitInfo  -- ^ Initialization information from the invocation.+          -> IO ()+runKernel profileSrc initInfo = do   -- Switch to a temporary directory so that any files we create aren't   -- visible. On Unix, this is usually /tmp.  If there is no temporary   -- directory available, just stay in the current one and ignore the@@ -71,20 +194,31 @@   state <- initialKernelState    -- Receive and reply to all messages on the shell socket.-  interpret $ forever $ do-    -- Read the request from the request channel.-    request <- liftIO $ readChan $ shellRequestChannel interface+  interpret $ do+    -- Initialize the context by evaluating everything we got from the  +    -- command line flags. This includes enabling some extensions and also+    -- running some code.+    let extLines = map (":extension " ++) $ extensions initInfo+        noPublish _ _ = return ()       +        zero = 0   -- To please hlint+        evaluator line = evaluate zero line noPublish+    mapM_ evaluator extLines+    mapM_ evaluator $ initCells initInfo -    -- Create a header for the reply.-    replyHeader <- createReplyHeader (header request)+    forever $ do+      -- Read the request from the request channel.+      request <- liftIO $ readChan $ shellRequestChannel interface -    -- Create the reply, possibly modifying kernel state.-    oldState <- liftIO $ takeMVar state-    (newState, reply) <- replyTo interface request replyHeader oldState -    liftIO $ putMVar state newState+      -- Create a header for the reply.+      replyHeader <- createReplyHeader (header request) -    -- Write the reply to the reply channel.-    liftIO $ writeChan (shellReplyChannel interface) reply+      -- Create the reply, possibly modifying kernel state.+      oldState <- liftIO $ takeMVar state+      (newState, reply) <- replyTo interface request replyHeader oldState +      liftIO $ putMVar state newState++      -- Write the reply to the reply channel.+      liftIO $ writeChan (shellReplyChannel interface) reply  -- Initial kernel state. initialKernelState :: IO (MVar KernelState)
ihaskell.cabal view
@@ -7,7 +7,7 @@ -- PVP summary:      +-+------- breaking API changes --                   | | +----- non-breaking API additions --                   | | | +--- code changes with no API change-version:             0.2.0.3+version:             0.2.0.4  -- A short (one-line) description of the package. synopsis:            A Haskell backend kernel for the IPython project.@@ -47,32 +47,32 @@  library   build-depends:       base ==4.6.*,+                       cmdargs >= 0.10,                        tar,                        ghc-parser,                        unix >= 2.6,                        hspec,-                       zeromq3-haskell ==0.5.*,-                       aeson ==0.6.*,-                       MissingH ==1.2.*,-                       basic-prelude ==0.3.*,+                       zeromq3-haskell >=0.5,+                       aeson >=0.6,+                       MissingH >=1.2,                        classy-prelude >=0.6,-                       bytestring ==0.10.*,+                       bytestring >=0.10,                        uuid >=1.2.6,-                       containers ==0.5.*,+                       containers >=0.5,                        ghc ==7.6.*,                        ghc-paths ==0.1.*,-                       random ==1.0.*,+                       random >=1.0,                        split >= 0.2,                        utf8-string,-                       strict ==0.3.*,-                       shelly ==1.3.*,+                       strict >=0.3,+                       shelly >=1.3,                        system-argv0,                        directory,                        here,                        system-filepath,                        cereal ==0.3.*,-                       text ==0.11.*,-                       mtl == 2.1.*,+                       text >=0.11,+                       mtl >= 2.1,                        template-haskell   exposed-modules: IHaskell.Display,                    Paths_ihaskell,@@ -104,32 +104,32 @@      -- Other library packages from which modules are imported.   build-depends:       base ==4.6.*,+                       cmdargs >= 0.10,                        tar,                        ghc-parser,                        unix >= 2.6,                        hspec,-                       zeromq3-haskell ==0.5.*,-                       aeson ==0.6.*,-                       MissingH ==1.2.*,-                       basic-prelude ==0.3.*,-                       classy-prelude ==0.6.*,-                       bytestring ==0.10.*,+                       zeromq3-haskell >=0.5,+                       aeson >=0.6,+                       MissingH >=1.2,+                       classy-prelude >=0.6,+                       bytestring >=0.10,                        uuid >=1.2.6,-                       containers ==0.5.*,+                       containers >=0.5,                        ghc ==7.6.*,                        ghc-paths ==0.1.*,-                       random ==1.0.*,+                       random >=1.0,                        split >= 0.2,                        utf8-string,-                       strict ==0.3.*,-                       shelly ==1.3.*,+                       strict >=0.3,+                       shelly >=1.3,                        system-argv0,                        directory,                        here,                        system-filepath,                        cereal ==0.3.*,-                       text ==0.11.*,-                       mtl == 2.1.*,+                       text >=0.11,+                       mtl >= 2.1,                        template-haskell  Test-Suite hspec@@ -137,32 +137,32 @@   Ghc-Options: -threaded   Main-Is: Hspec.hs   build-depends:       base ==4.6.*,+                       cmdargs >= 0.10,                        tar,                        ghc-parser,                        unix >= 2.6,                        hspec,-                       zeromq3-haskell ==0.5.*,-                       aeson ==0.6.*,-                       MissingH ==1.2.*,-                       basic-prelude ==0.3.*,-                       classy-prelude ==0.6.*,-                       bytestring ==0.10.*,+                       zeromq3-haskell >=0.5,+                       aeson >=0.6,+                       MissingH >=1.2,+                       classy-prelude >=0.6,+                       bytestring >=0.10,                        uuid >=1.2.6,-                       containers ==0.5.*,+                       containers >=0.5,                        ghc ==7.6.*,                        ghc-paths ==0.1.*,-                       random ==1.0.*,+                       random >=1.0,                        split >= 0.2,                        utf8-string,-                       strict ==0.3.*,-                       shelly ==1.3.*,+                       strict >=0.3,+                       shelly >=1.3,                        system-argv0,                        directory,                        here,                        system-filepath,                        cereal ==0.3.*,-                       text ==0.11.*,-                       mtl == 2.1.*,+                       text >=0.11,+                       mtl >= 2.1,                        template-haskell  source-repository head
profile/profile.tar view

binary file changed (83968 → 83968 bytes)