commit 6bc52531e707eb4b9b875c418a84f2e100ff6e73 Author: Máximo Cuadros Date: Wed Jul 13 19:05:09 2016 +0200 code from domain diff --git a/auxiliary.go b/auxiliary.go new file mode 100644 index 0000000..2047118 --- /dev/null +++ b/auxiliary.go @@ -0,0 +1,41 @@ +package slinguist + +var AuxiliaryLanguages = map[string]bool{ + "Other": true, + "XML": true, + "YAML": true, + "TOML": true, + "INI": true, + "JSON": true, + "TeX": true, + "Public Key": true, + "AsciiDoc": true, + "AGS Script": true, + "VimL": true, + "Diff": true, + "CMake": true, + "fish": true, + "Awk": true, + "Graphviz (DOT)": true, + "Markdown": true, + "desktop": true, + "XSLT": true, + "SQL": true, + "RMarkdown": true, + "IRC log": true, + "reStructuredText": true, + "Twig": true, + "CSS": true, + "Batchfile": true, + "Text": true, + "HTML+ERB": true, + "HTML": true, + "Gettext Catalog": true, + "Smarty": true, + "Raw token data": true, +} + +func IsAuxiliaryLanguage(lang string) bool { + _, ok := AuxiliaryLanguages[lang] + return ok +} diff --git a/basic_test.go b/basic_test.go new file mode 100644 index 0000000..14f2624 --- /dev/null +++ b/basic_test.go @@ -0,0 +1,24 @@ +package slinguist + +import ( + "testing" + + . "gopkg.in/check.v1" +) + +func Test(t *testing.T) { TestingT(t) } + +type UtilsSuite struct{} + +var _ = Suite(&UtilsSuite{}) + +func (s *UtilsSuite) TestGetLanguage(c *C) { + c.Assert(GetLanguage("foo.foo"), Equals, "Other") + c.Assert(GetLanguage("foo.go"), Equals, "Go") + c.Assert(GetLanguage("foo.go.php"), Equals, "PHP") +} + +func (s *UtilsSuite) TestGetLanguageExtensions(c *C) { + c.Assert(GetLanguageExtensions("foo"), HasLen, 0) + c.Assert(GetLanguageExtensions("C"), Not(HasLen), 0) +} diff --git a/common.go b/common.go new file mode 100644 index 0000000..c373f6f --- /dev/null +++ b/common.go @@ -0,0 +1,813 @@ +package slinguist + +// Extracted from github/linguist. +// This one-liner prints the latest version: +// curl https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml | python -c 'from collections import defaultdict; import os; import json; import yaml; l = yaml.load(os.sys.stdin.read()); exts = reduce(lambda acc, x: acc + x, [v.get("extensions", []) for k, v in l.items()], []); m = {ext: [k for k, v in l.items() if ext in v.get("extensions", [])] for ext in exts}; print "package utils\n\nvar LanguagesByExtension = map[string][]string{\n"+ json.dumps(m).replace("]", "}").replace("},", "},\n").replace("[", "{")[1:-1] + ",\n}\n"' | gofmt +var LanguagesByExtension = map[string][]string{ + ".1": {"Groff"}, + ".2": {"Groff"}, + ".3": {"Groff"}, + ".4": {"Groff"}, + ".4th": {"Forth"}, + ".5": {"Groff"}, + ".6": {"Groff"}, + ".6pl": {"Perl6"}, + ".6pm": {"Perl6"}, + ".7": {"Groff"}, + "._coffee": {"CoffeeScript"}, + "._js": {"JavaScript"}, + "._ls": {"LiveScript"}, + ".a51": {"Assembly"}, + ".abap": {"ABAP"}, + ".ada": {"Ada"}, + ".adb": {"Ada"}, + ".ado": {"Stata"}, + ".adoc": {"AsciiDoc"}, + ".adp": {"Tcl"}, + ".ads": {"Ada"}, + ".agda": {"Agda"}, + ".ahk": {"AutoHotkey"}, + ".ahkl": {"AutoHotkey"}, + ".aj": {"AspectJ"}, + ".als": {"Alloy"}, + ".ant": {"XML"}, + ".apacheconf": {"ApacheConf"}, + ".apl": {"APL"}, + ".applescript": {"AppleScript"}, + ".arc": {"Arc"}, + ".as": {"ActionScript"}, + ".asax": {"ASP"}, + ".asc": {"Public Key", "AsciiDoc", "AGS Script"}, + ".asciidoc": {"AsciiDoc"}, + ".ascx": {"ASP"}, + ".asd": {"Common Lisp"}, + ".ash": {"AGS Script"}, + ".ashx": {"ASP"}, + ".ASM": {"Assembly"}, + ".asm": {"Assembly"}, + ".asmx": {"ASP"}, + ".asp": {"ASP"}, + ".aspx": {"ASP"}, + ".au3": {"AutoIt"}, + ".aug": {"Augeas"}, + ".auk": {"Awk"}, + ".aux": {"TeX"}, + ".aw": {"PHP"}, + ".awk": {"Awk"}, + ".axd": {"ASP"}, + ".axml": {"XML"}, + ".b": {"Brainfuck"}, + ".bas": {"Visual Basic"}, + ".bash": {"Shell"}, + ".bat": {"Batchfile"}, + ".bats": {"Shell"}, + ".bb": {"BitBake", "BlitzBasic"}, + ".bbx": {"TeX"}, + ".befunge": {"Befunge"}, + ".bf": {"Brainfuck"}, + ".bib": {"TeX"}, + ".bmx": {"BlitzMax"}, + ".bones": {"JavaScript"}, + ".boo": {"Boo"}, + ".brd": {"Eagle"}, + ".bro": {"Bro"}, + ".brs": {"Brightscript"}, + ".bsv": {"Bluespec"}, + ".builder": {"Ruby"}, + ".C": {"C"}, + ".c": {"C"}, + ".c++": {"C++"}, + ".c++-objdump": {"Cpp-ObjDump"}, + ".c++objdump": {"Cpp-ObjDump"}, + ".c-objdump": {"C-ObjDump"}, + ".capnp": {"Cap'n Proto"}, + ".cats": {"C"}, + ".cbl": {"COBOL"}, + ".cbx": {"TeX"}, + ".cc": {"C++"}, + ".ccp": {"COBOL"}, + ".ccxml": {"XML"}, + ".cdf": {"Mathematica"}, + ".ceylon": {"Ceylon"}, + ".cfc": {"ColdFusion CFC"}, + ".cfg": {"INI"}, + ".cfm": {"ColdFusion"}, + ".cfml": {"ColdFusion"}, + ".cgi": {"Python", "Shell", "Perl"}, + ".chpl": {"Chapel"}, + ".chs": {"C2hs Haskell"}, + ".cirru": {"Cirru"}, + ".cjsx": {"CoffeeScript"}, + ".ck": {"ChucK"}, + ".cl": {"Cool", "OpenCL", "Common Lisp"}, + ".cl2": {"Clojure"}, + ".clixml": {"XML"}, + ".clj": {"Clojure"}, + ".cljc": {"Clojure"}, + ".cljs": {"Clojure"}, + ".cljs.hl": {"Clojure"}, + ".cljscm": {"Clojure"}, + ".cljx": {"Clojure"}, + ".clp": {"CLIPS"}, + ".cls": {"Visual Basic", "Apex", "OpenEdge ABL", "TeX"}, + ".cmake": {"CMake"}, + ".cmake.in": {"CMake"}, + ".cmd": {"Batchfile"}, + ".cob": {"COBOL"}, + ".COB": {"COBOL"}, + ".cobol": {"COBOL"}, + ".coffee": {"CoffeeScript"}, + ".command": {"Shell"}, + ".conf": {"ApacheConf"}, + ".coq": {"Coq"}, + ".cp": {"Component Pascal", "C++"}, + ".cpp": {"C++"}, + ".cpp-objdump": {"Cpp-ObjDump"}, + ".cppobjdump": {"Cpp-ObjDump"}, + ".cproject": {"XML"}, + ".cps": {"Component Pascal"}, + ".cpy": {"COBOL"}, + ".CPY": {"COBOL"}, + ".cql": {"SQL"}, + ".cr": {"Crystal"}, + ".creole": {"Creole"}, + ".cs": {"C#", "Smalltalk"}, + ".csh": {"Tcsh"}, + ".cshtml": {"C#"}, + ".cson": {"CoffeeScript"}, + ".csproj": {"XML"}, + ".css": {"CSS"}, + ".csx": {"C#"}, + ".ct": {"XML"}, + ".ctp": {"PHP"}, + ".cu": {"Cuda"}, + ".cuh": {"Cuda"}, + ".cw": {"Redcode"}, + ".cxx": {"C++"}, + ".cxx-objdump": {"Cpp-ObjDump"}, + ".cy": {"Cycript"}, + ".d": {"D"}, + ".d-objdump": {"D-ObjDump"}, + ".darcspatch": {"Darcs Patch"}, + ".dart": {"Dart"}, + ".dats": {"ATS"}, + ".dcl": {"Clean"}, + ".ddl": {"SQL"}, + ".decls": {"BlitzBasic"}, + ".desktop": {"desktop"}, + ".desktop.in": {"desktop"}, + ".dfm": {"Pascal"}, + ".di": {"D"}, + ".diff": {"Diff"}, + ".dita": {"XML"}, + ".ditamap": {"XML"}, + ".ditaval": {"XML"}, + ".djs": {"Dogescript"}, + ".dll.config": {"XML"}, + ".dlm": {"IDL"}, + ".dm": {"DM"}, + ".do": {"Stata"}, + ".dockerfile": {"Dockerfile"}, + ".doh": {"Stata"}, + ".DOT": {"Graphviz (DOT)"}, + ".dot": {"Graphviz (DOT)"}, + ".dpatch": {"Darcs Patch"}, + ".dpr": {"Pascal"}, + ".druby": {"Mirah"}, + ".dtx": {"TeX"}, + ".duby": {"Mirah"}, + ".dyalog": {"APL"}, + ".dyl": {"Dylan"}, + ".dylan": {"Dylan"}, + ".E": {"E"}, + ".e": {"Eiffel"}, + ".ebuild": {"Gentoo Ebuild"}, + ".ec": {"eC"}, + ".ecl": {"Prolog", "ECL"}, + ".eclass": {"Gentoo Eclass"}, + ".eclxml": {"ECL"}, + ".edn": {"edn"}, + ".eh": {"eC"}, + ".el": {"Emacs Lisp"}, + ".eliom": {"OCaml"}, + ".eliomi": {"OCaml"}, + ".elm": {"Elm"}, + ".em": {"EmberScript"}, + ".emacs": {"Emacs Lisp"}, + ".emacs.desktop": {"Emacs Lisp"}, + ".emberscript": {"EmberScript"}, + ".epj": {"Ecere Projects"}, + ".eps": {"PostScript"}, + ".erb": {"HTML+ERB"}, + ".erb.deface": {"HTML+ERB"}, + ".erl": {"Erlang"}, + ".es": {"Erlang"}, + ".es6": {"JavaScript"}, + ".escript": {"Erlang"}, + ".ex": {"Elixir"}, + ".exs": {"Elixir"}, + ".F": {"Forth", "FORTRAN"}, + ".f": {"Forth", "FORTRAN"}, + ".f03": {"FORTRAN"}, + ".F03": {"FORTRAN"}, + ".f08": {"FORTRAN"}, + ".F08": {"FORTRAN"}, + ".F77": {"FORTRAN"}, + ".f77": {"FORTRAN"}, + ".f90": {"FORTRAN"}, + ".F90": {"FORTRAN"}, + ".F95": {"FORTRAN"}, + ".f95": {"FORTRAN"}, + ".factor": {"Factor"}, + ".fan": {"Fantom"}, + ".fancypack": {"Fancy"}, + ".fcgi": {"PHP", "Python", "Shell", "Perl", "Ruby", "Lua"}, + ".feature": {"Cucumber"}, + ".filters": {"XML"}, + ".fish": {"fish"}, + ".flux": {"FLUX"}, + ".for": {"Forth", "FORTRAN"}, + ".FOR": {"FORTRAN"}, + ".forth": {"Forth"}, + ".fp": {"GLSL"}, + ".FPP": {"FORTRAN"}, + ".fpp": {"FORTRAN"}, + ".fr": {"Forth", "Text", "Frege"}, + ".frag": {"GLSL", "JavaScript"}, + ".frg": {"GLSL"}, + ".frm": {"Visual Basic"}, + ".frt": {"Forth"}, + ".frx": {"Visual Basic"}, + ".fs": {"GLSL", "Forth", "F#"}, + ".fshader": {"GLSL"}, + ".fsi": {"F#"}, + ".fsproj": {"XML"}, + ".fsx": {"F#"}, + ".fth": {"Forth"}, + ".fun": {"Standard ML"}, + ".fx": {"FLUX"}, + ".fxml": {"XML"}, + ".fy": {"Fancy"}, + ".g": {"G-code", "GAP"}, + ".g4": {"ANTLR"}, + ".gap": {"GAP"}, + ".gawk": {"Awk"}, + ".gco": {"G-code"}, + ".gcode": {"G-code"}, + ".gd": {"GAP", "GDScript"}, + ".gemspec": {"Ruby"}, + ".geo": {"GLSL"}, + ".geom": {"GLSL"}, + ".gf": {"Grammatical Framework"}, + ".gi": {"GAP"}, + ".glade": {"XML"}, + ".glf": {"Glyph"}, + ".glsl": {"GLSL"}, + ".glslv": {"GLSL"}, + ".gml": {"Graph Modeling Language", "Game Maker Language"}, + ".gms": {"GAMS"}, + ".gnu": {"Gnuplot"}, + ".gnuplot": {"Gnuplot"}, + ".go": {"Go"}, + ".god": {"Ruby"}, + ".golo": {"Golo"}, + ".gp": {"Gnuplot"}, + ".grace": {"Grace"}, + ".gradle": {"Gradle"}, + ".groovy": {"Groovy"}, + ".grt": {"Groovy"}, + ".grxml": {"XML"}, + ".gs": {"Gosu", "JavaScript"}, + ".gshader": {"GLSL"}, + ".gsp": {"Groovy Server Pages"}, + ".gst": {"Gosu"}, + ".gsx": {"Gosu"}, + ".gtpl": {"Groovy"}, + ".gv": {"Graphviz (DOT)"}, + ".gvy": {"Groovy"}, + ".gyp": {"Python"}, + ".H": {"C"}, + ".h": {"C", "C++", "Objective-C"}, + ".h++": {"C++"}, + ".haml": {"Haml"}, + ".haml.deface": {"Haml"}, + ".handlebars": {"Handlebars"}, + ".hats": {"ATS"}, + ".hb": {"Harbour"}, + ".hbs": {"Handlebars"}, + ".hh": {"Hack", "C++"}, + ".hic": {"Clojure"}, + ".hpp": {"C++"}, + ".hqf": {"SQF"}, + ".hrl": {"Erlang"}, + ".hs": {"Haskell"}, + ".hsc": {"Haskell"}, + ".htm": {"HTML"}, + ".html": {"HTML"}, + ".html.hl": {"HTML"}, + ".http": {"HTTP"}, + ".hx": {"Haxe"}, + ".hxsl": {"Haxe"}, + ".hxx": {"C++"}, + ".hy": {"Hy"}, + ".i7x": {"Inform 7"}, + ".iced": {"CoffeeScript"}, + ".icl": {"Clean"}, + ".idc": {"C"}, + ".idr": {"Idris"}, + ".ihlp": {"Stata"}, + ".ijs": {"J"}, + ".ik": {"Ioke"}, + ".ily": {"LilyPond"}, + ".ini": {"INI"}, + ".inl": {"C++"}, + ".ino": {"Arduino"}, + ".ins": {"TeX"}, + ".intr": {"Dylan"}, + ".io": {"Io"}, + ".ipf": {"IGOR Pro"}, + ".ipp": {"C++"}, + ".irbrc": {"Ruby"}, + ".irclog": {"IRC log"}, + ".iss": {"Inno Setup"}, + ".ivy": {"XML"}, + ".j": {"Objective-J", "Jasmin"}, + ".jade": {"Jade"}, + ".jake": {"JavaScript"}, + ".java": {"Java"}, + ".jelly": {"XML"}, + ".jinja": {"HTML+Django"}, + ".jl": {"Julia"}, + ".jq": {"JSONiq"}, + ".js": {"JavaScript"}, + ".jsb": {"JavaScript"}, + ".jsfl": {"JavaScript"}, + ".jsm": {"JavaScript"}, + ".json": {"JSON"}, + ".json5": {"JSON5"}, + ".jsonld": {"JSONLD"}, + ".jsp": {"Java Server Pages"}, + ".jss": {"JavaScript"}, + ".jsx": {"JavaScript"}, + ".kid": {"Genshi"}, + ".kit": {"Kit"}, + ".kml": {"XML"}, + ".krl": {"KRL"}, + ".ksh": {"Shell"}, + ".kt": {"Kotlin"}, + ".ktm": {"Kotlin"}, + ".kts": {"Kotlin"}, + ".lagda": {"Literate Agda"}, + ".las": {"Lasso"}, + ".lasso": {"Lasso"}, + ".lasso8": {"Lasso"}, + ".lasso9": {"Lasso"}, + ".latte": {"Latte"}, + ".launch": {"XML"}, + ".lbx": {"TeX"}, + ".ldml": {"Lasso"}, + ".less": {"Less"}, + ".lfe": {"LFE"}, + ".lgt": {"Logtalk"}, + ".lhs": {"Literate Haskell"}, + ".lid": {"Dylan"}, + ".lidr": {"Idris"}, + ".liquid": {"Liquid"}, + ".lisp": {"NewLisp", "Common Lisp"}, + ".litcoffee": {"Literate CoffeeScript"}, + ".ll": {"LLVM"}, + ".lmi": {"Python"}, + ".lock": {"JSON"}, + ".logtalk": {"Logtalk"}, + ".lol": {"LOLCODE"}, + ".lookml": {"LookML"}, + ".lpr": {"Pascal"}, + ".ls": {"LoomScript", "LiveScript"}, + ".lsl": {"LSL"}, + ".lsp": {"NewLisp", "Common Lisp"}, + ".ltx": {"TeX"}, + ".lua": {"Lua"}, + ".lvproj": {"LabVIEW"}, + ".ly": {"LilyPond"}, + ".m": {"Objective-C", "Mercury", "M", "Mathematica", "Matlab"}, + ".ma": {"Mathematica"}, + ".mak": {"Makefile"}, + ".mako": {"Mako"}, + ".man": {"Groff"}, + ".mao": {"Mako"}, + ".markdown": {"Markdown"}, + ".mask": {"Mask"}, + ".mata": {"Stata"}, + ".matah": {"Stata"}, + ".mathematica": {"Mathematica"}, + ".matlab": {"Matlab"}, + ".mawk": {"Awk"}, + ".maxhelp": {"Max"}, + ".maxpat": {"Max"}, + ".maxproj": {"Max"}, + ".md": {"Markdown"}, + ".mediawiki": {"MediaWiki"}, + ".minid": {"MiniD"}, + ".mir": {"Mirah"}, + ".mirah": {"Mirah"}, + ".mk": {"Makefile"}, + ".mkd": {"Markdown"}, + ".mkdn": {"Markdown"}, + ".mkdown": {"Markdown"}, + ".mkii": {"TeX"}, + ".mkiv": {"TeX"}, + ".mkvi": {"TeX"}, + ".ml": {"OCaml"}, + ".ML": {"Standard ML"}, + ".ml4": {"OCaml"}, + ".mli": {"OCaml"}, + ".mll": {"OCaml"}, + ".mly": {"OCaml"}, + ".mm": {"Objective-C++", "XML"}, + ".mo": {"Modelica"}, + ".monkey": {"Monkey"}, + ".moo": {"Mercury", "Moocode"}, + ".moon": {"MoonScript"}, + ".mspec": {"Ruby"}, + ".mss": {"CartoCSS"}, + ".mtml": {"MTML"}, + ".mu": {"mupad"}, + ".mumps": {"M"}, + ".mustache": {"HTML+Django"}, + ".mxml": {"XML"}, + ".mxt": {"Max"}, + ".myt": {"Myghty"}, + ".n": {"Nemerle"}, + ".nawk": {"Awk"}, + ".nb": {"Mathematica"}, + ".nbp": {"Mathematica"}, + ".nc": {"nesC"}, + ".nginxconf": {"Nginx"}, + ".ni": {"Inform 7"}, + ".nim": {"Nimrod"}, + ".nimrod": {"Nimrod"}, + ".ninja": {"Ninja"}, + ".nit": {"Nit"}, + ".nix": {"Nix"}, + ".njs": {"JavaScript"}, + ".nl": {"NewLisp"}, + ".nlogo": {"NetLogo"}, + ".nproj": {"XML"}, + ".nqp": {"Perl6"}, + ".nse": {"Lua"}, + ".nsh": {"NSIS"}, + ".nsi": {"NSIS"}, + ".nu": {"Nu"}, + ".numpy": {"NumPy"}, + ".numpyw": {"NumPy"}, + ".numsc": {"NumPy"}, + ".nuspec": {"XML"}, + ".nut": {"Squirrel"}, + ".ny": {"Common Lisp"}, + ".objdump": {"ObjDump"}, + ".omgrofl": {"Omgrofl"}, + ".ooc": {"ooc"}, + ".opa": {"Opa"}, + ".opal": {"Opal"}, + ".opencl": {"OpenCL"}, + ".org": {"Org"}, + ".osm": {"XML"}, + ".owl": {"Web Ontology Language"}, + ".ox": {"Ox"}, + ".oxh": {"Ox"}, + ".oxo": {"Ox"}, + ".oxygene": {"Oxygene"}, + ".oz": {"Oz"}, + ".p": {"OpenEdge ABL"}, + ".p6": {"Perl6"}, + ".p6l": {"Perl6"}, + ".p6m": {"Perl6"}, + ".pac": {"JavaScript"}, + ".pan": {"Pan"}, + ".parrot": {"Parrot"}, + ".pas": {"Pascal"}, + ".pasm": {"Parrot Assembly"}, + ".pat": {"Max"}, + ".patch": {"Diff"}, + ".pb": {"PureBasic"}, + ".pbi": {"PureBasic"}, + ".pd": {"Pure Data"}, + ".pd_lua": {"Lua"}, + ".pde": {"Processing"}, + ".perl": {"Perl"}, + ".ph": {"Perl"}, + ".php": {"PHP", "Hack"}, + ".php3": {"PHP"}, + ".php4": {"PHP"}, + ".php5": {"PHP"}, + ".phpt": {"PHP"}, + ".phtml": {"HTML+PHP"}, + ".pig": {"PigLatin"}, + ".pike": {"Pike"}, + ".pir": {"Parrot Internal Representation"}, + ".PL": {"Perl"}, + ".pl": {"Perl6", "Perl", "Prolog"}, + ".pl6": {"Perl6"}, + ".plist": {"XML"}, + ".plot": {"Gnuplot"}, + ".plt": {"Gnuplot"}, + ".pluginspec": {"XML", "Ruby"}, + ".plx": {"Perl"}, + ".pm": {"Perl6", "Perl"}, + ".pm6": {"Perl6"}, + ".pmod": {"Pike"}, + ".po": {"Gettext Catalog"}, + ".pod": {"Perl", "Pod"}, + ".podsl": {"Common Lisp"}, + ".podspec": {"Ruby"}, + ".pogo": {"PogoScript"}, + ".pot": {"Gettext Catalog"}, + ".pp": {"Pascal", "Puppet"}, + ".prc": {"SQL"}, + ".prefs": {"INI"}, + ".prg": {"xBase"}, + ".pri": {"QMake"}, + ".pro": {"QMake", "Prolog", "IDL"}, + ".prolog": {"Prolog"}, + ".properties": {"INI"}, + ".proto": {"Protocol Buffer"}, + ".ps": {"PostScript"}, + ".ps1": {"PowerShell"}, + ".ps1xml": {"XML"}, + ".psc": {"Papyrus"}, + ".psc1": {"XML"}, + ".psd1": {"PowerShell"}, + ".psgi": {"Perl"}, + ".psm1": {"PowerShell"}, + ".pt": {"XML"}, + ".pub": {"Public Key"}, + ".purs": {"PureScript"}, + ".pwn": {"PAWN"}, + ".pxd": {"Cython"}, + ".pxi": {"Cython"}, + ".py": {"Python"}, + ".pyde": {"Python"}, + ".pyp": {"Python"}, + ".pyt": {"Python"}, + ".pytb": {"Python traceback"}, + ".pyw": {"Python"}, + ".pyx": {"Cython"}, + ".qml": {"QML"}, + ".R": {"R"}, + ".r": {"Rebol", "R"}, + ".r2": {"Rebol"}, + ".r3": {"Rebol"}, + ".rabl": {"Ruby"}, + ".rake": {"Ruby"}, + ".raml": {"RAML"}, + ".raw": {"Raw token data"}, + ".rb": {"Ruby"}, + ".rbbas": {"REALbasic"}, + ".rbfrm": {"REALbasic"}, + ".rbmnu": {"REALbasic"}, + ".rbres": {"REALbasic"}, + ".rbtbar": {"REALbasic"}, + ".rbuild": {"Ruby"}, + ".rbuistate": {"REALbasic"}, + ".rbw": {"Ruby"}, + ".rbx": {"Ruby"}, + ".rbxs": {"Lua"}, + ".rd": {"R"}, + ".Rd": {"R"}, + ".rdf": {"XML"}, + ".rdoc": {"RDoc"}, + ".reb": {"Rebol"}, + ".rebol": {"Rebol"}, + ".red": {"Red"}, + ".reds": {"Red"}, + ".reek": {"YAML"}, + ".rest": {"reStructuredText"}, + ".rg": {"Rouge"}, + ".rhtml": {"RHTML"}, + ".rkt": {"Racket"}, + ".rktd": {"Racket"}, + ".rktl": {"Racket"}, + ".rl": {"Ragel in Ruby Host"}, + ".Rmd": {"RMarkdown"}, + ".rmd": {"RMarkdown"}, + ".robot": {"RobotFramework"}, + ".ron": {"Markdown"}, + ".rq": {"SPARQL"}, + ".rs": {"Rust"}, + ".rss": {"XML"}, + ".rst": {"reStructuredText"}, + ".rsx": {"R"}, + ".ru": {"Ruby"}, + ".rviz": {"YAML"}, + ".S": {"GAS"}, + ".s": {"GAS"}, + ".sage": {"Sage"}, + ".sagews": {"Sage"}, + ".sas": {"SAS"}, + ".sass": {"Sass"}, + ".sats": {"ATS"}, + ".sbt": {"Scala"}, + ".sc": {"SuperCollider", "Scala"}, + ".scad": {"OpenSCAD"}, + ".scala": {"Scala"}, + ".scaml": {"Scaml"}, + ".scd": {"SuperCollider"}, + ".sce": {"Scilab"}, + ".sch": {"Eagle"}, + ".sci": {"Scilab"}, + ".scm": {"Scheme"}, + ".scpt": {"AppleScript"}, + ".scrbl": {"Racket"}, + ".scss": {"SCSS"}, + ".scxml": {"XML"}, + ".self": {"Self"}, + ".sh": {"Shell"}, + ".sh-session": {"ShellSession"}, + ".shader": {"GLSL"}, + ".shen": {"Shen"}, + ".sig": {"Standard ML"}, + ".sj": {"Objective-J"}, + ".sjs": {"JavaScript"}, + ".sl": {"Slash"}, + ".sld": {"Scheme"}, + ".slim": {"Slim"}, + ".sls": {"Scheme", "SaltStack"}, + ".sml": {"Standard ML"}, + ".sp": {"SourcePawn"}, + ".sparql": {"SPARQL"}, + ".spin": {"Propeller Spin"}, + ".sps": {"Scheme"}, + ".sqf": {"SQF"}, + ".sql": {"SQL"}, + ".srdf": {"XML"}, + ".ss": {"Scheme"}, + ".ssjs": {"JavaScript"}, + ".st": {"HTML", "Smalltalk"}, + ".sthlp": {"Stata"}, + ".ston": {"STON"}, + ".stTheme": {"XML"}, + ".sty": {"TeX"}, + ".styl": {"Stylus"}, + ".sublime-build": {"JavaScript"}, + ".sublime-commands": {"JavaScript"}, + ".sublime-completions": {"JavaScript"}, + ".sublime-keymap": {"JavaScript"}, + ".sublime-macro": {"JavaScript"}, + ".sublime-menu": {"JavaScript"}, + ".sublime-mousemap": {"JavaScript"}, + ".sublime-project": {"JavaScript"}, + ".sublime-settings": {"JavaScript"}, + ".sublime-snippet": {"XML"}, + ".sublime-theme": {"JavaScript"}, + ".sublime-workspace": {"JavaScript"}, + ".sublime_metrics": {"JavaScript"}, + ".sublime_session": {"JavaScript"}, + ".sv": {"SystemVerilog"}, + ".svg": {"XML"}, + ".svh": {"SystemVerilog"}, + ".swift": {"Swift"}, + ".t": {"Perl6", "Turing", "Perl"}, + ".tab": {"SQL"}, + ".tac": {"Python"}, + ".targets": {"XML"}, + ".tcc": {"C++"}, + ".tcl": {"Tcl"}, + ".tcsh": {"Tcsh"}, + ".tea": {"Tea"}, + ".tex": {"TeX"}, + ".textile": {"Textile"}, + ".thor": {"Ruby"}, + ".thrift": {"Thrift"}, + ".thy": {"Isabelle"}, + ".tm": {"Tcl"}, + ".tmCommand": {"XML"}, + ".tml": {"XML"}, + ".tmLanguage": {"XML"}, + ".tmPreferences": {"XML"}, + ".tmSnippet": {"XML"}, + ".tmTheme": {"XML"}, + ".tmux": {"Shell"}, + ".toc": {"TeX"}, + ".toml": {"TOML"}, + ".tpl": {"Smarty"}, + ".tpp": {"C++"}, + ".ts": {"XML", "TypeScript"}, + ".tst": {"Scilab", "GAP"}, + ".ttl": {"Turtle"}, + ".tu": {"Turing"}, + ".twig": {"Twig"}, + ".txl": {"TXL"}, + ".txt": {"Text"}, + ".uc": {"UnrealScript"}, + ".udf": {"SQL"}, + ".ui": {"XML"}, + ".upc": {"Unified Parallel C"}, + ".urdf": {"XML"}, + ".v": {"Verilog", "Coq"}, + ".vala": {"Vala"}, + ".vapi": {"Vala"}, + ".vark": {"Gosu"}, + ".vb": {"Visual Basic"}, + ".vba": {"Visual Basic"}, + ".vbhtml": {"Visual Basic"}, + ".vbproj": {"XML"}, + ".vbs": {"Visual Basic"}, + ".vcl": {"VCL"}, + ".vcxproj": {"XML"}, + ".veo": {"Verilog"}, + ".vert": {"GLSL"}, + ".vh": {"SystemVerilog"}, + ".vhd": {"VHDL"}, + ".vhdl": {"VHDL"}, + ".vhf": {"VHDL"}, + ".vhi": {"VHDL"}, + ".vho": {"VHDL"}, + ".vhs": {"VHDL"}, + ".vht": {"VHDL"}, + ".vhw": {"VHDL"}, + ".vim": {"VimL"}, + ".viw": {"SQL"}, + ".volt": {"Volt"}, + ".vrx": {"GLSL"}, + ".vshader": {"GLSL"}, + ".vxml": {"XML"}, + ".w": {"C"}, + ".watchr": {"Ruby"}, + ".webidl": {"WebIDL"}, + ".weechatlog": {"IRC log"}, + ".wisp": {"wisp"}, + ".wlua": {"Lua"}, + ".wsdl": {"XML"}, + ".wsf": {"XML"}, + ".wsgi": {"Python"}, + ".wxi": {"XML"}, + ".wxl": {"XML"}, + ".wxs": {"XML"}, + ".x": {"Logos"}, + ".x3d": {"XML"}, + ".xacro": {"XML"}, + ".xaml": {"XML"}, + ".xc": {"XC"}, + ".xht": {"HTML"}, + ".xhtml": {"HTML"}, + ".xi": {"Logos"}, + ".xlf": {"XML"}, + ".xliff": {"XML"}, + ".xm": {"Logos"}, + ".xmi": {"XML"}, + ".xml": {"XML"}, + ".xml.dist": {"XML"}, + ".xojo_code": {"Xojo"}, + ".xojo_menu": {"Xojo"}, + ".xojo_report": {"Xojo"}, + ".xojo_script": {"Xojo"}, + ".xojo_toolbar": {"Xojo"}, + ".xojo_window": {"Xojo"}, + ".xpl": {"XProc"}, + ".xproc": {"XProc"}, + ".xpy": {"Python"}, + ".xq": {"XQuery"}, + ".xql": {"XQuery"}, + ".xqm": {"XQuery"}, + ".xquery": {"XQuery"}, + ".xqy": {"XQuery"}, + ".xs": {"XS"}, + ".xsd": {"XML"}, + ".xsjs": {"JavaScript"}, + ".xsjslib": {"JavaScript"}, + ".xsl": {"XSLT"}, + ".xslt": {"XSLT"}, + ".xtend": {"Xtend"}, + ".xul": {"XML"}, + ".y": {"Bison"}, + ".yaml": {"YAML"}, + ".yml": {"YAML"}, + ".zcml": {"XML"}, + ".zep": {"Zephir"}, + ".zimpl": {"Zimpl"}, + ".zmpl": {"Zimpl"}, + ".zpl": {"Zimpl"}, + ".zsh": {"Shell"}, +} + +func init() { + ExtensionsByLanguage = reverseStringListMap(LanguagesByExtension) +} + +var ExtensionsByLanguage map[string][]string + +func GetLanguageExtensions(language string) []string { + return ExtensionsByLanguage[language] +} + +const OtherLanguage = "Other" + +func reverseStringListMap(input map[string][]string) (output map[string][]string) { + output = map[string][]string{} + for key, set := range input { + for _, value := range set { + output[value] = append(output[value], key) + } + } + return +} diff --git a/content.go b/content.go new file mode 100644 index 0000000..bb7fdd7 --- /dev/null +++ b/content.go @@ -0,0 +1,135 @@ +package slinguist + +import ( + "path/filepath" + + "gopkg.in/toqueteos/substring.v1" +) + +func GetLanguageByContent(filename string, content []byte) (lang string, safe bool) { + if fnMatcher, ok := matchers[filepath.Ext(filename)]; ok { + lang, safe = fnMatcher(content) + return + } + + return GetLanguageByExtension(filename) +} + +type langMatcher func([]byte) (string, bool) + +var matchers = map[string]langMatcher{ + ".cl": clExtLanguage, + ".cls": clsExtLanguage, + ".m": mExtLanguage, + ".h": hExtLanguage, + ".pl": plExtLanguage, +} + +var ( + cPlusPlusMatcher = substring.BytesOr( + substring.BytesRegexp(`^\s*template\s*<`), + substring.BytesRegexp(`^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>`), + substring.BytesRegexp(`^[ \t]*try`), + substring.BytesRegexp(`^[ \t]*(class|(using[ \t]+)?namespace)\s+\w+`), + substring.BytesRegexp(`^[ \t]*(private|public|protected):$`), + substring.BytesRegexp(`std::\w+`), + substring.BytesRegexp(`^[ \t]*catch\s*`), + ) +) + +func hExtLanguage(input []byte) (string, bool) { + if objectiveCMatcher.Match(input) { + return "Objective-C", true + } else if cPlusPlusMatcher.Match(input) { + return "C++", true + } + + return "C", true +} + +var ( + commonLispMatcher = substring.BytesRegexp("(?i)(defpackage|defun|in-package)") + coolMatcher = substring.BytesRegexp("(?i)class") + openCLMatcher = substring.BytesOr( + substring.BytesHas("\n}"), + substring.BytesHas("}\n"), + substring.BytesHas(`/*`), + substring.BytesHas(`//`), + ) +) + +func clExtLanguage(input []byte) (string, bool) { + if commonLispMatcher.Match(input) { + return "Common Lisp", true + } else if coolMatcher.Match(input) { + return "Cool", true + } else if openCLMatcher.Match(input) { + return "OpenCL", true + } + + return OtherLanguage, false +} + +var ( + apexMatcher = substring.BytesOr( + substring.BytesHas("{\n"), + substring.BytesHas("}\n"), + ) + texMatcher = substring.BytesOr( + substring.BytesHas(`%`), + substring.BytesHas(`\`), + ) + openEdgeABLMatcher = substring.BytesRegexp(`(?i)(class|define|interface|method|using)\b`) + visualBasicMatcher = substring.BytesOr( + substring.BytesHas("'*"), + substring.BytesRegexp(`(?i)(attribute|option|sub|private|protected|public|friend)\b`), + ) +) + +func clsExtLanguage(input []byte) (string, bool) { + if texMatcher.Match(input) { + return "TeX", true + } else if visualBasicMatcher.Match(input) { + return "Visual Basic", true + } else if openEdgeABLMatcher.Match(input) { + return "OpenEdge ABL", true + } else if apexMatcher.Match(input) { + return "Apex", true + } + + return OtherLanguage, false +} + +var ( + mathematicaMatcher = substring.BytesHas(`(*`) + matlabMatcher = substring.BytesRegexp(`\b(function\s*[\[a-zA-Z]+|classdef|figure|end|elseif)\b`) + objectiveCMatcher = substring.BytesRegexp( + `@(class|end|implementation|interface|property|protocol|selector|synchronised)`) +) + +func mExtLanguage(input []byte) (string, bool) { + if objectiveCMatcher.Match(input) { + return "Objective-C", true + } else if matlabMatcher.Match(input) { + return "Matlab", true + } else if mathematicaMatcher.Match(input) { + return "Mathematica", true + } + + return OtherLanguage, false +} + +var ( + prologMatcher = substring.BytesRegexp(`^[^#]+:-`) + perl6Matcher = substring.BytesRegexp(`^(use v6|(my )?class|module)`) +) + +func plExtLanguage(input []byte) (string, bool) { + if prologMatcher.Match(input) { + return "Prolog", true + } else if perl6Matcher.Match(input) { + return "Perl6", true + } + + return "Perl", false +} diff --git a/extension.go b/extension.go new file mode 100644 index 0000000..68aa33e --- /dev/null +++ b/extension.go @@ -0,0 +1,20 @@ +package slinguist + +import ( + "path/filepath" +) + +func GetLanguageByExtension(filename string) (lang string, safe bool) { + lang = OtherLanguage + langs, ok := LanguagesByExtension[filepath.Ext(filename)] + if !ok { + return + } + + lang = langs[0] + if len(langs) == 1 { + safe = true + } + + return +} diff --git a/files.go b/files.go new file mode 100644 index 0000000..369a1c8 --- /dev/null +++ b/files.go @@ -0,0 +1,286 @@ +package slinguist + +import ( + "bytes" + "path/filepath" + "strings" + + "gopkg.in/toqueteos/substring.v1" +) + +// From github/linguist. +// curl https://raw.githubusercontent.com/github/linguist/master/lib/linguist/vendor.yml | python -c 'import sys, yaml; l = yaml.load(sys.stdin.read()); print "var skipped = []*regexp.Regexp{\n" + "\n".join(["\tregexp.MustCompile(`" + i + "`)," for i in l]) + "\n}"' + +var vendorMatchers = substring.Or( + substring.Suffix(`.framer`), + substring.SuffixGroup(`.js`, + substring.After(`cordova-`, substring.Regexp(`\d\.\d(\.\d)?`)), + substring.After(`d3`, substring.Regexp(`(\.v\d+)?([^.]*)`)), + substring.After(`jquery-`, substring.Regexp(`\d\.\d+(\.\d+)?`)), + substring.After(`jquery-ui`, substring.Regexp(`(\-\d\.\d+(\.\d+)?)?(\.\w+)?`)), + substring.After(`knockout-`, substring.Regexp(`(\d+\.){3}(debug\.)?$`)), + substring.After(`microsoft`, substring.Regexp(`([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?`)), + substring.After(`Microsoft`, substring.Regexp(`([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?`)), + substring.After(`modernizr-`, substring.Regexp(`\d\.\d+(\.\d+)?`)), + substring.After(`mootools`, substring.Regexp(`([^.]*)\d+\.\d+.\d+([^.]*)`)), + substring.Has(`angular`), + substring.Has(`bootstrap`), + substring.Has(`cordova`), + substring.Has(`less`), + substring.Has(`custom.bootstrap`), + substring.Has(`extjs/`), + substring.Has(`foundation`), + substring.Has(`jquery.effects.`), + substring.Has(`jquery.ui.`), + substring.Has(`jquery`), + substring.Has(`modernizr.custom.`), + substring.Has(`prototype`), + substring.Has(`backbone`), + substring.Has(`three`), + substring.Has(`ember`), + substring.Has(`babylon`), + substring.Has(`react`), + substring.Has(`shBrush`), + substring.Has(`tiny_mce`), + substring.Has(`yahoo-`), + substring.Has(`html5-`), + substring.Has(`yui`), + substring.Has(`underscore`), + substring.Has(`lodash`), + substring.Has(`lodash.core`), + substring.Has(`coffee-script`), + substring.Suffixes( + `-vsdoc.js`, + `.intellisense.js`, + `Chart.js`, + `ckeditor.js`, + `controls.js`, + `dojo.js`, + `dragdrop.js`, + `effects.js`, + `html5shiv.js`, + `MochiKit.js`, + `shCore.js`, + `shLegacy.js`, + `.min.js`, + `-min.js`, + ), + ), + substring.SuffixGroup(`.css`, + substring.Has(`bootstrap`), + substring.Has(`custom.bootstrap`), + substring.Has(`jquery.effects.`), + substring.Has(`jquery.ui.`), + substring.Has(`octicons.css`), + substring.After(`jquery-ui`, substring.Regexp(`(\-\d\.\d+(\.\d+)?)?(\.\w+)?`)), + substring.Suffixes( + `animate.css`, + `bourbon.css`, + `Bourbon.css`, + `font-awesome.css`, + `foundation.css`, + `import.css`, + `normalize.css`, + `.min.css`, + `-min.css`, + ), + ), + substring.SuffixGroup(`.scss`, + substring.Has(`bootstrap`), + substring.Has(`custom.bootstrap`), + substring.Has(`sprockets-octicons.scss`), + substring.Suffixes( + `animate.scss`, + `bourbon.scss`, + `Bourbon.scss`, + `font-awesome.scss`, + `foundation.scss`, + `import.scss`, + `normalize.scss`, + ), + ), + substring.SuffixGroup(`.less`, + substring.Has(`bootstrap`), + substring.Has(`custom.bootstrap`), + substring.Suffixes( + `animate.less`, + `bourbon.less`, + `Bourbon.less`, + `font-awesome.less`, + `foundation.less`, + `import.less`, + `normalize.less`, + ), + ), + substring.SuffixGroup(`.styl`, + substring.Has(`bootstrap`), + substring.Has(`custom.bootstrap`), + substring.Suffixes( + `animate.styl`, + `bourbon.styl`, + `Bourbon.styl`, + `font-awesome.styl`, + `foundation.styl`, + `import.styl`, + `normalize.styl`, + ), + ), + substring.After(`codemirror/`, substring.Or( + substring.Exact(`lib`), + substring.Exact(`mode`), + substring.Exact(`theme`), + substring.Exact(`addon`), + substring.Exact(`keymap`), + )), + substring.After(`extjs/`, substring.Or( + substring.Suffixes(`.html`, `.properties`, `.txt`, `.xml`), + substring.Exact(`.sencha/`), + substring.Exact(`builds/`), + substring.Exact(`cmd/`), + substring.Exact(`docs/`), + substring.Exact(`examples/`), + substring.Exact(`locale/`), + substring.Exact(`packages/`), + substring.Exact(`plugins/`), + substring.Exact(`resources/`), + substring.Exact(`src/`), + substring.Exact(`welcome/`), + )), + substring.After(`tiny_mce/`, substring.Or( + substring.Exact(`langs`), + substring.Exact(`plugins`), + substring.Exact(`themes`), + substring.Exact(`utils`), + )), + substring.Has(`3rd-party/`), + substring.Has(`3rd_party/`), + substring.Has(`3rdparty/`), + substring.Has(`admin_media/`), + substring.Has(`bower_components/`), + substring.Has(`cache/`), + substring.Has(`Dependencies/`), + substring.Has(`dependencies/`), + substring.Has(`erlang.mk`), + substring.Has(`extern/`), + substring.Has(`external/`), + substring.Has(`Godeps/_workspace/`), + substring.Has(`gradle/wrapper/`), + substring.Has(`MathJax/`), + substring.Has(`node_modules/`), + substring.Has(`proguard-rules.pro`), + substring.Has(`proguard.pro`), + substring.Has(`Sparkle/`), + substring.Has(`third-party/`), + substring.Has(`third_party/`), + substring.Has(`thirdparty/`), + substring.Has(`vendor/`), + substring.Has(`vendors/`), + substring.Exact(`.osx`), + substring.Exact(`rebar`), + substring.Exact(`Vagrantfile`), + substring.Exact(`waf`), + substring.Prefixes( + `.google_apis/`, + `debian/`, + `deps/`, + `inst/extdata/`, + `packages/`, + `Packages/`, + `Pods/`, + `Samples/`, + `samples/`, + `Test/fixture/`, + `test/fixture/`, + `Test/fixtures/`, + `test/fixtures/`, + `tools/`, + `vignettes/`, + ), + substring.Suffixes( + `.d.ts`, + `.travis.yml`, + `activator.bat`, + `activator`, + `circle.yml`, + `config.guess`, + `config.sub`, + `configure.ac`, + `configure`, + `fabfile.py`, + `gitattributes`, + `gitignore`, + `gitmodules`, + `gradlew.bat`, + `gradlew`, + `run.n`, + `.DS_Store`, + `.DS_store`, + `.dS_Store`, + `.dS_store`, + `.Ds_Store`, + `.Ds_store`, + `.ds_Store`, + `.ds_store`, + ), +) + +var documentationMatchers = substring.Or( + substring.Regexp(`^docs?/`), + substring.Regexp(`(^|/)[Dd]ocumentation/`), + substring.Regexp(`(^|/)javadoc/`), + substring.Regexp(`^man/`), + substring.Regexp(`^[Ee]xamples/`), + substring.Regexp(`(^|/)CHANGE(S|LOG)?(\.|$)`), + substring.Regexp(`(^|/)CONTRIBUTING(\.|$)`), + substring.Regexp(`(^|/)COPYING(\.|$)`), + substring.Regexp(`(^|/)INSTALL(\.|$)`), + substring.Regexp(`(^|/)LICEN[CS]E(\.|$)`), + substring.Regexp(`(^|/)[Ll]icen[cs]e(\.|$)`), + substring.Regexp(`(^|/)README(\.|$)`), + substring.Regexp(`(^|/)[Rr]eadme(\.|$)`), + substring.Regexp(`^[Ss]amples/`), +) + +var configurationLanguages = []string{ + "XML", "JSON", "TOML", "YAML", "INI", "SQL", +} + +func VendorIndex(path string) int { + return findIndex(path, vendorMatchers) +} + +func DocumentationIndex(path string) int { + return findIndex(path, documentationMatchers) +} + +func findIndex(path string, matchers substring.StringsMatcher) int { + return matchers.MatchIndex(path) +} + +func IsVendor(path string) bool { + return VendorIndex(path) >= 0 +} + +func IsDotFile(path string) bool { + return strings.HasPrefix(filepath.Base(path), ".") +} + +func IsDocumentation(path string) bool { + return DocumentationIndex(path) >= 0 +} + +const sniffLen = 8000 + +//IsBinary detects if data is a binary value based on: +//http://git.kernel.org/cgit/git/git.git/tree/xdiff-interface.c?id=HEAD#n198 +func IsBinary(data []byte) bool { + if len(data) > sniffLen { + data = data[:sniffLen] + } + + if bytes.IndexByte(data, byte(0)) == -1 { + return false + } + + return true +} diff --git a/files_test.go b/files_test.go new file mode 100644 index 0000000..1dc4406 --- /dev/null +++ b/files_test.go @@ -0,0 +1,205 @@ +package slinguist + +import ( + "bytes" + "regexp" + + . "gopkg.in/check.v1" +) + +func (s *UtilsSuite) TestIsVendor(c *C) { + c.Assert(IsVendor("foo/bar"), Equals, false) + c.Assert(IsVendor("foo/vendor/foo"), Equals, true) + c.Assert(IsVendor(".travis.yml"), Equals, true) + c.Assert(IsVendor("foo.framer"), Equals, true) + c.Assert(IsVendor("foo/bar/coffee-script.js"), Equals, true) + c.Assert(IsVendor("foo/bar/less.js"), Equals, true) + c.Assert(IsVendor("foo/bar/underscore.js"), Equals, true) + c.Assert(IsVendor("foo/bar/lodash.js"), Equals, true) + c.Assert(IsVendor("foo/bar/lodash.js"), Equals, true) + c.Assert(IsVendor("foo/bar/lodash.core.js"), Equals, true) + c.Assert(IsVendor("foo/bar/backbone.js"), Equals, true) + c.Assert(IsVendor("foo/bar/ember.js"), Equals, true) + c.Assert(IsVendor("foo/bar/ember.debug.js"), Equals, true) + c.Assert(IsVendor("foo/bar/ember.prod.js"), Equals, true) + c.Assert(IsVendor("foo/bar/three.js"), Equals, true) + c.Assert(IsVendor("foo/bar/babylon.js"), Equals, true) + c.Assert(IsVendor("foo/bar/babylon.2.3.js"), Equals, true) + c.Assert(IsVendor("foo/bar/babylon.2.3.core.js"), Equals, true) + c.Assert(IsVendor("foo/bar/babylon.2.3.max.js"), Equals, true) + c.Assert(IsVendor("foo/bar/babylon.2.3.noworker.js"), Equals, true) + c.Assert(IsVendor("foo/bar/html5-3.6-respond-1.4.2.js"), Equals, true) +} + +func (s *UtilsSuite) TestIsDocumentation(c *C) { + c.Assert(IsDocumentation("foo"), Equals, false) + c.Assert(IsDocumentation("README"), Equals, true) +} + +func (s *UtilsSuite) TestIsConfiguration(c *C) { + c.Assert(IsConfiguration("foo"), Equals, false) + c.Assert(IsConfiguration("foo.ini"), Equals, true) + c.Assert(IsConfiguration("foo.json"), Equals, true) +} + +func (s *UtilsSuite) TestIsBinary(c *C) { + c.Assert(IsBinary([]byte("foo")), Equals, false) + + binary := []byte{0} + c.Assert(IsBinary(binary), Equals, true) + + binary = bytes.Repeat([]byte{'o'}, 8000) + binary = append(binary, byte(0)) + c.Assert(IsBinary(binary), Equals, false) +} + +const ( + htmlPath = "some/random/dir/file.html" + jsPath = "some/random/dir/file.js" +) + +func (s *UtilsSuite) BenchmarkVendor(c *C) { + for i := 0; i < c.N; i++ { + _ = IsVendor(htmlPath) + } +} + +func (s *UtilsSuite) BenchmarkVendorJS(c *C) { + for i := 0; i < c.N; i++ { + _ = IsVendor(jsPath) + } +} + +var vendorRegexp = []*regexp.Regexp{ + regexp.MustCompile(`(^|/)cache/`), + regexp.MustCompile(`^[Dd]ependencies/`), + regexp.MustCompile(`^deps/`), + regexp.MustCompile(`^tools/`), + regexp.MustCompile(`(^|/)configure$`), + regexp.MustCompile(`(^|/)configure.ac$`), + regexp.MustCompile(`(^|/)config.guess$`), + regexp.MustCompile(`(^|/)config.sub$`), + regexp.MustCompile(`node_modules/`), + regexp.MustCompile(`bower_components/`), + regexp.MustCompile(`^rebar$`), + regexp.MustCompile(`erlang.mk`), + regexp.MustCompile(`Godeps/_workspace/`), + regexp.MustCompile(`(\.|-)min\.(js|css)$`), + regexp.MustCompile(`([^\s]*)import\.(css|less|scss|styl)$`), + regexp.MustCompile(`(^|/)bootstrap([^.]*)\.(js|css|less|scss|styl)$`), + regexp.MustCompile(`(^|/)custom\.bootstrap([^\s]*)(js|css|less|scss|styl)$`), + regexp.MustCompile(`(^|/)font-awesome\.(css|less|scss|styl)$`), + regexp.MustCompile(`(^|/)foundation\.(css|less|scss|styl)$`), + regexp.MustCompile(`(^|/)normalize\.(css|less|scss|styl)$`), + regexp.MustCompile(`(^|/)[Bb]ourbon/.*\.(css|less|scss|styl)$`), + regexp.MustCompile(`(^|/)animate\.(css|less|scss|styl)$`), + regexp.MustCompile(`third[-_]?party/`), + regexp.MustCompile(`3rd[-_]?party/`), + regexp.MustCompile(`vendors?/`), + regexp.MustCompile(`extern(al)?/`), + regexp.MustCompile(`^debian/`), + regexp.MustCompile(`run.n$`), + regexp.MustCompile(`(^|/)jquery([^.]*)\.js$`), + regexp.MustCompile(`(^|/)jquery\-\d\.\d+(\.\d+)?\.js$`), + regexp.MustCompile(`(^|/)jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?\.(js|css)$`), + regexp.MustCompile(`(^|/)jquery\.(ui|effects)\.([^.]*)\.(js|css)$`), + regexp.MustCompile(`(^|/)prototype(.*)\.js$`), + regexp.MustCompile(`(^|/)effects\.js$`), + regexp.MustCompile(`(^|/)controls\.js$`), + regexp.MustCompile(`(^|/)dragdrop\.js$`), + regexp.MustCompile(`(.*?)\.d\.ts$`), + regexp.MustCompile(`(^|/)mootools([^.]*)\d+\.\d+.\d+([^.]*)\.js$`), + regexp.MustCompile(`(^|/)dojo\.js$`), + regexp.MustCompile(`(^|/)MochiKit\.js$`), + regexp.MustCompile(`(^|/)yahoo-([^.]*)\.js$`), + regexp.MustCompile(`(^|/)yui([^.]*)\.js$`), + regexp.MustCompile(`(^|/)ckeditor\.js$`), + regexp.MustCompile(`(^|/)tiny_mce([^.]*)\.js$`), + regexp.MustCompile(`(^|/)tiny_mce/(langs|plugins|themes|utils)`), + regexp.MustCompile(`(^|/)MathJax/`), + regexp.MustCompile(`(^|/)Chart\.js$`), + regexp.MustCompile(`(^|/)[Cc]ode[Mm]irror/(lib|mode|theme|addon|keymap)`), + regexp.MustCompile(`(^|/)shBrush([^.]*)\.js$`), + regexp.MustCompile(`(^|/)shCore\.js$`), + regexp.MustCompile(`(^|/)shLegacy\.js$`), + regexp.MustCompile(`(^|/)angular([^.]*)\.js$`), + regexp.MustCompile(`(^|\/)d3(\.v\d+)?([^.]*)\.js$`), + regexp.MustCompile(`(^|/)react(-[^.]*)?\.js$`), + regexp.MustCompile(`(^|/)modernizr\-\d\.\d+(\.\d+)?\.js$`), + regexp.MustCompile(`(^|/)modernizr\.custom\.\d+\.js$`), + regexp.MustCompile(`(^|/)knockout-(\d+\.){3}(debug\.)?js$`), + regexp.MustCompile(`(^|/)admin_media/`), + regexp.MustCompile(`^fabfile\.py$`), + regexp.MustCompile(`^waf$`), + regexp.MustCompile(`^.osx$`), + regexp.MustCompile(`^Pods/`), + regexp.MustCompile(`(^|/)Sparkle/`), + regexp.MustCompile(`(^|/)gradlew$`), + regexp.MustCompile(`(^|/)gradlew\.bat$`), + regexp.MustCompile(`(^|/)gradle/wrapper/`), + regexp.MustCompile(`-vsdoc\.js$`), + regexp.MustCompile(`\.intellisense\.js$`), + regexp.MustCompile(`(^|/)jquery([^.]*)\.validate(\.unobtrusive)?\.js$`), + regexp.MustCompile(`(^|/)jquery([^.]*)\.unobtrusive\-ajax\.js$`), + regexp.MustCompile(`(^|/)[Mm]icrosoft([Mm]vc)?([Aa]jax|[Vv]alidation)(\.debug)?\.js$`), + regexp.MustCompile(`^[Pp]ackages\/.+\.\d+\/`), + regexp.MustCompile(`(^|/)extjs/.*?\.js$`), + regexp.MustCompile(`(^|/)extjs/.*?\.xml$`), + regexp.MustCompile(`(^|/)extjs/.*?\.txt$`), + regexp.MustCompile(`(^|/)extjs/.*?\.html$`), + regexp.MustCompile(`(^|/)extjs/.*?\.properties$`), + regexp.MustCompile(`(^|/)extjs/.sencha/`), + regexp.MustCompile(`(^|/)extjs/docs/`), + regexp.MustCompile(`(^|/)extjs/builds/`), + regexp.MustCompile(`(^|/)extjs/cmd/`), + regexp.MustCompile(`(^|/)extjs/examples/`), + regexp.MustCompile(`(^|/)extjs/locale/`), + regexp.MustCompile(`(^|/)extjs/packages/`), + regexp.MustCompile(`(^|/)extjs/plugins/`), + regexp.MustCompile(`(^|/)extjs/resources/`), + regexp.MustCompile(`(^|/)extjs/src/`), + regexp.MustCompile(`(^|/)extjs/welcome/`), + regexp.MustCompile(`(^|/)html5shiv\.js$`), + regexp.MustCompile(`^[Ss]amples/`), + regexp.MustCompile(`^[Tt]est/fixtures/`), + regexp.MustCompile(`(^|/)cordova([^.]*)\.js$`), + regexp.MustCompile(`(^|/)cordova\-\d\.\d(\.\d)?\.js$`), + regexp.MustCompile(`foundation(\..*)?\.js$`), + regexp.MustCompile(`^Vagrantfile$`), + regexp.MustCompile(`.[Dd][Ss]_[Ss]tore$`), + regexp.MustCompile(`^vignettes/`), + regexp.MustCompile(`^inst/extdata/`), + regexp.MustCompile(`octicons.css`), + regexp.MustCompile(`sprockets-octicons.scss`), + regexp.MustCompile(`(^|/)activator$`), + regexp.MustCompile(`(^|/)activator\.bat$`), + regexp.MustCompile(`proguard.pro`), + regexp.MustCompile(`proguard-rules.pro`), + regexp.MustCompile(`gitattributes$`), + regexp.MustCompile(`gitignore$`), + regexp.MustCompile(`gitmodules$`), + regexp.MustCompile(`.travis.yml$`), + regexp.MustCompile(`circle.yml$`), +} + +func isVendorRegexp(s string) bool { + for _, re := range vendorRegexp { + found := re.FindStringIndex(s) + if found != nil { + return found[1] >= 0 + } + } + return false +} + +func (s *UtilsSuite) BenchmarkVendorRegexp(c *C) { + for i := 0; i < c.N; i++ { + _ = isVendorRegexp(htmlPath) + } +} + +func (s *UtilsSuite) BenchmarkVendorRegexpJS(c *C) { + for i := 0; i < c.N; i++ { + _ = isVendorRegexp(htmlPath) + } +}