mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
Move Linguist::Language.detect to Linguist.detect
This commit is contained in:
@@ -8,8 +8,85 @@ require 'linguist/shebang'
|
|||||||
require 'linguist/version'
|
require 'linguist/version'
|
||||||
|
|
||||||
class << Linguist
|
class << Linguist
|
||||||
|
# Public: Detects the Language of the blob.
|
||||||
|
#
|
||||||
|
# blob - an object that includes the Linguist `BlobHelper` interface;
|
||||||
|
# see Linguist::LazyBlob and Linguist::FileBlob for examples
|
||||||
|
#
|
||||||
|
# Returns Language or nil.
|
||||||
|
def detect(blob)
|
||||||
|
# Bail early if the blob is binary or empty.
|
||||||
|
return nil if blob.likely_binary? || blob.binary? || blob.empty?
|
||||||
|
|
||||||
|
Linguist.instrument("linguist.detection", :blob => blob) do
|
||||||
|
# Call each strategy until one candidate is returned.
|
||||||
|
languages = []
|
||||||
|
returning_strategy = nil
|
||||||
|
|
||||||
|
STRATEGIES.each do |strategy|
|
||||||
|
returning_strategy = strategy
|
||||||
|
candidates = Linguist.instrument("linguist.strategy", :blob => blob, :strategy => strategy, :candidates => languages) do
|
||||||
|
strategy.call(blob, languages)
|
||||||
|
end
|
||||||
|
if candidates.size == 1
|
||||||
|
languages = candidates
|
||||||
|
break
|
||||||
|
elsif candidates.size > 1
|
||||||
|
# More than one candidate was found, pass them to the next strategy.
|
||||||
|
languages = candidates
|
||||||
|
else
|
||||||
|
# No candidates, try the next strategy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Linguist.instrument("linguist.detected", :blob => blob, :strategy => returning_strategy, :language => languages.first)
|
||||||
|
|
||||||
|
languages.first
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Internal: The strategies used to detect the language of a file.
|
||||||
|
#
|
||||||
|
# A strategy is an object that has a `.call` method that takes two arguments:
|
||||||
|
#
|
||||||
|
# blob - An object that quacks like a blob.
|
||||||
|
# languages - An Array of candidate Language objects that were returned by the
|
||||||
|
# previous strategy.
|
||||||
|
#
|
||||||
|
# A strategy should return an Array of Language candidates.
|
||||||
|
#
|
||||||
|
# Strategies are called in turn until a single Language is returned.
|
||||||
|
STRATEGIES = [
|
||||||
|
Linguist::Strategy::Modeline,
|
||||||
|
Linguist::Shebang,
|
||||||
|
Linguist::Strategy::Filename,
|
||||||
|
Linguist::Heuristics,
|
||||||
|
Linguist::Classifier
|
||||||
|
]
|
||||||
|
|
||||||
|
# Public: Set an instrumenter.
|
||||||
|
#
|
||||||
|
# class CustomInstrumenter
|
||||||
|
# def instrument(name, payload = {})
|
||||||
|
# warn "Instrumenting #{name}: #{payload[:blob]}"
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Linguist.instrumenter = CustomInstrumenter
|
||||||
|
#
|
||||||
|
# The instrumenter must conform to the `ActiveSupport::Notifications`
|
||||||
|
# interface, which defines `#instrument` and accepts:
|
||||||
|
#
|
||||||
|
# name - the String name of the event (e.g. "linguist.detected")
|
||||||
|
# payload - a Hash of the exception context.
|
||||||
attr_accessor :instrumenter
|
attr_accessor :instrumenter
|
||||||
|
|
||||||
|
# Internal: Perform instrumentation on a block
|
||||||
|
#
|
||||||
|
# Linguist.instrument("linguist.dosomething", :blob => blob) do
|
||||||
|
# # logic to instrument here.
|
||||||
|
# end
|
||||||
|
#
|
||||||
def instrument(*args, &bk)
|
def instrument(*args, &bk)
|
||||||
if instrumenter
|
if instrumenter
|
||||||
instrumenter.instrument(*args, &bk)
|
instrumenter.instrument(*args, &bk)
|
||||||
@@ -17,4 +94,5 @@ class << Linguist
|
|||||||
yield if block_given?
|
yield if block_given?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ require 'yaml'
|
|||||||
|
|
||||||
module Linguist
|
module Linguist
|
||||||
# DEPRECATED Avoid mixing into Blob classes. Prefer functional interfaces
|
# DEPRECATED Avoid mixing into Blob classes. Prefer functional interfaces
|
||||||
# like `Language.detect` over `Blob#language`. Functions are much easier to
|
# like `Linguist.detect` over `Blob#language`. Functions are much easier to
|
||||||
# cache and compose.
|
# cache and compose.
|
||||||
#
|
#
|
||||||
# Avoid adding additional bloat to this module.
|
# Avoid adding additional bloat to this module.
|
||||||
@@ -325,7 +325,7 @@ module Linguist
|
|||||||
#
|
#
|
||||||
# Returns a Language or nil if none is detected
|
# Returns a Language or nil if none is detected
|
||||||
def language
|
def language
|
||||||
@language ||= Language.detect(self)
|
@language ||= Linguist.detect(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Internal: Get the TextMate compatible scope for the blob
|
# Internal: Get the TextMate compatible scope for the blob
|
||||||
|
|||||||
@@ -87,14 +87,6 @@ module Linguist
|
|||||||
language
|
language
|
||||||
end
|
end
|
||||||
|
|
||||||
STRATEGIES = [
|
|
||||||
Linguist::Strategy::Modeline,
|
|
||||||
Linguist::Shebang,
|
|
||||||
Linguist::Strategy::Filename,
|
|
||||||
Linguist::Heuristics,
|
|
||||||
Linguist::Classifier
|
|
||||||
]
|
|
||||||
|
|
||||||
# Public: Detects the Language of the blob.
|
# Public: Detects the Language of the blob.
|
||||||
#
|
#
|
||||||
# blob - an object that includes the Linguist `BlobHelper` interface;
|
# blob - an object that includes the Linguist `BlobHelper` interface;
|
||||||
@@ -102,34 +94,8 @@ module Linguist
|
|||||||
#
|
#
|
||||||
# Returns Language or nil.
|
# Returns Language or nil.
|
||||||
def self.detect(blob)
|
def self.detect(blob)
|
||||||
# Bail early if the blob is binary or empty.
|
warn "[DEPRECATED] `Linguist::Language.detect` is deprecated. Use `Linguist.detect`. #{caller[0]}"
|
||||||
return nil if blob.likely_binary? || blob.binary? || blob.empty?
|
Linguist.detect(blob)
|
||||||
|
|
||||||
Linguist.instrument("linguist.detection", :blob => blob) do
|
|
||||||
# Call each strategy until one candidate is returned.
|
|
||||||
languages = []
|
|
||||||
returning_strategy = nil
|
|
||||||
|
|
||||||
STRATEGIES.each do |strategy|
|
|
||||||
returning_strategy = strategy
|
|
||||||
candidates = Linguist.instrument("linguist.strategy", :blob => blob, :strategy => strategy, :candidates => languages) do
|
|
||||||
strategy.call(blob, languages)
|
|
||||||
end
|
|
||||||
if candidates.size == 1
|
|
||||||
languages = candidates
|
|
||||||
break
|
|
||||||
elsif candidates.size > 1
|
|
||||||
# More than one candidate was found, pass them to the next strategy.
|
|
||||||
languages = candidates
|
|
||||||
else
|
|
||||||
# No candidates, try the next strategy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Linguist.instrument("linguist.detected", :blob => blob, :strategy => returning_strategy, :language => languages.first)
|
|
||||||
|
|
||||||
languages.first
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Public: Get all Languages
|
# Public: Get all Languages
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class TestHeuristcs < Minitest::Test
|
|||||||
|
|
||||||
def test_detect_still_works_if_nothing_matches
|
def test_detect_still_works_if_nothing_matches
|
||||||
blob = Linguist::FileBlob.new(File.join(samples_path, "Objective-C/hello.m"))
|
blob = Linguist::FileBlob.new(File.join(samples_path, "Objective-C/hello.m"))
|
||||||
match = Language.detect(blob)
|
match = Linguist.detect(blob)
|
||||||
assert_equal Language["Objective-C"], match
|
assert_equal Language["Objective-C"], match
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class TestInstrumentation < Minitest::Test
|
|||||||
|
|
||||||
def test_detection_instrumentation_with_binary_blob
|
def test_detection_instrumentation_with_binary_blob
|
||||||
binary_blob = fixture_blob("Binary/octocat.ai")
|
binary_blob = fixture_blob("Binary/octocat.ai")
|
||||||
Language.detect(binary_blob)
|
Linguist.detect(binary_blob)
|
||||||
|
|
||||||
# Shouldn't instrument this (as it's binary)
|
# Shouldn't instrument this (as it's binary)
|
||||||
assert_equal 0, Linguist.instrumenter.events.size
|
assert_equal 0, Linguist.instrumenter.events.size
|
||||||
@@ -36,7 +36,7 @@ class TestInstrumentation < Minitest::Test
|
|||||||
|
|
||||||
def test_modeline_instrumentation
|
def test_modeline_instrumentation
|
||||||
blob = fixture_blob("Data/Modelines/ruby")
|
blob = fixture_blob("Data/Modelines/ruby")
|
||||||
Language.detect(blob)
|
Linguist.detect(blob)
|
||||||
|
|
||||||
detect_event = Linguist.instrumenter.events.last
|
detect_event = Linguist.instrumenter.events.last
|
||||||
detect_event_payload = detect_event[:args].first
|
detect_event_payload = detect_event[:args].first
|
||||||
|
|||||||
Reference in New Issue
Block a user