module JenkinsPipelineBuilder class ExtensionSet SET_METHODS = %i[ name plugin_id jenkins_name description announced type ].freeze SET_METHODS.each do |method_name| define_method method_name do |value = nil| return settings[method_name] if value.nil? settings[method_name] = value end end attr_accessor :blocks, :extensions, :settings def initialize(type, path = nil, &block) @blocks = {} @settings = {} @extensions = [] instance_eval(&block) blocks.each do |version, settings| add_extension type, version, settings, path end end def clear_installed_version @version = nil end def installed_version=(version) @version = Gem::Version.new version end def add_extension(type, version, settings, path = nil) ext = JenkinsPipelineBuilder::Extension.new ext.min_version version ext.type type self.settings.merge(settings).each do |key, value| ext.send key, value end ext.path path unless ext.path extensions << ext end def installed_version return @version if @version reg = JenkinsPipelineBuilder.registry version = reg.versions[settings[:plugin_id]] raise "Plugin #{settings[:name]} is not installed (plugin_id: #{settings[:plugin_id]})" if version.nil? self.installed_version = version @version end def extension # TODO: Support multiple xml sections for the native to jenkins plugins return extensions.first if settings[:plugin_id] == 'builtin' extension = versions[highest_allowed_version] unless extension raise %(Can't find version of #{name} lte #{installed_version}. Available versions: #{versions.keys.map(&:to_s)}) end extension end def merge(other_set) mismatch = [] SET_METHODS.each do |method_name| val1 = settings[method_name] val2 = other_set.settings[method_name] mismatch << "The values for #{method_name} do not match '#{val1}' : '#{val2}'" unless val1 == val2 end mismatch.each do |error| logger.error error end raise 'Values did not match, cannot merge extension sets' if mismatch.any? self.extensions = versions.merge(other_set.versions).values end def parameters(params) version = @min_version || '0' blocks[version] = {} unless blocks[version] blocks[version][:parameters] = params end def xml(path: false, version: '0', &block) if @min_version version = @min_version elsif version != '0' deprecation_warning(settings[:name], 'xml') end unless block raise "no block found for version #{version}" unless blocks.key version return blocks[version][:block] end store_xml version, block, path end def version(ver, &block) @min_version = ver yield block end %i[after before].each do |method_name| define_method method_name do |version: '0', &block| if @min_version version = @min_version elsif version != '0' deprecation_warning(settings[:name], method_name) end return instance_variable_get(method_name) unless block blocks[version] = {} unless blocks[version] blocks[version][method_name] = block end end def valid? valid = errors.empty? unless valid name ||= 'A plugin with no name provided' logger.error "Encountered errors while registering #{name}" logger.error errors.map { |k, v| "#{k}: #{v}" }.join(', ') end valid end def errors errors = {} errors['ExtensionSet'] = 'no extensions successfully registered' if extensions.empty? extensions.each do |ext| ver = ext.min_version || 'unknown' errors["#{ext.name} version #{ver}"] = ext.errors unless ext.valid? end errors end def versions # Don't memoize this, it will prevent local overrides extensions.each_with_object({}) do |ext, hash| hash[Gem::Version.new(ext.min_version)] = ext end end private def logger JenkinsPipelineBuilder.logger end def highest_allowed_version ordered_version_list.each do |version| return version if version <= installed_version end end def store_xml(version, block, path) if blocks[version] blocks[version].merge!(xml: block, path: path) else blocks[version] = { xml: block, path: path } end end def ordered_version_list versions.keys.sort.reverse end def deprecation_warning(name, block) logger.warn %(WARNING: #{name} set the version in the #{block} block, this is deprecated. Please use a version block.) end end end