Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,30 @@ Breaking changes:
BySignal signal -> ...
```
See https://pursuit.purescript.org/packages/purescript-node-event-emitter/3.0.0/docs/Node.EventEmitter for more details.
- Update `pid` type signature to return `Maybe Pid` rather than `Pid` (#44 by @JordanMartinez)
- Update `kill` returned value from `Effect Unit` to `Effect Boolean` (#44 by @JordanMartinez)


New features:
- Added event handler for `spawn` event (#43 by @JordanMartinez)
- Added missing APIs (#44 by @JordanMartinez)

- exitCode
- kill (no signal specified)
- kill' (kill with a `String` signal)
- killSignal (kill with an ADT `Signal` arg)
- killed
- signalCode
- spawnArgs
- spawnFile

Bugfixes:

Other improvements:
- Bumped CI's node version to `lts/*` (#41 by @JordanMartinez)
- Updated CI `actions/checkout` and `actions/setup-nodee` to `v3` (#41 by @JordanMartinez)
- Format codebase & enforce formatting in CI via purs-tidy (#42 by @JordanMartinez)
- Migrate more FFI to uncurried functions (#44 by @JordanMartinez)

## [v9.0.0](https://github.com/purescript-node/purescript-node-child-process/releases/tag/v9.0.0) - 2022-04-29

Expand Down
11 changes: 11 additions & 0 deletions src/Node/ChildProcess.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ export function unsafeFromNullable(msg) {
};
}

export const connectedImpl = (cp) => cp.connected;
export const disconnectImpl = (cp) => cp.disconnect();
export const exitCodeImpl = (cp) => cp.exitCode;
export const pidImpl = (cp) => cp.pid;
export const killImpl = (cp) => cp.kill();
export const killStrImpl = (cp, str) => cp.kill(str);
export const killedImpl = (cp) => cp.killed;
export const signalCodeImpl = (cp) => cp.signalCode;
export const spawnArgs = (cp) => cp.spawnArgs;
export const spawnFile = (cp) => cp.spawnFile;

export function spawnImpl(command) {
return args => opts => () => spawn(command, args, opts);
}
Expand Down
56 changes: 48 additions & 8 deletions src/Node/ChildProcess.purs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ module Node.ChildProcess
, stderr
, pid
, connected
, disconnect
, exitCode
, kill
, kill'
, killSignal
, killed
, signalCode
, send
, disconnect
, Error
, toStandardError
, Exit(..)
Expand Down Expand Up @@ -61,7 +66,7 @@ import Data.Posix.Signal (Signal)
import Data.Posix.Signal as Signal
import Effect (Effect)
import Effect.Exception as Exception
import Effect.Uncurried (EffectFn2, mkEffectFn1, mkEffectFn2)
import Effect.Uncurried (EffectFn1, EffectFn2, mkEffectFn1, mkEffectFn2, runEffectFn1, runEffectFn2)
import Foreign (Foreign)
import Foreign.Object (Object)
import Node.Buffer (Buffer)
Expand Down Expand Up @@ -152,13 +157,22 @@ foreign import unsafeFromNullable :: forall a. String -> Nullable a -> a

-- | The process ID of a child process. Note that if the process has already
-- | exited, another process may have taken the same ID, so be careful!
pid :: ChildProcess -> Pid
pid = _.pid <<< runChildProcess
pid :: ChildProcess -> Effect (Maybe Pid)
pid cp = map toMaybe $ runEffectFn1 pidImpl cp

foreign import pidImpl :: EffectFn1 (ChildProcess) (Nullable Pid)

-- | Indicates whether it is still possible to send and receive
-- | messages from the child process.
connected :: ChildProcess -> Effect Boolean
connected (ChildProcess cp) = mkEffect \_ -> cp.connected
connected cp = runEffectFn1 connectedImpl cp

foreign import connectedImpl :: EffectFn1 (ChildProcess) (Boolean)

exitCode :: ChildProcess -> Effect (Maybe Int)
exitCode cp = map toMaybe $ runEffectFn1 exitCodeImpl cp

foreign import exitCodeImpl :: EffectFn1 (ChildProcess) (Nullable Int)

-- | Send messages to the (`nodejs`) child process.
-- |
Expand All @@ -174,7 +188,19 @@ send msg handle (ChildProcess cp) = mkEffect \_ -> runFn2 cp.send msg handle

-- | Closes the IPC channel between parent and child.
disconnect :: ChildProcess -> Effect Unit
disconnect = _.disconnect <<< runChildProcess
disconnect cp = runEffectFn1 disconnectImpl cp

foreign import disconnectImpl :: EffectFn1 (ChildProcess) (Unit)

kill :: ChildProcess -> Effect Boolean
kill cp = runEffectFn1 killImpl cp

foreign import killImpl :: EffectFn1 (ChildProcess) (Boolean)

kill' :: String -> ChildProcess -> Effect Boolean
kill' sig cp = runEffectFn2 killStrImpl cp sig

foreign import killStrImpl :: EffectFn2 (ChildProcess) (String) (Boolean)

-- | Send a signal to a child process. In the same way as the
-- | [unix kill(2) system call](https://linux.die.net/man/2/kill),
Expand All @@ -184,8 +210,22 @@ disconnect = _.disconnect <<< runChildProcess
-- | and the signal. They can vary from system to system.
-- | The child process might emit an `"error"` event if the signal
-- | could not be delivered.
kill :: Signal -> ChildProcess -> Effect Unit
kill sig (ChildProcess cp) = mkEffect \_ -> cp.kill (Signal.toString sig)
killSignal :: Signal -> ChildProcess -> Effect Boolean
killSignal sig cp = kill' (Signal.toString sig) cp

killed :: ChildProcess -> Effect Boolean
killed cp = runEffectFn1 killedImpl cp

signalCode :: ChildProcess -> Effect (Maybe String)
signalCode cp = map toMaybe $ runEffectFn1 signalCodeImpl cp

foreign import signalCodeImpl :: EffectFn1 (ChildProcess) (Nullable String)

foreign import killedImpl :: EffectFn1 (ChildProcess) (Boolean)

foreign import spawnArgs :: ChildProcess -> Array String

foreign import spawnFile :: ChildProcess -> String

mkEffect :: forall a. (Unit -> a) -> Effect a
mkEffect = unsafeCoerce
Expand Down
4 changes: 2 additions & 2 deletions test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ main = do

log "doesn't perform effects too early"
spawn "ls" [ "-la" ] defaultSpawnOptions >>= \ls -> do
let _ = kill SIGTERM ls
let _ = kill ls
ls # on_ exitH \exit ->
case exit of
Normally 0 ->
Expand All @@ -34,7 +34,7 @@ main = do

log "kills processes"
spawn "ls" [ "-la" ] defaultSpawnOptions >>= \ls -> do
_ <- kill SIGTERM ls
_ <- kill ls
ls # on_ exitH \exit ->
case exit of
BySignal SIGTERM ->
Expand Down