Skip to content

Instantly share code, notes, and snippets.

@asterite
Created December 21, 2016 22:21
Show Gist options
  • Save asterite/7fc71c4b11e5ad8cee57a836c99c61f4 to your computer and use it in GitHub Desktop.
Save asterite/7fc71c4b11e5ad8cee57a836c99c61f4 to your computer and use it in GitHub Desktop.
require "http/client"
require "yaml"
record PosRange, start : Int32, end : Int32
repo = ARGV[0]?
unless repo
abort "missing repo"
end
unless repo =~ %r(https?://github.com/([^/]+)/([^/]+)/?)
abort "not a github repo"
end
user = $1
repo_name = $2
response = HTTP::Client.get("https://raw.githubusercontent.com/#{user}/#{repo_name}/master/shard.yml")
unless response.success?
if HTTP::Client.head(repo).success?
abort "shard.yml not found in #{repo}"
else
abort "unknown GitHub repository: #{repo}"
end
end
body = response.body
shard = YAML.parse(body)
shard_name = shard["name"]?
unless shard_name
abort "missing 'name' attribute in remote shard.yml"
end
shard_name = shard_name.raw.as?(String)
unless shard_name
abort "missing 'name' attribute in remote shard.yml is not a string"
end
yaml_contents = File.read("./shard.yml")
yaml = YAML.parse(yaml_contents)
# Quick check to see if the shard is already in shard.yml
if yaml["dependencies"]?.try &.[shard_name]?
abort "shard '#{shard_name}' is already specified in shard.yml"
end
lines = yaml_contents.lines
ranges = {} of String => PosRange
parser = YAML::PullParser.new(yaml_contents)
parser.read_stream do
parser.read_document do
parser.read_mapping do
until parser.kind.mapping_end?
line = parser.line_number
name = parser.read_scalar
parser.skip
ranges[name] = PosRange.new(line.to_i, parser.line_number.to_i)
end
end
end
end
insert_dependencies = false
insert_begin_newline = false
insert_end_newline = false
index = nil
dependencies_range = ranges["dependencies"]?
if dependencies_range
end_line = dependencies_range.end - 1
index = end_line.downto(0).find { |i| !lines[i].blank? }.not_nil! + 1
else
insert_dependencies = true
{"authors", "version"}.each do |section|
if section_range = ranges[section]?
end_line = section_range.end - 1
insert_end_newline = !lines[end_line].blank?
index = end_line.downto(0).find { |i| !lines[i].blank? }.not_nil! + 1
insert_begin_newline = true
break
end
end
unless index
index = lines.size
insert_begin_newline = true
end
end
lines.insert(index, "") if insert_end_newline
lines.insert(index, " github: #{user}/#{repo_name}")
lines.insert(index, " #{shard_name}:")
lines.insert(index, "dependencies:") if insert_dependencies
lines.insert(index, "") if insert_begin_newline
File.write("./shard.yml", lines.join("\n"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment