Skip to content

Instantly share code, notes, and snippets.

@amclain
Last active August 29, 2015 13:58
Show Gist options
  • Save amclain/10025484 to your computer and use it in GitHub Desktop.
Save amclain/10025484 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# -----------------------------------------------------------------------------
#
# The MIT License (MIT)
#
# Copyright (c) 2014 Alex McLain
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# -----------------------------------------------------------------------------
threads = []
cmd_queue = Queue.new
puts_queue = Queue.new
# Terminate gracefully on interrupt.
Signal.trap 'INT' do
threads.each { |t| t.kill }
puts "Aborted."
exit
end
# Select directories and normalize zip file names.
d = Dir['*']
.select { |f| File.directory? f }
.map { |f|
[f.downcase
.gsub(/[\&\']\s*/, '')
.gsub(',', '_')
.gsub(/\s+/, '_')
.gsub(/[_]+/, '_')
.gsub('_-_', '_'),
f]
}
.sort
# Create each command and put it in the queue.
d.each { |dir| cmd_queue.push "tar czf \"#{dir[0]}.tar.gz\" \"#{dir[1]}\"" }
# Get number of cores available.
cores = IO.popen("nproc").read.to_i
# Throttle threads to number of cores.
cores.times do
threads.push Thread.new {
until cmd_queue.empty?
cmd = cmd_queue.pop
puts_queue << cmd
system cmd
end
}
end
puts "Creating archives..."
# Cancel the puts_queue when the worker threads are finished.
joiner_thread = Thread.new do
threads.each { |t| t.join }
puts_queue << nil
end
# Print output from worker threads until they're finished.
str = ''
puts str while str = puts_queue.pop
joiner_thread.join
puts "Done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment