Last active
September 12, 2019 12:31
-
-
Save ysbaddaden/3ce4cd72a0ad1e8bd4533213785069e1 to your computer and use it in GitHub Desktop.
Crystal Shards bootstrap (Ruby)
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 | |
# | |
# A bootstrap to install locked Crystal Shards dependencies. Written in Ruby so | |
# it doesn't need Crystal. This coul be useful to extract stdlib as distinct | |
# shards from the main crystal-lang/crystal repository, while still allowing to | |
# install and distribute them to build crystal, avoiding the crystal <-> shards | |
# requirement loop. | |
require "yaml" | |
# helpers: | |
def fatal(message) | |
STDERR.puts "fatal: #{message}" | |
exit 1 | |
end | |
def execute(command) | |
puts "+ #{command}" | |
system(command) | |
end | |
def installed_version(name) | |
return unless Dir.exists?(name) | |
specfile = File.join(name, "shard.yml") | |
return unless File.exists?(File.join(specfile)) | |
spec = YAML.load(File.read(specfile)) | |
spec["version"] | |
end | |
# configuration: | |
LIB_DIR = File.join(Dir.pwd, "lib") | |
lockfile = "shard.lock" | |
# validation: | |
unless File.exists?(lockfile) | |
fatal "No shard.lock file in the current directory" | |
end | |
locked = YAML.load(File.read(lockfile)) | |
unless (version = locked["version"].to_s) == "1.0" | |
fatal "Unsupported lock version: #{version}" | |
end | |
# installation: | |
Dir.mkdir(LIB_DIR) unless Dir.exists?(LIB_DIR) | |
Dir.chdir(LIB_DIR) | |
locked["shards"].each do |name, dependency| | |
repo = | |
if dependency.has_key?("git") | |
dependency["git"] | |
elsif dependency.has_key?("github") | |
"https://github.com/#{dependency["github"]}.git" | |
elsif dependency.has_key?("bitbucket") | |
"https://bitbucket.org/#{dependency["bitbucket"]}.git" | |
elsif dependency.has_key?("gitlab") | |
"https://gitlab.com/#{dependency["gitlab"]}.git" | |
end | |
refs = | |
if dependency.has_key?("version") | |
if installed_version(name) == dependency["version"] | |
STDERR.puts "Using #{name} (#{dependency["version"]})" | |
next | |
end | |
"v" + dependency["version"] | |
else | |
if File.exists?("#{name}.sha1") && File.read("#{name}.sha1") == dependency["commit"] | |
STDERR.puts "Using #{name} (#{installed_version(name)} at #{commit})" | |
next | |
end | |
dependency["commit"] | |
end | |
STDERR.puts "Installing #{name} at #{refs}" | |
execute "rm -rf #{name} #{name}.sha1" | |
# should use git archive, but it's not supported by Git HTTP protocol :( | |
unless execute "git clone -q --depth=1 --branch=#{refs} --single-branch --no-checkout #{repo} #{name}" | |
fatal "failed to install #{name} at #{refs}" | |
end | |
execute "cd #{name} && git checkout #{refs} 2> /dev/null" | |
execute "rm -rf #{name}/.git" | |
if refs == dependency["commit"] | |
File.write("#{name}.sha1", refs) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment