I’m looking for things to automate and I challenge you to do the same.
In this post, I’m going to automate a task that does not spark joy. This time I’ve decided that it’s going to be optimizing images for this blog.
Optimizing images
This blog is built with Jekyll and is running on GitHub pages. Jekyll is built with Ruby (a new language to me), so I’ll
be using a Ruby gem called image_optim
to apply the optimizations. I do this by adding the dependency
to my Gemfile
:
group :development do
gem "image_optim", require: false
gem "image_optim_pack", require: false
end
And then installing the dependency:
bundle install
I’m going to organize scripts in the aptly named scripts
folder, and the Ruby script to optimize images will be named
scripts/optimize-images.rb
🤯:
#!/usr/bin/env ruby
require 'rubygems'
require 'bundler/setup'
require 'image_optim'
# resolve the root folder of the repository
root_folder = `git rev-parse --show-toplevel`.strip
if !File.directory?(root_folder)
root_folder = `pwd`.strip
end
# files to optimize: jpg, png, and gif files under assets/img
target_files = "#{root_folder}/assets/img/*.{jpg,png,gif}"
# instantiate ImageOtim with configuration options
image_optim = ImageOptim.new(
:pngout => false,
:svgo => false,
:cache_dir => "#{root_folder}/temp"
)
# execute image optimization
image_optim.optimize_images!(Dir[target_files]) do |unoptimized, optimized|
if optimized
# print filename to stdout
puts "#{optimized}"
end
end
Nothing too crazy going on here. Its not rocket surgery… 🚀🩺
A couple of things to note:
- I’ve specified the option
:cache_dir
which is a performance optimization. This allowsimage_optim
to remember that it has already seen and optimized an image, and it won’t do it again. The image optimization process can be slow and taxing on the CPU. - I am writing the file path of the optimized image (
puts "#{optimized}"
). This will come in handy later.
I can trigger an image optimization by executing the following command:
ruby scripts/optimize-images.rb
Automation
Having a script to optimize images is a great first step, but it still doesn’t spark any joy.
I need to figure out which event I should use as a trigger and I’ve settled on pre-commit
(instead of something like
build). The reason being that this is required step in my workflow which is create/edit a post locally on my computer,
commit the changes, and push to GitHub.
I’m creating a script called scripts/pre-commit.sh
:
#!/usr/bin/env bash
set -e
# get the repository root
repo_folder=`git rev-parse --show-toplevel`
# use repository root if there is a value, otherwise use the current folder
root_folder=${repo_folder:-`pwd`}
echo "Performing image optimization for the first time can take a while. Sit tight..."
# execute image optimization and store results in a variable
optimized_images=`ruby $root_folder/scripts/optimize-images.rb`
if [ -n "$optimized_images" ]
then
echo "$optimized_images" | while read image; do
echo " - Optimized $image"
git add "$image"
done
fi
echo "Done."
Don’t forget to make sure this script is executable (chmod +x scripts/pre-commit.sh
).
This is where output-ing the file path from the scripts/optimize-images.rb
script comes into play. It is assigned to
the $optimized_images
variable where we loop over each of them optimized images and stage them to the repository with
git add
.
In order to get this script executed on pre-commit
, I need to install it as a git pre-commit
hook which can be done
by copying this file to .git/hooks/pre-commit
(without the .sh
extension). I’ve created a little script to help me
install it in case I need to re-install it on another device (scripts/install-pre-commit.sh
):
#!/usr/bin/env bash
set -e
script_folder=`cd $(dirname $0) && pwd`
repo_folder=`git rev-parse --show-toplevel`
cp -f $script_folder/pre-commit.sh $repo_folder/.git/hooks/pre-commit
Again, don’t forget to make this script executable. Install using scripts/install-pre-commit.sh
.
Once installed, any images that have not already been optimized every time I call git commit
.
Sparking joy
With very little effort, I’ve been able to automate an otherwise mindless activity.
And here are the results:
Image | Size before | Size after | Improvement |
---|---|---|---|
github-pages-config.png | 102K | 51K | 51K (50%) |
google-pay-vue.gif | 2.9M | 2.4M | 0.5M (17%) |
jekyll-screenshot.png | 520K | 272K | 248K (48%) |
jekyll-theming-1.png | 570K | 307K | 263K (46%) |
jekyll-theming-2.png | 536K | 285K | 251K (47%) |
jekyll-theming-3.png | 569K | 311K | 258K (45%) |
I’m sure Marie Kondo would approve.
I challenge you to find something/anything to automate. I want to hear about it: @aussoc.