BigW Consortium Gitlab

file_detector.rb 2.13 KB
Newer Older
1 2 3 4 5 6 7
require 'set'

module Gitlab
  # Module that can be used to detect if a path points to a special file such as
  # a README or a CONTRIBUTING file.
  module FileDetector
    PATTERNS = {
8
      # Project files
9 10 11 12 13
      readme: /\Areadme/i,
      changelog: /\A(changelog|history|changes|news)/i,
      license: /\A(licen[sc]e|copying)(\..+|\z)/i,
      contributing: /\Acontributing/i,
      version: 'version',
14 15 16
      avatar: /\Alogo\.(png|jpg|gif)\z/,

      # Configuration files
17 18 19
      gitignore: '.gitignore',
      koding: '.koding.yml',
      gitlab_ci: '.gitlab-ci.yml',
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
      route_map: 'route-map.yml',

      # Dependency files
      cartfile: /\ACartfile/,
      composer_json: 'composer.json',
      gemfile: /\A(Gemfile|gems\.rb)\z/,
      gemfile_lock: 'Gemfile.lock',
      gemspec: /\.gemspec\z/,
      godeps_json: 'Godeps.json',
      package_json: 'package.json',
      podfile: 'Podfile',
      podspec_json: /\.podspec\.json\z/,
      podspec: /\.podspec\z/,
      requirements_txt: /requirements\.txt\z/,
      yarn_lock: 'yarn.lock'
35
    }.freeze
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

    # Returns an Array of file types based on the given paths.
    #
    # This method can be used to check if a list of file paths (e.g. of changed
    # files) involve any special files such as a README or a LICENSE file.
    #
    # Example:
    #
    #     types_in_paths(%w{README.md foo/bar.txt}) # => [:readme]
    def self.types_in_paths(paths)
      types = Set.new

      paths.each do |path|
        type = type_of(path)

        types << type if type
      end

      types.to_a
    end

    # Returns the type of a file path, or nil if none could be detected.
    #
    # Returned types are Symbols such as `:readme`, `:version`, etc.
    #
    # Example:
    #
    #     type_of('README.md') # => :readme
    #     type_of('VERSION') # => :version
    def self.type_of(path)
      name = File.basename(path)

      PATTERNS.each do |type, search|
        did_match = if search.is_a?(Regexp)
                      name =~ search
                    else
                      name.casecmp(search) == 0
                    end

        return type if did_match
      end

      nil
    end
  end
end