Skip to content

Instantly share code, notes, and snippets.

@e2
Last active April 22, 2016 15:22
Show Gist options
  • Save e2/de7e91620535bb5857073c45c05be9d4 to your computer and use it in GitHub Desktop.
Save e2/de7e91620535bb5857073c45c05be9d4 to your computer and use it in GitHub Desktop.
Simple script to help web designers work with and release compiled assets in the same git branch as the source assets.
#!/usr/bin/env ruby
#----------------------------------------------------------------------------
# INFO:
#
# Simple script for web designers working on git repositories where source
# assets and compiled assets have to be stored in the same branch.
#
# The goal: generating assets safely and into a separate commit.
#
# This script helps prevent workflow errors (compiled assets in a separate
# commit, and lots of checking to avoid mistakes).
#
# USAGE:
#
# 1. Copy this script into your project, modify the MyConfig methods
# 2. Add and commit this file.
# 3. Run it on a clean repository.
#
# SUPPORT:
#
# None promised, but feel free to ask.
#
# If tool is useful enough, I'll turn it into an official project/gem and
# release, etc.
#
# TODO
# - check to make sure compiled assets were NOT committed accidentally (only "generated commits" should include them)
# - turn this into a proper gem.
#
#----------------------------------------------------------------------------
# Copyright 2016 Cezary Baginski <[email protected]>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License.
#
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#----------------------------------------------------------------------------
require 'English'
require 'fileutils'
class MyConfig
def commit_message
"regenerated assets"
end
def compiled_asset_dir
"dist"
end
def compile_assets_command_args
%w(sass -C foo.scss dist/foo.css)
end
end
class AssetCommit
attr_reader :config
def initialize(config)
@config = config
end
def commit
reset_asset_dir
check_modified_files
check_untracked_files
clean_asset_dir
generate_asset_files
add_asset_files
check_unmodified_assets
commit_assets
end
private
def run(*args)
abort "Error: Command failed: #{args.join(" ").inspect}" unless system(*args)
end
def reset_asset_dir
puts "Checking out existing assets"
FileUtils.rm_rf(config.compiled_asset_dir)
args = %W(git checkout HEAD #{config.compiled_asset_dir})
run(*args)
end
def clean_asset_dir
puts "Removing asset dir"
FileUtils.rm_rf(config.compiled_asset_dir)
FileUtils.mkpath(config.compiled_asset_dir)
end
def generate_asset_files
puts "Generating assets"
run(*config.compile_assets_command_args)
end
def check_clean(fail_if_dirty, kind, solution, args)
puts "Checking for #{kind} ..."
files = `#{args.join(' ')}`.lines.map(&:chomp)
result = $CHILD_STATUS.exitstatus
abort "Error checking for #{kind} files" unless result.zero?
message =
if fail_if_dirty
"Error: #{kind} files present: #{files.join(', ')}! #{solution}"
else
"Error: no new files/changes present! #{solution}"
end
ok = (fail_if_dirty == files.empty?)
abort message unless ok
end
def check_modified_files
kind = "modified/uncommitted changes"
solution = "Either add+commit them first, or undo your changes with git checkout"
args = %w(git diff-index --name-only HEAD)
check_clean(true, kind, solution, args)
end
def check_untracked_files
kind = "untracked changes"
solution = "Either ignore them (gitignore) or remove them."
args = %w(git ls-files --other --error-unmatch --exclude-standard)
check_clean(true, kind, solution, args)
end
def check_unmodified_assets
kind = "unmodified compiled assets"
solution = "Did you really change anything? (The assets seem to not have changed since last time)."
args = %w(git diff-index --name-only --cached HEAD)
check_clean(false, kind, solution, args)
end
def commit_assets
message = config.commit_message
args = %W(git commit -m #{message})
run(*args)
end
def add_asset_files
puts "Adding asset files"
args = %W(git add -fu #{config.compiled_asset_dir})
run(*args)
end
def puts(message)
STDOUT.puts(format(" >> %s ...", message))
end
end
AssetCommit.new(MyConfig.new).commit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment