Starting and stopping a server task

I’m experimenting with tasks, more specifically, a task which fires up “rails server” in an external iTerm terminal. This is necessary, because when debugging, the server has to run with a tty attached. (It would be cool, if tasks could run inside a Nova terminal e.g. by adding a “run in terminal” checkbox to the task.)

The simple “run” solution builds a temp script and fires iTerm up with it:

#!/bin/sh
script=$(mktemp)
workdir=$(pwd)
cat > $script << END
  source ~/.bash_profile
  cd $workdir
  bundle exec rails server
END
chmod a+x $script
open -Wa iTerm.app $script

The -W there causes open to wait.

A more complicated and flexible AppleScript looks as follows (first time I write AppleScript, so this is certainly ugly):

#!/bin/sh
workdir=$(pwd)
osascript -i <<END
  tell application "iTerm"
    activate
    if not (exists window 1) then
	  create window with default profile
    else
	  tell current window
	    create tab with default profile
      end tell
    end if
    tell current window
      tell the current session
	    write text "cd \"$workdir\""
        write text "rails server && exit"
      end tell
	  repeat while exists current tab
	    delay 1
      end repeat  
    end tell
  end tell
END

This should wait due to the repeat loop.

I somewhat expected the square “stop” button to execute the clean script which could be something like:

#!/bin/sh
pkill -f "ruby.*rails server"

So I start the server with “run” alright, but when I click the “stop” button next to it, the clean script is not executed and the server keeps running in the external terminal. However, if I execute “clean” using the command palette, the process is killed and the iTerm tab closed.

Is there a way to solve this more elegantly? Maybe if I write an extension rather than just use the tasks UI?

I guess what I’m missing is a custom “stop” script. And maybe to give the user full control over which task buttons to show: build, start, stop and cleanup. (Btw: Kinda funky IMO that the buttons of disabled tasks are only greyed out rather than removed.)

Thanks for your help!

I had a similar problem in my TeX Suite where I start Skim to live-preview the generated PDF. What I did is:

trap "kill 0" SIGINT SIGTERM EXIT
/Applications/Skim.app/Contents/MacOS/Skim

Running Skim directly makes it a child process of this script. kill 0 kills all processes started by the shell. trap makes it so that kill 0 is called when the script exits for the reasons given (SIGINT, SIGTERM or EXIT). This way, when nova stops the script, the Skim instance is also stopped.

(Hardcoding the Skim path is not ideal and I’m working on improving this)

Thanx for the hint, @flyx. Unfortunately, it doesn’t really work in my case for several reasons:

  • Running iTerm the way you run Skim launches a second, third etc instance of iTerm even if another one is already running.
  • When Nova stops/kills the script, iTerm is terminated, but the server process running in it remains alive.