Skip to content

Instantly share code, notes, and snippets.

@smellsblue
Created December 11, 2015 01:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smellsblue/53f5a6757dcc91ad10bc to your computer and use it in GitHub Desktop.
Save smellsblue/53f5a6757dcc91ad10bc to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# This program will fix any private gems for your Gemstash 1.0.0.pre.1
# instance. If you never installed 1.0.0.pre.1 or never pushed private gems to
# it, then you shouldn't need to run this.
#
# If you have a custom config outside of your ~/.gemstash directory, please run:
# $ ./fix_resources.rb --config-file path/to/gemstash-config.yml
#
# If you want to be prompted for each file, please run:
# $ ./fix_resources.rb --ask
#
# If you want all files changed to be backed up, please run:
# $ ./fix_resources.rb --backup
#
# If you want to be prompted for each file and back them up, please run:
# $ ./fix_resources.rb --ask --backup
#
# Backups will be stored in the current directory, but you may override that:
# $ ./fix_resources.rb --backup /tmp/gemstash-backups
require "fileutils"
require "gemstash"
require "optparse"
require "pathname"
require "yaml"
Gemstash::Env.current = Gemstash::Env.new
OPTIONS = {}
OPTION_PARSER = OptionParser.new do |opts|
opts.on("--config-file file", "Sepcify custom Gemstash config file") do |opt|
OPTIONS[:config_file] = opt
end
opts.on("--ask", "Ask before updating any file") do |opt|
OPTIONS[:ask] = opt
end
opts.on("--backup [DIR]", "Backup changed files to the current directory", " (backup to DIR if provided)") do |dir|
OPTIONS[:backup] = dir || "."
end
end
OPTION_PARSER.program_name = __FILE__
OPTION_PARSER.parse!
def error(message, with_usage: false)
message = "\e[31m#{message}\e[0m"
message = "#{message}\n#{OPTION_PARSER}" if with_usage
abort message
end
error("No arguments are allowed", with_usage: true) unless ARGV.empty?
error("Backup directory does not exist: #{OPTIONS[:backup]}") if OPTIONS[:backup] && !Dir.exist?(OPTIONS[:backup])
if OPTIONS[:config_file]
file = OPTIONS[:config_file]
error "Missing config file: #{file}" unless File.exist?(file)
Gemstash::Env.current.config = Gemstash::Configuration.new(file: file)
end
# This class contains the actual fixes
class FixResources
def check_needs_fixing
metadata_file = Gemstash::Env.current.base_file("metadata.yml")
error "Cannot find Gemstash metadata!" unless File.exist?(metadata_file)
metadata = YAML.load_file(metadata_file)
metadata_version = metadata[:gemstash_version]
return if metadata_version == "1.0.0.pre.1"
error "Metadata version: #{metadata_version}, you should not need to run this"
end
def check_gemstash_version
return if Gemstash::VERSION == "1.0.0.pre.2"
error "This fix was intended to run when moving to 1.0.0.pre.2\n" \
"It may not function properly on other versions\n" \
"Your version: #{Gemstash::VERSION}"
end
def check_private_gems
return if private_gems_path.directory?
error "You don't appear to have private gems in your Gemstash instance, you shouldn't need to run this"
end
def fix_resources
fixed = 0
Dir[private_gems_path.join("**/properties.yaml")].each do |properties_file|
properties = YAML.load_file(properties_file)
next if properties[:gemstash_resource_version]
if properties[:gemstash_storage_version] != Gemstash::Resource::VERSION
error "Unexpected resource version: #{properties[:gemstash_storage_version].inspect} in: #{properties_file}"
end
next unless fix?(properties_file)
puts "Fixing: #{properties_file}"
backup(properties_file)
properties[:gemstash_resource_version] = properties[:gemstash_storage_version]
properties.delete(:gemstash_storage_version)
File.open(properties_file, "w") {|file| file.write(properties.to_yaml) }
fixed += 1
end
puts "\e[32mDone fixing #{fixed} resources\e[0m"
end
private
def private_gems_path
@private_gems_path ||= Pathname.new(Gemstash::Env.current.base_file("private/gems"))
end
def fix?(file)
return true unless OPTIONS[:ask]
puts "About to automatically fix #{file}"
answer = nil
until %w(yes no).include?(answer)
print "Continue? [yes/no] "
answer = gets
error "Aborting any further fixes" if answer.nil?
answer = answer.strip.downcase
end
answer == "yes"
end
def backup(file)
return unless OPTIONS[:backup]
backup_file = Pathname.new(file).relative_path_from(private_gems_path).to_s.gsub("/", "__")
today = Time.now.strftime("%Y-%m-%d")
backup_file = File.join(OPTIONS[:backup], "#{backup_file}.#{today}.bak")
if File.exist?(backup_file)
error "Backup file already exists: #{backup_file}"
end
puts "Backing up to: #{backup_file}"
FileUtils.copy(file, backup_file)
end
end
fix = FixResources.new
fix.check_needs_fixing
fix.check_gemstash_version
fix.check_private_gems
fix.fix_resources
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment