git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
[psc-ide] adds a reset command (#2112)
b5af366Christoph Hegemann
psc-ide-server/Main.hs+15−22
@@ -72,12 +72,13 @@ data Options = Options
72 { optionsDirectory :: Maybe FilePath
72 { optionsDirectory :: Maybe FilePath
73 , optionsOutputPath :: FilePath
73 , optionsOutputPath :: FilePath
74 , optionsPort :: PortID
74 , optionsPort :: PortID
75+ , optionsNoWatch :: Bool
75 , optionsDebug :: Bool
76 , optionsDebug :: Bool
76 }
77 }
77
78
78main :: IO ()
79main :: IO ()
79main = do
80main = do
80− Options dir outputPath port debug <- execParser opts
81+ Options dir outputPath port noWatch debug <- execParser opts
81 maybe (pure ()) setCurrentDirectory dir
82 maybe (pure ()) setCurrentDirectory dir
82 serverState <- newTVarIO emptyPscIdeState
83 serverState <- newTVarIO emptyPscIdeState
83 cwd <- getCurrentDirectory
84 cwd <- getCurrentDirectory
@@ -88,31 +89,23 @@ main = do
88 (do putStrLn ("Your output directory didn't exist. I'll create it at: " <> fullOutputPath)
89 (do putStrLn ("Your output directory didn't exist. I'll create it at: " <> fullOutputPath)
89 createDirectory fullOutputPath
90 createDirectory fullOutputPath
90 putStrLn "This usually means you didn't compile your project yet."
91 putStrLn "This usually means you didn't compile your project yet."
91− putStrLn "psc-ide needs you to compile your project (for example by running pulp build)"
92+ putStrLn "psc-ide needs you to compile your project (for example by running pulp build)")
92− )
93
93
94+ unless noWatch $
94− _ <- forkFinally (watcher serverState fullOutputPath) print
95+ void (forkFinally (watcher serverState fullOutputPath) print)
95− let conf =
96+
96− Configuration
97− {
98− confDebug = debug
99− , confOutputPath = outputPath
97+ let conf = Configuration {confDebug = debug, confOutputPath = outputPath}
100− }
101− let env =
102− PscIdeEnvironment
103− {
104− envStateVar = serverState
98+ env = PscIdeEnvironment {envStateVar = serverState, envConfiguration = conf}
105− , envConfiguration = conf
106− }
107 startServer port env
99 startServer port env
108 where
100 where
109 parser =
101 parser =
110− Options <$>
102+ Options
111− optional (strOption (long "directory" <> short 'd')) <*>
103+ <$> optional (strOption (long "directory" <> short 'd'))
112− strOption (long "output-directory" <> value "output/") <*>
104+ <*> strOption (long "output-directory" <> value "output/")
113− (PortNumber . fromIntegral <$>
105+ <*> (PortNumber . fromIntegral <$>
114− option auto (long "port" <> short 'p' <> value (4242 :: Integer))) <*>
106+ option auto (long "port" <> short 'p' <> value (4242 :: Integer)))
107+ <*> switch (long "no-watch")
115− switch (long "debug")
108+ <*> switch (long "debug")
116 opts = info (version <*> helper <*> parser) mempty
109 opts = info (version <*> helper <*> parser) mempty
117 version = abortOption
110 version = abortOption
118 (InfoMsg (showVersion Paths.version))
111 (InfoMsg (showVersion Paths.version))
psc-ide-server/PROTOCOL.md+4−2
@@ -407,14 +407,16 @@ Hiding Import(`import Data.Array hiding (filter, filterM, join)`):
407 }
407 }
408]
408]
409```
409```
410−### Cwd/Quit
410+### Cwd/Quit/Reset
411`cwd` returns the working directory of the server(should be your project root).
411`cwd` returns the working directory of the server(should be your project root).
412
412
413`quit` quits the server.
413`quit` quits the server.
414
414
415+`reset` resets all loaded modules.
416+
415```json
417```json
416{
418{
417− "command": "cwd|quit"
419+ "command": "cwd|quit|reset"
418}
420}
419```
421```
420
422
psc-ide-server/README.md+1
@@ -20,6 +20,7 @@ It supports the following options:
20 project directory. Defaults to `output/`, relative to either the current
20 project directory. Defaults to `output/`, relative to either the current
21 directory or the directory specified by `-d`.
21 directory or the directory specified by `-d`.
22- `--debug`: Enables some logging meant for debugging
22- `--debug`: Enables some logging meant for debugging
23+- `--no-watch`: Disables the filewatcher
23- `--version`: Output psc-ide version
24- `--version`: Output psc-ide version
24
25
25## Issuing queries
26## Issuing queries
src/Language/PureScript/Ide.hs+1
@@ -90,6 +90,7 @@ handleCommand (Rebuild file) =
90 rebuildFile file
90 rebuildFile file
91handleCommand Cwd =
91handleCommand Cwd =
92 TextResult . T.pack <$> liftIO getCurrentDirectory
92 TextResult . T.pack <$> liftIO getCurrentDirectory
93+handleCommand Reset = resetPscIdeState *> pure (TextResult "State has been reset.")
93handleCommand Quit = liftIO exitSuccess
94handleCommand Quit = liftIO exitSuccess
94
95
95findCompletions :: (PscIde m, MonadLogger m) =>
96findCompletions :: (PscIde m, MonadLogger m) =>
src/Language/PureScript/Ide/Command.hs+2
@@ -63,6 +63,7 @@ data Command
63 | List { listType :: ListType }
63 | List { listType :: ListType }
64 | Rebuild FilePath -- ^ Rebuild the specified file using the loaded externs
64 | Rebuild FilePath -- ^ Rebuild the specified file using the loaded externs
65 | Cwd
65 | Cwd
66+ | Reset
66 | Quit
67 | Quit
67
68
68data ImportCommand
69data ImportCommand
@@ -104,6 +105,7 @@ instance FromJSON Command where
104 return $ List (fromMaybe LoadedModules listType')
105 return $ List (fromMaybe LoadedModules listType')
105 "cwd" -> return Cwd
106 "cwd" -> return Cwd
106 "quit" -> return Quit
107 "quit" -> return Quit
108+ "reset" -> pure Reset
107 "load" ->
109 "load" ->
108 maybe (pure (Load [] [])) (\params -> do
110 maybe (pure (Load [] [])) (\params -> do
109 mods <- params .:? "modules"
111 mods <- params .:? "modules"
src/Language/PureScript/Ide/State.hs+5
@@ -35,6 +35,11 @@ import Language.PureScript.Ide.Reexports
35import Language.PureScript.Ide.Types
35import Language.PureScript.Ide.Types
36import Language.PureScript.Names
36import Language.PureScript.Names
37
37
38+resetPscIdeState :: PscIde m => m ()
39+resetPscIdeState = do
40+ stateVar <- envStateVar <$> ask
41+ liftIO $ atomically (writeTVar stateVar emptyPscIdeState)
42+
38getPscIdeState :: (PscIde m) =>
43getPscIdeState :: (PscIde m) =>
39 m (M.Map ModuleIdent [ExternDecl])
44 m (M.Map ModuleIdent [ExternDecl])
40getPscIdeState = do
45getPscIdeState = do
tests/Language/PureScript/Ide/Imports/IntegrationSpec.hs+3−10
@@ -1,7 +1,7 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2module Language.PureScript.Ide.Imports.IntegrationSpec where
2module Language.PureScript.Ide.Imports.IntegrationSpec where
3
3
4−import Control.Monad
4+import Control.Monad (void)
5import Data.Text (Text)
5import Data.Text (Text)
6import qualified Data.Text as T
6import qualified Data.Text as T
7import qualified Data.Text.IO as TIO
7import qualified Data.Text.IO as TIO
@@ -13,16 +13,9 @@ import System.FilePath
13
13
14setup :: IO ()
14setup :: IO ()
15setup = do
15setup = do
16− Integration.deleteOutputFolder
16+ Integration.reset
17− s <- Integration.compileTestProject
18− unless s $ fail "Failed to compile .purs sources"
19− -- Integration.quitServer -- kill a eventually running psc-ide-server instance
20− _ <- Integration.startServer
21 mapM_ Integration.loadModuleWithDeps ["ImportsSpec", "ImportsSpec1"]
17 mapM_ Integration.loadModuleWithDeps ["ImportsSpec", "ImportsSpec1"]
22
18
23−teardown :: IO ()
24−teardown = Integration.quitServer
25−
26withSupportFiles :: (FilePath -> FilePath -> IO a) -> IO ()
19withSupportFiles :: (FilePath -> FilePath -> IO a) -> IO ()
27withSupportFiles test = do
20withSupportFiles test = do
28 pdir <- Integration.projectDirectory
21 pdir <- Integration.projectDirectory
@@ -38,7 +31,7 @@ outputFileShouldBe expectation = do
38 shouldBe (T.lines outRes) expectation
31 shouldBe (T.lines outRes) expectation
39
32
40spec :: Spec
33spec :: Spec
41−spec = beforeAll_ setup $ afterAll_ teardown $ describe "Adding imports" $ do
34+spec = beforeAll_ setup . describe "Adding imports" $ do
42 let
35 let
43 sourceFileSkeleton :: [Text] -> [Text]
36 sourceFileSkeleton :: [Text] -> [Text]
44 sourceFileSkeleton importSection =
37 sourceFileSkeleton importSection =
tests/Language/PureScript/Ide/Integration.hs+19−10
@@ -27,29 +27,30 @@ module Language.PureScript.Ide.Integration
27 , projectDirectory
27 , projectDirectory
28 , deleteFileIfExists
28 , deleteFileIfExists
29 -- sending commands
29 -- sending commands
30+ , addImport
31+ , addImplicitImport
30 , loadModule
32 , loadModule
31 , loadModuleWithDeps
33 , loadModuleWithDeps
32 , getFlexCompletions
34 , getFlexCompletions
33 , getType
35 , getType
34− , addImport
35− , addImplicitImport
36 , rebuildModule
36 , rebuildModule
37+ , reset
37 -- checking results
38 -- checking results
38 , resultIsSuccess
39 , resultIsSuccess
39 , parseCompletions
40 , parseCompletions
40 , parseTextResult
41 , parseTextResult
41 ) where
42 ) where
42
43
43−import Control.Concurrent (threadDelay)
44+import Control.Concurrent (threadDelay)
44import Control.Exception
45import Control.Exception
45−import Control.Monad (join, when)
46+import Control.Monad (join, when)
46import Data.Aeson
47import Data.Aeson
47import Data.Aeson.Types
48import Data.Aeson.Types
48−import qualified Data.ByteString.Lazy.UTF8 as BSL
49+import qualified Data.ByteString.Lazy.UTF8 as BSL
49−import Data.Either (isRight)
50+import Data.Either (isRight)
50−import Data.Maybe (fromJust)
51+import Data.Maybe (fromJust)
51−import qualified Data.Text as T
52+import qualified Data.Text as T
52−import qualified Data.Vector as V
53+import qualified Data.Vector as V
53import Language.PureScript.Ide.Util
54import Language.PureScript.Ide.Util
54import System.Directory
55import System.Directory
55import System.Exit
56import System.Exit
@@ -64,7 +65,9 @@ projectDirectory = do
64startServer :: IO ProcessHandle
65startServer :: IO ProcessHandle
65startServer = do
66startServer = do
66 pdir <- projectDirectory
67 pdir <- projectDirectory
68+ -- Turn off filewatching since it creates race condition in a testing environment
67− (_, _, _, procHandle) <- createProcess $ (shell "psc-ide-server") {cwd=Just pdir}
69+ (_, _, _, procHandle) <- createProcess $
70+ (shell "psc-ide-server --no-watch") {cwd = Just pdir}
68 threadDelay 500000 -- give the server 500ms to start up
71 threadDelay 500000 -- give the server 500ms to start up
69 return procHandle
72 return procHandle
70
73
@@ -128,6 +131,12 @@ quitServer = do
128 _ <- try $ sendCommand quitCommand :: IO (Either SomeException String)
131 _ <- try $ sendCommand quitCommand :: IO (Either SomeException String)
129 return ()
132 return ()
130
133
134+reset :: IO ()
135+reset = do
136+ let resetCommand = object ["command" .= ("reset" :: String)]
137+ _ <- try $ sendCommand resetCommand :: IO (Either SomeException String)
138+ return ()
139+
131loadModuleWithDeps :: String -> IO String
140loadModuleWithDeps :: String -> IO String
132loadModuleWithDeps m = sendCommand $ load [] [m]
141loadModuleWithDeps m = sendCommand $ load [] [m]
133
142
tests/Language/PureScript/Ide/MatcherSpec.hs+8−16
@@ -2,21 +2,22 @@
2
2
3module Language.PureScript.Ide.MatcherSpec where
3module Language.PureScript.Ide.MatcherSpec where
4
4
5+import Control.Monad (void)
5import Data.Text (Text)
6import Data.Text (Text)
7+import qualified Language.PureScript as P
6import Language.PureScript.Ide.Integration
8import Language.PureScript.Ide.Integration
7import Language.PureScript.Ide.Matcher
9import Language.PureScript.Ide.Matcher
8import Language.PureScript.Ide.Types
10import Language.PureScript.Ide.Types
9−import qualified Language.PureScript as P
10import Test.Hspec
11import Test.Hspec
11
12
12value :: Text -> ExternDecl
13value :: Text -> ExternDecl
13value s = ValueDeclaration s $ P.TypeWildcard $ P.SourceSpan "" (P.SourcePos 0 0) (P.SourcePos 0 0)
14value s = ValueDeclaration s $ P.TypeWildcard $ P.SourceSpan "" (P.SourcePos 0 0) (P.SourcePos 0 0)
14
15
15completions :: [Match]
16completions :: [Match]
16−completions = [
17+completions =
17− Match "" $ value "firstResult",
18+ [ Match "" (value "firstResult")
18− Match "" $ value "secondResult",
19+ , Match "" (value "secondResult")
19− Match "" $ value "fiult"
20+ , Match "" (value "fiult")
20 ]
21 ]
21
22
22mkResult :: [Int] -> [Match]
23mkResult :: [Int] -> [Match]
@@ -26,15 +27,7 @@ runFlex :: Text -> [Match]
26runFlex s = runMatcher (flexMatcher s) completions
27runFlex s = runMatcher (flexMatcher s) completions
27
28
28setup :: IO ()
29setup :: IO ()
29−setup = do
30− deleteOutputFolder
31− _ <- compileTestProject
32− _ <- startServer
33− _ <- loadModuleWithDeps "Main"
30+setup = reset *> void (loadModuleWithDeps "Main")
34− return ()
35−
36−teardown :: IO ()
37−teardown = quitServer
38
31
39spec :: Spec
32spec :: Spec
40spec = do
33spec = do
@@ -46,8 +39,7 @@ spec = do
46 it "scores short matches higher and sorts accordingly" $
39 it "scores short matches higher and sorts accordingly" $
47 runFlex "filt" `shouldBe` mkResult [2, 0]
40 runFlex "filt" `shouldBe` mkResult [2, 0]
48
41
49− beforeAll_ setup $ afterAll_ teardown $
50− describe "Integration Tests: Flex Matcher" $ do
42+ beforeAll_ setup . describe "Integration Tests: Flex Matcher" $ do
51 it "doesn't match on an empty string" $ do
43 it "doesn't match on an empty string" $ do
52 cs <- getFlexCompletions ""
44 cs <- getFlexCompletions ""
53 cs `shouldBe` []
45 cs `shouldBe` []
tests/Language/PureScript/Ide/RebuildSpec.hs+2−17
@@ -1,22 +1,8 @@
1module Language.PureScript.Ide.RebuildSpec where
1module Language.PureScript.Ide.RebuildSpec where
2
2
3−import Control.Monad
4import qualified Language.PureScript.Ide.Integration as Integration
3import qualified Language.PureScript.Ide.Integration as Integration
5−import Test.Hspec
6−
7import System.FilePath
4import System.FilePath
8−
5+import Test.Hspec
9−compile :: IO ()
10−compile = do
11− Integration.deleteOutputFolder
12− s <- Integration.compileTestProject
13− unless s $ fail "Failed to compile .purs sources"
14−
15−teardown :: IO ()
16−teardown = Integration.quitServer
17−
18−restart :: IO ()
19−restart = Integration.quitServer *> (void Integration.startServer)
20
6
21shouldBeSuccess :: String -> IO ()
7shouldBeSuccess :: String -> IO ()
22shouldBeSuccess = shouldBe True . Integration.resultIsSuccess
8shouldBeSuccess = shouldBe True . Integration.resultIsSuccess
@@ -25,8 +11,7 @@ shouldBeFailure :: String -> IO ()
25shouldBeFailure = shouldBe False . Integration.resultIsSuccess
11shouldBeFailure = shouldBe False . Integration.resultIsSuccess
26
12
27spec :: Spec
13spec :: Spec
28−spec = beforeAll_ compile $ afterAll_ teardown $ before_ restart $ do
29− describe "Rebuilding single modules" $ do
14+spec = before_ Integration.reset $ describe "Rebuilding single modules" $ do
30 it "rebuilds a correct module without dependencies successfully" $ do
15 it "rebuilds a correct module without dependencies successfully" $ do
31 _ <- Integration.loadModuleWithDeps "RebuildSpecSingleModule"
16 _ <- Integration.loadModuleWithDeps "RebuildSpecSingleModule"
32 pdir <- Integration.projectDirectory
17 pdir <- Integration.projectDirectory
tests/TestPscIde.hs+9−2
@@ -1,7 +1,14 @@
1module TestPscIde where
1module TestPscIde where
2
2
3+import Control.Monad (unless)
4+import Language.PureScript.Ide.Integration
3import qualified PscIdeSpec
5import qualified PscIdeSpec
4−import Test.Hspec
6+import Test.Hspec
5
7
6main :: IO ()
8main :: IO ()
9+main = do
10+ deleteOutputFolder
11+ s <- compileTestProject
12+ unless s $ fail "Failed to compile .purs sources"
13+
7−main = hspec PscIdeSpec.spec
14+ withServer (hspec PscIdeSpec.spec)