Skip to content
Snippets Groups Projects

Reproduce Repository X-Ray functionality - Introduce lock file classes

Merged Leaminn Ma requested to merge introduce-lock-file-classes into master
1 unresolved thread
Files
5
 
# frozen_string_literal: true
 
 
module Ai
 
module Context
 
module Dependencies
 
module LockFiles
 
# This class represents a dependency manager lock file. It contains logic
 
# to parse and extract libraries from the file content. To support a new
 
# lock file type/language, create a new class that inherits from this Base.
 
# Then append the new class name to LockFiles::Constants::LOCK_FILE_CLASSES.
 
class Base
 
include Gitlab::Utils::StrongMemoize
 
 
# This value is supposed to indicate the version of Repository X-Ray we are using;
 
# however, it's not applicable here so we just set it to a placeholder value.
 
# It may be removed entirely in https://gitlab.com/gitlab-org/gitlab/-/issues/479185.
 
SCANNER_VERSION = '0.0.0'
 
 
Lib = Struct.new(:name, :version, keyword_init: true)
 
 
def self.file_name_glob
 
raise NotImplementedError
 
end
 
 
def self.lang_name
 
raise NotImplementedError
 
end
 
 
def self.lang
 
CodeSuggestions::ProgrammingLanguage::LANGUAGE_XRAY_NAMING[lang_name]
 
end
 
 
def self.matches?(path)
 
File.fnmatch?("**/#{file_name_glob}", path, File::FNM_PATHNAME | File::FNM_DOTMATCH)
 
end
 
 
def initialize(blob)
 
@content = blob.data
 
@path = blob.path
 
@errors = []
 
end
 
 
+1
def parse!
 
return error('file empty') if content.blank?
 
 
@libs = extract_libs
 
 
# Default error message if there are no other errors
 
error('format not recognized or dependencies not present') if libs.blank? && errors.empty?
 
end
 
 
# This hash matches the current XrayReport payload schema
 
def payload
 
return unless libs.present?
 
 
{
 
libs: formatted_libs,
 
checksum: checksum,
 
fileName: path,
 
scannerVersion: SCANNER_VERSION
 
}
 
end
 
 
def valid?
 
errors.empty?
 
end
 
 
def error_message
 
return if valid?
 
 
"Error(s) while parsing file `#{path}`: #{errors.join(', ')}"
 
end
 
 
private
 
 
attr_reader :content, :path, :libs, :errors
 
 
def extract_libs
 
raise NotImplementedError
 
end
 
 
def formatted_libs
 
libs.map do |lib|
 
+1
lib_name = lib.version ? "#{lib.name} (#{lib.version})" : lib.name
 
 
{ name: lib_name }
 
end
 
end
 
 
def error(message)
 
@errors << message
 
end
 
 
def checksum
 
Digest::SHA256.hexdigest(content)
 
end
 
strong_memoize_attr :checksum
 
end
 
end
 
end
 
end
 
end
Loading