Test that grammars.yml lists the right scopes for each submodule

convert-grammars now supports a few flags that we can use to make it
dump out the YAML just for the local grammar submodules. We can then
compare this to the YAML that's actually in grammars.yml to check that
they're the same. If they aren't, grammars.yml needs to be updated.
This will help catch mistakes like using the wrong scope name.
This commit is contained in:
Adam Roben
2014-12-22 16:35:01 -05:00
parent 78a0030d46
commit ada6f6882a
2 changed files with 63 additions and 10 deletions

View File

@@ -2,6 +2,7 @@
require 'json' require 'json'
require 'net/http' require 'net/http'
require 'optparse'
require 'plist' require 'plist'
require 'set' require 'set'
require 'tmpdir' require 'tmpdir'
@@ -13,6 +14,13 @@ GRAMMARS_PATH = File.join(ROOT, "grammars")
SOURCES_FILE = File.join(ROOT, "grammars.yml") SOURCES_FILE = File.join(ROOT, "grammars.yml")
CSONC = File.join(ROOT, "node_modules", ".bin", "csonc") CSONC = File.join(ROOT, "node_modules", ".bin", "csonc")
$options = {
:add => false,
:install => true,
:output => SOURCES_FILE,
:remote => true,
}
class SingleFile class SingleFile
def initialize(path) def initialize(path)
@path = path @path = path
@@ -148,8 +156,9 @@ def load_grammar(path)
end end
end end
def install_grammar(tmp_dir, source, all_scopes) def load_grammars(tmp_dir, source, all_scopes)
is_url = source.start_with?("http:", "https:") is_url = source.start_with?("http:", "https:")
return [] if is_url && !$options[:remote]
is_single_file = source.end_with?('.tmLanguage', '.plist') is_single_file = source.end_with?('.tmLanguage', '.plist')
p = if !is_url p = if !is_url
@@ -172,9 +181,7 @@ def install_grammar(tmp_dir, source, all_scopes)
raise "Unsupported source: #{source}" unless p raise "Unsupported source: #{source}" unless p
installed = [] p.fetch(tmp_dir).map do |path|
p.fetch(tmp_dir).each do |path|
grammar = load_grammar(path) grammar = load_grammar(path)
scope = grammar['scopeName'] scope = grammar['scopeName']
@@ -184,9 +191,17 @@ def install_grammar(tmp_dir, source, all_scopes)
" Previous package: #{all_scopes[scope]}" " Previous package: #{all_scopes[scope]}"
next next
end end
File.write(File.join(GRAMMARS_PATH, "#{scope}.json"), JSON.pretty_generate(grammar))
all_scopes[scope] = p.url all_scopes[scope] = p.url
grammar
end
end
def install_grammars(grammars)
installed = []
grammars.each do |grammar|
scope = grammar['scopeName']
File.write(File.join(GRAMMARS_PATH, "#{scope}.json"), JSON.pretty_generate(grammar))
installed << scope installed << scope
end end
@@ -206,7 +221,8 @@ def run_thread(queue, all_scopes)
dir = "#{tmpdir}/#{index}" dir = "#{tmpdir}/#{index}"
Dir.mkdir(dir) Dir.mkdir(dir)
install_grammar(dir, source, all_scopes) grammars = load_grammars(dir, source, all_scopes)
install_grammars(grammars) if $options[:install]
end end
end end
end end
@@ -232,9 +248,9 @@ def main(sources)
all_scopes = {} all_scopes = {}
if ARGV[0] == '--add' if $options[:add]
Dir.mktmpdir do |tmpdir| Dir.mktmpdir do |tmpdir|
install_grammar(tmpdir, ARGV[1], all_scopes) install_grammar(tmpdir, ARGV[0], all_scopes)
end end
generate_yaml(all_scopes, sources) generate_yaml(all_scopes, sources)
else else
@@ -252,12 +268,36 @@ def main(sources)
end end
end end
OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [options]"
opts.on("--add GRAMMAR", "Add a new grammar. GRAMMAR may be a file path or URL.") do |a|
$options[:add] = a
end
opts.on("--[no-]install", "Install grammars into grammars/ directory.") do |i|
$options[:install] = i
end
opts.on("--output FILE", "Write output to FILE. Use - for stdout.") do |o|
$options[:output] = o == "-" ? $stdout : o
end
opts.on("--[no-]remote", "Download remote grammars.") do |r|
$options[:remote] = r
end
end.parse!
sources = File.open(SOURCES_FILE) do |file| sources = File.open(SOURCES_FILE) do |file|
YAML.load(file) YAML.load(file)
end end
yaml = main(sources) yaml = main(sources)
File.write(SOURCES_FILE, YAML.dump(yaml)) if $options[:output].is_a?(IO)
$options[:output].write(YAML.dump(yaml))
else
File.write($options[:output], YAML.dump(yaml))
end
$stderr.puts("Done") $stderr.puts("Done")

View File

@@ -36,4 +36,17 @@ class TestGrammars < Minitest::Test
assert nonexistent_submodules.empty? && unlisted_submodules.empty?, message assert nonexistent_submodules.empty? && unlisted_submodules.empty?, message
end end
def test_local_scopes_are_in_sync
actual = YAML.load(`"#{File.join(ROOT, "script", "convert-grammars")}" --output - --no-install --no-remote 2>/dev/null`)
assert_predicate $?, :success?
# We're not checking remote grammars. That can take a long time and make CI
# flaky if network conditions are poor.
@grammars.delete_if { |k, v| k.start_with?("http:", "https:") }
@grammars.each do |k, v|
assert_equal v, actual[k], "The scopes listed for #{k} in grammars.yml don't match the scopes found in that repository"
end
end
end end