module EnvironmentInformation
#¶ ↑
require 'environment_information/class/add.rb'
#¶ ↑
#¶ ↑
require 'environment_information/class/constants.rb'
#¶ ↑
#¶ ↑
require 'environment_information/class/register_sigint.rb'
#¶ ↑
#¶ ↑
require 'environment_information/class/reset.rb'
#¶ ↑
#¶ ↑
require 'environment_information/class/ruby.rb'
#¶ ↑
#¶ ↑
require 'environment_information/class/run.rb'
#¶ ↑
#¶ ↑
require 'environment_information/colours/colours.rb' EnvironmentInformation.colour_for_the_left_side
#¶ ↑
#¶ ↑
require 'environment_information/constants/error_line.rb'
#¶ ↑
#¶ ↑
require 'environment_information/constants/namespace.rb'
#¶ ↑
#¶ ↑
require 'environment_information/constants/newline.rb'
#¶ ↑
#¶ ↑
require 'environment_information/constants/regex.rb'
#¶ ↑
#¶ ↑
require 'environment_information/constants/temp_directory.rb'
#¶ ↑
#¶ ↑
EnvironmentInformation::GUI::GtkEnvironmentInformation
¶ ↑
#¶ ↑
require 'environment_information/gui/gtk/bindings.rb' EnvironmentInformation.run_gtk
#¶ ↑
#¶ ↑
require 'environment_information/misc_components/cflags.rb'
#¶ ↑
#¶ ↑
require 'environment_information/misc_components/ram.rb'
#¶ ↑
#¶ ↑
require 'environment_information/project/project.rb'
#¶ ↑
#¶ ↑
require 'environment_information/toplevel_methods/cd.rb'
#¶ ↑
#¶ ↑
require 'environment_information/toplevel_methods/e.rb'
#¶ ↑
#¶ ↑
require 'environment_information/toplevel_methods/internet_is_available.rb'
#¶ ↑
#¶ ↑
require 'environment_information/toplevel_methods/is_on_roebe.rb'
#¶ ↑
#¶ ↑
require 'environment_information/toplevel_methods/prefix_to_use.rb'
#¶ ↑
#¶ ↑
require 'environment_information/toplevel_methods/register_this_component_is_missing.rb' EnvironmentInformation.register_this_component_is_missing
#¶ ↑
#¶ ↑
require 'environment_information/toplevel_methods/remote_url_of_this_program.rb'
#¶ ↑
#¶ ↑
require 'environment_information/toplevel_methods/write_what_into.rb' EnvironmentInformation.write_what_into
#¶ ↑
#¶ ↑
require 'environment_information/version/version.rb'
#¶ ↑
Constants
- ARRAY_COMPARE_PROGRAM_VERSIONS
#¶ ↑
EnvironmentInformation::ARRAY_COMPARE_PROGRAM_VERSIONS
¶ ↑#¶ ↑
- ARRAY_DEFAULT_PROGRAMS_ON_LINUX
#¶ ↑
ARRAY_DEFAULT_PROGRAMS_ON_LINUX
¶ ↑This Array keeps track of the default programs on a linux computer.
#¶ ↑
- ARRAY_LFS_CORE_PROGRAMS
#¶ ↑
ARRAY_LFS_CORE_PROGRAMS
¶ ↑All the LFS core programs are registered here in this Array.
#¶ ↑
- ARRAY_LFS_TEMPORARY_PROGRAMS
#¶ ↑
ARRAY_LFS_TEMPORARY_PROGRAMS
¶ ↑All programs that are temporary, e. g. for enabling the bootstrapping of the compiler, are stored in the following Array.
#¶ ↑
- ARRAY_SCIENCE_CLUSTER
#¶ ↑
ARRAY_SCIENCE_CLUSTER
(science tag)¶ ↑Science-specific applications are gathered in this array.
#¶ ↑
- ARRAY_TRACKED_NON_PROGRAMS
#¶ ↑
ARRAY_TRACKED_NON_PROGRAMS
¶ ↑The entry
rubygems_installation_directory
depends on the executable called “gem”, which is part of ruby.This Array has also been called “registered extra functionality” in the past. The entries here are special in one way or another. Usually these entries are NOT standalone-programs, which is why they are tracked separately.
#¶ ↑
- ARRAY_TRACKED_PROGRAMS
- ARRAY_VERSION
#¶ ↑
EnvironmentInformation::ARRAY_VERSION
¶ ↑#¶ ↑
- ARRAY_XORG_COMPONENTS
#¶ ↑
ARRAY_XORG_COMPONENTS
(xorg tag)¶ ↑All xorg-components will be collected here. Sort alphabetically, please, and keep the entries downcased.
xf86dga is an xorg-component, but since as of October 2018 it has been removed and will no longer be checked - it seems to have been abandoned, more or less.
#¶ ↑
- ASCIITABLE_IS_AVAILABLE
puts 'asciitable is not available, consider installing it.' puts 'We will, however, continue, as it is not a mandatory package.'
- COMMAND_NOT_FOUND
#¶ ↑
EnvironmentInformation::COMMAND_NOT_FOUND
¶ ↑#¶ ↑
- ERROR_LINE
#¶ ↑
ERROR_LINE
¶ ↑#¶ ↑
- FILE_ARRAY_DEFAULT_PROGRAMS_ON_LINUX
#¶ ↑
EnvironmentInformation::FILE_ARRAY_DEFAULT_PROGRAMS_ON_LINUX
¶ ↑#¶ ↑
- FILE_ARRAY_LFS_CORE_PROGRAMS
#¶ ↑
EnvironmentInformation::FILE_ARRAY_LFS_CORE_PROGRAMS
¶ ↑#¶ ↑
- FILE_ARRAY_SCIENCE_CLUSTER
#¶ ↑
EnvironmentInformation::FILE_ARRAY_SCIENCE_CLUSTER
¶ ↑#¶ ↑
- FILE_ARRAY_TRACKED_NON_PROGRAMS
#¶ ↑
EnvironmentInformation::FILE_ARRAY_TRACKED_NON_PROGRAMS
¶ ↑#¶ ↑
- FILE_ARRAY_TRACKED_PROGRAMS
#¶ ↑
EnvironmentInformation::FILE_ARRAY_TRACKED_PROGRAMS
¶ ↑#¶ ↑
- FILE_ARRAY_TRACKED_XORG_COMPONENTS
#¶ ↑
EnvironmentInformation::FILE_ARRAY_TRACKED_XORG_COMPONENTS
¶ ↑#¶ ↑
- FILE_QUERY_TO_USE_FOR_THE_INDIVIDUAL_COMPONENTS
#¶ ↑
EnvironmentInformation::FILE_QUERY_TO_USE_FOR_THE_INDIVIDUAL_COMPONENTS
¶ ↑#¶ ↑
- FILE_THESE_PROGRAMS_CAN_BE_UPGRADED
#¶ ↑
FILE_THESE_PROGRAMS_CAN_BE_UPGRADED
¶ ↑We may store which programs could be upgraded into a local file.
#¶ ↑
- LAST_UPDATE
#¶ ↑
LAST_UPDATE
¶ ↑#¶ ↑
- MAIN_ENCODING
#¶ ↑
EnvironmentInformation::MAIN_ENCODING
¶ ↑#¶ ↑
- N
#¶ ↑
EnvironmentInformation::N
¶ ↑A newline constant to simplify our life.
#¶ ↑
- NAMESPACE
#¶ ↑
NAMESPACE
¶ ↑#¶ ↑
- NOT_FOUND
#¶ ↑
EnvironmentInformation::NOT_FOUND
¶ ↑#¶ ↑
- NOT_FOUND_IN_PKG_CONFIG_SEARCH_PATH
#¶ ↑
EnvironmentInformation::NOT_FOUND_IN_PKG_CONFIG_SEARCH_PATH
¶ ↑#¶ ↑
- NO_SUCH_FILE_OR_DIRECTORY
#¶ ↑
EnvironmentInformation::NO_SUCH_FILE_OR_DIRECTORY
¶ ↑#¶ ↑
- PKGCONFIG_COMMAND_NOT_FOUND
#¶ ↑
EnvironmentInformation::PKGCONFIG_COMMAND_NOT_FOUND
¶ ↑The constant that follows next is used to determine whether pkg-config could find a corresponding .pc file. If not then pkg-config will typically report a line such as this:
Package libdr was not found in the pkg-config search path.
We will include the last part of this string, as a generic message that can be used to indicate “this package could not be found on the given computer system at hand”.
#¶ ↑
- PROJECT_BASE_DIRECTORY
#¶ ↑
EnvironmentInformation::PROJECT_BASE_DIRECTORY
¶ ↑#¶ ↑
- SAVE_FILE
#¶ ↑
EnvironmentInformation::SAVE_FILE
¶ ↑Where to save stuff to. This depends on a proper setting of the toplevel variable called @temp_directory.
#¶ ↑
- TEMP_DIRECTORY
- URL_TO_THE_DOCUMENTATION
#¶ ↑
EnvironmentInformation::URL_TO_THE_DOCUMENTATION
¶ ↑#¶ ↑
- UTF_ENCODING
#¶ ↑
EnvironmentInformation::UTF_ENCODING
¶ ↑#¶ ↑
- VERSION
#¶ ↑
EnvironmentInformation::VERSION
¶ ↑#¶ ↑
- VERSION_STRING
#¶ ↑
EnvironmentInformation::VERSION_STRING
¶ ↑#¶ ↑
Public Class Methods
#¶ ↑
EnvironmentInformation.autogenerate_all_relevant_methods¶ ↑
#¶ ↑
# File lib/environment_information/toplevel_methods/autogenerate_all_relevant_methods.rb, line 18 def self.autogenerate_all_relevant_methods( i = ARRAY_TRACKED_PROGRAMS+ ARRAY_XORG_COMPONENTS ) i.flatten! # ======================================================================= # # Add some aliases which will be defined next. # ======================================================================= # hash_aliases = { atk: :libatk, # === EnvironmentInformation.return_version_of_libatk pcre2: :libpcre2, # === EnvironmentInformation.return_version_of_libpcre2 pcre: :libpcre, # === EnvironmentInformation.return_version_of_libpcre zlib: :libzlib # === EnvironmentInformation.return_version_of_libzlib } # ======================================================================= # # Iterate over our Array next: # ======================================================================= # i.each {|this_program| case this_program when :kde this_program = :kde_frameworks end self.class.instance_eval { # =================================================================== # # To test this method, try to do: # # EnvironmentInformation.return_version_of_valgrind # => "3.15.0" # # =================================================================== # this_method = "return_version_of_#{this_program}" define_method(this_method) { return_version_of_this_program(this_program) } if hash_aliases.has_key?(this_program) # ================================================================= # # To test this, try: # # EnvironmentInformation.return_version_of_libzlib # # ================================================================= # use_this_as_the_alias_target = "return_version_of_#{hash_aliases[this_program]}" define_method(use_this_as_the_alias_target) { return_version_of_this_program(this_program) } end } } end
#¶ ↑
EnvironmentInformation.cflags? (cflags tag)¶ ↑
The following is equivalent to the value stored in the variable $CFLAGS, which on unix-like systems may be obtained by issuing the following command:
echo $CFLAGS
#¶ ↑
# File lib/environment_information/misc_components/cflags.rb, line 19 def self.cflags? version = ENV['CFLAGS'].to_s.strip version = '<none>' if version.empty? # Display special status if it is empty. version end
#¶ ↑
EnvironmentInformation.colourize_and_pad_the_left_side¶ ↑
#¶ ↑
# File lib/environment_information/toplevel_methods/replay_from_the_stored_file.rb, line 42 def self.colourize_and_pad_the_left_side(i) left_side = i.to_s.ljust(32) # Pad to the left-hand side. if use_colours? " #{Colours.send(::EnvironmentInformation.colour_for_the_left_side, left_side)}" else " #{left_side}" end end
#¶ ↑
EnvironmentInformation.colourize_and_pad_the_right_side¶ ↑
#¶ ↑
# File lib/environment_information/toplevel_methods/replay_from_the_stored_file.rb, line 17 def self.colourize_and_pad_the_right_side( i, colour_for_the_right_side = ::EnvironmentInformation.colour_for_the_right_side ) case colour_for_the_right_side # ======================================================================= # # === :notify_if_missing # ======================================================================= # when :notify_if_missing colour_for_the_right_side = ::EnvironmentInformation.colour_for_the_right_side if i.to_s.empty? i = '[Not found]' colour_for_the_right_side = :orange end end if use_colours? Colours.send(colour_for_the_right_side, i) else i end end
#¶ ↑
EnvironmentInformation.consider_storing_these_results_into_a_local_file¶ ↑
This method will always take the dataset stored in the main hash when saving the yaml file at hand.
#¶ ↑
# File lib/environment_information/toplevel_methods/misc.rb, line 48 def self.consider_storing_these_results_into_a_local_file( be_verbose = true ) unless @hash_available_programs.empty? what = YAML.dump(@hash_available_programs) # ===================================================================== # # The file will be stored under the temp_directory. # ===================================================================== # into = return_path_to_the_all_programs_file e "Storing the yaml-file into: #{sfile(into)}" if be_verbose write_what_into(what, into) end end
#¶ ↑
EnvironmentInformation.cpuinfo? (cpuinfo tag)¶ ↑
This method currently relies on /proc/cpuinfo, thus favouring Linux-based systems.
It will become the display part of “CPU Model”.
#¶ ↑
# File lib/environment_information/misc_components/cpuinfo.rb, line 20 def self.cpuinfo? result = '/proc/cpuinfo' if File.exist? result readlines = File.readlines(result) _ = readlines.grep(/model name/).first.chomp splitted = _.split(':') _ = splitted[1].strip # => "model name\t: AMD Sempron(tm) 145 Processor" # ===================================================================== # # Next, add the amount of cores. We use "nproc" for this but "lscpu" # also contains this information. The following regex could be used # for lscpu: # # Core\(s\) per socket: (.+) # # Ok, we use lscpu for now. # ===================================================================== # n_cores = `nproc --all`.strip case n_cores.to_s when '1' n_cores << ' core' # Singular. else n_cores << ' cores' # Plural then. end _ << ", #{n_cores}" unless n_cores.empty? result = _ else result = nil end result end
#¶ ↑
EnvironmentInformation.environment_information?¶ ↑
This method will return a very long string containing all information about the locally installed/available programs.
#¶ ↑
# File lib/environment_information/class/initialize.rb, line 176 def self.environment_information? ::EnvironmentInformation::EnvironmentInformation.new(:full_be_silent).stringified end
#¶ ↑
EnvironmentInformation.internet_is_available?¶ ↑
#¶ ↑
# File lib/environment_information/toplevel_methods/internet_is_available.rb, line 12 def self.internet_is_available? require 'resolv' dns_resolver = Resolv::DNS.new begin # ===================================================================== # # The first domain name ever. Will probably not be removed. # ===================================================================== # dns_resolver.getaddress('symbolics.com') return true rescue Resolv::ResolvError => _error return false end end
#¶ ↑
EnvironmentInformation.is_this_component_included?¶ ↑
This is a more extensive check than .is_this_program_included?()
#¶ ↑
# File lib/environment_information/constants/array_tracked_components.rb, line 199 def self.is_this_component_included?(i) array = ( ARRAY_TRACKED_PROGRAMS + ARRAY_XORG_COMPONENTS + ARRAY_TRACKED_NON_PROGRAMS ) array.flatten.include? i.to_sym # Need a symbol. end
#¶ ↑
EnvironmentInformation.is_this_program_included?
¶ ↑
This will include the two Arrays ARRAY_TRACKED_PROGRAMS
and ARRAY_XORG_COMPONENTS
, but it will NOT include ARRAY_TRACKED_NON_PROGRAMS
.
#¶ ↑
# File lib/environment_information/constants/array_tracked_components.rb, line 187 def self.is_this_program_included?(i) ( ARRAY_TRACKED_PROGRAMS + ARRAY_XORG_COMPONENTS ).flatten.include? i.to_sym # Need a symbol. end
#¶ ↑
EnvironmentInformation.n_subcommands?¶ ↑
Return how many subcommands are available/registered. These are the tracked programs; and the xorg-components.
The non-programs will not be gathered by this method, on purpose; they are not standalone programs after all.
#¶ ↑
# File lib/environment_information/constants/array_tracked_components.rb, line 169 def self.n_subcommands? ARRAY_TRACKED_PROGRAMS.size+ ARRAY_XORG_COMPONENTS.size end
#¶ ↑
EnvironmentInformation.operating_system (os tag)¶ ↑
This method is also known as “bit type”.
The return value of this method may be a String such as this one here:
"GNU/Linux"
#¶ ↑
# File lib/environment_information/misc_components/operating_system.rb, line 22 def self.operating_system cmd = 'uname -mo' result = `#{cmd}`.chomp if result.start_with? 'GNU' # ===================================================================== # # The next part removes 'GNU/' specifically. It is a simpler name # than "GNU Linux" and variants, just as "BSD" is simpler than # e. g. "FreeBSD". You can reason that it may be "less accurate", # but it makes the notification-part of this gem simpler. # ===================================================================== # result.sub!(/^GNU\//,'') # Experimental as of Sep 2019. end if result.include? ' ' result = result.split(' ').last end result end
#¶ ↑
EnvironmentInformation.operating_system_bit_type_information (bit tag, bit type tag)¶ ↑
This method will return the bit type in use, as a String, such as “x86_64”.
#¶ ↑
# File lib/environment_information/misc_components/operating_system_bit_type.rb, line 18 def self.operating_system_bit_type_information cmd = 'uname -m' result = `#{cmd}`.chomp result = result.split(' ')[-1] if result.include?(' ') result = result.dup if result.frozen? case result when 'x86_64' result << ' (64 bit)' end result end
#¶ ↑
EnvironmentInformation.ram?
(ram tag)¶ ↑
This method will determine how much RAM the given computer host has.
The result will be given in n MB.
#¶ ↑
# File lib/environment_information/misc_components/ram.rb, line 16 def self.ram? result_in_n_mb = `free -m 2>&1`.split("\n")[1] if result_in_n_mb and result_in_n_mb.include?(' ') result_in_n_mb = result_in_n_mb.split(' ')[1] end result_in_n_mb end
#¶ ↑
EnvironmentInformation.register_this_component_is_missing¶ ↑
# ¶ ↑
# File lib/environment_information/toplevel_methods/register_this_component_is_missing.rb, line 28 def self.register_this_component_is_missing(i) if i.is_a? Symbol copy = i.to_s if copy.include?('_') i = copy.split('_').last.to_sym end end i = i.to_sym unless i.is_a? Symbol # ======================================================================= # # Do not register the same missing component twice: # ======================================================================= # unless @array_this_component_is_missing.include? i @array_this_component_is_missing << i end end
#¶ ↑
EnvironmentInformation.replay_from_the_stored_file¶ ↑
To invoke this method from the commandline, try:
envi --replay
#¶ ↑
# File lib/environment_information/toplevel_methods/replay_from_the_stored_file.rb, line 59 def self.replay_from_the_stored_file _ = return_path_to_the_all_programs_file if File.exist? _ e "Loading from the file #{_}." @hash_available_programs = YAML.load_file(_) @hash_available_programs.each_pair {|key, value| e colourize_and_pad_the_left_side("#{key}:")+ colourize_and_pad_the_right_side( value.to_s, :notify_if_missing ) } else e "No file exists at #{_}." end end
#¶ ↑
EnvironmentInformation.require_all_individual_components¶ ↑
This method can be used to load all the individual components that are part of the EnvironmentInformation
project.
#¶ ↑
# File lib/environment_information/requires/require_the_individual_components.rb, line 17 def self.require_all_individual_components # ======================================================================= # # Batch-require the components in the misc_components/ directory next: # ======================================================================= # tracked_non_programs?.each {|this_component| require "environment_information/misc_components/#{this_component}.rb" } end
#¶ ↑
EnvironmentInformation.require_the_toplevel_methods¶ ↑
#¶ ↑
# File lib/environment_information/requires/require_the_toplevel_methods.rb, line 14 def self.require_the_toplevel_methods Dir["#{PROJECT_BASE_DIRECTORY}toplevel_methods/*.rb"].each {|this_file| require "environment_information/toplevel_methods/#{File.basename(this_file)}" } end
#¶ ↑
EnvironmentInformation.return_remote_gtk2_version
¶ ↑
This method can be used to obtain the latest gtk2-version, from a remote URL.
The reason why this was necessary is because the RBT project may not always keep the latest gtk2 version, since gtk3 (and so forth) is more recent. Since we may still have to find out which gtk2 version is the most recent, we need a method to do so - which is precisely what this method here is doing.
#¶ ↑
# File lib/environment_information/toplevel_methods/return_remote_gtk2_version.rb, line 24 def self.return_remote_gtk2_version # ======================================================================= # # We will use a hardcoded URL: # ======================================================================= # remote_url = 'https://ftp.gnome.org/pub/GNOME/sources/gtk+/2.24/?C=M;O=D' require 'open-uri' newest_version = '' # ======================================================================= # # We will next try to obtain the remote dataset, but this would # fail if we have no www-connection, so we must rescue this step. # ======================================================================= # if internet_is_available? begin dataset = URI.open(remote_url).read use_this_regex = /<a href="gtk\+\-(\d.\d\d.\d\d).tar.xz"><img src=/ scanned = dataset.scan(use_this_regex).flatten newest_version = scanned.first rescue SocketError => error puts "It seems as if we have no working internet "\ "connection (#{sfancy(error.class)})" end end return newest_version.strip # ← And return it here. end
#¶ ↑
EnvironmentInformation.return_remote_url_of_this_program¶ ↑
This method will try to return the remote URL of the given program.
Note that this functionality depends on the RBT project, which explains the rescued required statement in the method.
#¶ ↑
# File lib/environment_information/toplevel_methods/remote_url_of_this_program.rb, line 17 def self.return_remote_url_of_this_program(i = ARGV) if i.is_a? Array i = i.first end begin require 'rbt/utility_scripts/url.rb' i = RBT.return_url1_of_this_program(i) rescue LoadError; end i end
#¶ ↑
EnvironmentInformation.return_version_of_this_program¶ ↑
This is the general method that will return the version of a particular program at hand.
The method must be able to deal with using pkg-config, but also querying some program's version via –version, via the commandline, Furthermore, some programs may require an ad-hoc fix.
#¶ ↑
# File lib/environment_information/toplevel_methods/return_version_of_this_program.rb, line 45 def self.return_version_of_this_program( this_program, prefix_to_use = @prefix_to_use ) prefix_to_use = prefix_to_use.dup if prefix_to_use version = nil # ← This is the default. if this_program.is_a? Array this_program = this_program.flatten.first end # Next define a few aliases. case this_program.to_s when 'diff' this_program = 'diffutils' when 'yacc' this_program = 'bison' end if ARRAY_TRACKED_NON_PROGRAMS.include? this_program return ::EnvironmentInformation.send(this_program) elsif @query_to_use_for_the_individual_components.has_key? this_program.to_sym use_this_command = @query_to_use_for_the_individual_components[this_program.to_sym] case use_this_command # ======================================================================= # # === :mate_desktop # # This entry is special. # ======================================================================= # when :mate_desktop return ::RBT.return_mate_desktop_version_array # ======================================================================= # # === :pkgconfig # ======================================================================= # when :pkgconfig # =================================================================== # # In this case it must be generic. # =================================================================== # cmd = "pkg-config --modversion #{this_program} #{ERROR_LINE}" version = `#{cmd}` version = COMMAND_NOT_FOUND if version.include? NOT_FOUND_IN_PKG_CONFIG_SEARCH_PATH # ======================================================================= # # === :custom_gtk2 # ======================================================================= # when :custom_gtk2 cmd = "pkg-config --modversion gtk+-2.0 #{ERROR_LINE}" version = `#{cmd}` version = COMMAND_NOT_FOUND if version.include? NOT_FOUND_IN_PKG_CONFIG_SEARCH_PATH # ======================================================================= # # === :custom_mpc # # We rely on the header called mpc.h. # ======================================================================= # when :custom_mpc target_file = '/usr/include/mpc.h' if File.exist? target_file dataset = File.read(target_file) use_this_regex = /MPC_VERSION_STRING "([0-9\.]+)"$/ dataset = dataset.scan(use_this_regex).flatten version = dataset.first end # ======================================================================= # # === :custom_boost # ======================================================================= # when :custom_boost target_file = '/usr/include/boost/version.hpp' if File.exist?('/System/Index/include/boost/version.hpp') and !File.exist?(target_file) # Custom fix. target_file = '/System/Index/include/boost/version.hpp' end if File.exist? target_file dataset = File.readlines(target_file) version = dataset.select {|line| line.include? '#define BOOST_LIB_VERSION' }.first.sub(/#define BOOST_LIB_VERSION/,'').strip.delete('"').tr('_','.') if version.count('.') < 2 version << '.0' end else register_this_component_is_missing(:boost) end # ======================================================================= # # === :version # # This entry point is typically for "program_name --version" # entries. Some of them require custom modifications. # ======================================================================= # when :version # =================================================================== # # Next enable support for AppDir layout, where programs will # ultimately reside in the same directory. # =================================================================== # unless prefix_to_use.empty? prefix_to_use << "#{this_program.to_s.capitalize}/Current/bin/" end cmd = "#{prefix_to_use}#{this_program} --version #{ERROR_LINE}" if @debug e Colours.crimson('DEBUG: ')+ Colours.steelblue(cmd) end # =================================================================== # # === Run the system command # # Next run the system command: # =================================================================== # _ = `#{cmd}`.strip case this_program.to_sym when :bison, :libtool, :gcc, :gettext, :m4, :grep _ = _.split(N).first.split(' ').last when :screen # ================================================================= # # Assume a String like this: "Screen version 4.08.00 (GNU) 05-Feb-20" # ================================================================= # version = _.scan(/version (\d{1}\.?\d{1,2}\.?\d{1})/).flatten.first.to_s.strip # ================================================================= # # Must still correct the middle part. # ================================================================= # splitted = version.split('.') splitted[1][0,1] = '' # Kill the leading '0'. version = splitted.join('.') _ = nil when :php # ================================================================= # # This check has to be a bit more sophisticated, so we # use scan. # # Examples: # # PHP 5.6.23 (cli) (built: Jun 24 2016 16:19:35) # PHP 7.4.2 (cli) (built: Jan 21 2020 16:57:46) ( NTS ) # # ================================================================= # result = _.scan( /PHP (\d{1,2}\.?\d{1,2}\.?\d{1,2}) \(cli\)/ ) _ = result.flatten.first.strip when :ruby _ = _.split(' ')[1] if _.include? 'p' _ = _[0 .. (_.index('p') - 1)] end end # =================================================================== # # The program could not be found. # =================================================================== # if _.include? NO_SUCH_FILE_OR_DIRECTORY _ = nil version = nil # =================================================================== # # Assume output like this: # # This is perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux-thread-multi # # =================================================================== # elsif _.include?('This is perl ') use_this_regex = /\(v(\d{1,2}.\d{1,2}.\d{1,2})\)/ # See: https://rubular.com/r/I1z0M5T9oNaVm4 _ =~ use_this_regex _ = $1.to_s.dup # =================================================================== # # === Handle cmake-related errors # =================================================================== # elsif _.include?('Could not find CMAKE_ROOT') _ = nil version = nil # =================================================================== # # === Handle VIM next # =================================================================== # elsif _.include?('VIM - Vi IMproved ') _ = _.scan( /VIM - Vi IMproved (\d{1,2}\.?\d{1,2}) / ).flatten.first.to_s.dup # =================================================================== # # === Handle XZ utils next # =================================================================== # elsif _.include?('xz (XZ Utils) ') _ = _.scan( /xz \(XZ Utils\) (\d{1,2}\.?\d{1,2}\.?\d{1,2})/ ).flatten.first.to_s elsif _.include? 'GNU tar' use_this_regex = /tar \(GNU tar\) (\d+\.?\d{2})/ _ =~ use_this_regex _ = $1.to_s.dup elsif _.include? 'sed (GNU sed) ' _ = _.scan(/sed \(GNU sed\) (\d+.\d+)/).flatten.first.to_s elsif _.include? N _ = _.split(N).first end if _ if _ _.sub!(/^GNU /,'') if _.start_with? 'GNU ' _.sub!(/ built on linux-gnu./,'') if _.include? ' built on linux-gnu.' if _.include? ', version ' # =============================================================== # # This is specifically for bash. # # Example: # GNU bash, version 5.0.0(1)-release (x86_64-pc-linux-gnu) # =============================================================== # version = _.scan( /, version (\d{1,2}\.?\d{1,2}\.?\d{1,2})/ ).flatten.first.strip if this_program == :bash version.chop!; version.chop! # Ad-hoc workaround. end elsif _.include? ' Version ' version = _.scan(/\d{1,2}\.?\d{1,2}\.?\d{1,2}/).flatten.first.to_s elsif _.include? ' version ' version = _.scan(/ version (\d{1,2}\.?\d{1,2}\.?\d{1,2})/).flatten.first.to_s else if _.include? ', ' _ = _.split(',').first # Fix entries like: "Awk 5.0.1, API: 2.0" end # =============================================================== # # Assume a String like this, which has to be modified a bit: # # "gnuplot 5.2 patchlevel 8" # # =============================================================== # _.sub!(/ patchlevel /,'.') if _.include? ' patchlevel ' # =============================================================== # # Else assume a result such as this: # # bison (GNU Bison) 3.5.1 # # =============================================================== # if _.include?(' ') and !_.include?(' (') # <- The second case will be for vim. version = _.split(' ').last.strip # =============================================================== # # The next clause is specifically for this: # # file-5.38 # # =============================================================== # elsif _.include?('-') and !_.include?(' (') version = _.split('-').last.strip elsif _.include? ' (' # =============================================================== # # This must also handle cases such as: "xz (XZ Utils) 5.2.4" # =============================================================== # version = _.split(' (').last.to_s.strip else version = _ end # =============================================================== # # Next specifically remove 'v' because "node --version" may # include that. # =============================================================== # version.delete!('v') if version.include? 'v' end end else # else tag cmd = "#{@prefix_to_use}#{use_this_command} #{ERROR_LINE}" first_line = nil # =================================================================== # # Next, run that system-command: # =================================================================== # result_of_system_cmd = `#{cmd}` if result_of_system_cmd.encoding.to_s == 'US-ASCII' result_of_system_cmd = result_of_system_cmd.force_encoding(UTF_ENCODING) end newline_splitted = result_of_system_cmd.split(N) if newline_splitted.first.include? 'hmmpgmd :: search a query against a database' newline_splitted.shift end # =================================================================== # # Handle the case where the .pc file could not be found. # =================================================================== # if result_of_system_cmd.include? NOT_FOUND_IN_PKG_CONFIG_SEARCH_PATH first_line = COMMAND_NOT_FOUND version = nil elsif result_of_system_cmd.include? COMMAND_NOT_FOUND first_line = COMMAND_NOT_FOUND elsif result_of_system_cmd.include? 'java version "' first_line = result_of_system_cmd.scan( /java version "(\d{1,2}\.?\d{1,2}\.?\d{1,2})/ ).flatten.first.to_s.strip elsif result_of_system_cmd.include? 'KDE Frameworks: ' first_line = result_of_system_cmd.scan( /KDE Frameworks: (\d{1,2}\.?\d{1,2}\.?\d{1,2})/ ).flatten.first end if this_program == :ncurses first_line = result_of_system_cmd.split(' ').last.strip first_line = first_line.split('.')[0..-2].join('.') elsif this_program == :ffmpeg first_line = result_of_system_cmd.split(N).first.split(' ')[2] elsif result_of_system_cmd.include? 'LLVM version ' first_line = result_of_system_cmd.scan( /LLVM version (\d{1,2}\.?\d{1,2}\.?\d{1,2})/ ).flatten.first else first_line = newline_splitted.first if first_line.nil? end if first_line if first_line.include? '# ' if first_line.start_with? '# ' first_line.sub!(/# /,'') end elsif first_line.include? ' #' first_line = first_line[0 .. first_line.index(' #')].strip end end if first_line.include? COMMAND_NOT_FOUND version = nil elsif first_line.include? 'Version: ImageMagick ' version = first_line.scan( /Version: ImageMagick (\d{1,2}\.?\d{1,2}\.?\d{1,2}-\d{1,2})/ ).flatten.first.to_s.strip.tr('-','.') elsif first_line.include? 'HMMER' version = first_line.scan( /HMMER (\d{1,2}\.?\d{1,2}\.?\d{1,2})/ ).flatten.first.to_s.strip # === "XTerm(353)" elsif first_line.include?('(') and first_line.include?(')') version = first_line.split('(').last.delete(')') elsif first_line.include? ' Version ' version = first_line.scan( / Version (\d{1,2}\.?\d{1,2}\.?\d{1,2})/ ).flatten.first.to_s.strip elsif first_line.include? ' version ' version = first_line.scan( / version (\d{1,2}\.?\d{1,2}\.?\d{1,2})/ ).flatten.first.to_s.strip else version = first_line if version.include? ' ' version = version.split(' ').last end version.strip! end if version if version.include?('/') # =============================================================== # # Assume input such as: # # nginx version: nginx/1.16.1 # # =============================================================== # version = version.split('/').last.strip end if version.include? ' ' version = version.split(' ').last # Always assume the last part in this case. end end end else e 'Not registered any key for the program: '+this_program.to_s e 'This is currently not allowed - please add this missing information.' exit end if version and version.include? 'n' version = version.dup if version.frozen? version.delete!('n') # Ad-hoc fix for "node --version". end result = version if result unless result.include? COMMAND_NOT_FOUND result = result.dup if result.frozen? result.strip! end end if result and (result == 'found' or result == 'foud') register_this_component_is_missing(this_program) elsif result and result.include?(COMMAND_NOT_FOUND) register_this_component_is_missing(this_program) # ======================================================================= # # Check whether pkg-config is available or not. # ======================================================================= # elsif result and ( result.include?(PKGCONFIG_COMMAND_NOT_FOUND) or result.include?(NO_SUCH_FILE_OR_DIRECTORY) ) register_this_component_is_missing(this_program) elsif result.nil? register_this_component_is_missing(this_program) end return result end
#¶ ↑
EnvironmentInformation.rubygems_installation_directory¶ ↑
This method will return the path to the rubygems installation directory, if possible (if it exists).
As this ought to be a directory, we will ensure that a trailing '/' character exists.
#¶ ↑
# File lib/environment_information/misc_components/rubygems_installation_directory.rb, line 22 def self.rubygems_installation_directory( prefix_to_use = @prefix_to_use ) result = `#{prefix_to_use}gem env #{ERROR_LINE}` # We need the 2>&1 to check if gem is available. unless result.include? 'not found' # ===================================================================== # # Apply a regex next. # ===================================================================== # path_to_the_rubygem_directory = result.to_s.scan( /INSTALLATION DIRECTORY: (.+)/ # Obtain the proper match here. ).flatten.first.to_s if File.directory? path_to_the_rubygem_directory path_to_the_rubygem_directory << '/' end unless path_to_the_rubygem_directory.end_with? '/' result = path_to_the_rubygem_directory else result = nil end result end
#¶ ↑
EnvironmentInformation.run_gtk¶ ↑
Use this method if you wish to run the gtk-component of the EnvironmentInformation
project.
#¶ ↑
# File lib/environment_information/gui/gtk/bindings.rb, line 206 def self.run_gtk x = ::EnvironmentInformation.gtk_bindings r = Gtk.run( ::EnvironmentInformation::EnvironmentInformation::GUI::GtkEnvironmentInformation.width, ::EnvironmentInformation::EnvironmentInformation::GUI::GtkEnvironmentInformation.height, :tabble, 'Environment Information',2 ) r << x # ← Add the widget here. r.add_shortcut(1, 'focus(:left)', :alt) r.modify_bg( Gtk::STATE_NORMAL, Gdk::Color.parse('grey') ) r.top_left_then_run end
#¶ ↑
EnvironmentInformation.screen_resolution (screen tag)¶ ↑
This method will typically make use of xdpyinfo first, as it also works in a .cgi environment. For non-cgi environments, on linux, we could use xrandr, which is a bit more elegant.
On success, the method here will return a String such as “1920x1080”.
#¶ ↑
# File lib/environment_information/misc_components/screen_resolution.rb, line 21 def self.screen_resolution result = '(unknown)' # This is the default return-value, then. # ======================================================================= # # === Check for linux as host OS first # ======================================================================= # if RUBY_PLATFORM.downcase.include? 'linux' # ================================================================= # # We have to be careful as xdpyinfo may not be installed on the # given computer system. # ================================================================= # resolution = `xdpyinfo #{ERROR_LINE}`.scan(/dimensions:.+$/).first # The error here may be: "xdpyinfo: unable to open display" if resolution and resolution.include? ':' result = resolution.split(':').last.strip.split('pixels').first.strip end # ======================================================================= # # === Else simply assume to be on windows here # ======================================================================= # else result = `wmic desktopmonitor get screenheight,screenwidth` end result end
#¶ ↑
EnvironmentInformation.set_use_colours
¶ ↑
Determine whether the EnvironmentInformation
project will use colours or whether it will not.
#¶ ↑
# File lib/environment_information/colours/colours.rb, line 37 def self.set_use_colours(i = true) @use_colours = i end
#¶ ↑
EnvironmentInformation.show_all_available_components¶ ↑
This method will quickly and easily show all available (registered) components. If you need more fine-tuning when you wish to display the main dataset at hand, then you should use other methods that are also a bit more complex. This method here is really just a fast version-display overview.
The second argument to this method contains the programs that we wish to display through this method.
#¶ ↑
# File lib/environment_information/toplevel_methods/show_all_available_components.rb, line 41 def self.show_all_available_components( n_ljust = 18, show_these_components = ARRAY_DEFAULT_PROGRAMS_ON_LINUX+ ARRAY_TRACKED_PROGRAMS, use_colours = use_colours? ) clear_main_hash if show_these_components.is_a? Array show_these_components.flatten! end # ======================================================================= # # The next variable determines whether we will also compare the # program versions. # ======================================================================= # compare_program_versions = false default_nljust_value = 30 # ← Detemine default padding. if n_ljust.is_a?(Array) and n_ljust.empty? n_ljust = default_nljust_value # Use the default value in this case. end # ======================================================================= # # First we will treat n_ljust as a commandline-flag if it is a String # and additionally begins with "--". # ======================================================================= # if n_ljust.is_a?(Array) and n_ljust.first.start_with?('--') _ = n_ljust.first case _ # ===================================================================== # # === --compare-to-program-versions # # To invoke this, try: # # show_components --compare # envi --compare-version # # ===================================================================== # when *ARRAY_COMPARE_PROGRAM_VERSIONS compare_program_versions = true n_ljust = default_nljust_value # ===================================================================== # # === --xorg # ===================================================================== # when /^-?-?xorg$/i show_these_components = EnvironmentInformation.xorg_components? n_ljust = default_nljust_value # ===================================================================== # # === --help # ===================================================================== # when /^-?-?help$/i e 'The following options are available for bin/fast_envi (fenvi):' e e ' --xorg # show only the xorg-components' e ' --compare-to-program-versions # also compare the program versions' e exit end end e uniq = show_these_components.uniq uniq.sort.each {|this_program| use_this_name_for_send = "return_version_of_#{this_program}" # ===================================================================== # # Next, add the name of the program at hand, onto the left hand side: # ===================================================================== # result = this_program.to_s.ljust(n_ljust) if use_colours result = ::EnvironmentInformation.colourize_and_pad_the_left_side(result) end # ===================================================================== # # Some components may not be installed on the user's computer system, # which we have to keep in mind in the following code. This is # why we will first apply the .send(), before checking whether # the program at hand is actually missing or not. # ===================================================================== # result_of_send = send(use_this_name_for_send) if result_of_send result_of_send = result_of_send.dup if result_of_send.frozen? result_of_send.strip! end @hash_available_programs[this_program.to_sym] = result_of_send.to_s right_component = ''.dup if @array_this_component_is_missing.include?(this_program.to_sym) right_component << "not installed (or otherwise not found)".ljust(12) else right_component << result_of_send.ljust(12) end if use_colours # =================================================================== # # We will distinguish between components that have been found and # components that have not been found. # =================================================================== # if right_component.include?('not installed') right_component = ::Colours.send(:mediumslateblue, right_component) else right_component = ::Colours.send(colour_for_the_right_side, right_component) end end result = result.dup if result.frozen? result << right_component if compare_program_versions if is_this_program_included?(this_program) registered_local_version = RBT.swift_return_version_of_this_program(this_program.to_sym).to_s.dup if registered_local_version.include? 'v' # =============================================================== # # Modify entries such as 'v12.15.0' into '12.15.0'. # =============================================================== # registered_local_version.delete!('v') end case this_program.to_s when 'gtk2' registered_local_version = return_remote_gtk2_version else if result_of_send.nil? # ^^^ This is missing, then, so it will be ignored. elsif registered_local_version <= result_of_send # This is ok. else result << royalblue( "\n "\ "^^^ This could be updated; the version in "\ "RBT is: #{mediumpurple(registered_local_version)}" ) end end end end # ===================================================================== # # Finally display our findings to the end user. # ===================================================================== # e result } e if is_on_roebe? # And store it on my home system too. ::EnvironmentInformation.store_relevant_files end end
#¶ ↑
EnvironmentInformation.show_detailed_information_about_all_available_components¶ ↑
This method is mostly for testing purposes only; for real use for the project you should consider making use of Environment.silent_run instead.
Do note that this method will always show all available components; if you need more fine-tuned control then you have to use the class EnvironmentInformation
instead.
#¶ ↑
# File lib/environment_information/toplevel_methods/misc.rb, line 97 def self.show_detailed_information_about_all_available_components @hash_available_programs = {} # Clear it every time this method is run. work_on_these_programs = [] work_on_these_programs << YAML.load_file(FILE_ARRAY_TRACKED_NON_PROGRAMS) work_on_these_programs << YAML.load_file(FILE_ARRAY_TRACKED_PROGRAMS) work_on_these_programs << YAML.load_file(FILE_ARRAY_TRACKED_XORG_COMPONENTS) work_on_these_programs << YAML.load_file(FILE_ARRAY_SCIENCE_CLUSTER) work_on_these_programs.flatten! work_on_these_programs.uniq! e work_on_these_programs.each {|this_program| version_of_this_program = ::EnvironmentInformation.return_version_of_this_program(this_program) # ===================================================================== # # Do a little sanitizing next: # ===================================================================== # case this_program.to_s when 'kde_frameworks' this_program = 'KDE Frameworks'.to_sym end left_side = colourize_and_pad_the_left_side(this_program) case version_of_this_program when COMMAND_NOT_FOUND, '' version_of_this_program = nil colour_for_the_right_side = :orange else colour_for_the_right_side = :notify_if_missing end # ===================================================================== # # Next register this program into the main hash. # ===================================================================== # @hash_available_programs[this_program] = version_of_this_program right_side = colourize_and_pad_the_right_side( version_of_this_program, colour_for_the_right_side ) e " #{left_side} #{right_side}" } e # ======================================================================= # # Report missing programs. # ======================================================================= # _ = missing_components? unless _.empty? e 'The following components were not found:' e _.each {|this_component| e lightseagreen(" #{this_component}") } e end consider_storing_these_results_into_a_local_file end
#¶ ↑
EnvironmentInformation.show_remote_url_of_this_program¶ ↑
This method will try to show the remote URL of the given program.
#¶ ↑
# File lib/environment_information/toplevel_methods/remote_url_of_this_program.rb, line 33 def self.show_remote_url_of_this_program(i = ARGV) puts return_remote_url_of_this_program(i) end
#¶ ↑
Environment.silent_run¶ ↑
#¶ ↑
# File lib/environment_information/toplevel_methods/misc.rb, line 65 def self.silent_run @hash_available_programs = {} # Clear it every time this method is run. work_on_these_programs = [] work_on_these_programs << YAML.load_file(FILE_ARRAY_TRACKED_NON_PROGRAMS) work_on_these_programs << YAML.load_file(FILE_ARRAY_TRACKED_PROGRAMS) work_on_these_programs << YAML.load_file(FILE_ARRAY_TRACKED_XORG_COMPONENTS) work_on_these_programs << YAML.load_file(FILE_ARRAY_SCIENCE_CLUSTER) work_on_these_programs.flatten.each {|this_program| version_of_this_program = ::EnvironmentInformation.return_version_of_this_program(this_program) if version_of_this_program version_of_this_program = version_of_this_program.to_s end @hash_available_programs[this_program] = version_of_this_program } consider_storing_these_results_into_a_local_file(false) return @hash_available_programs end
#¶ ↑
EnvironmentInformation.start_gtk_component
¶ ↑
We have to rescue the code so to notify the user what exactly may have failed.
#¶ ↑
# File lib/environment_information/toplevel_methods/menu.rb, line 75 def self.start_gtk_component begin this_file = 'environment_information/gui/gtk/bindings.rb' require this_file rescue LoadError => error e "An error happened - file #{sfile(this_file)} could not be found." pp error end ::EnvironmentInformation.run_gtk end
#¶ ↑
EnvironmentInformation.start_sinatra_interface¶ ↑
This method can be used to start the sinatra interface.
#¶ ↑
# File lib/environment_information/www/sinatra_interface.rb, line 204 def self.start_sinatra_interface puts 'Trying to start the sinatra-interface of EnvironmentInformation next.' ::EnvironmentInformation::Sinatra.run! end
#¶ ↑
EnvironmentInformation.tracked_non_programs?¶ ↑
Simpler toplevel-method to find out which non-programs are registered within the EnvironmentInformation
project.
#¶ ↑
# File lib/environment_information/constants/array_tracked_components.rb, line 156 def self.tracked_non_programs? ARRAY_TRACKED_NON_PROGRAMS end