118 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| module Gitlab
 | |
|   module Changelog
 | |
|     # Configuration settings used when generating changelogs.
 | |
|     class Config
 | |
|       # When rendering changelog entries, authors are not included.
 | |
|       AUTHORS_NONE = 'none'
 | |
| 
 | |
|       # The default path to the configuration file as stored in the project's Git
 | |
|       # repository.
 | |
|       DEFAULT_FILE_PATH = '.gitlab/changelog_config.yml'
 | |
| 
 | |
|       # The default date format to use for formatting release dates.
 | |
|       DEFAULT_DATE_FORMAT = '%Y-%m-%d'
 | |
| 
 | |
|       # The default template to use for generating release sections.
 | |
|       DEFAULT_TEMPLATE = File.read(File.join(__dir__, 'template.tpl'))
 | |
| 
 | |
|       # The regex to use for extracting the version from a Git tag.
 | |
|       #
 | |
|       # This regex is based on the official semantic versioning regex (as found
 | |
|       # on https://semver.org/), with the addition of allowing a "v" at the
 | |
|       # start of a tag name.
 | |
|       #
 | |
|       # We default to a strict regex as we simply don't know what kind of data
 | |
|       # users put in their tags. As such, using simpler patterns (e.g. just
 | |
|       # `\d+` for the major version) could lead to unexpected results.
 | |
|       #
 | |
|       # We use a String here as `Gitlab::UntrustedRegexp` is a mutable object.
 | |
|       DEFAULT_TAG_REGEX = '^v?(?P<major>0|[1-9]\d*)' \
 | |
|         '\.(?P<minor>0|[1-9]\d*)' \
 | |
|         '\.(?P<patch>0|[1-9]\d*)' \
 | |
|         '(?:-(?P<pre>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))' \
 | |
|         '?(?:\+(?P<meta>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
 | |
| 
 | |
|       attr_accessor :date_format, :categories, :template, :tag_regex, :always_credit_user_ids
 | |
| 
 | |
|       def self.from_git(project, user = nil, path = nil)
 | |
|         yaml = project.repository.changelog_config('HEAD', path.presence || DEFAULT_FILE_PATH)
 | |
|         if yaml.present?
 | |
|           from_hash(project, YAML.safe_load(yaml), user)
 | |
|         else
 | |
|           new(project)
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       def self.from_hash(project, hash, user = nil)
 | |
|         config = new(project)
 | |
| 
 | |
|         if (date = hash['date_format'])
 | |
|           config.date_format = date
 | |
|         end
 | |
| 
 | |
|         if (template = hash['template'])
 | |
|           config.template =
 | |
|             begin
 | |
|               TemplateParser::Parser.new.parse_and_transform(template)
 | |
|             rescue TemplateParser::Error => e
 | |
|               raise Error, e.message
 | |
|             end
 | |
|         end
 | |
| 
 | |
|         if (categories = hash['categories'])
 | |
|           if categories.is_a?(Hash)
 | |
|             config.categories = categories
 | |
|           else
 | |
|             raise Error, 'The "categories" configuration key must be a Hash'
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         if (regex = hash['tag_regex'])
 | |
|           config.tag_regex = regex
 | |
|         end
 | |
| 
 | |
|         config.always_credit_user_ids = Set.new
 | |
|         if (group_paths = Array(hash['include_groups']))
 | |
|           group_paths.each do |group_path|
 | |
|             group = Group.find_by_full_path(group_path)
 | |
|             config.always_credit_user_ids.merge(group&.users_ids_of_direct_members&.compact) if user&.can?(:read_group, group)
 | |
|           end
 | |
|         end
 | |
| 
 | |
|         config
 | |
|       end
 | |
| 
 | |
|       def initialize(project)
 | |
|         @project = project
 | |
|         @date_format = DEFAULT_DATE_FORMAT
 | |
|         @template =
 | |
|           begin
 | |
|             TemplateParser::Parser.new.parse_and_transform(DEFAULT_TEMPLATE)
 | |
|           rescue TemplateParser::Error => e
 | |
|             raise Error, e.message
 | |
|           end
 | |
|         @categories = {}
 | |
|         @tag_regex = DEFAULT_TAG_REGEX
 | |
|       end
 | |
| 
 | |
|       def contributor?(user)
 | |
|         @project.team.contributor?(user&.id)
 | |
|       end
 | |
| 
 | |
|       def always_credit_author?(user)
 | |
|         always_credit_user_ids&.include?(user&.id) || false
 | |
|       end
 | |
| 
 | |
|       def category(name)
 | |
|         @categories[name] || name
 | |
|       end
 | |
| 
 | |
|       def format_date(date)
 | |
|         date.strftime(@date_format)
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 |