Be explicit about ambiguous extensions

This commit is contained in:
Joshua Peek
2011-07-05 19:51:54 -05:00
parent d984640546
commit 1e453a22b5
3 changed files with 60 additions and 11 deletions

View File

@@ -9,12 +9,27 @@ module Linguist
# Languages are defined in `lib/linguist/languages.yml`. # Languages are defined in `lib/linguist/languages.yml`.
class Language class Language
@languages = [] @languages = []
@overrides = {}
@index = {} @index = {}
@name_index = {} @name_index = {}
@alias_index = {} @alias_index = {}
@extension_index = {} @extension_index = {}
@filename_index = {} @filename_index = {}
# Internal: Test if extension maps to multiple Languages.
#
# Returns true or false.
def self.ambiguous?(extension)
@overrides.include?(extension)
end
# Include?: Return overridden extensions.
#
# Returns extensions Array.
def self.overridden_extensions
@overrides.keys
end
# Internal: Create a new Language object # Internal: Create a new Language object
# #
# attributes - A hash of attributes # attributes - A hash of attributes
@@ -47,18 +62,22 @@ module Linguist
warn "Extension is missing a '.': #{extension.inspect}" warn "Extension is missing a '.': #{extension.inspect}"
end end
# All Language extensions should be unique. Warn if there is a unless ambiguous?(extension)
# duplicate.
if @extension_index.key?(extension)
warn "Duplicate extension: #{extension}"
end
# Index the extension with a leading ".": ".rb" # Index the extension with a leading ".": ".rb"
@extension_index[extension] = language @extension_index[extension] = language
# Index the extension without a leading ".": "rb" # Index the extension without a leading ".": "rb"
@extension_index[extension.sub(/^\./, '')] = language @extension_index[extension.sub(/^\./, '')] = language
end end
end
language.overrides.each do |extension|
if extension !~ /^\./
warn "Extension is missing a '.': #{extension.inspect}"
end
@overrides[extension] = language
end
language.filenames.each do |filename| language.filenames.each do |filename|
@filename_index[filename] = language @filename_index[filename] = language
@@ -191,6 +210,7 @@ module Linguist
# Set extensions or default to []. # Set extensions or default to [].
@extensions = attributes[:extensions] || [] @extensions = attributes[:extensions] || []
@overrides = attributes[:overrides] || []
@filenames = attributes[:filenames] || [] @filenames = attributes[:filenames] || []
# Set popular, major, and searchable flags # Set popular, major, and searchable flags
@@ -260,6 +280,11 @@ module Linguist
# Returns the extensions Array # Returns the extensions Array
attr_reader :extensions attr_reader :extensions
# Internal: Get overridden extensions.
#
# Returns the extensions Array.
attr_reader :overrides
# Public: Get filenames # Public: Get filenames
# #
# Examples # Examples
@@ -381,6 +406,7 @@ module Linguist
:searchable => options.key?('searchable') ? options['searchable'] : true, :searchable => options.key?('searchable') ? options['searchable'] : true,
:search_term => options['search_term'], :search_term => options['search_term'],
:extensions => options['extensions'], :extensions => options['extensions'],
:overrides => options['overrides'],
:filenames => options['filenames'], :filenames => options['filenames'],
:major => options['major'], :major => options['major'],
:popular => popular.include?(name) :popular => popular.include?(name)

View File

@@ -9,6 +9,7 @@
# aliases - An Array of additional aliases (implicitly # aliases - An Array of additional aliases (implicitly
# includes name.downcase) # includes name.downcase)
# extension - An Array of associated extensions # extension - An Array of associated extensions
# overrides - An Array of extensions that takes precedence over conflicts
# major - Boolean flag major programming languages. Please leave # major - Boolean flag major programming languages. Please leave
# this option to GitHub staff to decide. # this option to GitHub staff to decide.
# searchable - Boolean flag to enable searching (defaults to true) # searchable - Boolean flag to enable searching (defaults to true)
@@ -477,6 +478,7 @@ Markdown:
Matlab: Matlab:
extensions: extensions:
- .m
- .matlab - .matlab
Max/MSP: Max/MSP:
@@ -542,6 +544,8 @@ ObjDump:
Objective-C: Objective-C:
major: true major: true
overrides:
- .m
extensions: extensions:
- .m - .m
- .mm - .mm
@@ -580,6 +584,8 @@ Parrot Internal Representation:
Perl: Perl:
major: true major: true
overrides:
- .pl
extensions: extensions:
- .pl - .pl
- .ph - .ph
@@ -593,6 +599,7 @@ Perl:
Prolog: Prolog:
major: true major: true
extensions: extensions:
- .pl
- .pro - .pro
- .prolog - .prolog
@@ -620,6 +627,8 @@ Python traceback:
R: R:
major: true major: true
lexer: S lexer: S
overrides:
- .r
extensions: extensions:
- .r - .r
- .R - .R
@@ -648,9 +657,10 @@ Raw token data:
Rebol: Rebol:
lexer: REBOL lexer: REBOL
extensions: extensions:
- .rebol - .r
- .r2 - .r2
- .r3 - .r3
- .rebol
Redcode: Redcode:
extensions: extensions:

View File

@@ -5,6 +5,17 @@ require 'test/unit'
class TestLanguage < Test::Unit::TestCase class TestLanguage < Test::Unit::TestCase
include Linguist include Linguist
def test_ambiguous_extensions
assert Language.ambiguous?('.m')
assert_equal Language['Objective-C'], Language.find_by_extension('m')
assert Language.ambiguous?('.pl')
assert_equal Language['Perl'], Language.find_by_extension('pl')
assert Language.ambiguous?('.r')
assert_equal Language['R'], Language.find_by_extension('r')
end
def test_lexer def test_lexer
# Add an assertion to this list if you add/change any lexers # Add an assertion to this list if you add/change any lexers
# in languages.yml. Please keep this list alphabetized. # in languages.yml. Please keep this list alphabetized.
@@ -383,10 +394,12 @@ class TestLanguage < Test::Unit::TestCase
def test_find_all_by_extension def test_find_all_by_extension
Language.all.each do |language| Language.all.each do |language|
language.extensions.each do |extension| language.extensions.each do |extension|
unless Language.ambiguous?(extension)
assert_equal language, Language.find_by_extension(extension) assert_equal language, Language.find_by_extension(extension)
end end
end end
end end
end
def test_find_by_filename def test_find_by_filename
assert_equal Language['Ruby'], Language.find_by_filename('foo.rb') assert_equal Language['Ruby'], Language.find_by_filename('foo.rb')