# frozen_string_literal: true require 'json' require 'etc' module Diffend module Voting # Module responsible for handling both local and remote gem versions module Versions # Module responsible for fetching safe/malicious votes # for current or current/new versions of gems module Remote # API version API_VERSION = '0.1' # Platform type ruby PLATFORM_TYPE = 0 private_constant :API_VERSION, :PLATFORM_TYPE class << self # @param command [String] either install or update # @param definition [Bundler::Definition] definition for your source def call(command, definition) config = fetch_config response = Request.call( command, payload(command, config&.project_id, definition), config ) JSON.parse(response.body) end # Build diffend, host, packages, and platform specific information # # @param command [String] either install or update # @param project_id [String] diffend project_id # @param definition [Bundler::Definition] definition for your source # # @return [Hash] payload for diffend endpoint def payload(command, project_id, definition) { 'diffend' => build_diffend(project_id), 'host' => build_host, 'packages' => Local.call(command, definition), 'platform' => build_platform }.freeze end # Build diffend information # # @param project_id [String, nil] diffend project_id # # @return [Hash] def build_diffend(project_id) { 'api_version' => API_VERSION, 'environment' => build_diffend_environment, 'project_id' => project_id, 'type' => PLATFORM_TYPE, 'version' => Diffend::VERSION }.freeze end # Build diffend environment information # # @return [String] def build_diffend_environment ENV['DIFFEND_ENV'] || 'development' end # Build platform information # # @return [Hash] def build_platform { 'bundler' => { 'version' => Bundler::VERSION }, 'environment' => build_platform_environment, 'ruby' => build_platform_ruby, 'rubygems' => { 'specification_version' => Gem::Specification::CURRENT_SPECIFICATION_VERSION, 'version' => Gem::VERSION } }.freeze end def build_platform_ruby if defined?(JRUBY_VERSION) revision = JRUBY_REVISION.to_s version = JRUBY_VERSION else revision = RUBY_REVISION.to_s version = RUBY_ENGINE_VERSION end { 'engine' => RUBY_ENGINE, 'patchlevel' => RUBY_PATCHLEVEL, 'release_date' => RUBY_RELEASE_DATE, 'revision' => revision, 'version' => version } end # Build platform environment information # # @return [String] def build_platform_environment ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development' end # Build host information # # @return [Hash] def build_host uname = Etc.uname { 'command' => { 'name' => '', 'options' => '' }, 'ips' => build_host_ips, 'name' => uname[:nodename], 'system' => { 'machine' => uname[:machine], 'name' => uname[:sysname], 'release' => uname[:release], 'version' => uname[:version] }, 'tags' => build_host_tags, 'user' => Etc.getpwuid(Process.uid).name }.freeze end def build_host_ips Socket.ip_address_list.map do |ip| next if ip.ipv4_loopback? || ip.ipv6_loopback? || ip.ipv6_linklocal? ip.ip_address end.compact end def build_host_tags tags = [] if ENV.key?('GITHUB_ACTIONS') tags << 'ci' tags << 'ci-github' end if ENV.key?('CIRCLECI') tags << 'ci' tags << 'ci-circle' end tags end # Fetch coditsu config file # # @return [OpenStruct, nil] configuration object # # @raise [Errors::MissingConfigurationFile] when no config file def fetch_config Config::Fetcher.call( File.expand_path('..', Bundler.bin_path) ) end end end end end end