Last active
August 29, 2015 14:00
-
-
Save rye/82ca4c494d705a8644c7 to your computer and use it in GitHub Desktop.
My data synchronization system.
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 "json" | |
module DataSync | |
EXAMPLE_CONFIGURATION_FILE_NAME = "z_datasync-configuration.sample.json" | |
CONFIGURATION_FILE_NAME = "configuration.json" | |
OutputProperties = { | |
cronMode: false, | |
debugMode: true | |
} | |
class Configuration | |
attr_accessor :hash | |
def load(filename) | |
if File.exists?(File.join(File.dirname(__FILE__), filename)) | |
configurationFilename = File.join(File.dirname(__FILE__), filename) | |
else | |
configurationFilename = File.join(File.dirname(__FILE__), EXAMPLE_CONFIGURATION_FILE_NAME) | |
end | |
@hash = JSON.parse(IO.read(configurationFilename)) | |
return @hash | |
end | |
end | |
class GenericAction | |
attr_accessor :command, :path, :output, :progressCharacter | |
def to_proc | |
commandString = "cd #{self.path}; #{command} 2>&1" | |
return Proc.new { `#{commandString}` } | |
end | |
def to_fiber | |
commandString = "cd #{@command}; #{command} 2>&1" | |
return Fiber.new { `#{commandString}` } | |
end | |
end | |
class FetchAction < GenericAction | |
def initialize(command, path, progressCharacter) | |
raise ArgumentError, "Command not correct class!" unless command.class == String | |
raise ArgumentError, "Path not correct class!" unless path.class == String | |
raise ArgumentError, "ProgressCharacter not correct class!" unless progressCharacter.class == String | |
@command = command | |
@path = path | |
@progressCharacter = progressCharacter | |
end | |
end | |
end | |
def generateActions(configurationHash) | |
actionPile = [] | |
if configurationHash["defaults"] | |
defaults = configurationHash["defaults"] | |
else | |
defaults = { | |
"git" => { | |
"fetch" => { | |
"command" => "git fetch", | |
"recurse" => false, | |
"progress-character" => "." | |
} | |
} | |
} | |
end | |
if configurationHash["git"] | |
if configurationHash["git"]["fetch"] | |
configurationHash["git"]["fetch"].each do |directory| | |
directoryPath = nil | |
# Extract the directory's path. | |
if directory["directory"] | |
# Complain about types and stuff if they aren't all right. | |
raise TypeError, "directory[\"directory\"] property needs to be a string" unless | |
directory["directory"].class == String | |
directoryPath = directory["directory"] | |
end | |
recursive = nil | |
# Ascertain as to whether or not to recurse through the directory's first-level | |
# subdirectories | |
if directory["recurse"] | |
# If we have a value in our directory["recurse"] property (i.e. the property is set explicitly for the directory), then store it. | |
recursive = directory["recurse"] | |
else | |
# If we don't, | |
if directory["recurse"] == nil | |
# Use the default (if we have one) | |
recursive = defaults["git"]["fetch"]["recurse"] | |
end | |
end | |
gitFetchCommand = nil | |
# Determine which command to call in each repository. | |
if directory["command"] | |
# If we have an explicit value, use it as the command. | |
gitFetchCommand = directory["command"] | |
else | |
# If we don't, | |
if directory["command"] == nil | |
# Use the default (if we have one) | |
gitFetchCommand = defaults["git"]["fetch"]["command"] | |
end | |
end | |
# Complain under non-ideal circumstances | |
raise "No directory specified for directory (#{directory.inspect}) (defaults not allowed)!" unless directoryPath != nil | |
raise "Recursion setting not specified, nor a default (#{directory.inspect})!" if recursive == nil | |
raise "Command setting not specified, nor a default (#{directory.inspect})!" if gitFetchCommand == nil | |
# If we're operating recursively on the current directory | |
if recursive | |
# Then make a Action pile for the directory | |
directoryPile = [] | |
# Go through the array of subdirectory paths | |
Dir.glob(File.join(File.expand_path("#{directoryPath}"), "*/")).each do |subdirectoryPath| | |
# And generate a action on the directory's Action pile. | |
directoryPile << DataSync::FetchAction.new(gitFetchCommand, subdirectoryPath, "NOPE") | |
end | |
# Push that directory Pile onto the main action Pile | |
actionPile << directoryPile | |
else # If we're NOT operating recursively on the current directory | |
# Then just generate a Action for the directory (no need to recurse) | |
actionPile << DataSync::FetchAction.new(gitFetchCommand, directoryPath, "NOPE") | |
end | |
end | |
end | |
end | |
# Flatten out the Action pile and return it. | |
return actionPile.flatten | |
end | |
# If a configuration file exists named "configuration.json", load that, but else load | |
# "configuration.sample.json" | |
configurationHash = DataSync::Configuration.new.load(DataSync::CONFIGURATION_FILE_NAME) | |
# Generate an array of Actions to call. | |
actions = generateActions(configurationHash) | |
# Iterate through the array and call each one. | |
actions.each do |action| | |
print action.progressCharacter unless DataSync::OutputProperties[:cronMode] | |
action.output = action.to_proc.call | |
end | |
print "\n" unless DataSync::OutputProperties[:cronMode] | |
actions.each do |action| | |
puts "Action (#{action.command}<#{action.path}>):\n#{action.output.gsub(/^/, " ")}\n" if action.output.gsub(/\s+/, "").length > 0 unless DataSync::OutputProperties[:cronMode] | |
end |
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
{ | |
"defaults": { | |
"git": { | |
"fetch": { | |
"command": "git fetch", | |
"recurse": true, | |
"progress-character": "." | |
} | |
} | |
}, | |
"git": { | |
"fetch": [ | |
{ | |
"command": "git fetch", | |
"directory": "~/git/github/kryestofer", | |
"recurse": true | |
}, | |
{ | |
"command": "git fetch", | |
"directory": "~/git/github/kotct", | |
"recurse": true | |
}, | |
{ | |
"command": "git fetch", | |
"directory": "~/git/github/team461wbi", | |
"recurse": true | |
}, | |
{ | |
"command": "git fetch", | |
"directory": "~/git/github/wlcsc", | |
"recurse": true | |
}, | |
{ | |
"command": "git fetch", | |
"directory": "~/git/github/promyloph", | |
"recurse": true | |
}, | |
{ | |
"command": "git fetch", | |
"directory": "~/git/github/cantino", | |
"recurse": true | |
} | |
] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment