summaryrefslogtreecommitdiff
path: root/lib/gitlab/slug/path.rb
blob: 434f36829a68f31154db2b82c6542b149cf9ce28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# frozen_string_literal: true

module Gitlab
  module Slug
    class Path
      LEADING_DASHES = /\A-+/.freeze
      # Eextract local email part if given an email. Will remove @ sign and everything following it.
      EXTRACT_LOCAL_EMAIL_PART = /@.*\z/.freeze
      FORBIDDEN_CHARACTERS = /[^a-zA-Z0-9_\-.]/.freeze
      PATH_TRAILING_VIOLATIONS = %w[.git .atom .].freeze
      DEFAULT_SLUG = 'blank'

      def initialize(input)
        @input = input.dup.to_s
      end

      def generate
        slug = input.gsub(EXTRACT_LOCAL_EMAIL_PART, "")
        slug = slug.gsub(FORBIDDEN_CHARACTERS, "")

        # Remove trailing violations ('.atom', '.git', or '.')
        loop do
          orig = slug
          PATH_TRAILING_VIOLATIONS.each { |extension| slug = slug.chomp extension }
          break if orig == slug
        end
        slug = slug.sub(LEADING_DASHES, "")

        # If all characters were of forbidden nature and filtered out we use this
        # fallback to avoid empty paths
        slug = DEFAULT_SLUG if slug.blank?

        slug
      end

      alias_method :to_s, :generate

      private

      attr_reader :input
    end
  end
end