Shell.svelte 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <script>
  2. import { Command } from "@tauri-apps/api/shell"
  3. const windows = navigator.userAgent.includes('Windows')
  4. let cmd = windows ? 'cmd' : 'sh'
  5. let args = windows ? ['/C'] : ['-c']
  6. export let onMessage;
  7. let script = 'echo "hello world"'
  8. let cwd = null
  9. let env = 'SOMETHING=value ANOTHER=2'
  10. let stdin = ''
  11. let child
  12. function _getEnv() {
  13. return env.split(' ').reduce((env, clause) => {
  14. let [key, value] = clause.split('=')
  15. return {
  16. ...env,
  17. [key]: value
  18. }
  19. }, {})
  20. }
  21. function spawn() {
  22. child = null
  23. const command = new Command(cmd, [...args, script], { cwd: cwd || null, env: _getEnv() })
  24. command.on('close', data => {
  25. onMessage(`command finished with code ${data.code} and signal ${data.signal}`)
  26. child = null
  27. })
  28. command.on('error', error => onMessage(`command error: "${error}"`))
  29. command.stdout.on('data', line => onMessage(`command stdout: "${line}"`))
  30. command.stderr.on('data', line => onMessage(`command stderr: "${line}"`))
  31. command.spawn()
  32. .then(c => {
  33. child = c
  34. })
  35. .catch(onMessage)
  36. }
  37. function kill() {
  38. child.kill().then(() => onMessage('killed child process')).catch(onMessage)
  39. }
  40. function writeToStdin() {
  41. child.write(stdin).catch(onMessage)
  42. }
  43. </script>
  44. <div>
  45. <div>
  46. <input bind:value={script}>
  47. <button class="button" on:click={spawn}>Run</button>
  48. <button class="button" on:click={kill}>Kill</button>
  49. {#if child}
  50. <input placeholder="write to stdin" bind:value={stdin}>
  51. <button class="button" on:click={writeToStdin}>Write</button>
  52. {/if}
  53. </div>
  54. <div>
  55. <input bind:value={cwd} placeholder="Working directory">
  56. <input bind:value={env} placeholder="Environment variables" style="width: 300px">
  57. </div>
  58. </div>