mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
Merge branch 'master' into 2821-slim
This commit is contained in:
@@ -111,7 +111,7 @@ def git_linguist(args)
|
||||
parser.parse!(args)
|
||||
|
||||
git_dir = `git rev-parse --git-dir`.strip
|
||||
raise "git-linguist must be ran in a Git repository" unless $?.success?
|
||||
raise "git-linguist must be ran in a Git repository (#{Dir.pwd})" unless $?.success?
|
||||
wrapper = GitLinguist.new(git_dir, commit, incremental)
|
||||
|
||||
case args.pop
|
||||
|
||||
@@ -9,8 +9,85 @@ require 'linguist/shebang'
|
||||
require 'linguist/version'
|
||||
|
||||
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
|
||||
|
||||
# Internal: Perform instrumentation on a block
|
||||
#
|
||||
# Linguist.instrument("linguist.dosomething", :blob => blob) do
|
||||
# # logic to instrument here.
|
||||
# end
|
||||
#
|
||||
def instrument(*args, &bk)
|
||||
if instrumenter
|
||||
instrumenter.instrument(*args, &bk)
|
||||
@@ -18,4 +95,5 @@ class << Linguist
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ require 'yaml'
|
||||
|
||||
module Linguist
|
||||
# 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.
|
||||
#
|
||||
# Avoid adding additional bloat to this module.
|
||||
@@ -325,7 +325,7 @@ module Linguist
|
||||
#
|
||||
# Returns a Language or nil if none is detected
|
||||
def language
|
||||
@language ||= Language.detect(self)
|
||||
@language ||= Linguist.detect(self)
|
||||
end
|
||||
|
||||
# Internal: Get the TextMate compatible scope for the blob
|
||||
|
||||
@@ -313,6 +313,14 @@ module Linguist
|
||||
end
|
||||
end
|
||||
|
||||
disambiguate ".props" do |data|
|
||||
if /^(\s*)(<Project|<Import|<Property|<?xml|xmlns)/i.match(data)
|
||||
Language["XML"]
|
||||
elsif /\w+\s*=\s*/i.match(data)
|
||||
Language["INI"]
|
||||
end
|
||||
end
|
||||
|
||||
disambiguate ".r" do |data|
|
||||
if /\bRebol\b/i.match(data)
|
||||
Language["Rebol"]
|
||||
@@ -346,7 +354,7 @@ module Linguist
|
||||
end
|
||||
|
||||
disambiguate ".sql" do |data|
|
||||
if /^\\i\b|AS \$\$|LANGUAGE '+plpgsql'+/i.match(data) || /SECURITY (DEFINER|INVOKER)/i.match(data) || /BEGIN( WORK| TRANSACTION)?;/i.match(data)
|
||||
if /^\\i\b|AS \$\$|LANGUAGE '?plpgsql'?/i.match(data) || /SECURITY (DEFINER|INVOKER)/i.match(data) || /BEGIN( WORK| TRANSACTION)?;/i.match(data)
|
||||
#Postgres
|
||||
Language["PLpgSQL"]
|
||||
elsif /(alter module)|(language sql)|(begin( NOT)+ atomic)/i.match(data) || /signal SQLSTATE '[0-9]+'/i.match(data)
|
||||
|
||||
@@ -87,14 +87,6 @@ module Linguist
|
||||
language
|
||||
end
|
||||
|
||||
STRATEGIES = [
|
||||
Linguist::Strategy::Modeline,
|
||||
Linguist::Shebang,
|
||||
Linguist::Strategy::Filename,
|
||||
Linguist::Heuristics,
|
||||
Linguist::Classifier
|
||||
]
|
||||
|
||||
# Public: Detects the Language of the blob.
|
||||
#
|
||||
# blob - an object that includes the Linguist `BlobHelper` interface;
|
||||
@@ -102,34 +94,8 @@ module Linguist
|
||||
#
|
||||
# Returns Language or nil.
|
||||
def self.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
|
||||
warn "[DEPRECATED] `Linguist::Language.detect` is deprecated. Use `Linguist.detect`. #{caller[0]}"
|
||||
Linguist.detect(blob)
|
||||
end
|
||||
|
||||
# Public: Get all Languages
|
||||
|
||||
@@ -3863,6 +3863,7 @@ XML:
|
||||
- .osm
|
||||
- .plist
|
||||
- .pluginspec
|
||||
- .props
|
||||
- .ps1xml
|
||||
- .psc1
|
||||
- .pt
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module Linguist
|
||||
VERSION = "4.7.6"
|
||||
VERSION = "4.8.0"
|
||||
end
|
||||
|
||||
31
samples/PLpgSQL/procedures.sql
Normal file
31
samples/PLpgSQL/procedures.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
load 'plpgsql';
|
||||
load 'plpgsql_lint';
|
||||
|
||||
DROP FUNCTION IF EXISTS list_sites();
|
||||
CREATE OR REPLACE FUNCTION list_sites() RETURNS TABLE (fc json) AS
|
||||
$func$
|
||||
BEGIN
|
||||
RETURN QUERY SELECT row_to_json(feat_col) FROM (
|
||||
SELECT 'FeatureCollection' AS type, array_to_json(array_agg(feat)) AS features FROM (
|
||||
SELECT DISTINCT ON (new_id) 'Feature' AS type, ST_ASGeoJSON(loc.geom)::json AS geometry, row_to_json(
|
||||
(SELECT prop FROM (SELECT new_id) AS prop)) AS properties FROM location loc) AS feat) AS feat_col;
|
||||
END;
|
||||
$func$ LANGUAGE plpgsql;
|
||||
|
||||
|
||||
DROP FUNCTION IF EXISTS get_observations(character varying, integer);
|
||||
CREATE OR REPLACE FUNCTION get_observations(kind varchar, site_id integer) RETURNS TABLE (fc json) AS
|
||||
$func$
|
||||
BEGIN
|
||||
IF kind = 'o2_abs' THEN
|
||||
RETURN QUERY SELECT array_to_json(array_agg(row_to_json(obs))) FROM (
|
||||
SELECT observation_date AS date, o2_abs AS value FROM oxygen WHERE new_id = site_id) AS obs;
|
||||
ELSIF kind = 'o2_rel' THEN
|
||||
RETURN QUERY SELECT array_to_json(array_agg(row_to_json(obs))) FROM (
|
||||
SELECT observation_date AS date, o2_rel AS value FROM oxygen WHERE new_id = site_id) AS obs;
|
||||
ELSIF kind = 'temp' THEN
|
||||
RETURN QUERY SELECT array_to_json(array_agg(row_to_json(obs))) FROM (
|
||||
SELECT observation_date AS date, temp AS value FROM oxygen WHERE new_id = site_id) AS obs;
|
||||
END IF;
|
||||
END;
|
||||
$func$ LANGUAGE plpgsql;
|
||||
29
samples/XML/Default.props
Normal file
29
samples/XML/Default.props
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
***********************************************************************************************
|
||||
Default.props
|
||||
|
||||
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
|
||||
created a backup copy. Incorrect changes to this file will make it
|
||||
impossible to load or build your projects from the command-line or the IDE.
|
||||
|
||||
Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
***********************************************************************************************
|
||||
-->
|
||||
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<!-- Import Before -->
|
||||
<Import Condition="Exists('$(MSBuildThisFileDirectory)ImportBefore\Default')" Project="$(MSBuildThisFileDirectory)ImportBefore\Default\*.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetOsAndVersion>Windows Phone Silverlight 8.1</TargetOsAndVersion>
|
||||
<RealOSVersion>6.3</RealOSVersion>
|
||||
<PlatformToolset Condition="'$(PlatformToolset)' == ''">v120</PlatformToolset>
|
||||
|
||||
<_PlatformToolsetFriendlyNameFor_v120>Windows Phone Silverlight 8.1 (v120)</_PlatformToolsetFriendlyNameFor_v120>
|
||||
<_PlatformToolsetShortNameFor_v120>Windows Phone Silverlight 8.1</_PlatformToolsetShortNameFor_v120>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Import After -->
|
||||
<Import Condition="Exists('$(MSBuildThisFileDirectory)ImportAfter\Default')" Project="$(MSBuildThisFileDirectory)ImportAfter\Default\*.props" />
|
||||
</Project>
|
||||
@@ -36,7 +36,7 @@ class TestHeuristcs < Minitest::Test
|
||||
|
||||
def test_detect_still_works_if_nothing_matches
|
||||
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
|
||||
end
|
||||
|
||||
@@ -189,6 +189,16 @@ class TestHeuristcs < Minitest::Test
|
||||
})
|
||||
end
|
||||
|
||||
# Candidate languages = ["SQL", "PLpgSQL", "SQLPL", "PLSQL"]
|
||||
def test_sql_by_heuristics
|
||||
assert_heuristics({
|
||||
"SQL" => ["SQL/create_stuff.sql", "SQL/db.sql", "SQL/dual.sql"],
|
||||
"PLpgSQL" => all_fixtures("PLpgSQL", "*.sql"),
|
||||
"SQLPL" => ["SQLPL/trigger.sql"],
|
||||
"PLSQL" => all_fixtures("PLSQL", "*.sql")
|
||||
})
|
||||
end
|
||||
|
||||
# Candidate languages = ["Perl", "Perl6"]
|
||||
def test_t_perl_by_heuristics
|
||||
assert_heuristics({
|
||||
|
||||
@@ -28,7 +28,7 @@ class TestInstrumentation < Minitest::Test
|
||||
|
||||
def test_detection_instrumentation_with_binary_blob
|
||||
binary_blob = fixture_blob("Binary/octocat.ai")
|
||||
Language.detect(binary_blob)
|
||||
Linguist.detect(binary_blob)
|
||||
|
||||
# Shouldn't instrument this (as it's binary)
|
||||
assert_equal 0, Linguist.instrumenter.events.size
|
||||
@@ -36,7 +36,7 @@ class TestInstrumentation < Minitest::Test
|
||||
|
||||
def test_modeline_instrumentation
|
||||
blob = fixture_blob("Data/Modelines/ruby")
|
||||
Language.detect(blob)
|
||||
Linguist.detect(blob)
|
||||
|
||||
detect_event = Linguist.instrumenter.events.last
|
||||
detect_event_payload = detect_event[:args].first
|
||||
|
||||
2
vendor/grammars/AutoHotkey
vendored
2
vendor/grammars/AutoHotkey
vendored
Submodule vendor/grammars/AutoHotkey updated: 4da62de23d...d31adb9184
2
vendor/grammars/Elm.tmLanguage
vendored
2
vendor/grammars/Elm.tmLanguage
vendored
Submodule vendor/grammars/Elm.tmLanguage updated: 437033bd48...155ce91c81
2
vendor/grammars/Lean.tmbundle
vendored
2
vendor/grammars/Lean.tmbundle
vendored
Submodule vendor/grammars/Lean.tmbundle updated: 943ac84bf6...a1a3818ecf
2
vendor/grammars/MagicPython
vendored
2
vendor/grammars/MagicPython
vendored
Submodule vendor/grammars/MagicPython updated: 82c76aff70...7d07d6f5b0
2
vendor/grammars/NimLime
vendored
2
vendor/grammars/NimLime
vendored
Submodule vendor/grammars/NimLime updated: 4db349dda5...0c6c6207a6
2
vendor/grammars/Vala-TMBundle
vendored
2
vendor/grammars/Vala-TMBundle
vendored
Submodule vendor/grammars/Vala-TMBundle updated: 1c5ebb62d1...935bd21c13
2
vendor/grammars/apache.tmbundle
vendored
2
vendor/grammars/apache.tmbundle
vendored
Submodule vendor/grammars/apache.tmbundle updated: a4a494e845...a12e895533
2
vendor/grammars/api-blueprint-sublime-plugin
vendored
2
vendor/grammars/api-blueprint-sublime-plugin
vendored
Submodule vendor/grammars/api-blueprint-sublime-plugin updated: 550417b9bb...076ee9bd62
2
vendor/grammars/atom-language-stan
vendored
2
vendor/grammars/atom-language-stan
vendored
Submodule vendor/grammars/atom-language-stan updated: f8d855eab9...2fa2745da7
2
vendor/grammars/ats.sublime
vendored
2
vendor/grammars/ats.sublime
vendored
Submodule vendor/grammars/ats.sublime updated: a3f24abbe7...fd6bd223d1
2
vendor/grammars/chapel-tmbundle
vendored
2
vendor/grammars/chapel-tmbundle
vendored
Submodule vendor/grammars/chapel-tmbundle updated: 469476b285...d6c9e926e7
2
vendor/grammars/factor
vendored
2
vendor/grammars/factor
vendored
Submodule vendor/grammars/factor updated: 97d1ec759e...d99c9e1663
2
vendor/grammars/gap-tmbundle
vendored
2
vendor/grammars/gap-tmbundle
vendored
Submodule vendor/grammars/gap-tmbundle updated: 52c8fafb66...cf05fa8df1
2
vendor/grammars/haxe-sublime-bundle
vendored
2
vendor/grammars/haxe-sublime-bundle
vendored
Submodule vendor/grammars/haxe-sublime-bundle updated: 94cc8eea31...e9559a2c53
2
vendor/grammars/jade-tmbundle
vendored
2
vendor/grammars/jade-tmbundle
vendored
Submodule vendor/grammars/jade-tmbundle updated: d27b61d178...81093433d6
2
vendor/grammars/kotlin-sublime-package
vendored
2
vendor/grammars/kotlin-sublime-package
vendored
Submodule vendor/grammars/kotlin-sublime-package updated: 3ddc52e8db...535967fd2c
2
vendor/grammars/language-babel
vendored
2
vendor/grammars/language-babel
vendored
Submodule vendor/grammars/language-babel updated: e2fd09d7d9...5f63df46cc
2
vendor/grammars/language-clojure
vendored
2
vendor/grammars/language-clojure
vendored
Submodule vendor/grammars/language-clojure updated: a0193ad2a9...fa482c39a3
2
vendor/grammars/language-csharp
vendored
2
vendor/grammars/language-csharp
vendored
Submodule vendor/grammars/language-csharp updated: f635e67ede...96ab79f45b
2
vendor/grammars/language-gfm
vendored
2
vendor/grammars/language-gfm
vendored
Submodule vendor/grammars/language-gfm updated: 298a8a3eb1...1472c976c5
2
vendor/grammars/language-javascript
vendored
2
vendor/grammars/language-javascript
vendored
Submodule vendor/grammars/language-javascript updated: f68e4bfe54...b28af094cc
2
vendor/grammars/language-renpy
vendored
2
vendor/grammars/language-renpy
vendored
Submodule vendor/grammars/language-renpy updated: cc2f1c69f0...c259c5d3ac
2
vendor/grammars/latex.tmbundle
vendored
2
vendor/grammars/latex.tmbundle
vendored
Submodule vendor/grammars/latex.tmbundle updated: 82986b93a4...bec21c8bcd
2
vendor/grammars/mathematica-tmbundle
vendored
2
vendor/grammars/mathematica-tmbundle
vendored
Submodule vendor/grammars/mathematica-tmbundle updated: 3b4b826dbe...5067a25b9b
2
vendor/grammars/sas.tmbundle
vendored
2
vendor/grammars/sas.tmbundle
vendored
Submodule vendor/grammars/sas.tmbundle updated: 3759a19719...ba5c74624c
2
vendor/grammars/smali-sublime
vendored
2
vendor/grammars/smali-sublime
vendored
Submodule vendor/grammars/smali-sublime updated: 28a4336421...60a1fdb344
2
vendor/grammars/sublime-nginx
vendored
2
vendor/grammars/sublime-nginx
vendored
Submodule vendor/grammars/sublime-nginx updated: fcf644ecea...e72eb75814
2
vendor/grammars/sublime-robot-plugin
vendored
2
vendor/grammars/sublime-robot-plugin
vendored
Submodule vendor/grammars/sublime-robot-plugin updated: bf5dc7fa9f...07069ebf20
2
vendor/grammars/sublime-rust
vendored
2
vendor/grammars/sublime-rust
vendored
Submodule vendor/grammars/sublime-rust updated: 621e4f6117...f75f2b1026
2
vendor/grammars/sublime-typescript
vendored
2
vendor/grammars/sublime-typescript
vendored
Submodule vendor/grammars/sublime-typescript updated: 26fd717a79...2da61f59d2
2
vendor/grammars/sublime_cobol
vendored
2
vendor/grammars/sublime_cobol
vendored
Submodule vendor/grammars/sublime_cobol updated: 3d2b6dbcd1...7c60c10849
2
vendor/grammars/vue-syntax-highlight
vendored
2
vendor/grammars/vue-syntax-highlight
vendored
Submodule vendor/grammars/vue-syntax-highlight updated: f20c9bab7e...fbcccaee10
Reference in New Issue
Block a user