diff --git a/lib/linguist.rb b/lib/linguist.rb index 544bb250..c6733a67 100644 --- a/lib/linguist.rb +++ b/lib/linguist.rb @@ -59,8 +59,9 @@ class << Linguist # Strategies are called in turn until a single Language is returned. STRATEGIES = [ Linguist::Strategy::Modeline, - Linguist::Shebang, Linguist::Strategy::Filename, + Linguist::Shebang, + Linguist::Strategy::Extension, Linguist::Heuristics, Linguist::Classifier ] diff --git a/lib/linguist/language.rb b/lib/linguist/language.rb index 3e698b01..6874a511 100644 --- a/lib/linguist/language.rb +++ b/lib/linguist/language.rb @@ -11,6 +11,7 @@ require 'linguist/samples' require 'linguist/file_blob' require 'linguist/blob_helper' require 'linguist/strategy/filename' +require 'linguist/strategy/extension' require 'linguist/strategy/modeline' require 'linguist/shebang' @@ -129,41 +130,46 @@ module Linguist # Public: Look up Languages by filename. # + # The behaviour of this method recently changed. + # See the second example below. + # # filename - The path String. # # Examples # + # Language.find_by_filename('Cakefile') + # # => [#] # Language.find_by_filename('foo.rb') - # # => [#] + # # => [] # # Returns all matching Languages or [] if none were found. def self.find_by_filename(filename) basename = File.basename(filename) - - # find the first extension with language definitions - extname = FileBlob.new(filename).extensions.detect do |e| - !@extension_index[e].empty? - end - - (@filename_index[basename] + @extension_index[extname]).compact.uniq + @filename_index[basename] end # Public: Look up Languages by file extension. # - # extname - The extension String. + # The behaviour of this method recently changed. + # See the second example below. + # + # filename - The path String. # # Examples # - # Language.find_by_extension('.rb') + # Language.find_by_extension('dummy.rb') # # => [#] - # # Language.find_by_extension('rb') - # # => [#] + # # => [] # # Returns all matching Languages or [] if none were found. - def self.find_by_extension(extname) - extname = ".#{extname}" unless extname.start_with?(".") - @extension_index[extname.downcase] + def self.find_by_extension(filename) + # find the first extension with language definitions + extname = FileBlob.new(filename.downcase).extensions.detect do |e| + !@extension_index[e].empty? + end + + @extension_index[extname] end # Public: Look up Languages by interpreter. diff --git a/lib/linguist/strategy/extension.rb b/lib/linguist/strategy/extension.rb new file mode 100644 index 00000000..161dc34c --- /dev/null +++ b/lib/linguist/strategy/extension.rb @@ -0,0 +1,10 @@ +module Linguist + module Strategy + # Detects language based on extension + class Extension + def self.call(blob, _) + Language.find_by_extension(blob.name.to_s) + end + end + end +end diff --git a/lib/linguist/strategy/filename.rb b/lib/linguist/strategy/filename.rb index b8c819eb..f3656515 100644 --- a/lib/linguist/strategy/filename.rb +++ b/lib/linguist/strategy/filename.rb @@ -1,9 +1,10 @@ module Linguist module Strategy - # Detects language based on filename and/or extension + # Detects language based on filename class Filename def self.call(blob, _) - Language.find_by_filename(blob.name.to_s) + name = blob.name.to_s + Language.find_by_filename(name) end end end diff --git a/test/fixtures/CMake/CMakeLists.txt b/test/fixtures/CMake/CMakeLists.txt new file mode 100644 index 00000000..41effdc3 --- /dev/null +++ b/test/fixtures/CMake/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 2.8 FATAL_ERROR) + +project("To do list") + +enable_testing() + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(warnings "-Wall -Wextra -Werror") +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(warnings "/W4 /WX /EHsc") +endif() + +set(optimize "-O2") + +if (NOT CONFIGURED_ONCE) + set(CMAKE_CXX_FLAGS "${warnings} ${optimize}" + CACHE STRING "Flags used by the compiler during all build types." FORCE) + set(CMAKE_C_FLAGS "${warnings} ${optimize}" + CACHE STRING "Flags used by the compiler during all build types." FORCE) +endif() + + +add_executable(toDo main.cpp ToDo.cpp) + +add_test(toDoTest toDo) + +set(CONFIGURED_ONCE TRUE CACHE INTERNAL + "A flag showing that CMake has configured at least once.") \ No newline at end of file diff --git a/test/fixtures/CoffeeScript/Cakefile b/test/fixtures/CoffeeScript/Cakefile new file mode 100755 index 00000000..05dddf54 --- /dev/null +++ b/test/fixtures/CoffeeScript/Cakefile @@ -0,0 +1,200 @@ +http = require 'http' +https = require 'https' +fs = require 'fs' +path = require 'path' +{spawn, exec} = require 'child_process' +semver = require 'semver' +AdmZip = require('adm-zip') +GitHubApi = require 'github' + +github = new GitHubApi(version: '3.0.0') + +# ---------------- +# Server / Builder +# ---------------- + +option '-P', '--production', 'run server in production mode' +option null, '--port [PORT]', 'listen on specified port (default 3333)' + +LOCAL_BRUNCH = path.join('.', 'node_modules', '.bin', 'brunch') + +spawnBrunch = (flags, env) -> + if fs.existsSync(LOCAL_BRUNCH) + brunch = spawn LOCAL_BRUNCH, flags, env + else + console.error 'Warning, using global brunch. Run `npm install`.' + brunch = spawn 'brunch', flags, env + + brunch.stdout.on 'data', (data) -> console.log data.toString().trim() + brunch.stderr.on 'data', (data) -> console.log data.toString().trim() + +runBrunchWatch = (options, shouldStartServer) -> + flags = ['w'] + flags.push '-s' if shouldStartServer + + if options.production? + flags.push('-P') + process.env.BRUNCH_ENV = 'production' + + if options.port? + flags.push '-p' + flags.push options.port + + spawnBrunch flags, process.env + +task 'server', 'start the brunch server in development', (options) -> + runBrunchWatch(options, true) + +task 'watch', 'build the app continuously without a server', (options) -> + runBrunchWatch(options, false) + +task 'build', 'build for production', -> + process.env.BRUNCH_ENV = 'production' + spawnBrunch ['b', '-P'], process.env + +task 'test', 'run brunch in the test environment', -> + flags = ['w', '-s'] + process.env.BRUNCH_ENV = 'test' + spawnBrunch flags, process.env + +# ------------- +# Tapas Updates +# ------------- +updateMessage = 'update Tapas to latest (Cakefile, package.json, portkey.json, + config.coffee, generators/*)' +task 'tapas:update', updateMessage, (options) -> + url = 'https://codeload.github.com/mutewinter/tapas-with-ember/zip/master' + filesToUpdate = [ + 'Cakefile' + 'package.json' + 'portkey.json' + 'config.coffee' + 'generators/' + 'testem.json' + 'bower.json' + ] + https.get url, (res) -> + data = [] + dataLen = 0 + + res.on('data', (chunk) -> + data.push(chunk) + dataLen += chunk.length + ).on('end', -> + buf = new Buffer(dataLen) + + pos = 0 + for dataItem in data + dataItem.copy(buf, pos) + pos += dataItem.length + + zip = new AdmZip(buf) + + filesToUpdate.forEach (file) -> + targetFile = "tapas-with-ember-master/#{file}" + if /\/$/.test(file) + zip.extractEntryTo(targetFile, file, false, true) + else + zip.extractEntryTo(targetFile, '', false, true) + ) + +# -------------- +# Script Updates +# -------------- + +EMBER_BASE_URL = 'http://builds.emberjs.com' +GITHUB_API_URL = 'https://api.github.com' +EMBER = {} +EMBER_DATA = {} +['release', 'beta', 'canary'].forEach (build) -> + EMBER[build] = + prod: "#{EMBER_BASE_URL}/#{build}/ember.prod.js" + dev: "#{EMBER_BASE_URL}/#{build}/ember.js" + EMBER_DATA[build] = + prod: "#{EMBER_BASE_URL}/#{build}/ember-data.prod.js" + dev: "#{EMBER_BASE_URL}/#{build}/ember-data.js" + +EMBER['tag'] = + prod: "#{EMBER_BASE_URL}/tags/{{tag}}/ember.prod.js" + dev: "#{EMBER_BASE_URL}/tags/{{tag}}/ember.js" + +EMBER_DATA['tag'] = + prod: "#{EMBER_BASE_URL}/tags/{{tag}}/ember-data.prod.js" + dev: "#{EMBER_BASE_URL}/tags/{{tag}}/ember-data.js" + +downloadFile = (src, dest) -> + console.log('Downloading ' + src + ' to ' + dest) + data = '' + request = http.get src, (response) -> + response.on('data', (chunk) -> + data += chunk + ) + response.on('end', -> + fs.writeFileSync(dest, data) + ) + +downloadEmberFile = (src, dest) -> + downloadFile(src, "vendor/ember/#{dest}") + +listTags = (user, repo, since, name, command) -> + github.repos.getTags(user: user, repo: repo, (resp, tags) -> + for tag in tags + if semver.valid(tag.name) and !semver.lt(tag.name, since) + firstTag = tag.name unless firstTag + console.log " #{tag.name}" + console.log "Install with cake -t \"#{firstTag}\" #{command}" + ) + +installEmberFiles = (project, filename, options) -> + if 'tag' of options + # Download a Tag + tag = options.tag + tag = "v#{tag}" unless /^v/.test(tag) + downloadEmberFile(project['tag'].dev.replace(/{{tag}}/, tag), + "development/#{filename}") + downloadEmberFile(project['tag'].prod.replace(/{{tag}}/, tag), + "production/#{filename}") + else + # Download a Channel + channel = options.channel ? 'release' + downloadEmberFile project[channel].dev, "development/#{filename}" + downloadEmberFile project[channel].prod, "production/#{filename}" + +# Channel +option '-c', '--channel "[CHANNEL_NAME]"', + 'relase, beta, or canary (http://emberjs.com/builds)' + +# Tag +option '-t', '--tag "[TAG_NAME]"', + 'a tagged release to install. Run cake ember:list to see known tags' + +# ----- +# Ember +# ----- +task 'ember:install', 'install latest Ember', (options) -> + installEmberFiles(EMBER, 'ember.js', options) + +task 'ember:list', 'list tagged relases of Ember since v1.0.0', (options) -> + listTags 'emberjs', 'ember.js', 'v1.0.0', 'Ember', 'ember:install' + +# ---------- +# Ember Data +# ---------- +task 'ember-data:install', 'install latest Ember Data', (options) -> + options.channel or= 'beta' + installEmberFiles(EMBER_DATA, 'ember-data.js', options) + +task 'ember-data:list', 'list tagged relases of Ember Data', (options) -> + listTags 'emberjs', 'data', 'v0.0.1', 'Ember Data', + 'ember-data:install' + +# ----------- +# Ember Model +# ----------- +EMBER_MODEL = + dev: 'http://builds.erikbryn.com/ember-model/ember-model-latest.js' + prod: 'http://builds.erikbryn.com/ember-model/ember-model-latest.prod.js' + +task 'ember-model:install', 'install latest Ember Model', (options) -> + downloadEmberFile EMBER_MODEL.dev, 'development/ember-model.js' + downloadEmberFile EMBER_MODEL.prod, 'production/ember-model.js' diff --git a/test/fixtures/Dockerfile/Dockerfile b/test/fixtures/Dockerfile/Dockerfile new file mode 100755 index 00000000..c61ae8d0 --- /dev/null +++ b/test/fixtures/Dockerfile/Dockerfile @@ -0,0 +1,97 @@ +FROM ubuntu:14.04 + +MAINTAINER Wesley Hales + +# Install. +RUN \ + sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \ + apt-get update && \ + apt-get -y upgrade && \ + apt-get install -y build-essential && \ + apt-get install -y software-properties-common && \ + apt-get install -y byobu curl git htop man unzip vim wget && \ + rm -rf /var/lib/apt/lists/* + +# Set environment variables. +ENV HOME /root + +# Define working directory. +WORKDIR /root + +# Install Java. +RUN \ + echo oracle-java7-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections && \ + add-apt-repository -y ppa:webupd8team/java && \ + apt-get update && \ + apt-get install -y oracle-java7-installer && \ + rm -rf /var/lib/apt/lists/* \ + echo "done" + +# Install Phantom2 build requirements (Won't build on systems < 2GB ram) +RUN \ + sudo apt-get update && apt-get -y install g++ flex bison gperf ruby perl \ + libsqlite3-dev libfontconfig1-dev libicu-dev libfreetype6 libssl-dev libjpeg-dev libqt5webkit5-dev + +#####################################build latest phantom +######################################+++++ only do this in dev when needed + +#RUN rm -rf phantomjs + +#RUN git clone git://github.com/ariya/phantomjs.git + +#RUN cd /root/phantomjs/ && ./build.sh --confirm + +#RUN ln -s /root/phantomjs/bin/phantomjs /usr/bin/phantomjs +######################################+++++ END only do this in dev when needed + +######################################+++++ comment out when building new version of phantomjs +ADD phantomjs /root/phantomjs + +RUN ln -s /root/phantomjs /usr/bin/phantomjs +######################################+++++ END comment out when building new version of phantomjs + +RUN git clone git://github.com/wesleyhales/speedgun.git + +#RUN mkdir /root/speedgun/core/reports + +#VOLUME ["/root/speedgun/core/reports"] + +RUN cd speedgun/core && phantomjs --ssl-protocol=any --ignore-ssl-errors=yes speedgun.js http://www.google.com performance csv + +RUN cd /root && wget https://dl.dropboxusercontent.com/u/12278845/server.tar + +RUN cd /root && tar -xvf server.tar + +#RUN echo "cd /root/jboss-as-7.1.1.Final-fluxui/ && ./bin/standalone.sh --server-config=standalone-full.xml -b 0.0.0.0" >> /root/.bashrc + +# install maven +RUN sudo apt-get update && apt-get install -y maven + +ADD src /root/src +ADD pom.xml /root/pom.xml +RUN mvn clean install + +#RUN cp -rf /root/target/speedgun.war /root/jboss-as-7.1.1.Final-fluxui/standalone/deployments/ + +RUN ln -s /root/target/speedgun /root/jboss-as-7.1.1.Final-fluxui/standalone/deployments/speedgun.war + +RUN touch /root/jboss-as-7.1.1.Final-fluxui/standalone/deployments/speedgun.war.dodeploy + +# Cleanup old JMS queue +RUN rm -rf /root/jboss-as-7.1.1.Final-fluxui/standalone/tmp/ /root/jboss-as-7.1.1.Final-fluxui/standalone/data/* + +RUN mkdir /root/jboss-as-7.1.1.Final-fluxui/speedgun +RUN cd /root/jboss-as-7.1.1.Final-fluxui/speedgun && curl -O https://raw.githubusercontent.com/wesleyhales/speedgun/master/core/speedgun.js +RUN cd /root/jboss-as-7.1.1.Final-fluxui/speedgun && curl -O https://raw.githubusercontent.com/wesleyhales/speedgun/master/core/config.json + +COPY server-entrypoint.sh / + +ENTRYPOINT ["/server-entrypoint.sh"] + +RUN apt-get install -y postgresql-client + +COPY speedgun.sql / + +EXPOSE 3306 8080 8443 + +#CMD ["postgres"] \ No newline at end of file diff --git a/test/fixtures/Makefile/Makefile b/test/fixtures/Makefile/Makefile new file mode 100755 index 00000000..b79c161d --- /dev/null +++ b/test/fixtures/Makefile/Makefile @@ -0,0 +1,5 @@ +SUBDIRS:=components test +.PHONY: ${SUBDIRS} clean +all:${SUBDIRS} +${SUBDIRS}: + ${MAKE} -C $@ all diff --git a/test/fixtures/Maven POM/pom.xml b/test/fixtures/Maven POM/pom.xml new file mode 100644 index 00000000..36e06664 --- /dev/null +++ b/test/fixtures/Maven POM/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 +awilbur.personal + hudsel + 1.0-SNAPSHOT + jar +hudsel + + src/test/resources/testng.xml + false + + + + + org.testng + testng + 6.8 + + + + org.seleniumhq.selenium + selenium-server + 2.41.0 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.6 + + + + + ${suiteXmlFile} + + + ${skipTests} + true + + + + + diff --git a/test/test_language.rb b/test/test_language.rb index 6adca263..8e7253ea 100644 --- a/test/test_language.rb +++ b/test/test_language.rb @@ -170,10 +170,16 @@ class TestLanguage < Minitest::Test def test_find_by_extension assert_equal [], Language.find_by_extension('.factor-rc') - assert_equal [], Language.find_by_extension('foo.rb') - assert_equal [Language['Ruby']], Language.find_by_extension('rb') - assert_equal [Language['Ruby']], Language.find_by_extension('.rb') - assert_equal [Language['Limbo'], Language['M'], Language['MUF'], Language['Mathematica'], Language['Matlab'], Language['Mercury'], Language['Objective-C']], Language.find_by_extension('.m') + assert_equal [Language['Limbo'], Language['M'], Language['MUF'], Language['Mathematica'], Language['Matlab'], Language['Mercury'], Language['Objective-C']], Language.find_by_extension('foo.m') + assert_equal [Language['Ruby']], Language.find_by_extension('foo.rb') + assert_equal [Language['Ruby']], Language.find_by_extension('foo/bar.rb') + assert_equal [Language['Ruby']], Language.find_by_extension('PKGBUILD.rb') + assert_equal ['C', 'C++', 'Objective-C'], Language.find_by_extension('foo.h').map(&:name).sort + assert_equal [], Language.find_by_extension('rb') + assert_equal [], Language.find_by_extension('.null') + assert_equal [Language['HTML+Django']], Language.find_by_extension('index.jinja') + assert_equal [Language['Chapel']], Language.find_by_extension('examples/hello.chpl') + assert_equal [], Language.find_by_filename('F.I.L.E.') end def test_find_all_by_extension @@ -186,23 +192,17 @@ class TestLanguage < Minitest::Test def test_find_by_filename assert_equal [Language['Shell']], Language.find_by_filename('PKGBUILD') - assert_equal [Language['Ruby']], Language.find_by_filename('foo.rb') - assert_equal [Language['Ruby']], Language.find_by_filename('foo/bar.rb') assert_equal [Language['Ruby']], Language.find_by_filename('Rakefile') - assert_equal [Language['Ruby']], Language.find_by_filename('PKGBUILD.rb') assert_equal Language['ApacheConf'], Language.find_by_filename('httpd.conf').first assert_equal [Language['ApacheConf']], Language.find_by_filename('.htaccess') assert_equal Language['Nginx'], Language.find_by_filename('nginx.conf').first - assert_equal ['C', 'C++', 'Objective-C'], Language.find_by_filename('foo.h').map(&:name).sort + assert_equal [], Language.find_by_filename('foo.rb') assert_equal [], Language.find_by_filename('rb') assert_equal [], Language.find_by_filename('.null') assert_equal [Language['Shell']], Language.find_by_filename('.bashrc') assert_equal [Language['Shell']], Language.find_by_filename('bash_profile') assert_equal [Language['Shell']], Language.find_by_filename('.zshrc') assert_equal [Language['Clojure']], Language.find_by_filename('riemann.config') - assert_equal [Language['HTML+Django']], Language.find_by_filename('index.jinja') - assert_equal [Language['Chapel']], Language.find_by_filename('examples/hello.chpl') - assert_equal [], Language.find_by_filename('F.I.L.E.') end def test_find_by_interpreter