Skip to content
This repository was archived by the owner on May 1, 2020. It is now read-only.

Commit ed6f8cf

Browse files
committed
Propagating option parsing errors
When an option is provided with an invalid type of value, the error is propagated upwards as a plugin error. Resolves #31
1 parent a7ffd2b commit ed6f8cf

File tree

3 files changed

+55
-20
lines changed

3 files changed

+55
-20
lines changed

src/Options.purs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,18 +263,17 @@ foldPscOptions (Psc a) = mkBoolean noPreludeOpt a.noPrelude <>
263263
mkBoolean noPrefixOpt a.noPrefix <>
264264
mkPathArray ffiOpt a.ffi
265265

266-
pscOptions :: Foreign -> [String]
267-
pscOptions opts = either (const []) foldPscOptions parsed
268-
where parsed = read opts :: F Psc
266+
pscOptions :: Foreign -> Either ForeignError [String]
267+
pscOptions opts = foldPscOptions <$> (read opts :: F Psc)
269268

270-
pscOptionsNoOutput :: Foreign -> Tuple (Maybe String) [String]
271-
pscOptionsNoOutput opts = either (const $ tuple2 Nothing []) fold parsed
269+
pscOptionsNoOutput :: Foreign -> Either ForeignError (Tuple (Maybe String) [String])
270+
pscOptionsNoOutput opts = fold <$> parsed
272271
where parsed = read opts :: F Psc
273272
fold (Psc a) = tuple2 (runNullOrUndefined a.output)
274273
(foldPscOptions (Psc $ a { output = NullOrUndefined Nothing }))
275274

276-
pscMakeOptions :: Foreign -> [String]
277-
pscMakeOptions opts = either (const []) fold parsed
275+
pscMakeOptions :: Foreign -> Either ForeignError [String]
276+
pscMakeOptions opts = fold <$> parsed
278277
where parsed = read opts :: F PscMake
279278
fold (PscMake a) = mkString outputOpt a.output <>
280279
mkBoolean noPreludeOpt a.noPrelude <>
@@ -286,8 +285,8 @@ pscMakeOptions opts = either (const []) fold parsed
286285
mkBoolean noPrefixOpt a.noPrefix <>
287286
mkPathArray ffiOpt a.ffi
288287

289-
pscDocsOptions :: Foreign -> [String]
290-
pscDocsOptions opts = either (const []) fold parsed
288+
pscDocsOptions :: Foreign -> Either ForeignError [String]
289+
pscDocsOptions opts = fold <$> parsed
291290
where parsed = read opts :: F PscDocs
292291
fold (PscDocs a) = mkFormat formatOpt a.format <>
293292
mkDocgen docgenOpt a.docgen

src/Plugin.purs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Control.Monad.Eff.Class (liftEff)
1212
import Control.Monad.Eff.Exception (Error())
1313
import Control.Monad.Error.Class (catchError, throwError)
1414

15+
import Data.Either (Either(..), either)
1516
import Data.Foreign (Foreign())
1617
import Data.Foreign.Class (IsForeign, read, readProp)
1718
import Data.Maybe (Maybe(Just), maybe, fromMaybe)
@@ -72,8 +73,9 @@ foreign import cwd "var cwd = process.cwd();" :: String
7273

7374
foreign import argv "var argv = process.argv.slice(2);" :: [String]
7475

75-
pluginError :: forall eff. String -> Aff (Effects eff) Error
76-
pluginError msg = liftEff $ flip mkPluginError msg <$> (maybe "" (\(Package a) -> a.name)) <$> package
76+
throwPluginError :: forall eff. String -> Aff (Effects eff) _
77+
throwPluginError msg = liftEff (flip mkPluginError msg <$> (maybe "" (\(Package a) -> a.name))
78+
<$> package) >>= throwError
7779

7880
resolve :: forall eff. String -> [String] -> Aff (Effects eff) (Tuple String [String])
7981
resolve cmd args = catchError primary fallback
@@ -90,9 +92,7 @@ resolve cmd args = catchError primary fallback
9092
fallback _ = (const $ tuple2 cmd args) <$> catchError (which cmd) mapError
9193

