Mac OSX Tasks Automation with JavaScript

I love automation and often use automation tools to improve my productivity. I’m using a MacBook Pro as my main workstation, which includes the Unix Like Mac OSX. I wanted to find a way to ease my everyday tasks, for example, programming and writing on my blog. Open many apps and setting them up, slows down my cognitive system, and doing that can take a couple of minutes. What if I could reduce that to a few seconds by writing a script to perform those repetitive tasks for me.

Here’s an example of the set of tasks I need to do in order to start writing a new blog post (I use the Hugo static site generator).

  1. Open the terminal.
  2. Navigate to the path in which my blog is located /my/user/directory/ottogiron.me.
  3. Run the server command hugo serve -D.
  4. In the current (iTerm) terminal open a new horizontal panel/session.
  5. Navigate again to the path (yes my default iTerm session doesn’t remember my the path I was).
  6. Run visual studio code code .
  7. Start writing.

Ok, so if I am focused enough these steps take 20 seconds (maybe). If I am a little distracted 1 minute?.

So I found OSX includes its own interpreter for automating those type of tasks. It supports their own automation scripting language called Applescript. I started using and didn’t enjoy it since it lacked features you would expect. I accept the idea they had for a declarative language was good. I imagine they were looking to reach a wider audience, not only programmers.

I used Applescript at the beginning and felt a little frustrated because of the workarounds I needed for basic stuff. An example was the lack of associative arrays. Later, I found they also support JavasScript. The JavaScript option provides the full power of the language, which is much better.

Example

Here’s a simple example. It opens a new iTerm window and writes a command.

#!/usr/bin/env osascript -l JavaScript //(optional)
//myscript.js
const projectPath = '/path/to/my/project'
const app = Application("iTerm");
 var window = app.currentWindow();

 if (!window) {
      window = app.createWindowWithDefaultProfile();
 }

 const serviceSession = window.currentSession();
 serviceSession.write({text:`cd ${projectPath}`});

The above script checks if an iTerm window is already open, if not it opens a new one, it gets the current session an writes a simple command.

Running the script

osascript, the interpreter, is already installed on OSX

Option 1

To run your script use in your terminal:

   osascript -l JavaScript myscript.js

And magic! that will perform those tasks.

In my use case, I wanted this script to be available as a binary

Option 2

Did you notice the #!/usr/bin/env osascript -l JavaScript at the top of the script? You can make the file executable or just run it with your favorite shell.

Make it executable

chmod + x
/path/to/script/myscript.js

Or

Run it with the shell

sh /path/to/script/myscript.js

Caveats

I didn’t find an easy way to modularize my code. For example, the part in which I validate if the window is already open, I had to copy and paste everywhere. I solved that using Webpack transpiling modular code to a plain old ES5/JavaScript. I’ll write another blog post explaining how I did that.

Conclusion

Automation is not only fun but can increase your productivity a lot. I showed you a simple example, but with imagination, you can write more sophisticated automation scripts. That can help you to focus on what you care when working with anything.


comments powered by Disqus