diff options
Diffstat (limited to 'lib/gitlab/slug/path.rb')
-rw-r--r-- | lib/gitlab/slug/path.rb | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/lib/gitlab/slug/path.rb b/lib/gitlab/slug/path.rb new file mode 100644 index 00000000000..434f36829a6 --- /dev/null +++ b/lib/gitlab/slug/path.rb @@ -0,0 +1,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 |