9294
mapError :: Error -> Aff (Effects eff) String
93-
mapError _ = pluginError ( "Failed to find " ++ cmd ++ ". " ++
94-
"Please ensure it is available on your system."
95-
) >>= throwError
95+
mapError _ = throwPluginError ("Failed to find " ++ cmd ++ ". " ++ "Please ensure it is available on your system.")
9696

9797
execute :: forall eff. String -> [String] -> Aff (Effects eff) String
9898
execute cmd args = do
@@ -103,30 +103,35 @@ execute cmd args = do
103103
pathsStream :: forall eff. Eff (through2 :: Through2 | eff) (Stream File [String])
104104
pathsStream = accStream run
105105
where run i = if fileIsStream i
106-
then pluginError "Streaming is not supported" >>= throwError
106+
then throwPluginError "Streaming is not supported"
107107
else pure $ filePath i
108108

109109
psc :: forall eff. Foreign -> Eff (Effects eff) (Stream File File)
110110
psc opts = multipipe2 <$> pathsStream <*> objStream run
111111
where run i = case pscOptionsNoOutput opts of
112-
Tuple out opt ->
112+
Left e -> throwPluginError (show e)
113+
Right (Tuple out opt) ->
113114
mkFile (fromMaybe pscOutputDefault out) <$> mkBufferFromString
114115
<$> execute pscCommand (i <> opt)
115116

116117
pscMake :: forall eff. Foreign -> Eff (Effects eff) (Stream File Unit)
117118
pscMake opts = multipipe2 <$> pathsStream <*> objStream run
118-
where run i = do output <- execute pscMakeCommand (i <> pscMakeOptions opts)
119+
where run i = do output <- either (throwPluginError <<< show)
120+
(\a -> execute pscMakeCommand (i <> a))
121+
(pscMakeOptions opts)
119122
if isVerbose
120123
then liftEff $ info $ pscMakeCommand ++ "\n" ++ output
121124
else pure unit
122125

123126
pscDocs :: forall eff. Foreign -> Eff (Effects eff) (Stream File File)
124127
pscDocs opts = multipipe2 <$> pathsStream <*> objStream run
125-
where run i = mkFile "." <$> mkBufferFromString
126-
<$> execute pscDocsCommand (pscDocsOptions opts <> i)
128+
where run i = case pscDocsOptions opts of
129+
Left e -> throwPluginError (show e)
130+
Right a-> mkFile "." <$> mkBufferFromString
131+
<$> execute pscDocsCommand (a <> i)
127132

128133
dotPsci :: forall eff. Eff (Effects eff) (Stream File Unit)
129134
dotPsci = multipipe2 <$> objStream run <*> createWriteStream psciFilename
130135
where run i = if fileIsStream i
131-
then pluginError "Streaming is not supported" >>= throwError
136+
then throwPluginError "Streaming is not supported"
132137
else pure $ psciLoadCommand ++ " " ++ relative cwd (filePath i) ++ "\n"

test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
var fs = require('fs');
44

5+
var path = require('path');
6+
57
var test = require('tape');
68

79
var gulp = require('gulp');
@@ -58,6 +60,21 @@ test('psc - failure', function(t){
5860
});
5961
});
6062

63+
test('psc - invalid option type', function(t){
64+
t.plan(2);
65+
66+
var fixture = 'Fixture1.purs';
67+
68+
var moduleName = path.basename(fixture, '.purs');
69+
70+
var stream = purescript.psc({noPrelude: true, module: moduleName});
71+
72+
gulp.src(fixture).pipe(stream).
73+
on('error', function(e){
74+
t.ok(/type mismatch/i.test(e.message), 'should have a failure message');
75+
t.equal('Error', e.name);
76+
});
77+
});
6178

6279
test('psci - basic', function(t){
6380
t.plan(1);
@@ -111,3 +128,17 @@ test('psc-make - error', function(t){
111128
t.equal('Error', e.name);
112129
});
113130
});
131+
132+
test('psc-make - invalid option type', function(t){
133+
t.plan(2);
134+
135+
var stream = purescript.pscMake({noPrelude: 'invalid'});
136+
137+
var fixture = 'Fixture1.purs';
138+
139+
gulp.src(fixture).pipe(stream).
140+
on('error', function(e){
141+
t.ok(/type mismatch/i.test(e.message), 'should have a failure message');
142+
t.equal('Error', e.name);
143+
});
144+
});

0 commit comments

Comments
 (0)