Skip to content

Instantly share code, notes, and snippets.

@alex-quiterio
Created February 7, 2025 20:22
Show Gist options
  • Select an option

  • Save alex-quiterio/837438fc2972c189c80ad8b9d7db0c08 to your computer and use it in GitHub Desktop.

Select an option

Save alex-quiterio/837438fc2972c189c80ad8b9d7db0c08 to your computer and use it in GitHub Desktop.
Repository manager written in ruby
require 'fileutils'
require 'optparse'
class RepoSyncConfig
attr_reader :home_path, :code_path, :config_file_path, :command, :repo_url
def initialize
# Set defaults
@home_path = ENV['HOME']
@code_path = "#{@home_path}/code"
@config_file_path = "#{@code_path}/.subscribed-repos"
@command = 'sync'
@repo_url = nil
parse_options
ensure_config_directory
end
private
def parse_options
OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [options] [command]"
opts.separator("\nCommands:")
opts.separator(" sync Sync all repositories (default)")
opts.separator(" add REPO_URL Add repository to sync list")
opts.separator(" remove REPO_URL Remove repository from sync list")
opts.separator(" list Show all repositories in sync list")
opts.separator("\nOptions:")
opts.on('--code-path PATH', 'Set code directory path') do |path|
@code_path = path
end
opts.on('--config-file PATH', 'Set config file path') do |path|
@config_file_path = path
end
opts.on('-h', '--help', 'Display this help message') do
puts opts
exit
end
end.parse!
# Parse command and repository URL if provided
if ARGV.any?
@command = ARGV[0]
@repo_url = ARGV[1] if ARGV[1]
end
end
def ensure_config_directory
config_dir = File.dirname(@config_file_path)
FileUtils.mkdir_p(config_dir) unless Dir.exist?(config_dir)
FileUtils.touch(@config_file_path) unless File.exist?(@config_file_path)
end
end
class RepoManager
def initialize(config)
@config = config
FileUtils.mkdir_p(@config.code_path) unless Dir.exist?(@config.code_path)
end
def run
case @config.command
when 'sync'
sync_all_repos
when 'add'
add_repo
when 'remove'
remove_repo
when 'list'
list_repos
else
puts "Unknown command: #{@config.command}"
exit 1
end
end
private
def update_repo(url)
repo_name = url.split('/').last.gsub('.git', '')
repo_path = "#{@config.code_path}/#{repo_name}"
if Dir.exist?(repo_path)
update_existing_repo(repo_path, repo_name)
else
clone_new_repo(url, repo_path, repo_name)
end
end
def sync_all_repos
File.readlines(@config.config_file_path).each do |line|
url = line.strip
next if url.empty?
update_repo(url)
end
puts "Done 🤖"
end
def add_repo
unless @config.repo_url
puts "Error: Repository URL is required"
exit 1
end
repos = File.readlines(@config.config_file_path).map(&:strip)
if repos.include?(@config.repo_url)
puts "Repository already in sync list"
return
end
File.open(@config.config_file_path, 'a') do |file|
file.puts @config.repo_url
end
puts "Added #{@config.repo_url} to sync list"
end
def remove_repo
unless @config.repo_url
puts "Error: Repository URL is required"
exit 1
end
repos = File.readlines(@config.config_file_path).map(&:strip)
unless repos.include?(@config.repo_url)
puts "Repository not found in sync list"
return
end
repos.delete(@config.repo_url)
File.write(@config.config_file_path, repos.join("\n") + "\n")
puts "Removed #{@config.repo_url} from sync list"
end
def list_repos
puts "Repositories in sync list:"
File.readlines(@config.config_file_path).each do |line|
url = line.strip
next if url.empty?
puts "- #{url}"
end
end
def update_existing_repo(repo_path, repo_name)
Dir.chdir(repo_path) do
puts "Pulling latest changes for #{repo_name}..."
system("git checkout main && git pull")
end
end
def clone_new_repo(url, repo_path, repo_name)
puts "Cloning repository #{repo_name} into #{repo_path}..."
system("git clone #{url} #{repo_path}")
end
end
# Main script execution
if __FILE__ == $0
config = RepoSyncConfig.new
manager = RepoManager.new(config)
manager.run
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment