Skip to content

Instantly share code, notes, and snippets.

@pbyrne
Created July 18, 2011 22:09
Show Gist options
  • Save pbyrne/1090808 to your computer and use it in GitHub Desktop.
Save pbyrne/1090808 to your computer and use it in GitHub Desktop.
Simple script to perform SCM (svn, hg, git) commands across your workspace
#!/usr/bin/env ruby
#
# Simple script to perform SCM (svn, hg, git) commands across your workspace
# Edit the SHARED_WORKSPACE environment variable if your code isn't checked out to ~/workspace
# Skip to the end for the actual execution ... to keep it all in one file, had to define the class first
# Get the latest version from https://gist.github.com/1090808
USAGE = <<-end_usage
SSS performs SCM commands on all projects in your workspace. Set the
SHARED_WORKSPACE environment variable if your workspace is not ~/workspace.
usage: sss <command>
Available commands:
up, update, pull Update to the latest changes
st, status Check the status for any uncommitted changes
push (hg, git) Push all committed changes to central repo
out, outgoing (hg) Show outgoing changes, not pushed to central repo
in, incoming (hg) Show incoming changes, not updated
wtf (git) Compare local to tracked remote branch
end_usage
class SCM
GIT = :git
MERCURIAL = :mercurial
SVN = :svn
UNKNOWN = :unknown
# Set of available commands
COMMANDS = {
MERCURIAL => {
:update => "hg pull -u",
:status => "hg status",
:push => "hg push",
:incoming => "hg incoming",
:outgoing => "hg outgoing",
}, GIT => {
:update => "git pull",
:status => "git status",
:push => "git push",
:wtf => "git wtf",
}, SVN => {
:update => "svn up",
:status => "svn st",
}, UNKNOWN => {
}
}
# Support methods
def self.shared_workspace
ENV['SHARED_WORKSPACE'] or File.expand_path("~/workspace")
end
def self.directories
Dir["#{shared_workspace}/*"].select { |d| File.directory?(d) }
end
def self.scm(directory)
if File.exists?("#{directory}/.svn")
SVN
elsif File.exists?("#{directory}/.hg")
MERCURIAL
elsif File.exists?("#{directory}/.git")
GIT
else
UNKNOWN
end
end
def self.bold(str)
"\033[1m#{str}\033[0m"
end
# Global methods
def self.update
directories.each { |dir| perform_command(:update, dir, "Updating") }
end
def self.status
directories.each { |dir| perform_command(:status, dir, "Checking status of") }
end
def self.incoming
directories.each { |dir| perform_command(:incoming, dir, "Incoming changes for") }
end
def self.outgoing
directories.each { |dir| perform_command(:outgoing, dir, "Outgoing changes for") }
end
def self.push
directories.each { |dir| perform_command(:push, dir, "Pushing") }
end
def self.wtf
directories.each { |dir| perform_command(:wtf, dir, "WTF") }
end
def self.perform_command(cmd, dir, msg)
if COMMANDS[scm(dir)][cmd]
Dir.chdir(dir)
# puts COMMANDS[scm(dir)][cmd]
puts "#{msg} #{bold(File.basename(dir))} (#{scm(dir)})"
system(COMMANDS[scm(dir)][cmd])
end
end
end
# Begin execution
scm = SCM.new
case ARGV[0]
when "up", "update", "pull"
SCM.update
when "st", "status"
SCM.status
when "push"
SCM.push
when "out", "outgoing"
SCM.outgoing
when "in", "incoming"
SCM.incoming
when "wtf"
SCM.wtf
else
# Usage
puts USAGE
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment