mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Be explicit about ambiguous extensions
This commit is contained in:
		@@ -9,12 +9,27 @@ module Linguist
 | 
			
		||||
  # Languages are defined in `lib/linguist/languages.yml`.
 | 
			
		||||
  class Language
 | 
			
		||||
    @languages       = []
 | 
			
		||||
    @overrides       = {}
 | 
			
		||||
    @index           = {}
 | 
			
		||||
    @name_index      = {}
 | 
			
		||||
    @alias_index     = {}
 | 
			
		||||
    @extension_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
 | 
			
		||||
    #
 | 
			
		||||
    # attributes - A hash of attributes
 | 
			
		||||
@@ -47,18 +62,22 @@ module Linguist
 | 
			
		||||
          warn "Extension is missing a '.': #{extension.inspect}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # All Language extensions should be unique. Warn if there is a
 | 
			
		||||
        # duplicate.
 | 
			
		||||
        if @extension_index.key?(extension)
 | 
			
		||||
          warn "Duplicate extension: #{extension}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        unless ambiguous?(extension)
 | 
			
		||||
          # Index the extension with a leading ".": ".rb"
 | 
			
		||||
          @extension_index[extension] = language
 | 
			
		||||
 | 
			
		||||
          # Index the extension without a leading ".": "rb"
 | 
			
		||||
          @extension_index[extension.sub(/^\./, '')] = language
 | 
			
		||||
        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|
 | 
			
		||||
        @filename_index[filename] = language
 | 
			
		||||
@@ -191,6 +210,7 @@ module Linguist
 | 
			
		||||
 | 
			
		||||
      # Set extensions or default to [].
 | 
			
		||||
      @extensions = attributes[:extensions] || []
 | 
			
		||||
      @overrides  = attributes[:overrides]  || []
 | 
			
		||||
      @filenames  = attributes[:filenames]  || []
 | 
			
		||||
 | 
			
		||||
      # Set popular, major, and searchable flags
 | 
			
		||||
@@ -260,6 +280,11 @@ module Linguist
 | 
			
		||||
    # Returns the extensions Array
 | 
			
		||||
    attr_reader :extensions
 | 
			
		||||
 | 
			
		||||
    # Internal: Get overridden extensions.
 | 
			
		||||
    #
 | 
			
		||||
    # Returns the extensions Array.
 | 
			
		||||
    attr_reader :overrides
 | 
			
		||||
 | 
			
		||||
    # Public: Get filenames
 | 
			
		||||
    #
 | 
			
		||||
    # Examples
 | 
			
		||||
@@ -381,6 +406,7 @@ module Linguist
 | 
			
		||||
      :searchable  => options.key?('searchable') ? options['searchable'] : true,
 | 
			
		||||
      :search_term => options['search_term'],
 | 
			
		||||
      :extensions  => options['extensions'],
 | 
			
		||||
      :overrides   => options['overrides'],
 | 
			
		||||
      :filenames   => options['filenames'],
 | 
			
		||||
      :major       => options['major'],
 | 
			
		||||
      :popular     => popular.include?(name)
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@
 | 
			
		||||
# aliases     - An Array of additional aliases (implicitly
 | 
			
		||||
#               includes name.downcase)
 | 
			
		||||
# extension   - An Array of associated extensions
 | 
			
		||||
# overrides   - An Array of extensions that takes precedence over conflicts
 | 
			
		||||
# major       - Boolean flag major programming languages. Please leave
 | 
			
		||||
#               this option to GitHub staff to decide.
 | 
			
		||||
# searchable  - Boolean flag to enable searching (defaults to true)
 | 
			
		||||
@@ -477,6 +478,7 @@ Markdown:
 | 
			
		||||
 | 
			
		||||
Matlab:
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .m
 | 
			
		||||
  - .matlab
 | 
			
		||||
 | 
			
		||||
Max/MSP:
 | 
			
		||||
@@ -542,6 +544,8 @@ ObjDump:
 | 
			
		||||
 | 
			
		||||
Objective-C:
 | 
			
		||||
  major: true
 | 
			
		||||
  overrides:
 | 
			
		||||
  - .m
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .m
 | 
			
		||||
  - .mm
 | 
			
		||||
@@ -580,6 +584,8 @@ Parrot Internal Representation:
 | 
			
		||||
 | 
			
		||||
Perl:
 | 
			
		||||
  major: true
 | 
			
		||||
  overrides:
 | 
			
		||||
  - .pl
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .pl
 | 
			
		||||
  - .ph
 | 
			
		||||
@@ -593,6 +599,7 @@ Perl:
 | 
			
		||||
Prolog:
 | 
			
		||||
  major: true
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .pl
 | 
			
		||||
  - .pro
 | 
			
		||||
  - .prolog
 | 
			
		||||
 | 
			
		||||
@@ -620,6 +627,8 @@ Python traceback:
 | 
			
		||||
R:
 | 
			
		||||
  major: true
 | 
			
		||||
  lexer: S
 | 
			
		||||
  overrides:
 | 
			
		||||
  - .r
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .r
 | 
			
		||||
  - .R
 | 
			
		||||
@@ -648,9 +657,10 @@ Raw token data:
 | 
			
		||||
Rebol:
 | 
			
		||||
  lexer: REBOL
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .rebol
 | 
			
		||||
  - .r
 | 
			
		||||
  - .r2
 | 
			
		||||
  - .r3
 | 
			
		||||
  - .rebol
 | 
			
		||||
 | 
			
		||||
Redcode:
 | 
			
		||||
  extensions:
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,17 @@ require 'test/unit'
 | 
			
		||||
class TestLanguage < Test::Unit::TestCase
 | 
			
		||||
  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
 | 
			
		||||
    # Add an assertion to this list if you add/change any lexers
 | 
			
		||||
    # in languages.yml. Please keep this list alphabetized.
 | 
			
		||||
@@ -383,10 +394,12 @@ class TestLanguage < Test::Unit::TestCase
 | 
			
		||||
  def test_find_all_by_extension
 | 
			
		||||
    Language.all.each do |language|
 | 
			
		||||
      language.extensions.each do |extension|
 | 
			
		||||
        unless Language.ambiguous?(extension)
 | 
			
		||||
          assert_equal language, Language.find_by_extension(extension)
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_find_by_filename
 | 
			
		||||
    assert_equal Language['Ruby'], Language.find_by_filename('foo.rb')
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user