diff --git a/.gitmodules b/.gitmodules index 1fff9e4b..5c0588bc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -503,7 +503,6 @@ [submodule "vendor/grammars/sublime-mask"] path = vendor/grammars/sublime-mask url = https://github.com/tenbits/sublime-mask - branch = release [submodule "vendor/grammars/sublime_cobol"] path = vendor/grammars/sublime_cobol url = https://bitbucket.org/bitlang/sublime_cobol diff --git a/test/test_grammars.rb b/test/test_grammars.rb index a80e690d..7afbea32 100644 --- a/test/test_grammars.rb +++ b/test/test_grammars.rb @@ -3,6 +3,14 @@ require_relative "./helper" class TestGrammars < Minitest::Test ROOT = File.expand_path("../..", __FILE__) + # These grammars have no license but have been grandfathered in. New grammars + # must have a license that allows redistribution. + UNLICENSED_GRAMMARS_WHITELIST = %w[ + vendor/grammars/Sublime-Lasso + vendor/grammars/Sublime-REBOL + vendor/grammars/x86-assembly-textmate-bundle + ].freeze + def setup @grammars = YAML.load(File.read(File.join(ROOT, "grammars.yml"))) end @@ -14,12 +22,11 @@ class TestGrammars < Minitest::Test end def test_submodules_are_in_sync - submodules = `git config --list --file "#{File.join(ROOT, ".gitmodules")}"`.lines.grep(/\.path=/).map { |line| line.chomp.split("=", 2).last } # Strip off paths inside the submodule so that just the submodule path remains. listed_submodules = @grammars.keys.grep(/vendor\/grammars/).map { |source| source[%r{vendor/grammars/[^/]+}] } - nonexistent_submodules = listed_submodules - submodules - unlisted_submodules = submodules - listed_submodules + nonexistent_submodules = listed_submodules - submodule_paths + unlisted_submodules = submodule_paths - listed_submodules message = "" unless nonexistent_submodules.empty? @@ -49,4 +56,79 @@ class TestGrammars < Minitest::Test assert_equal v, actual[k], "The scopes listed for #{k} in grammars.yml don't match the scopes found in that repository" end end + + def test_submodules_have_licenses + categories = submodule_paths.group_by do |submodule| + files = Dir[File.join(ROOT, submodule, "*")] + license = files.find { |path| File.basename(path) =~ /\blicense\b/i } || files.find { |path| File.basename(path) =~ /\bcopying\b/i } + if license.nil? + if readme = files.find { |path| File.basename(path) =~ /\Areadme\b/i } + license = readme if File.read(readme) =~ /\blicense\b/i + end + end + if license.nil? + :unlicensed + elsif classify_license(license) + :licensed + else + :unrecognized + end + end + + unlicensed = categories[:unlicensed] || [] + unrecognized = categories[:unrecognized] || [] + disallowed_unlicensed = unlicensed - UNLICENSED_GRAMMARS_WHITELIST + disallowed_unrecognized = unrecognized - UNLICENSED_GRAMMARS_WHITELIST + extra_whitelist_entries = UNLICENSED_GRAMMARS_WHITELIST - (unlicensed | unrecognized) + + message = "" + if disallowed_unlicensed.any? + message << "The following grammar submodules don't seem to have a license. All grammars must have a license that permits redistribution.\n" + message << disallowed_unlicensed.sort.join("\n") + end + if disallowed_unrecognized.any? + message << "\n\n" unless message.empty? + message << "The following grammar submodules have an unrecognized license. Please update #{__FILE__} to recognize the license.\n" + message << disallowed_unrecognized.sort.join("\n") + end + if extra_whitelist_entries.any? + message << "\n\n" unless message.empty? + message << "The following grammar submodules are listed in UNLICENSED_GRAMMARS_WHITELIST but either have a license (yay!)\n" + message << "or have been removed from the repository. Please remove them from the whitelist.\n" + message << extra_whitelist_entries.sort.join("\n") + end + + assert disallowed_unlicensed.empty? && disallowed_unrecognized.empty? && extra_whitelist_entries.empty?, message + end + + private + + def submodule_paths + @submodule_paths ||= `git config --list --file "#{File.join(ROOT, ".gitmodules")}"`.lines.grep(/\.path=/).map { |line| line.chomp.split("=", 2).last } + end + + def classify_license(path) + content = File.read(path) + if content.include?("Apache License") && content.include?("2.0") + "Apache 2.0" + elsif content.include?("GNU") && content =~ /general/i && content =~ /public/i + if content =~ /version 2/i + "GPLv2" + elsif content =~ /version 3/i + "GPLv3" + end + elsif content.include?("GPL") && content.include?("http://www.gnu.org/licenses/gpl.html") + "GPLv3" + elsif content.include?("Creative Commons") + "CC" + elsif content.include?("tidy-license.txt") || content.include?("If not otherwise specified (see below)") + "textmate" + elsif content =~ /^\s*[*-]\s+Redistribution/ || content.include?("Redistributions of source code") + "BSD" + elsif content.include?("Permission is hereby granted") || content =~ /\bMIT\b/ + "MIT" + elsif content.include?("unlicense.org") + "unlicense" + end + end end diff --git a/vendor/grammars/NimLime b/vendor/grammars/NimLime index 9cef4b65..a7067c60 160000 --- a/vendor/grammars/NimLime +++ b/vendor/grammars/NimLime @@ -1 +1 @@ -Subproject commit 9cef4b6547da06a85122a087b325022dccb5e09e +Subproject commit a7067c605b893585c056d32a20a1b953f100e138 diff --git a/vendor/grammars/Scalate.tmbundle b/vendor/grammars/Scalate.tmbundle index 4f85314f..0307535a 160000 --- a/vendor/grammars/Scalate.tmbundle +++ b/vendor/grammars/Scalate.tmbundle @@ -1 +1 @@ -Subproject commit 4f85314fca2ebe3641c678010489b80e81acb8ea +Subproject commit 0307535add076965c8cd438d0f4109bec7d68d2d diff --git a/vendor/grammars/fsharpbinding b/vendor/grammars/fsharpbinding index d0974762..99d2e9a5 160000 --- a/vendor/grammars/fsharpbinding +++ b/vendor/grammars/fsharpbinding @@ -1 +1 @@ -Subproject commit d097476208bfa11a961734907d190b78bc5af5fb +Subproject commit 99d2e9a53924ae5ba850985f3df1dc8c11cb6731 diff --git a/vendor/grammars/language-clojure b/vendor/grammars/language-clojure index d649d9f5..bae6eee8 160000 --- a/vendor/grammars/language-clojure +++ b/vendor/grammars/language-clojure @@ -1 +1 @@ -Subproject commit d649d9f5b227722f5a35fd0e9430cb14325b8e83 +Subproject commit bae6eee8557c2158592ac485a7168ccd10fc6dfb diff --git a/vendor/grammars/language-coffee-script b/vendor/grammars/language-coffee-script index c6e8d337..d86c8963 160000 --- a/vendor/grammars/language-coffee-script +++ b/vendor/grammars/language-coffee-script @@ -1 +1 @@ -Subproject commit c6e8d33715fe883da8411b7149cfb3eb76d23698 +Subproject commit d86c8963dcee0ab811da05a175b2218045d0c124 diff --git a/vendor/grammars/language-gfm b/vendor/grammars/language-gfm index 7b62290a..6af44a08 160000 --- a/vendor/grammars/language-gfm +++ b/vendor/grammars/language-gfm @@ -1 +1 @@ -Subproject commit 7b62290a08d635e98f7bc2c8cb8f51e97b0d3935 +Subproject commit 6af44a08718668035f45270898389ae4fc8eeb8b diff --git a/vendor/grammars/language-javascript b/vendor/grammars/language-javascript index 6690feb3..51575193 160000 --- a/vendor/grammars/language-javascript +++ b/vendor/grammars/language-javascript @@ -1 +1 @@ -Subproject commit 6690feb3a0aedb191e3c28b7a7a3961c24245b6f +Subproject commit 515751937df1d397b495e4a92fec5a0933994cdb diff --git a/vendor/grammars/language-python b/vendor/grammars/language-python index f518e495..46072e32 160000 --- a/vendor/grammars/language-python +++ b/vendor/grammars/language-python @@ -1 +1 @@ -Subproject commit f518e495f6bb13124d44cfc2366c424dc58859ac +Subproject commit 46072e32e3060eb8e2fea98a106a86db89acc842 diff --git a/vendor/grammars/language-shellscript b/vendor/grammars/language-shellscript index cbec163c..98397197 160000 --- a/vendor/grammars/language-shellscript +++ b/vendor/grammars/language-shellscript @@ -1 +1 @@ -Subproject commit cbec163cc1640f46f2d5ba145f5cb2cace8e3405 +Subproject commit 9839719721e3fb67c2df8461b2b296e6ff027e7f diff --git a/vendor/grammars/language-yaml b/vendor/grammars/language-yaml index eddd0793..ce8b4414 160000 --- a/vendor/grammars/language-yaml +++ b/vendor/grammars/language-yaml @@ -1 +1 @@ -Subproject commit eddd079347ee6854d37887168daff4a32688d8c2 +Subproject commit ce8b441467852f766a34d22ba6661099496e22e4 diff --git a/vendor/grammars/sublime-mask b/vendor/grammars/sublime-mask index 632ff3c6..6f12d284 160000 --- a/vendor/grammars/sublime-mask +++ b/vendor/grammars/sublime-mask @@ -1 +1 @@ -Subproject commit 632ff3c6f58d4cbf0863db79c22f4f64ed229b25 +Subproject commit 6f12d2841d008fb02eee912485cebcad7151d4f0