diff --git a/lib/linguist/blob.rb b/lib/linguist/blob.rb index d472381f..88d9ffb6 100644 --- a/lib/linguist/blob.rb +++ b/lib/linguist/blob.rb @@ -1,3 +1,4 @@ +require 'linguist/language' require 'linguist/mime' require 'linguist/pathname' @@ -77,5 +78,65 @@ module Linguist def viewable? !file? && !large? end + + def language + if text? + shebang_language || name.language + else + Language['Text'] + end + end + + def lexer + language.lexer + end + + def shebang_script + return if !text? || large? + + if (match = data.match(/(.+)\n?/)) && (bang = match[0]) =~ /^#!/ + bang.sub!(/^#! /, '#!') + tokens = bang.split(' ') + pieces = tokens.first.split('/') + if pieces.size > 1 + script = pieces.last + else + script = pieces.first.sub('#!', '') + end + + script = script == 'env' ? tokens[1] : script + + # python2.4 => python + if script =~ /((?:\d+\.?)+)/ + script.sub! $1, '' + end + + script + end + end + + def shebang_language + if script = shebang_script + case script + when 'bash' + Language['Shell'] + when 'groovy' + Language['Java'] + when 'macruby' + Language['Ruby'] + when 'node' + Language['JavaScript'] + when 'rake' + Language['Ruby'] + when 'sh' + Language['Shell'] + when 'zsh' + Language['Shell'] + else + lang = Language.find_by_lexer(shebang_script) + lang != Language['Text'] ? lang : nil + end + end + end end end diff --git a/test/fixtures/blob/Capfile b/test/fixtures/blob/Capfile new file mode 100644 index 00000000..96291a7f --- /dev/null +++ b/test/fixtures/blob/Capfile @@ -0,0 +1,3 @@ +load 'deploy' +Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) } +load 'config/deploy' diff --git a/test/fixtures/blob/README b/test/fixtures/blob/README new file mode 100644 index 00000000..082a4aac --- /dev/null +++ b/test/fixtures/blob/README @@ -0,0 +1,2 @@ +README +====== diff --git a/test/fixtures/blob/Rakefile b/test/fixtures/blob/Rakefile new file mode 100644 index 00000000..9d51ff7c --- /dev/null +++ b/test/fixtures/blob/Rakefile @@ -0,0 +1,3 @@ +task :default do + puts "Rake" +end diff --git a/test/fixtures/blob/dude-thing-okay--001.patch b/test/fixtures/blob/dude-thing-okay--001.patch new file mode 100644 index 00000000..d3dbba1d --- /dev/null +++ b/test/fixtures/blob/dude-thing-okay--001.patch @@ -0,0 +1,4 @@ +diff --git a/lib/linguist.rb b/lib/linguist.rb +index d472341..8ad9ffb 100644 +--- a/lib/linguist.rb ++++ b/lib/linguist.rb diff --git a/test/fixtures/blob/dude.el b/test/fixtures/blob/dude.el new file mode 100644 index 00000000..70c61171 --- /dev/null +++ b/test/fixtures/blob/dude.el @@ -0,0 +1 @@ +(print "Dude!") diff --git a/test/fixtures/blob/dude.js b/test/fixtures/blob/dude.js new file mode 100644 index 00000000..89ac059b --- /dev/null +++ b/test/fixtures/blob/dude.js @@ -0,0 +1 @@ +alert("dude!") diff --git a/test/fixtures/blob/grit.rb b/test/fixtures/blob/grit.rb new file mode 100644 index 00000000..fc847530 --- /dev/null +++ b/test/fixtures/blob/grit.rb @@ -0,0 +1,2 @@ +module Grit +end diff --git a/test/fixtures/blob/script.bash b/test/fixtures/blob/script.bash new file mode 100644 index 00000000..0c2172c2 --- /dev/null +++ b/test/fixtures/blob/script.bash @@ -0,0 +1,2 @@ +#!/bin/bash +echo "bash" diff --git a/test/fixtures/blob/script.foo b/test/fixtures/blob/script.foo new file mode 100644 index 00000000..f94d7407 --- /dev/null +++ b/test/fixtures/blob/script.foo @@ -0,0 +1,2 @@ +#!/bin/foo +??? diff --git a/test/fixtures/blob/script.groovy b/test/fixtures/blob/script.groovy new file mode 100644 index 00000000..1ee357a7 --- /dev/null +++ b/test/fixtures/blob/script.groovy @@ -0,0 +1,2 @@ +#!/usr/bin/env groovy +println "Groovy!" diff --git a/test/fixtures/blob/script.js b/test/fixtures/blob/script.js new file mode 100644 index 00000000..a399ce3f --- /dev/null +++ b/test/fixtures/blob/script.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +console.log("Node") diff --git a/test/fixtures/blob/script.mrb b/test/fixtures/blob/script.mrb new file mode 100644 index 00000000..491be11e --- /dev/null +++ b/test/fixtures/blob/script.mrb @@ -0,0 +1,2 @@ +#!/usr/bin/env macruby +puts "MacRuby" diff --git a/test/fixtures/blob/script.pl b/test/fixtures/blob/script.pl new file mode 100644 index 00000000..bb20fbc2 --- /dev/null +++ b/test/fixtures/blob/script.pl @@ -0,0 +1,2 @@ +#!/usr/local/bin/perl +print "Perl\n" diff --git a/test/fixtures/blob/script.py b/test/fixtures/blob/script.py new file mode 100644 index 00000000..bcebcd48 --- /dev/null +++ b/test/fixtures/blob/script.py @@ -0,0 +1,2 @@ +#!/usr/bin/env python2.4 +print "Python" diff --git a/test/fixtures/blob/script.rake b/test/fixtures/blob/script.rake new file mode 100644 index 00000000..96992aa6 --- /dev/null +++ b/test/fixtures/blob/script.rake @@ -0,0 +1,4 @@ +#!/usr/bin/env rake +task :default do + puts "Rake" +end diff --git a/test/fixtures/blob/script.rb b/test/fixtures/blob/script.rb new file mode 100644 index 00000000..01a30f8a --- /dev/null +++ b/test/fixtures/blob/script.rb @@ -0,0 +1,2 @@ +#!/usr/bin/env ruby +puts "Ruby" diff --git a/test/fixtures/blob/script.sh b/test/fixtures/blob/script.sh new file mode 100644 index 00000000..e5ed467e --- /dev/null +++ b/test/fixtures/blob/script.sh @@ -0,0 +1,2 @@ +#!/bin/sh +echo "sh" diff --git a/test/fixtures/blob/script.zsh b/test/fixtures/blob/script.zsh new file mode 100644 index 00000000..ed274ab4 --- /dev/null +++ b/test/fixtures/blob/script.zsh @@ -0,0 +1,2 @@ +#!/bin/zsh +echo "zsh" diff --git a/test/fixtures/blob/script2.rb b/test/fixtures/blob/script2.rb new file mode 100644 index 00000000..40aeb7cb --- /dev/null +++ b/test/fixtures/blob/script2.rb @@ -0,0 +1,2 @@ +#! /usr/bin/env ruby -w -Ilib:test +echo "Ruby" diff --git a/test/fixtures/blob/subdir/Rakefile b/test/fixtures/blob/subdir/Rakefile new file mode 100644 index 00000000..885ab4ab --- /dev/null +++ b/test/fixtures/blob/subdir/Rakefile @@ -0,0 +1,3 @@ +task :default do + puts "Rake (subdir)" +end diff --git a/test/test_blob.rb b/test/test_blob.rb index 747e886c..1b3ed47e 100644 --- a/test/test_blob.rb +++ b/test/test_blob.rb @@ -92,4 +92,53 @@ class TestBlob < Test::Unit::TestCase assert blob("octocat.gif").image? assert !blob("octocat.psd").image? end + + def test_language + assert_equal Language['Ruby'], blob("foo.rb").language + assert_equal Language['Ruby'], blob("script.rb").language + assert_equal Language['Text'], blob("octocat.png").language + end + + def test_lexer + assert_equal 'ruby', blob("grit.rb").lexer + assert_equal 'text', blob("README").lexer + assert_equal 'diff', blob("dude-thing-okay--001.patch").lexer + assert_equal 'scheme', blob("dude.el").lexer + assert_equal 'javascript', blob("dude.js").lexer + assert_equal 'ruby', blob("Capfile").lexer + + assert_equal 'ruby', blob("Rakefile").lexer + assert_equal 'ruby', blob("subdir/Rakefile").lexer + end + + def test_shebang_script + assert_equal 'sh', blob("script.sh").shebang_script + assert_equal 'bash', blob("script.bash").shebang_script + assert_equal 'zsh', blob("script.zsh").shebang_script + assert_equal 'perl', blob("script.pl").shebang_script + assert_equal 'ruby', blob("script.rb").shebang_script + assert_equal 'ruby', blob("script2.rb").shebang_script + assert_equal 'python', blob("script.py").shebang_script + assert_equal 'node', blob("script.js").shebang_script + assert_equal 'groovy', blob("script.groovy").shebang_script + assert_equal 'macruby', blob("script.mrb").shebang_script + assert_equal 'rake', blob("script.rake").shebang_script + assert_equal 'foo', blob("script.foo").shebang_script + assert_equal nil, blob("foo.rb").shebang_script + end + + def test_shebang_language + assert_equal Language['Shell'], blob("script.sh").shebang_language + assert_equal Language['Shell'], blob("script.bash").shebang_language + assert_equal Language['Shell'], blob("script.zsh").shebang_language + assert_equal Language['Perl'], blob("script.pl").shebang_language + assert_equal Language['Ruby'], blob("script.rb").shebang_language + assert_equal Language['Python'], blob("script.py").shebang_language + assert_equal Language['JavaScript'], blob("script.js").shebang_language + assert_equal Language['Java'], blob("script.groovy").shebang_language + assert_equal Language['Ruby'], blob("script.mrb").shebang_language + assert_equal Language['Ruby'], blob("script.rake").shebang_language + assert_equal nil, blob("script.foo").shebang_language + assert_equal nil, blob("foo.rb").shebang_language + end end