After spending some time working in AWS Cloudformation and running cfn-lint manually, I decided to incorporate it into my Emacs config.

Here’s a basic cloudformation-mode for DOOM Emacs, complete with a flycheck checker for cfn-lint:

;; cloudformation-mode

(define-derived-mode cfn-mode yaml-mode
  "Cloudformation"
  "Cloudformation template mode.")

(add-to-list 'auto-mode-alist '(".template\\'" . cfn-mode))
(after! flycheck
  (flycheck-define-checker cfn-lint
    "A Cloudformation linter using cfn-python-lint.

See URL 'https://github.com/awslabs/cfn-python-lint'."
    :command ("cfn-lint" "-f" "parseable" source)
    :error-patterns (
                     (warning line-start (file-name) ":" line ":" column
                              ":" (one-or-more digit) ":" (one-or-more digit) ":"
                              (id "W" (one-or-more digit)) ":" (message) line-end)
                     (error line-start (file-name) ":" line ":" column
                            ":" (one-or-more digit) ":" (one-or-more digit) ":"
                            (id "E" (one-or-more digit)) ":" (message) line-end)
                     )
    :modes (cfn-mode)
    )
    (add-to-list 'flycheck-checkers 'cfn-lint)
  )

Of course, this only covers the YAML case, and technically JSON is valid Cloudformation as well… but who hates themselves enough to write Cloudformation in JSON?

inotifywait is a handy utility that listens for filesystem events you specify and prints them to standard out. This is particularly useful if, say, you want to automatically redeploy a website whenever something changes.

(Jekyll comes with this functionality out-of-the-box, but if you have more than one site, or other non-Jekyll content that changes, it may be desirable to deploy everything together.)

The naive approach to this problem might look something like:

# Filesystem events specific to file creation or modification
events="modify,attrib,close_write,move,create,delete"

# -m = monitor (don’t quit after the first event)
# -r = recursive
inotifywait -m -r -e "$events" $site_dir | while read ; do deploy_site ; done

But the problem with filesystem events is that lots of them can fire simultaneously. A single file save produces multiple events, and a project-wide find/replace opens the floodgates. Since the site will deploy on every individual event, even minor changes kick off 3-4 rebuilds in a row. That’s pretty silly.

I found a few patterns out on the ’net to batch inotifywait messages, but most of them were pretty complicated. I wondered if it might be possible to do the same thing in a more straightforward fashion, and came up with this:

echo "Watching source directory for changes."

events="modify,attrib,close_write,move,create,delete"

while true
do

    count=0

    while read -t 1
    do
        (( count++ ))
    done

    if [[ $count -gt 0 ]]
    then
        echo "$count changes detected."
        deploy_site
    fi

done < <(inotifywait -m -r -e "$events" --exclude '/\..+' $dir 2>/dev/null)

As it turns out, read accepts a timeout value! Now any inotify events less than a second apart will be counted as part of the same batch and will result in only a single deploy_site call.

A word of warning: failure to exclude .git folders will result in a ton of filesystem events. In the above code, I ignore all dotfiles (and folders) to avoid this problem.

I’d been looking for some space on the internet where I could put some words for others to see. Then I decided to make my own space instead.

awk.space is written in Emacs and powered by Jekyll and Amazon S3. Plus some of my own magic that I’ll probably talk about in future blog posts.

The site is split into two different spaces: fiction-writing and blog-writing. Or fiction and nonfiction, if you like. Like a library, except not as cool. Or instagramable.

There’s not much here at the moment, but I hope you enjoy your visit anyway.