From ada6f6882a7b9e239231ef6e1c813d84e8843c07 Mon Sep 17 00:00:00 2001 From: Adam Roben Date: Mon, 22 Dec 2014 16:35:01 -0500 Subject: [PATCH] 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. --- script/convert-grammars | 58 ++++++++++++++++++++++++++++++++++------- test/test_grammars.rb | 13 +++++++++ 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/script/convert-grammars b/script/convert-grammars index 3792f4513f..4f67edd576 100755 --- a/script/convert-grammars +++ b/script/convert-grammars @@ -2,6 +2,7 @@ require 'json' require 'net/http' +require 'optparse' require 'plist' require 'set' require 'tmpdir' @@ -13,6 +14,13 @@ GRAMMARS_PATH = File.join(ROOT, "grammars") SOURCES_FILE = File.join(ROOT, "grammars.yml") CSONC = File.join(ROOT, "node_modules", ".bin", "csonc") +$options = { + :add => false, + :install => true, + :output => SOURCES_FILE, + :remote => true, +} + class SingleFile def initialize(path) @path = path @@ -148,8 +156,9 @@ def load_grammar(path) 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:") + return [] if is_url && !$options[:remote] is_single_file = source.end_with?('.tmLanguage', '.plist') p = if !is_url @@ -172,9 +181,7 @@ def install_grammar(tmp_dir, source, all_scopes) raise "Unsupported source: #{source}" unless p - installed = [] - - p.fetch(tmp_dir).each do |path| + p.fetch(tmp_dir).map do |path| grammar = load_grammar(path) scope = grammar['scopeName'] @@ -184,9 +191,17 @@ def install_grammar(tmp_dir, source, all_scopes) " Previous package: #{all_scopes[scope]}" next end + 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)) - all_scopes[scope] = p.url installed << scope end @@ -206,7 +221,8 @@ def run_thread(queue, all_scopes) dir = "#{tmpdir}/#{index}" 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 @@ -232,9 +248,9 @@ def main(sources) all_scopes = {} - if ARGV[0] == '--add' + if $options[:add] Dir.mktmpdir do |tmpdir| - install_grammar(tmpdir, ARGV[1], all_scopes) + install_grammar(tmpdir, ARGV[0], all_scopes) end generate_yaml(all_scopes, sources) else @@ -252,12 +268,36 @@ def main(sources) 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| YAML.load(file) end 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") diff --git a/test/test_grammars.rb b/test/test_grammars.rb index 574833483a..871ba19561 100644 --- a/test/test_grammars.rb +++ b/test/test_grammars.rb @@ -36,4 +36,17 @@ def test_submodules_are_in_sync assert nonexistent_submodules.empty? && unlisted_submodules.empty?, message 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