Intellij IdeaCygWingitorange@2x

I didn’t find much existing basic documentation on how to get started with scripting in earnest, so I decided to fill the gap with my own experience. I had never been an avid user of command windows or terminals or scripting, and I admit to complaining that Cygwin is be a confusing heap. But that hasn’t stopped me from realizing their benefits, and I am ready to give them the respect they deserve since they have saved me time and drudgery.

Solving Script Amnesia

A successful script automates some tedious activity on the OS and is soon forgotten. That’s my problem: when I need to write or edit a script its hard to pick up where I left off or remember arcane syntax that I don’t use anywhere else. I don’t write scripts all day, so I often don’t remember where I put it, what environment I edited in, let alone some arcane syntax and other context information.

I should have realized a long time ago that if a script is worth writing, it is worth safeguarding and properly maintaining like any source code. But script editing happens in spurts as a means to an end – it’s hard to justify taking the time to build up an infrastructure and become more proficient. This post documents how I set up a script repository and IDE using Git, Bitbucket, IntelliJ, Cygwin and some assorted environmental variables. So this documents my effort to get a a scripting environment set up that I can get familiar with and rely on. I’ll know it’s successful if I start writing more scripts because I feel more confident that I will get a longer return from the effort.

Before I set up my scripting environment I asked my self some questions to help determine what tools and techniques I would need, and I encourage you to do answer these as well:

Scripting Environment Questions:

  • Portability: How portable does my script need to be?
    • What OS(s) will it run on? My case: Win/Mac/Linux
    • What user(s) will use it? Me/Coworkers/My boss/Continuous Integration
  • IDE? Can I edit my scripts in the same IDE I use for everything else? Yes (detailed follow)
  • Extensibility: If my script can’t do everything natively, is there a strategy to add functionality? (Yes, details follow)
    • For example, if your script needs to do a REST call, do you: script a browser? import a cURL library?
  • Conventions: Is there a convention I can follow to put my scripts where both the OS and I can find them without tweaking? (Yes, requires some care)
    • For example: home/user/bin

My answers lead me to a create a setup that prioritizes flexibility across OS and users and tries to follow general conventions. So, it should work for anybody, but you can sacrifice some of the generalization for your own convenience if you want to.

Portability

Once you combine Windows with another OS you are probably going to run into Cygwin as your go-to solution because you can write bash scripts that can run on Windows, MacOS and Linux. It is still very possible/maybe necessary to write Windows-only scripts in Cygwin. All my scripts are .sh except some narrow Windows cases.

Portability also pertains to editing and running scripts on multiple machines in multiple user accounts. It means creating a project definition that can be put under version control to allow me to edit and run scripts on any machine as any user. To do this I followed conventions regarding where to house scripts (see Conventions below) and set my cygwin user folder as the project root and committed this to BitBucket using Git.

IDE Support

Maybe it should have been obvious, but it took me awhile to decide that I should strive to use my regular editor to edit scripts. I use IntelliJ, and I found a plugin called BashSupport that supports syntax highlighting, rename refactoring, documentation lookup, inspections, quickfixes and such. I can also run scripts from run configurations within IntelliJ- not sure if that is due to BashSupport or not honestly. Before that I used Notepad++, or simply Notepad. Another big advantage of using an IDE: it creates a project definition so you can reopen the project and see your scripts! Again, should have thought of this earlier, but my scripts were all small and scattered and this seemed like a heavyweight tank cracking a nut.

Extensibility

Cygwin has cultivated a large library of plugins that scratch the itch of various developer needs. It is likely to cover any requirement I will have. Install Cygwin to C:\ and don’t install any optional components. Save the installer (setup-x86_64.exe in my case) in the cygwin folder inside a folder you create called installer. Cygwin will create a cache of the plugins library in there. You will need the installer if you ever decide to install a plugin, so its a good idea to keep it with the project folder instead of losing in in the downloads folder like I have done.

cygwinAlwaysRunAsAdmin

Tip: In Cygwin Shortcut select Preferences: Shortcut Pane: Click Run as Administrator

Conventions

Cygwin tries to follow conventions whenever possible. It puts a directory structure that mimics Linux root, but it is located inside the Cygwin installation folder. Instead of accepting the default “Program files” location, install cygwin at C:\ to avoid spaces in any paths. My user dir is therefore: C:\cygwin64\home\[windows username]\bin. I added bin to .bashrc so I can run scripts from anywhere in Cygwin.

Running Scripts

From Intellij: As I mentioned, you can run shell scripts from within Intellij using run configurations. This seems like a lot of work after getting past the cool idea factor. It doesn’t open up any debugging options as far as I can tell. It’s a good idea to check the “Show this page” box to fill in any necessary arguments before running a script.

cygwinRunConfiguration

Intellij Script Run Configuration

scriptRunInIDE

Script output in Run Output of Intellij

From Cygwin: cd bin, then ./script.sh to execute. Or add bin to .bashrc and execute script.sh from any location. Add Cygwin to context menu in Windows.

From Git Bash: Open it from your bin directory to run a script on a Windows dev box lacking Cygwin. Otherwise useless because it is not extensible and conventional.

You can run Cygwin in the IntelliJ terminal or in a terminal emulator like Conemu as well – Google for details.