Created
October 30, 2014 10:50
-
-
Save ollie/e79c3cd0779ac4f54913 to your computer and use it in GitHub Desktop.
Multithreaded Ruby "git pull".
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'pathname' | |
require 'open3' | |
# Mass-pull git repositories. | |
# | |
# GitPull.mass_pull(Dir.pwd) | |
class GitPull | |
# Check for this string in directory names. | |
GIT_DIR = '.git' | |
# Recursively crawl down the +directory+ and +git pull+ it if it's | |
# a Git repo. Shortcut method for creating an instance. | |
# | |
# @param directory [String, Pathname] | |
def self.mass_pull(directory) | |
new.mass_pull(Pathname.new(directory)) | |
end | |
# Setup threads array. | |
def initialize | |
@threads = [] | |
end | |
# Recursively crawl down the +directory+ and +git pull+ it if it's | |
# a Git repo. Waits for all threads to finish. | |
# | |
# @param directory [Pathname] | |
def mass_pull(directory) | |
crawl(directory) | |
@threads.each(&:join) | |
end | |
# Recursively crawl down the +directory+ and +git pull+ it if it's | |
# a Git repo. Adds threads and does not wait. | |
# | |
# @param directory [Pathname] | |
def crawl(directory) | |
subdirectories = list_directories(directory) | |
if git?(subdirectories) | |
@threads << Thread.new do | |
pull(directory) | |
end | |
else | |
subdirectories.each do |subdirectory| | |
crawl(subdirectory) | |
end | |
end | |
end | |
# List all relevant subdirectories in +directory+. | |
# | |
# @param directory [Pathname] | |
def list_directories(directory) | |
directory.children.select(&:directory?) | |
end | |
# Is there a +.git+ directory among the subdirectories? | |
# | |
# @param subdirectories [Array<Pathname>] | |
# | |
# @return [Bool] | |
def git?(subdirectories) | |
subdirectories.find do |directory| | |
directory_name = directory.basename.to_s | |
directory_name == GIT_DIR | |
end | |
end | |
# Create a new process which updates the repository. | |
# Process is needed because +Dir.chdir+ is not thread-safe. | |
def pull(directory) | |
command = "cd #{ directory } && git pull" | |
puts command | |
out, _ = Open3.capture2(command) | |
puts out | |
end | |
end | |
# Do it! | |
GitPull.mass_pull(Dir.pwd) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment