environment_information 1.4.124 → 1.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +91 -15
- data/doc/README.gen +42 -14
- data/doc/todo/TODO_FOR_THE_ENVIRONMENT_INFORMATION_PROJECT.md +16 -12
- data/lib/environment_information/base/base.rb +483 -99
- data/lib/environment_information/colours/colours.rb +92 -66
- data/lib/environment_information/commandline/commandline.rb +137 -0
- data/lib/environment_information/constants/constants.rb +372 -11
- data/lib/environment_information/project/project.rb +1 -1
- data/lib/environment_information/query/constants.rb +46 -0
- data/lib/environment_information/query/help.rb +88 -0
- data/lib/environment_information/query/menu.rb +487 -0
- data/lib/environment_information/query/misc.rb +2006 -0
- data/lib/environment_information/query/query.rb +245 -0
- data/lib/environment_information/query/reset.rb +202 -0
- data/lib/environment_information/query/run.rb +70 -0
- data/lib/environment_information/requires/require_the_environment_information_project.rb +2 -7
- data/lib/environment_information/requires/require_the_toplevel_methods.rb +1 -3
- data/lib/environment_information/toplevel_methods/toplevel_methods.rb +2258 -0
- data/lib/environment_information/version/version.rb +2 -2
- data/lib/environment_information/www/sinatra_interface.rb +20 -17
- data/lib/environment_information/www/webobject_interface.cgi +6 -7
- data/lib/environment_information/yaml/colours.yml +3 -3
- data/lib/environment_information/yaml/query_to_use_for_all_components.yml +284 -0
- data/lib/environment_information/yaml/{array_tracked_programs.yml → track_these_components.yml} +77 -11
- metadata +18 -60
- data/lib/environment_information/class/class.rb +0 -2580
- data/lib/environment_information/class/colours.rb +0 -282
- data/lib/environment_information/colours/sfancy.rb +0 -19
- data/lib/environment_information/colours/simp.rb +0 -19
- data/lib/environment_information/constants/array_tracked_components.rb +0 -210
- data/lib/environment_information/constants/encoding.rb +0 -21
- data/lib/environment_information/constants/error_line.rb +0 -17
- data/lib/environment_information/constants/file_constants.rb +0 -102
- data/lib/environment_information/constants/misc.rb +0 -86
- data/lib/environment_information/constants/namespace.rb +0 -14
- data/lib/environment_information/constants/newline.rb +0 -16
- data/lib/environment_information/constants/regex.rb +0 -30
- data/lib/environment_information/constants/temp_directory.rb +0 -52
- data/lib/environment_information/misc_components/README.md +0 -3
- data/lib/environment_information/misc_components/cflags.rb +0 -36
- data/lib/environment_information/misc_components/cpuinfo.rb +0 -64
- data/lib/environment_information/misc_components/operating_system.rb +0 -54
- data/lib/environment_information/misc_components/operating_system_bit_type.rb +0 -42
- data/lib/environment_information/misc_components/ram.rb +0 -30
- data/lib/environment_information/misc_components/rubygems_installation_directory.rb +0 -54
- data/lib/environment_information/misc_components/screen_resolution.rb +0 -50
- data/lib/environment_information/queries/README.md +0 -2
- data/lib/environment_information/queries/complex_version.rb +0 -273
- data/lib/environment_information/queries/pkg_config.rb +0 -125
- data/lib/environment_information/queries/simple_version.rb +0 -272
- data/lib/environment_information/requires/require_the_individual_misc_components.rb +0 -30
- data/lib/environment_information/toplevel_methods/autogenerate_all_relevant_methods.rb +0 -153
- data/lib/environment_information/toplevel_methods/cd.rb +0 -16
- data/lib/environment_information/toplevel_methods/e.rb +0 -43
- data/lib/environment_information/toplevel_methods/hash.rb +0 -65
- data/lib/environment_information/toplevel_methods/internet_is_available.rb +0 -30
- data/lib/environment_information/toplevel_methods/is_on_roebe.rb +0 -16
- data/lib/environment_information/toplevel_methods/menu.rb +0 -90
- data/lib/environment_information/toplevel_methods/misc.rb +0 -324
- data/lib/environment_information/toplevel_methods/n_subcommands.rb +0 -31
- data/lib/environment_information/toplevel_methods/prefix_to_use.rb +0 -39
- data/lib/environment_information/toplevel_methods/register_this_component_is_missing.rb +0 -61
- data/lib/environment_information/toplevel_methods/remote_url_of_this_program.rb +0 -45
- data/lib/environment_information/toplevel_methods/replay_from_the_stored_file.rb +0 -84
- data/lib/environment_information/toplevel_methods/return_alias_to.rb +0 -30
- data/lib/environment_information/toplevel_methods/return_pkgconfig_based_programs.rb +0 -28
- data/lib/environment_information/toplevel_methods/return_remote_gtk2_version.rb +0 -54
- data/lib/environment_information/toplevel_methods/return_simple_version_based_programs.rb +0 -28
- data/lib/environment_information/toplevel_methods/return_version_of_this_program.rb +0 -182
- data/lib/environment_information/toplevel_methods/show_all_available_components.rb +0 -192
- data/lib/environment_information/toplevel_methods/write_what_into.rb +0 -24
- data/lib/environment_information/yaml/array_default_programs_on_linux.yml +0 -15
- data/lib/environment_information/yaml/array_lfs_core_programs.yml +0 -37
- data/lib/environment_information/yaml/array_science_cluster.yml +0 -12
- data/lib/environment_information/yaml/array_tracked_non_programs.yml +0 -13
- data/lib/environment_information/yaml/array_tracked_xorg_components.yml +0 -37
- data/lib/environment_information/yaml/query_to_use_for_the_individual_components.yml +0 -284
|
@@ -0,0 +1,2258 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# require 'environment_information/toplevel_methods/toplevel_methods.rb'
|
|
6
|
+
# EnvironmentInformation.return_simple_version_based_programs
|
|
7
|
+
# EnvironmentInformation.return_version_of_this_program(:ccache)
|
|
8
|
+
# EnvironmentInformation.return_pkgconfig_based_programs
|
|
9
|
+
# EnvironmentInformation.return_version_of_mpc
|
|
10
|
+
# =========================================================================== #
|
|
11
|
+
module EnvironmentInformation
|
|
12
|
+
|
|
13
|
+
require 'yaml'
|
|
14
|
+
require 'environment_information/constants/constants.rb'
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
require 'rbt/requires/swift_version.rb'
|
|
18
|
+
rescue LoadError; end
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
require 'rbt/toplevel_methods/url.rb'
|
|
22
|
+
rescue LoadError; end
|
|
23
|
+
|
|
24
|
+
# ========================================================================= #
|
|
25
|
+
# === @hash_available_programs
|
|
26
|
+
#
|
|
27
|
+
# This hash stores the available programs.
|
|
28
|
+
#
|
|
29
|
+
# We need to use a Hash, rather than an Array, because we may save
|
|
30
|
+
# the result into a file, such as a yaml file. It is then more
|
|
31
|
+
# convenient to have the names of the program appear on the left
|
|
32
|
+
# side directoy, and the version on the right side.
|
|
33
|
+
#
|
|
34
|
+
# This Hash will hold the program name on the left side, and the
|
|
35
|
+
# program version on the right side. A nil value on the right
|
|
36
|
+
# side indicates that this program is NOT installed - which
|
|
37
|
+
# makes this the default value.
|
|
38
|
+
# ========================================================================= #
|
|
39
|
+
@hash_available_programs = {}
|
|
40
|
+
|
|
41
|
+
# ========================================================================= #
|
|
42
|
+
# === EnvironmentInformation.hash?
|
|
43
|
+
#
|
|
44
|
+
# This method will return the Hash of all available programs.
|
|
45
|
+
# ========================================================================= #
|
|
46
|
+
def self.hash?
|
|
47
|
+
@hash_available_programs
|
|
48
|
+
end; self.instance_eval { alias hash hash? } # === EnvironmentInformation.hash
|
|
49
|
+
self.instance_eval { alias dataset? hash? } # === EnvironmentInformation.dataset?
|
|
50
|
+
self.instance_eval { alias hash_available_programs? hash? } # === EnvironmentInformation.hash_available_programs?
|
|
51
|
+
|
|
52
|
+
# ========================================================================== #
|
|
53
|
+
# === EnvironmentInformation.e
|
|
54
|
+
# ========================================================================== #
|
|
55
|
+
def self.e(
|
|
56
|
+
i = '',
|
|
57
|
+
hash = {}
|
|
58
|
+
)
|
|
59
|
+
if hash and
|
|
60
|
+
hash.has_key?(:display_everything_in_short_format) and
|
|
61
|
+
hash[:display_everything_in_short_format]
|
|
62
|
+
# ===================================================================== #
|
|
63
|
+
# Display the results in a single line in this case, separated
|
|
64
|
+
# via ',' tokens.
|
|
65
|
+
# ===================================================================== #
|
|
66
|
+
print "#{i}, "
|
|
67
|
+
else # This variant here is the default.
|
|
68
|
+
puts i
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# ========================================================================= #
|
|
73
|
+
# === EnvironmentInformation.add_to_hash
|
|
74
|
+
#
|
|
75
|
+
# a refers to left; b refers to right.
|
|
76
|
+
# ========================================================================= #
|
|
77
|
+
def self.add_to_hash(a, b)
|
|
78
|
+
b.strip! if b.is_a?(String) and !b.frozen?
|
|
79
|
+
if b.nil? # Here we did not provide a value for b.
|
|
80
|
+
::EnvironmentInformation.register_this_component_is_missing(a)
|
|
81
|
+
end
|
|
82
|
+
@hash_available_programs[a] = b
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# ========================================================================= #
|
|
86
|
+
# === EnvironmentInformation.clear_hash
|
|
87
|
+
#
|
|
88
|
+
# This method can be used to clear the main (toplevel) Hash.
|
|
89
|
+
# ========================================================================= #
|
|
90
|
+
def self.clear_hash
|
|
91
|
+
@hash_available_programs.clear
|
|
92
|
+
end; self.instance_eval { alias clear_toplevel_hash clear_hash } # === EnvironmentInformation.clear_toplevel_hash
|
|
93
|
+
self.instance_eval { alias clear_main_hash clear_hash } # === EnvironmentInformation.clear_main_hash
|
|
94
|
+
|
|
95
|
+
# ========================================================================== #
|
|
96
|
+
# === @debug
|
|
97
|
+
#
|
|
98
|
+
# This variable can be used to control whether we debug the project
|
|
99
|
+
# or not. It should be false by default (and upon re-destribution of
|
|
100
|
+
# the project to other users).
|
|
101
|
+
# ========================================================================== #
|
|
102
|
+
@debug = false
|
|
103
|
+
|
|
104
|
+
# ========================================================================== #
|
|
105
|
+
# === EnvironmentInformation.return_the_most_important_info
|
|
106
|
+
#
|
|
107
|
+
# This method will just return a String that can be used right away
|
|
108
|
+
# in, for example, a sinatra application or a RoR application.
|
|
109
|
+
# ========================================================================== #
|
|
110
|
+
def self.return_the_most_important_info
|
|
111
|
+
"Operating system: "+
|
|
112
|
+
"#{::EnvironmentInformation.operating_system}<br>"+
|
|
113
|
+
"Operating system bit type: "+
|
|
114
|
+
"#{::EnvironmentInformation.operating_system_bit_type}<br>"+
|
|
115
|
+
"CPU model: "+
|
|
116
|
+
"#{::EnvironmentInformation.cpu_model}<br>"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# ========================================================================== #
|
|
120
|
+
# === EnvironmentInformation.n_subcommands?
|
|
121
|
+
#
|
|
122
|
+
# Return how many subcommands are available/registered. These are
|
|
123
|
+
# the tracked programs; and the xorg-components.
|
|
124
|
+
#
|
|
125
|
+
# The non-programs will not be gathered by this method, on purpose; they
|
|
126
|
+
# are not standalone programs after all.
|
|
127
|
+
#
|
|
128
|
+
# As of August 2020, 167 programs were tracked by this gem.
|
|
129
|
+
#
|
|
130
|
+
# As of March 2024, 256 components were tracked by this gem, so about
|
|
131
|
+
# 250 programs, give or take.
|
|
132
|
+
# ========================================================================== #
|
|
133
|
+
def self.n_subcommands?
|
|
134
|
+
ARRAY_TRACKED_PROGRAMS.size
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# ========================================================================== #
|
|
138
|
+
# === @prefix_to_use
|
|
139
|
+
#
|
|
140
|
+
# This variable can be used to designate another base directory to
|
|
141
|
+
# be used, such as at /home/Programs/ or opt. This allows us to scan
|
|
142
|
+
# through an AppDir and output the programs found there.
|
|
143
|
+
#
|
|
144
|
+
# By default it must be an empty String, as many other files check
|
|
145
|
+
# on the content of this variable - so only change it if you really
|
|
146
|
+
# need to use another prefix to use.
|
|
147
|
+
#
|
|
148
|
+
# The functionality was specifically added to support versioned
|
|
149
|
+
# AppDirs on a given computer system.
|
|
150
|
+
# ========================================================================== #
|
|
151
|
+
@prefix_to_use = ''.dup
|
|
152
|
+
|
|
153
|
+
# ========================================================================== #
|
|
154
|
+
# === EnvironmentInformation.set_prefix_to_use
|
|
155
|
+
# ========================================================================== #
|
|
156
|
+
def self.set_prefix_to_use(i)
|
|
157
|
+
@prefix_to_use = i.to_s.dup
|
|
158
|
+
end; self.instance_eval { alias set_prefix set_prefix_to_use } # === EnvironmentInformation.set_prefix
|
|
159
|
+
|
|
160
|
+
# ========================================================================== #
|
|
161
|
+
# === EnvironmentInformation.prefix?
|
|
162
|
+
# ========================================================================== #
|
|
163
|
+
def self.prefix?
|
|
164
|
+
@prefix_to_use
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# ========================================================================== #
|
|
168
|
+
# === EnvironmentInformation.return_version_of_doubleconversion
|
|
169
|
+
# ========================================================================== #
|
|
170
|
+
def self.return_version_of_doubleconversion(
|
|
171
|
+
target_file = '/usr/lib/cmake/double-conversion/double-conversionConfigVersion.cmake'
|
|
172
|
+
)
|
|
173
|
+
if File.exist? target_file
|
|
174
|
+
dataset = File.read(target_file)
|
|
175
|
+
result = dataset.scan(
|
|
176
|
+
/PACKAGE_VERSION "(.+)"/
|
|
177
|
+
).flatten.first.to_s
|
|
178
|
+
return result
|
|
179
|
+
else
|
|
180
|
+
return nil
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# ========================================================================== #
|
|
185
|
+
# === EnvironmentInformation.return_version_of_boost
|
|
186
|
+
#
|
|
187
|
+
# This method will either return a String (the version of boost),
|
|
188
|
+
# or nil if boost was not found.
|
|
189
|
+
# ========================================================================== #
|
|
190
|
+
def self.return_version_of_boost
|
|
191
|
+
target_file = '/usr/include/boost/version.hpp'
|
|
192
|
+
if File.exist?('/System/Index/include/boost/version.hpp') and
|
|
193
|
+
!File.exist?(target_file) # Custom fix.
|
|
194
|
+
target_file = '/System/Index/include/boost/version.hpp'
|
|
195
|
+
end
|
|
196
|
+
if File.exist? target_file
|
|
197
|
+
dataset = File.readlines(target_file)
|
|
198
|
+
version = dataset.select {|line|
|
|
199
|
+
line.include? '#define BOOST_LIB_VERSION'
|
|
200
|
+
}.first.sub(/#define BOOST_LIB_VERSION/,'').
|
|
201
|
+
strip.delete('"').tr('_','.')
|
|
202
|
+
if version.count('.') < 2
|
|
203
|
+
version << '.0'
|
|
204
|
+
end
|
|
205
|
+
else
|
|
206
|
+
version = nil
|
|
207
|
+
end
|
|
208
|
+
return version
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# ========================================================================== #
|
|
212
|
+
# === EnvironmentInformation.return_version_of_xvid
|
|
213
|
+
# ========================================================================== #
|
|
214
|
+
def self.return_version_of_xvid(
|
|
215
|
+
target_file = '/usr/include/xvid.h'
|
|
216
|
+
)
|
|
217
|
+
if File.exist?('/System/Index/include/'+File.basename(target_file)) and
|
|
218
|
+
!File.exist?(target_file) # Custom fix.
|
|
219
|
+
target_file = '/System/Index/include/'+File.basename(target_file)
|
|
220
|
+
end
|
|
221
|
+
if File.exist? target_file
|
|
222
|
+
dataset = File.readlines(target_file)
|
|
223
|
+
version = dataset.select {|line|
|
|
224
|
+
line.include? ' XVID_MAKE_VERSION(' # #define XVID_VERSION XVID_MAKE_VERSION(1,3,7)
|
|
225
|
+
}
|
|
226
|
+
if version.is_a? Array
|
|
227
|
+
version = version.flatten.first.to_s
|
|
228
|
+
end
|
|
229
|
+
version = version.scan( # See: https://rubular.com/r/4anuroBmb40yzh
|
|
230
|
+
/XVID_MAKE_VERSION\((\d{0,1},\d{0,1},\d{0,1})/
|
|
231
|
+
)
|
|
232
|
+
if version.is_a? Array
|
|
233
|
+
version = version.flatten.first.to_s
|
|
234
|
+
end
|
|
235
|
+
version.tr!(',','.')
|
|
236
|
+
else
|
|
237
|
+
version = nil
|
|
238
|
+
end
|
|
239
|
+
return version
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# ========================================================================== #
|
|
243
|
+
# === EnvironmentInformation.is_this_program_included?
|
|
244
|
+
#
|
|
245
|
+
# This will include the two Arrays ARRAY_TRACKED_PROGRAMS and
|
|
246
|
+
# ARRAY_XORG_COMPONENTS, but it will NOT include ARRAY_TRACKED_NON_PROGRAMS.
|
|
247
|
+
# ========================================================================== #
|
|
248
|
+
def self.is_this_program_included?(i)
|
|
249
|
+
(
|
|
250
|
+
ARRAY_TRACKED_PROGRAMS
|
|
251
|
+
).flatten.include? i.to_sym # Need a symbol.
|
|
252
|
+
end; self.instance_eval { alias is_this_a_registered_program? is_this_program_included? } # === ::EnvironmentInformation.is_this_a_registered_program?
|
|
253
|
+
|
|
254
|
+
# ========================================================================== #
|
|
255
|
+
# === EnvironmentInformation.cd (cd tag)
|
|
256
|
+
# ========================================================================== #
|
|
257
|
+
def self.cd(i)
|
|
258
|
+
Dir.chdir(i) if File.directory? i
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# ========================================================================== #
|
|
262
|
+
# === EnvironmentInformation.is_on_roebe?
|
|
263
|
+
# ========================================================================== #
|
|
264
|
+
def self.is_on_roebe?
|
|
265
|
+
ENV['IS_ROEBE'].to_i == 1
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# ========================================================================= #
|
|
269
|
+
# === EnvironmentInformation.show_all_available_components
|
|
270
|
+
#
|
|
271
|
+
# This method will quickly and easily show all available (registered)
|
|
272
|
+
# components. If you need more fine-tuning when you wish to display
|
|
273
|
+
# the main dataset at hand, then you should use other methods that
|
|
274
|
+
# are also a bit more complex. This method here is really just a
|
|
275
|
+
# fast version-display overview.
|
|
276
|
+
#
|
|
277
|
+
# The second argument to this method contains the programs that we
|
|
278
|
+
# wish to display through this method.
|
|
279
|
+
# ========================================================================= #
|
|
280
|
+
def self.show_all_available_components(
|
|
281
|
+
n_ljust = 18,
|
|
282
|
+
show_these_components = tracked_programs?,
|
|
283
|
+
use_colours = use_colours?
|
|
284
|
+
)
|
|
285
|
+
clear_main_hash
|
|
286
|
+
if show_these_components.is_a? Array
|
|
287
|
+
show_these_components.flatten!
|
|
288
|
+
end
|
|
289
|
+
# ======================================================================= #
|
|
290
|
+
# The next variable determines whether we will also compare the
|
|
291
|
+
# program versions.
|
|
292
|
+
# ======================================================================= #
|
|
293
|
+
compare_program_versions = false
|
|
294
|
+
default_nljust_value = 30 # ← Detemine default padding.
|
|
295
|
+
if n_ljust.is_a?(Array) and n_ljust.empty?
|
|
296
|
+
n_ljust = default_nljust_value # Use the default value in this case.
|
|
297
|
+
end
|
|
298
|
+
# ======================================================================= #
|
|
299
|
+
# First we will treat n_ljust as a commandline-flag if it is a String
|
|
300
|
+
# and additionally begins with "--".
|
|
301
|
+
# ======================================================================= #
|
|
302
|
+
if n_ljust.is_a?(Array) and n_ljust.first.start_with?('--')
|
|
303
|
+
_ = n_ljust.first
|
|
304
|
+
case _
|
|
305
|
+
# ===================================================================== #
|
|
306
|
+
# === --help
|
|
307
|
+
#
|
|
308
|
+
# Invocation example:
|
|
309
|
+
#
|
|
310
|
+
# showcomponents --help
|
|
311
|
+
#
|
|
312
|
+
# ===================================================================== #
|
|
313
|
+
when /^-?-?help$/i
|
|
314
|
+
e 'The following options are available for bin/fast_envi (fenvi):'
|
|
315
|
+
e
|
|
316
|
+
e ' --xorg # show only the xorg-components'
|
|
317
|
+
e ' --compare-to-program-versions # also compare the program versions'
|
|
318
|
+
e
|
|
319
|
+
exit
|
|
320
|
+
# ===================================================================== #
|
|
321
|
+
# === --compare-to-program-versions
|
|
322
|
+
#
|
|
323
|
+
# To invoke this, try:
|
|
324
|
+
#
|
|
325
|
+
# show_components --compare
|
|
326
|
+
# envi --compare-version
|
|
327
|
+
#
|
|
328
|
+
# ===================================================================== #
|
|
329
|
+
when *ARRAY_COMPARE_PROGRAM_VERSIONS
|
|
330
|
+
compare_program_versions = true
|
|
331
|
+
n_ljust = default_nljust_value
|
|
332
|
+
# ===================================================================== #
|
|
333
|
+
# === --xorg
|
|
334
|
+
# ===================================================================== #
|
|
335
|
+
when /^-?-?xorg$/i
|
|
336
|
+
show_these_components = ::EnvironmentInformation.xorg_components?
|
|
337
|
+
n_ljust = default_nljust_value
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
e
|
|
341
|
+
uniq = show_these_components.uniq
|
|
342
|
+
uniq.sort.each {|this_program|
|
|
343
|
+
use_this_name_for_send = "return_version_of_#{this_program}"
|
|
344
|
+
# ===================================================================== #
|
|
345
|
+
# Next, add the name of the program at hand, onto the left hand side:
|
|
346
|
+
# ===================================================================== #
|
|
347
|
+
result = this_program.to_s.ljust(n_ljust)
|
|
348
|
+
if use_colours
|
|
349
|
+
result = ::EnvironmentInformation.colourize_and_pad_the_left_side(result)
|
|
350
|
+
end
|
|
351
|
+
# ===================================================================== #
|
|
352
|
+
# Some components may not be installed on the user's computer system,
|
|
353
|
+
# which we have to keep in mind in the following code. This is
|
|
354
|
+
# why we will first apply the .send(), before checking whether
|
|
355
|
+
# the program at hand is actually missing or not.
|
|
356
|
+
# ===================================================================== #
|
|
357
|
+
result_of_send = send(use_this_name_for_send)
|
|
358
|
+
if result_of_send
|
|
359
|
+
result_of_send = result_of_send.dup if result_of_send.frozen?
|
|
360
|
+
result_of_send.strip!
|
|
361
|
+
end
|
|
362
|
+
@hash_available_programs[this_program.to_sym] = result_of_send.to_s
|
|
363
|
+
right_component = ''.dup
|
|
364
|
+
if @array_this_component_is_missing.include?(this_program.to_sym)
|
|
365
|
+
right_component << "not installed (or otherwise not found)".ljust(12)
|
|
366
|
+
else
|
|
367
|
+
right_component << result_of_send.ljust(12) if result_of_send
|
|
368
|
+
end
|
|
369
|
+
if use_colours
|
|
370
|
+
# =================================================================== #
|
|
371
|
+
# We will distinguish between components that have been found and
|
|
372
|
+
# components that have not been found.
|
|
373
|
+
# =================================================================== #
|
|
374
|
+
if right_component.include?('not installed')
|
|
375
|
+
right_component = ::Colours.send(:mediumslateblue, right_component)
|
|
376
|
+
else
|
|
377
|
+
right_component = ::Colours.send(colour_for_the_right_side, right_component)
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
result = result.dup if result.frozen?
|
|
381
|
+
result << right_component
|
|
382
|
+
if compare_program_versions
|
|
383
|
+
if is_this_program_included?(this_program)
|
|
384
|
+
registered_local_version = RBT.swift_return_version_of_this_program(this_program.to_sym).to_s.dup
|
|
385
|
+
if registered_local_version.include? 'v'
|
|
386
|
+
# =============================================================== #
|
|
387
|
+
# Modify entries such as 'v12.15.0' into '12.15.0'.
|
|
388
|
+
# =============================================================== #
|
|
389
|
+
registered_local_version.delete!('v')
|
|
390
|
+
end
|
|
391
|
+
case this_program.to_s
|
|
392
|
+
when 'gtk2'
|
|
393
|
+
registered_local_version = query_pkgconfig_version_for(:gtk2)
|
|
394
|
+
else
|
|
395
|
+
if result_of_send.nil?
|
|
396
|
+
# ^^^ This is missing, then, so it will be ignored.
|
|
397
|
+
elsif registered_local_version <= result_of_send
|
|
398
|
+
# This is ok.
|
|
399
|
+
else
|
|
400
|
+
result <<
|
|
401
|
+
royalblue(
|
|
402
|
+
"\n "\
|
|
403
|
+
"^^^ This could be updated; the version in "\
|
|
404
|
+
"RBT is: #{mediumpurple(registered_local_version)}"
|
|
405
|
+
)
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
# ===================================================================== #
|
|
411
|
+
# Finally display our findings to the end user.
|
|
412
|
+
# ===================================================================== #
|
|
413
|
+
e result
|
|
414
|
+
}
|
|
415
|
+
e
|
|
416
|
+
if is_on_roebe? # And store it on my home system too.
|
|
417
|
+
::EnvironmentInformation.store_relevant_files
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
# ========================================================================= #
|
|
422
|
+
# === EnvironmentInformation.replay_from_the_stored_file
|
|
423
|
+
#
|
|
424
|
+
# To invoke this method from the commandline, try:
|
|
425
|
+
#
|
|
426
|
+
# envi --replay
|
|
427
|
+
#
|
|
428
|
+
# ========================================================================= #
|
|
429
|
+
def self.replay_from_the_stored_file(
|
|
430
|
+
_ = return_path_to_the_all_programs_file
|
|
431
|
+
)
|
|
432
|
+
if File.exist? _
|
|
433
|
+
e "Loading from the file #{_}."
|
|
434
|
+
@hash_available_programs = YAML.load_file(_)
|
|
435
|
+
@hash_available_programs.each_pair {|key, value|
|
|
436
|
+
e "#{key}:"+value.to_s
|
|
437
|
+
}
|
|
438
|
+
else
|
|
439
|
+
e "No file exists at #{_}."
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
# ========================================================================== #
|
|
444
|
+
# === EnvironmentInformation.ee
|
|
445
|
+
#
|
|
446
|
+
# This is simply a wrapper over print, as well as adding a ', ' to that.
|
|
447
|
+
# ========================================================================== #
|
|
448
|
+
def self.ee(
|
|
449
|
+
i = ''
|
|
450
|
+
)
|
|
451
|
+
print "#{i}, "
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# ========================================================================== #
|
|
455
|
+
# === EnvironmentInformation.internet_is_available?
|
|
456
|
+
# ========================================================================== #
|
|
457
|
+
def self.internet_is_available?
|
|
458
|
+
require 'resolv'
|
|
459
|
+
dns_resolver = Resolv::DNS.new
|
|
460
|
+
begin
|
|
461
|
+
# ====================================================================== #
|
|
462
|
+
# The first domain name ever. Will probably not be removed.
|
|
463
|
+
# ====================================================================== #
|
|
464
|
+
dns_resolver.getaddress('symbolics.com')
|
|
465
|
+
return true
|
|
466
|
+
rescue Resolv::ResolvError => _error
|
|
467
|
+
return false
|
|
468
|
+
end
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# ========================================================================== #
|
|
472
|
+
# === EnvironmentInformation.return_alias_to
|
|
473
|
+
#
|
|
474
|
+
# This method will return some abbreviations to programs.
|
|
475
|
+
# ========================================================================== #
|
|
476
|
+
def self.return_alias_to(i)
|
|
477
|
+
if i.is_a? Array
|
|
478
|
+
i = i.first
|
|
479
|
+
end
|
|
480
|
+
case i.to_sym
|
|
481
|
+
# ======================================================================== #
|
|
482
|
+
# === :find
|
|
483
|
+
# ======================================================================== #
|
|
484
|
+
when :find
|
|
485
|
+
i = :findutils
|
|
486
|
+
# ======================================================================== #
|
|
487
|
+
# === :diff
|
|
488
|
+
# ======================================================================== #
|
|
489
|
+
when :diff
|
|
490
|
+
i = :diffutils
|
|
491
|
+
# ======================================================================== #
|
|
492
|
+
# === :yacc
|
|
493
|
+
# ======================================================================== #
|
|
494
|
+
when :yacc
|
|
495
|
+
i = :bison
|
|
496
|
+
end
|
|
497
|
+
return i # Always return something.
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
# ========================================================================== #
|
|
501
|
+
# === Environment.verbose_truth
|
|
502
|
+
# ========================================================================== #
|
|
503
|
+
def self.verbose_truth(i)
|
|
504
|
+
case i
|
|
505
|
+
when /true/
|
|
506
|
+
'Yes.'
|
|
507
|
+
when /false/
|
|
508
|
+
'No.'
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
# ========================================================================== #
|
|
513
|
+
# === EnvironmentInformation.load_file_query_to_use_for_the_individual_components
|
|
514
|
+
# ========================================================================== #
|
|
515
|
+
def self.load_file_query_to_use_for_the_individual_components(
|
|
516
|
+
i = ::EnvironmentInformation.project_base_directory?+
|
|
517
|
+
'yaml/query_to_use_for_all_components.yml' # FILE_QUERY_TO_USE_FOR_THE_INDIVIDUAL_COMPONENTS
|
|
518
|
+
)
|
|
519
|
+
if File.exist? i
|
|
520
|
+
return YAML.load_file(i)
|
|
521
|
+
else
|
|
522
|
+
return {}
|
|
523
|
+
end
|
|
524
|
+
end; self.instance_eval { alias all_the_queries load_file_query_to_use_for_the_individual_components } # === EnvironmentInformation.all_the_queries
|
|
525
|
+
self.instance_eval { alias query_to_use_for_all_components load_file_query_to_use_for_the_individual_components } # === EnvironmentInformation.query_to_use_for_all_components
|
|
526
|
+
self.instance_eval { alias query_to_use_for_all_components? load_file_query_to_use_for_the_individual_components } # === EnvironmentInformation.query_to_use_for_all_components?
|
|
527
|
+
|
|
528
|
+
# ========================================================================== #
|
|
529
|
+
# === EnvironmentInformation.return_remote_gtk2_version
|
|
530
|
+
#
|
|
531
|
+
# This method can be used to obtain the latest gtk2-version, from a
|
|
532
|
+
# remote URL.
|
|
533
|
+
#
|
|
534
|
+
# The reason why this was necessary is because the RBT project may not
|
|
535
|
+
# always keep the latest gtk2 version, since gtk3 (and so forth) is more
|
|
536
|
+
# recent. Since we may still have to find out which gtk2 version is the
|
|
537
|
+
# most recent, we need a method to do so - which is precisely what this
|
|
538
|
+
# method here is doing.
|
|
539
|
+
# ========================================================================== #
|
|
540
|
+
def self.return_remote_gtk2_version
|
|
541
|
+
# ======================================================================= #
|
|
542
|
+
# We will use a hardcoded URL pointing towards gtk2:
|
|
543
|
+
# ======================================================================= #
|
|
544
|
+
remote_url = 'https://ftp.gnome.org/pub/GNOME/sources/gtk+/2.24/?C=M;O=D'
|
|
545
|
+
require 'open-uri'
|
|
546
|
+
newest_version = ''
|
|
547
|
+
# ======================================================================= #
|
|
548
|
+
# We will next try to obtain the remote dataset, but this would
|
|
549
|
+
# fail if we have no www-connection, so we must rescue this step.
|
|
550
|
+
# ======================================================================= #
|
|
551
|
+
if internet_is_available?
|
|
552
|
+
begin
|
|
553
|
+
dataset = URI.open(remote_url).read
|
|
554
|
+
use_this_regex =
|
|
555
|
+
/<a href="gtk\+\-(\d.\d\d.\d\d).tar.xz"><img src=/
|
|
556
|
+
scanned = dataset.scan(use_this_regex).flatten
|
|
557
|
+
newest_version = scanned.first
|
|
558
|
+
rescue SocketError => error
|
|
559
|
+
puts "It seems as if we have no working internet "\
|
|
560
|
+
"connection (#{sfancy(error.class)})"
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
return newest_version.strip # ← And return it here.
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
# ========================================================================== #
|
|
567
|
+
# === EnvironmentInformation.is_this_component_included?
|
|
568
|
+
#
|
|
569
|
+
# This is a more extensive check than .is_this_program_included?()
|
|
570
|
+
# ========================================================================== #
|
|
571
|
+
def self.is_this_component_included?(i)
|
|
572
|
+
array = tracked_components?
|
|
573
|
+
array.flatten.include? i.to_sym # Need a Symbol as input.
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
# ========================================================================== #
|
|
577
|
+
# === EnvironmentInformation.lfs_core_programs?
|
|
578
|
+
# ========================================================================== #
|
|
579
|
+
def self.lfs_core_programs?
|
|
580
|
+
ARRAY_LFS_CORE_PROGRAMS
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
# ========================================================================== #
|
|
584
|
+
# === EnvironmentInformation.return_version_of_busybox (busybox tag)
|
|
585
|
+
# ========================================================================== #
|
|
586
|
+
def self.return_version_of_busybox(
|
|
587
|
+
i = "busybox #{ERROR_LINE}"
|
|
588
|
+
)
|
|
589
|
+
result = ::EnvironmentInformation.return_very_silent_system_output_from(i)
|
|
590
|
+
if result and result.is_a?(String) and result.include?("\n")
|
|
591
|
+
first_line = result.split("\n").first
|
|
592
|
+
if first_line.include? ' v'
|
|
593
|
+
# "BusyBox v1.32.0 (2020-11-08 04:41:56 Etc) multi-call binary.\n"
|
|
594
|
+
use_this_regex = /v(\d{0,1}.\d{0,2}.\d{0,1})/ # See: https://rubular.com/r/MpnFXlalLCXXGI
|
|
595
|
+
result = first_line.scan(use_this_regex).flatten.first.to_s
|
|
596
|
+
return result
|
|
597
|
+
end
|
|
598
|
+
end
|
|
599
|
+
return nil
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
# ========================================================================== #
|
|
603
|
+
# === EnvironmentInformation.return_version_of_xrandr
|
|
604
|
+
# ========================================================================== #
|
|
605
|
+
def self.return_version_of_xrandr(
|
|
606
|
+
i = 'xrandr --version'
|
|
607
|
+
)
|
|
608
|
+
result = ::EnvironmentInformation.return_very_silent_system_output_from(i)
|
|
609
|
+
if result
|
|
610
|
+
version = result.strip.split("\n")
|
|
611
|
+
if version.is_a?(Array)
|
|
612
|
+
version = version.first.split(' ').last.strip # Assume: "xrandr program version 1.5.1"
|
|
613
|
+
# or: result = splitted.first.sub(/xrandr program version/,'')
|
|
614
|
+
return version.strip
|
|
615
|
+
end
|
|
616
|
+
end
|
|
617
|
+
return nil
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
# ========================================================================== #
|
|
621
|
+
# === EnvironmentInformation.cflags? (cflags tag)
|
|
622
|
+
#
|
|
623
|
+
# The following is equivalent to the value stored in the variable
|
|
624
|
+
# $CFLAGS, which on unix-like systems may be obtained by issuing
|
|
625
|
+
# the following command:
|
|
626
|
+
#
|
|
627
|
+
# echo $CFLAGS
|
|
628
|
+
#
|
|
629
|
+
# The output may be like this:
|
|
630
|
+
#
|
|
631
|
+
# -O2 -fPIC -fno-strict-overflow -Wno-error
|
|
632
|
+
#
|
|
633
|
+
# ========================================================================== #
|
|
634
|
+
def self.cflags?
|
|
635
|
+
_ = ENV['CFLAGS'].to_s.strip
|
|
636
|
+
_ = '<none>' if _.empty? # Display special status if it is empty.
|
|
637
|
+
return _
|
|
638
|
+
end; self.instance_eval { alias return_version_of_cflags cflags? } # === EnvironmentInformation.return_version_of_cflags
|
|
639
|
+
self.instance_eval { alias cflags cflags? } # === EnvironmentInformation.cflags
|
|
640
|
+
self.instance_eval { alias cflags_in_use? cflags? } # === EnvironmentInformation.cflags_in_use?
|
|
641
|
+
|
|
642
|
+
# ========================================================================== #
|
|
643
|
+
# === EnvironmentInformation.rubygems_installation_directory
|
|
644
|
+
#
|
|
645
|
+
# This method will return the path to the rubygems installation
|
|
646
|
+
# directory, if possible (if it exists).
|
|
647
|
+
#
|
|
648
|
+
# As this ought to be a directory, we will ensure that a trailing '/'
|
|
649
|
+
# token is returned.
|
|
650
|
+
#
|
|
651
|
+
# This method may return a String such as "/root/.gem/".
|
|
652
|
+
# ========================================================================== #
|
|
653
|
+
def self.rubygems_installation_directory(
|
|
654
|
+
prefix_to_use = @prefix_to_use
|
|
655
|
+
)
|
|
656
|
+
result = silent_sys_command("#{prefix_to_use}gem env")
|
|
657
|
+
unless result.include? 'not found'
|
|
658
|
+
# ===================================================================== #
|
|
659
|
+
# Apply a regex next.
|
|
660
|
+
# ===================================================================== #
|
|
661
|
+
path_to_the_rubygem_directory = result.to_s.scan(
|
|
662
|
+
/INSTALLATION DIRECTORY: (.+)/ # Obtain the proper match here.
|
|
663
|
+
).flatten.first.to_s
|
|
664
|
+
if File.directory? path_to_the_rubygem_directory
|
|
665
|
+
path_to_the_rubygem_directory << '/' # Append the trailing '/' here.
|
|
666
|
+
end unless path_to_the_rubygem_directory.end_with? '/'
|
|
667
|
+
result = path_to_the_rubygem_directory
|
|
668
|
+
else
|
|
669
|
+
result = nil
|
|
670
|
+
end
|
|
671
|
+
return result
|
|
672
|
+
end; self.instance_eval { alias add_rubygems_installation_directory_information rubygems_installation_directory } # === EnvironmentInformation.add_rubygems_installation_directory_information
|
|
673
|
+
self.instance_eval { alias add_rubygem_directory_information rubygems_installation_directory } # === EnvironmentInformation.add_rubygem_directory_information
|
|
674
|
+
self.instance_eval { alias append_rubygem_installation_directory rubygems_installation_directory } # === EnvironmentInformation.append_rubygem_installation_directory
|
|
675
|
+
self.instance_eval { alias return_version_of_rubygems_installation_directory rubygems_installation_directory } # === EnvironmentInformation.return_version_of_rubygems_installation_directory
|
|
676
|
+
self.instance_eval { alias rubygems_installation_directory? rubygems_installation_directory } # === EnvironmentInformation.rubygems_installation_directory?
|
|
677
|
+
|
|
678
|
+
# ========================================================================== #
|
|
679
|
+
# === EnvironmentInformation.screen_resolution (screen tag)
|
|
680
|
+
#
|
|
681
|
+
# This method will typically make use of xdpyinfo first, as it also
|
|
682
|
+
# works in a .cgi environment. For non-cgi environments, on linux,
|
|
683
|
+
# we could use xrandr, which is a bit more elegant.
|
|
684
|
+
#
|
|
685
|
+
# On success, the method here will return a String such as "1920x1080".
|
|
686
|
+
# ========================================================================== #
|
|
687
|
+
def self.screen_resolution
|
|
688
|
+
result = '(unknown)' # This is the default return-value, then.
|
|
689
|
+
# ======================================================================= #
|
|
690
|
+
# === Check for linux as host OS first
|
|
691
|
+
# ======================================================================= #
|
|
692
|
+
if RUBY_PLATFORM.downcase.include? 'linux'
|
|
693
|
+
# ================================================================= #
|
|
694
|
+
# We have to be careful as xdpyinfo may not be installed on the
|
|
695
|
+
# given computer system.
|
|
696
|
+
# ================================================================= #
|
|
697
|
+
# resolution = `xdpyinfo #{ERROR_LINE}`.scan(/dimensions:.+$/).first # The error here may be: "xdpyinfo: unable to open display"
|
|
698
|
+
resolution = silent_sys_command('xdpyinfo').scan(/dimensions:.+$/).first # The error here may be: "xdpyinfo: unable to open display"
|
|
699
|
+
if resolution and resolution.include? ':'
|
|
700
|
+
result = resolution.split(':').last.strip.split('pixels').first.strip # Or split on: /(\d{1,5}x\d{1,4})/
|
|
701
|
+
end
|
|
702
|
+
# ======================================================================= #
|
|
703
|
+
# === Else simply assume the computer to run windows here
|
|
704
|
+
# ======================================================================= #
|
|
705
|
+
else
|
|
706
|
+
result = `wmic desktopmonitor get screenheight,screenwidth #{ERROR_LINE}`
|
|
707
|
+
end
|
|
708
|
+
return result
|
|
709
|
+
end; self.instance_eval { alias screen_resolution? screen_resolution } # === EnvironmentInformation.screen_resolution?
|
|
710
|
+
self.instance_eval { alias return_version_of_screen_resolution screen_resolution } # === EnvironmentInformation.return_version_of_screen_resolution
|
|
711
|
+
|
|
712
|
+
# ========================================================================== #
|
|
713
|
+
# === EnvironmentInformation.ram? (ram tag)
|
|
714
|
+
#
|
|
715
|
+
# This method will determine how much RAM the given computer host has.
|
|
716
|
+
#
|
|
717
|
+
# The result will be given in n MB.
|
|
718
|
+
#
|
|
719
|
+
# Alternatively we could use /proc/meminfo and look for 'MemTotal:'.
|
|
720
|
+
# ========================================================================== #
|
|
721
|
+
def self.ram?
|
|
722
|
+
result_in_n_mb = silent_sys_command('free -m').split("\n")[1]
|
|
723
|
+
if result_in_n_mb and result_in_n_mb.include?(' ')
|
|
724
|
+
result_in_n_mb = result_in_n_mb.split(' ')[1]
|
|
725
|
+
end
|
|
726
|
+
return result_in_n_mb
|
|
727
|
+
end; self.instance_eval { alias return_version_of_ram ram? } # === EnvironmentInformation.return_version_of_ram
|
|
728
|
+
self.instance_eval { alias ram ram? } # === EnvironmentInformation.ram
|
|
729
|
+
|
|
730
|
+
# ========================================================================== #
|
|
731
|
+
# === EnvironmentInformation.operating_system (os tag)
|
|
732
|
+
#
|
|
733
|
+
# This method is also known as "bit type".
|
|
734
|
+
#
|
|
735
|
+
# The return value of this method may be a String such as this one here:
|
|
736
|
+
#
|
|
737
|
+
# "GNU/Linux"
|
|
738
|
+
#
|
|
739
|
+
# This is then further modified a bit to drop the "GNU/" part
|
|
740
|
+
# specifically.
|
|
741
|
+
#
|
|
742
|
+
# An alternative to "uname -mo" would be "uname -a".
|
|
743
|
+
# ========================================================================== #
|
|
744
|
+
def self.operating_system(
|
|
745
|
+
i = 'uname -mo'
|
|
746
|
+
)
|
|
747
|
+
result = silent_sys_command(i).chomp
|
|
748
|
+
if result.start_with? 'GNU'
|
|
749
|
+
# ====================================================================== #
|
|
750
|
+
# The next part removes 'GNU/' specifically. It is a simpler name
|
|
751
|
+
# than "GNU Linux" and variants, just as "BSD" is simpler than
|
|
752
|
+
# e. g. "FreeBSD". You can reason that it may be "less accurate",
|
|
753
|
+
# but it makes the notification-part of this gem simpler.
|
|
754
|
+
# ====================================================================== #
|
|
755
|
+
result.sub!(/^GNU\//,'') # Experimental as of Sep 2019.
|
|
756
|
+
end
|
|
757
|
+
if result.include? ' '
|
|
758
|
+
result = result.split(' ').last
|
|
759
|
+
end
|
|
760
|
+
return result
|
|
761
|
+
end; self.instance_eval { alias operating_system? operating_system } # === EnvironmentInformation.operating_system?
|
|
762
|
+
self.instance_eval { alias operating_system_information? operating_system } # === EnvironmentInformation.operating_system_information
|
|
763
|
+
self.instance_eval { alias add_operating_system_information operating_system } # === EnvironmentInformation.add_operating_system_information
|
|
764
|
+
self.instance_eval { alias append_operating_system_in_use operating_system } # === EnvironmentInformation.append_operating_system_in_use
|
|
765
|
+
self.instance_eval { alias add_os_information operating_system } # === EnvironmentInformation.add_os_information
|
|
766
|
+
self.instance_eval { alias operating_system_in_use? operating_system } # === EnvironmentInformation.operating_system_in_use?
|
|
767
|
+
self.instance_eval { alias return_version_of_operating_system operating_system } # === EnvironmentInformation.return_version_of_operating_system
|
|
768
|
+
self.instance_eval { alias return_version_of_operating_system_in_use operating_system } # === EnvironmentInformation.return_version_of_operating_system_in_use
|
|
769
|
+
|
|
770
|
+
# ========================================================================== #
|
|
771
|
+
# === EnvironmentInformation.operating_system_bit_type_information (bit tag, bit type tag)
|
|
772
|
+
#
|
|
773
|
+
# This method will return the bit type in use, as a String, such as "x86_64"
|
|
774
|
+
# or "x86_64 (64 bit)" specifically. The reason why this method appends
|
|
775
|
+
# ' (64 bit)' is mostly so that the user can quickly see whether a computer
|
|
776
|
+
# is on 32 bit or on 64 bit.
|
|
777
|
+
# ========================================================================== #
|
|
778
|
+
def self.operating_system_bit_type_information
|
|
779
|
+
result = silent_sys_command('uname -m')
|
|
780
|
+
result.chomp!
|
|
781
|
+
result = result.split(' ')[-1] if result.include?(' ')
|
|
782
|
+
result = result.dup if result.frozen?
|
|
783
|
+
case result
|
|
784
|
+
when 'x86_64'
|
|
785
|
+
result << ' (64 bit)'
|
|
786
|
+
end
|
|
787
|
+
return result
|
|
788
|
+
end; self.instance_eval { alias bit_type? operating_system_bit_type_information } # === EnvironmentInformation.bit_type?
|
|
789
|
+
self.instance_eval { alias return_version_of_operating_system_bit_type operating_system_bit_type_information } # === EnvironmentInformation.return_version_of_operating_system_bit_type
|
|
790
|
+
self.instance_eval { alias add_bit_type_information operating_system_bit_type_information } # === EnvironmentInformation.add_bit_type_information
|
|
791
|
+
self.instance_eval { alias add_operating_system_bit_type operating_system_bit_type_information } # === EnvironmentInformation.add_operating_system_bit_type
|
|
792
|
+
self.instance_eval { alias operating_system_bit_type? operating_system_bit_type_information } # === EnvironmentInformation.operating_system_bit_type?
|
|
793
|
+
self.instance_eval { alias operating_system_bit_type operating_system_bit_type_information } # === EnvironmentInformation.operating_system_bit_type
|
|
794
|
+
|
|
795
|
+
# ========================================================================== #
|
|
796
|
+
# === EnvironmentInformation.return_version_of_mpc
|
|
797
|
+
#
|
|
798
|
+
# This method will read the version-string from a .h header file.
|
|
799
|
+
# ========================================================================== #
|
|
800
|
+
def self.return_version_of_mpc
|
|
801
|
+
target_file = '/usr/include/mpc.h'
|
|
802
|
+
if File.exist? target_file
|
|
803
|
+
dataset = File.read(target_file)
|
|
804
|
+
use_this_regex = /MPC_VERSION_STRING "([0-9\.]+)"$/
|
|
805
|
+
dataset = dataset.scan(use_this_regex).flatten
|
|
806
|
+
version = dataset.first
|
|
807
|
+
return version
|
|
808
|
+
else
|
|
809
|
+
return THE_PROGRAM_WAS_NOT_FOUND
|
|
810
|
+
end
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
# ========================================================================== #
|
|
814
|
+
# === EnvironmentInformation.return_remote_url_of_this_program
|
|
815
|
+
#
|
|
816
|
+
# This method will try to return the remote URL of the given program.
|
|
817
|
+
#
|
|
818
|
+
# Note that this functionality depends on the RBT project, which
|
|
819
|
+
# explains the rescued required statement in the method. While in
|
|
820
|
+
# theory we could create a stand-alone solution, I don't want to
|
|
821
|
+
# duplicate code I already wrote for another project, so users
|
|
822
|
+
# are encouraged to install the rbt gem - it's what I use on my
|
|
823
|
+
# home system as well.
|
|
824
|
+
# ========================================================================== #
|
|
825
|
+
def self.return_remote_url_of_this_program(i = ARGV)
|
|
826
|
+
if i.is_a? Array
|
|
827
|
+
i = i.first
|
|
828
|
+
end
|
|
829
|
+
begin
|
|
830
|
+
require 'rbt/cookbooks/url/url.rb'
|
|
831
|
+
i = RBT.return_url1_of_this_program(i)
|
|
832
|
+
rescue LoadError; end
|
|
833
|
+
i
|
|
834
|
+
end
|
|
835
|
+
|
|
836
|
+
# ========================================================================== #
|
|
837
|
+
# === EnvironmentInformation.show_remote_url_of_this_program
|
|
838
|
+
#
|
|
839
|
+
# This method will try to show the remote URL of the given program.
|
|
840
|
+
# ========================================================================== #
|
|
841
|
+
def self.show_remote_url_of_this_program(i = ARGV)
|
|
842
|
+
puts return_remote_url_of_this_program(i)
|
|
843
|
+
end
|
|
844
|
+
|
|
845
|
+
# ========================================================================== #
|
|
846
|
+
# === EnvironmentInformation.cpuinfo? (cpuinfo tag)
|
|
847
|
+
#
|
|
848
|
+
# This method currently relies on /proc/cpuinfo, thus favouring
|
|
849
|
+
# Linux-based systems.
|
|
850
|
+
#
|
|
851
|
+
# The output will be similar to this:
|
|
852
|
+
#
|
|
853
|
+
# AMD A8-7600 Radeon R7, 10 Compute Cores 4C+6G, 4 cores
|
|
854
|
+
#
|
|
855
|
+
# It will become the display part of "CPU Model", so this method is
|
|
856
|
+
# also known as the "cpu model".
|
|
857
|
+
# ========================================================================== #
|
|
858
|
+
def self.cpuinfo?
|
|
859
|
+
result = '/proc/cpuinfo'
|
|
860
|
+
if File.exist? result
|
|
861
|
+
readlines = File.readlines(result)
|
|
862
|
+
_ = readlines.grep(/model name/).first.chomp
|
|
863
|
+
splitted = _.split(':')
|
|
864
|
+
_ = splitted[1].strip # => "model name\t: AMD Sempron(tm) 145 Processor"
|
|
865
|
+
# ====================================================================== #
|
|
866
|
+
# Next, add the amount of cores. We use "nproc" for this but "lscpu"
|
|
867
|
+
# also contains this information. The following regex could be used
|
|
868
|
+
# for lscpu:
|
|
869
|
+
#
|
|
870
|
+
# Core\(s\) per socket: (.+)
|
|
871
|
+
#
|
|
872
|
+
# Ok, we use lscpu for now.
|
|
873
|
+
# ====================================================================== #
|
|
874
|
+
n_cores = silent_sys_command('nproc --all').to_s.strip
|
|
875
|
+
case n_cores
|
|
876
|
+
when '1'
|
|
877
|
+
n_cores << ' core' # Singular.
|
|
878
|
+
else
|
|
879
|
+
n_cores << ' cores' # Plural then.
|
|
880
|
+
end
|
|
881
|
+
_ << ", #{n_cores}" unless n_cores.empty?
|
|
882
|
+
result = _
|
|
883
|
+
else
|
|
884
|
+
result = nil
|
|
885
|
+
end
|
|
886
|
+
result
|
|
887
|
+
end; self.instance_eval { alias append_operating_system_cpuinfo cpuinfo? } # === EnvironmentInformation.append_operating_system_cpuinfo
|
|
888
|
+
self.instance_eval { alias cpu_model cpuinfo? } # === EnvironmentInformation.cpu_model
|
|
889
|
+
self.instance_eval { alias cpu_model? cpuinfo? } # === EnvironmentInformation.cpu_model?
|
|
890
|
+
self.instance_eval { alias return_version_of_cpuinfo cpuinfo? } # === EnvironmentInformation.return_version_of_cpuinfo
|
|
891
|
+
self.instance_eval { alias cpuinfo cpuinfo? } # === EnvironmentInformation.cpuinfo
|
|
892
|
+
|
|
893
|
+
# ========================================================================== #
|
|
894
|
+
# === EnvironmentInformation.write_what_into
|
|
895
|
+
# ========================================================================== #
|
|
896
|
+
def self.write_what_into(
|
|
897
|
+
what,
|
|
898
|
+
into
|
|
899
|
+
)
|
|
900
|
+
what = what.join("\n") if what.is_a? Array
|
|
901
|
+
File.open(into, 'w+') {|entry| entry.write(what) }
|
|
902
|
+
end
|
|
903
|
+
|
|
904
|
+
# ========================================================================== #
|
|
905
|
+
# === EnvironmentInformation.query_pkgconfig_version_for
|
|
906
|
+
#
|
|
907
|
+
# This toplevel-method can be used to query infromation stored in
|
|
908
|
+
# .pc files, done via the pkg-config utility.
|
|
909
|
+
#
|
|
910
|
+
# The input-argument to this method should be the name of the
|
|
911
|
+
# program at hand; and that program should be registered in the
|
|
912
|
+
# corresponding.yml file. The query will then use "pkg-config",
|
|
913
|
+
# which in turn queries the local .pc file for the version. So
|
|
914
|
+
# the local .pc file must be available, as otherwise this
|
|
915
|
+
# method will not find the necessary information.
|
|
916
|
+
# ========================================================================== #
|
|
917
|
+
def self.query_pkgconfig_version_for(
|
|
918
|
+
i = :gtk2
|
|
919
|
+
)
|
|
920
|
+
result = silent_sys_command("pkg-config --modversion #{i}")
|
|
921
|
+
if result.include? 'was not found in the pkg-config search pa'
|
|
922
|
+
result = NOT_FOUND
|
|
923
|
+
end
|
|
924
|
+
return result
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
# ========================================================================== #
|
|
928
|
+
# === @array_missing_components
|
|
929
|
+
#
|
|
930
|
+
# This Array will keep track of all components that are missing on the
|
|
931
|
+
# given system.
|
|
932
|
+
# ========================================================================== #
|
|
933
|
+
@array_missing_components = []
|
|
934
|
+
|
|
935
|
+
# ========================================================================== #
|
|
936
|
+
# === EnvironmentInformation.clear_array_missing_components
|
|
937
|
+
# ========================================================================== #
|
|
938
|
+
def self.clear_array_missing_components
|
|
939
|
+
@array_missing_components
|
|
940
|
+
end; self.instance_eval { alias clear_missing_components clear_array_missing_components } # === EnvironmentInformation.clear_missing_components
|
|
941
|
+
|
|
942
|
+
# ========================================================================== #
|
|
943
|
+
# === EnvironmentInformation.register_this_component_is_missing
|
|
944
|
+
#
|
|
945
|
+
# The ideal input to this method is a Symbol, so that the Array
|
|
946
|
+
# stores only missing components that way.
|
|
947
|
+
# ========================================================================== #
|
|
948
|
+
def self.register_this_component_is_missing(i)
|
|
949
|
+
# ======================================================================== #
|
|
950
|
+
# First check if we have a Symbol as input:
|
|
951
|
+
# ======================================================================== #
|
|
952
|
+
if i.is_a? Symbol
|
|
953
|
+
copy = i.to_s
|
|
954
|
+
if copy.include?('_')
|
|
955
|
+
i = copy.split('_').last.to_sym
|
|
956
|
+
end
|
|
957
|
+
end
|
|
958
|
+
i = i.to_sym unless i.is_a? Symbol
|
|
959
|
+
# ======================================================================== #
|
|
960
|
+
# Do not register the same missing component twice:
|
|
961
|
+
# ======================================================================== #
|
|
962
|
+
unless @array_missing_components.include? i
|
|
963
|
+
@array_missing_components << i
|
|
964
|
+
end
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
# ========================================================================== #
|
|
968
|
+
# === EnvironmentInformation.is_this_component_missing?
|
|
969
|
+
# ========================================================================== #
|
|
970
|
+
def self.is_this_component_missing?(i)
|
|
971
|
+
!@array_missing_components.include?(i)
|
|
972
|
+
end
|
|
973
|
+
|
|
974
|
+
# ========================================================================== #
|
|
975
|
+
# === EnvironmentInformation.return_pkgconfig_based_programs
|
|
976
|
+
#
|
|
977
|
+
# This method will return all programs that are handled by pkgconfig.
|
|
978
|
+
#
|
|
979
|
+
# In March 2024, 150 programs depended on pkg-config (.pc files).
|
|
980
|
+
# ========================================================================== #
|
|
981
|
+
def self.return_pkgconfig_based_programs(
|
|
982
|
+
this_file = ::EnvironmentInformation.file_query_to_use_for_the_individual_components
|
|
983
|
+
)
|
|
984
|
+
dataset = YAML.load_file(this_file)
|
|
985
|
+
return dataset.select {|key, value|
|
|
986
|
+
# ====================================================================== #
|
|
987
|
+
# The next query will select both :pkgconfig and :"pkg-config".
|
|
988
|
+
# ====================================================================== #
|
|
989
|
+
value.to_s.start_with? 'pkg'
|
|
990
|
+
}.keys
|
|
991
|
+
end
|
|
992
|
+
|
|
993
|
+
# ========================================================================= #
|
|
994
|
+
# === EnvironmentInformation.autogenerate_all_relevant_methods
|
|
995
|
+
#
|
|
996
|
+
# By default this method will scan for all tracked programs, and
|
|
997
|
+
# for the xorg-components.
|
|
998
|
+
# ========================================================================= #
|
|
999
|
+
def self.autogenerate_all_relevant_methods(
|
|
1000
|
+
i = tracked_components?
|
|
1001
|
+
)
|
|
1002
|
+
i.flatten!
|
|
1003
|
+
# ======================================================================= #
|
|
1004
|
+
# Add some aliases which will be defined next.
|
|
1005
|
+
# ======================================================================= #
|
|
1006
|
+
hash_aliases = {
|
|
1007
|
+
atk: :libatk, # === EnvironmentInformation.return_version_of_libatk
|
|
1008
|
+
pcre2: :libpcre2, # === EnvironmentInformation.return_version_of_libpcre2
|
|
1009
|
+
pcre: :libpcre, # === EnvironmentInformation.return_version_of_libpcre
|
|
1010
|
+
zlib: :libzlib # === EnvironmentInformation.return_version_of_libzlib
|
|
1011
|
+
}
|
|
1012
|
+
# ======================================================================= #
|
|
1013
|
+
# Iterate over our Array next:
|
|
1014
|
+
# ======================================================================= #
|
|
1015
|
+
i.each {|this_program|
|
|
1016
|
+
case this_program
|
|
1017
|
+
when :kde
|
|
1018
|
+
this_program = :kde_frameworks
|
|
1019
|
+
end
|
|
1020
|
+
self.class.instance_eval {
|
|
1021
|
+
# =================================================================== #
|
|
1022
|
+
# To test this method, try to do:
|
|
1023
|
+
#
|
|
1024
|
+
# EnvironmentInformation.return_version_of_valgrind # => "3.15.0"
|
|
1025
|
+
#
|
|
1026
|
+
# =================================================================== #
|
|
1027
|
+
this_method = "return_version_of_#{this_program}"
|
|
1028
|
+
define_method(this_method) {
|
|
1029
|
+
return_version_of_this_program(this_program)
|
|
1030
|
+
}
|
|
1031
|
+
if hash_aliases.has_key?(this_program)
|
|
1032
|
+
# ================================================================= #
|
|
1033
|
+
# To test this, try:
|
|
1034
|
+
#
|
|
1035
|
+
# EnvironmentInformation.return_version_of_libzlib
|
|
1036
|
+
#
|
|
1037
|
+
# ================================================================= #
|
|
1038
|
+
use_this_as_the_alias_target = "return_version_of_#{hash_aliases[this_program]}"
|
|
1039
|
+
define_method(use_this_as_the_alias_target) {
|
|
1040
|
+
return_version_of_this_program(this_program)
|
|
1041
|
+
}
|
|
1042
|
+
end
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
# autogenerate_all_relevant_methods # ← And call it at once. No longer as of 2024.
|
|
1048
|
+
|
|
1049
|
+
# ========================================================================== #
|
|
1050
|
+
# And add a few more aliases. This list may have to be revisited again at
|
|
1051
|
+
# a later time.
|
|
1052
|
+
# ========================================================================== #
|
|
1053
|
+
# self.instance_eval { alias add_xz_information return_version_of_xz } # === EnvironmentInformation.add_xz_information
|
|
1054
|
+
# self.instance_eval { alias append_xz_version return_version_of_xz } # === EnvironmentInformation.append_xz_version
|
|
1055
|
+
# self.instance_eval { alias return_version_of_sed? return_version_of_sed } # === EnvironmentInformation.return_version_of_sed?
|
|
1056
|
+
# self.instance_eval { alias return_version_of_makeinfo return_version_of_texinfo } # === EnvironmentInformation.return_version_of_makeinfo
|
|
1057
|
+
# self.instance_eval { alias xfsprogs? return_version_of_xfsprogs } # === EnvironmentInformation.xfsprogs?
|
|
1058
|
+
# self.instance_eval { alias add_xfsprogs_information return_version_of_xfsprogs } # === EnvironmentInformation.add_xfsprogs_information
|
|
1059
|
+
# self.instance_eval { alias return_version_of_lftp? return_version_of_lftp } # === EnvironmentInformation.return_version_of_lftp?
|
|
1060
|
+
# self.instance_eval { alias add_llvm_information return_version_of_llvm } # === EnvironmentInformation.add_llvm_information
|
|
1061
|
+
# self.instance_eval { alias append_llvm_version return_version_of_llvm } # === EnvironmentInformation.append_llvm_version
|
|
1062
|
+
# self.instance_eval { alias add_mpc_information return_version_of_mpc } # === EnvironmentInformation.add_mpc_information
|
|
1063
|
+
# self.instance_eval { alias append_mpc_version return_version_of_mpc } # === EnvironmentInformation.append_mpc_version
|
|
1064
|
+
# self.instance_eval { alias try_to_show_re2c_version return_version_of_re2c } # === EnvironmentInformation.try_to_show_re2c_version
|
|
1065
|
+
# self.instance_eval { alias append_re2c_version return_version_of_re2c } # === EnvironmentInformation.append_nasm_version
|
|
1066
|
+
# self.instance_eval { alias return_version_of_pkg_config return_version_of_pkgconfig } # === EnvironmentInformation.return_version_of_pkg_config
|
|
1067
|
+
# self.instance_eval { alias add_readline_information return_version_of_readline } # === EnvironmentInformation.add_readline_information
|
|
1068
|
+
# self.instance_eval { alias append_readline_version return_version_of_readline } # === EnvironmentInformation.add_readline_information
|
|
1069
|
+
# self.instance_eval { alias return_version_of_liblibtasn1 return_version_of_libtasn1 } # === EnvironmentInformation.return_version_of_liblibtasn1
|
|
1070
|
+
# self.instance_eval { alias return_version_of_liblibtasn return_version_of_libtasn1 } # === EnvironmentInformation.return_version_of_liblibtasn
|
|
1071
|
+
# self.instance_eval { alias return_version_of_grep? return_version_of_grep } # === EnvironmentInformation.return_version_of_grep?
|
|
1072
|
+
# self.instance_eval { alias return_version_of_intltool? return_version_of_intltool } # === EnvironmentInformation.return_version_of_intltool?
|
|
1073
|
+
# self.instance_eval { alias glib? return_version_of_glib } # === EnvironmentInformation.glib?
|
|
1074
|
+
# self.instance_eval { alias add_gmp_information return_version_of_gmp } # === EnvironmentInformation.add_gmp_information
|
|
1075
|
+
# self.instance_eval { alias append_gmp_version return_version_of_gmp } # === EnvironmentInformation.append_gmp_version
|
|
1076
|
+
# self.instance_eval { alias kernel return_version_of_linux } # === EnvironmentInformation.kernel
|
|
1077
|
+
# self.instance_eval { alias linux_kernel return_version_of_linux } # === EnvironmentInformation.linux_kernel
|
|
1078
|
+
# self.instance_eval { alias linux_kernel? return_version_of_linux } # === EnvironmentInformation.linux_kernel?
|
|
1079
|
+
# self.instance_eval { alias return_information_about_the_component_called_linux_kernel return_version_of_linux } # === EnvironmentInformation.return_information_about_the_component_called_linux_kernel
|
|
1080
|
+
# self.instance_eval { alias append_kernel_version return_version_of_linux } # === EnvironmentInformation.append_kernel_version
|
|
1081
|
+
# self.instance_eval { alias add_kernel_information return_version_of_linux } # === EnvironmentInformation.add_kernel_information
|
|
1082
|
+
# self.instance_eval { alias return_version_of_linux_kernel return_version_of_linux } # === EnvironmentInformation.return_version_of_linux_kernel
|
|
1083
|
+
# self.instance_eval { alias return_version_of_linux_kernel? return_version_of_linux } # === EnvironmentInformation.return_version_of_linux_kernel?
|
|
1084
|
+
# self.instance_eval { alias boost? return_version_of_boost } # === EnvironmentInformation.boost?
|
|
1085
|
+
# self.instance_eval { alias return_version_of_boost? return_version_of_boost } # === EnvironmentInformation.return_version_of_boost?
|
|
1086
|
+
# self.instance_eval { alias return_version_of_find return_version_of_findutils } # === EnvironmentInformation.return_version_of_find
|
|
1087
|
+
# self.instance_eval { alias findutils? return_version_of_findutils } # === EnvironmentInformation.findutils?
|
|
1088
|
+
# self.instance_eval { alias awk? return_version_of_gawk } # === EnvironmentInformation.awk?
|
|
1089
|
+
# self.instance_eval { alias gawk? return_version_of_gawk } # === EnvironmentInformation.gawk?
|
|
1090
|
+
# self.instance_eval { alias return_information_about_the_component_called_awk return_version_of_gawk } # === EnvironmentInformation.return_information_about_the_component_called_awk
|
|
1091
|
+
# self.instance_eval { alias return_version_of_awk? return_version_of_gawk } # === EnvironmentInformation.return_version_of_awk?
|
|
1092
|
+
# self.instance_eval { alias return_version_of_awk return_version_of_gawk } # === EnvironmentInformation.return_version_of_awk
|
|
1093
|
+
# self.instance_eval { alias append_gdkpixbuf_version return_version_of_gdkpixbuf } # === EnvironmentInformation.append_gdkpixbuf_version
|
|
1094
|
+
# self.instance_eval { alias glibc? return_version_of_glibc } # === EnvironmentInformation.glibc?
|
|
1095
|
+
# self.instance_eval { alias glibc_version? return_version_of_glibc } # === EnvironmentInformation.glibc_version?
|
|
1096
|
+
# self.instance_eval { alias return_version_of_glibc? return_version_of_glibc } # === EnvironmentInformation.return_version_of_glibc?
|
|
1097
|
+
# self.instance_eval { alias ruby? return_version_of_ruby } # === EnvironmentInformation.ruby?
|
|
1098
|
+
# self.instance_eval { alias return_information_about_the_component_called_ruby return_version_of_ruby } # === EnvironmentInformation.return_information_about_the_component_called_ruby
|
|
1099
|
+
# self.instance_eval { alias return_version_of_ruby? return_version_of_ruby } # === EnvironmentInformation.return_version_of_ruby?
|
|
1100
|
+
# self.instance_eval { alias binutils? return_version_of_binutils } # === EnvironmentInformation.binutils?
|
|
1101
|
+
# self.instance_eval { alias return_version_of_binutils? return_version_of_binutils } # === EnvironmentInformation.return_version_of_binutils?
|
|
1102
|
+
# self.instance_eval { alias bison? return_version_of_bison } # === EnvironmentInformation.bison?
|
|
1103
|
+
# self.instance_eval { alias return_version_of_bison? return_version_of_bison } # === EnvironmentInformation.return_version_of_bison?
|
|
1104
|
+
# self.instance_eval { alias return_version_of_flex? return_version_of_flex } # === EnvironmentInformation.return_version_of_flex?
|
|
1105
|
+
# self.instance_eval { alias return_version_of_freetype2 return_version_of_freetype } # === EnvironmentInformation.return_version_of_freetype2
|
|
1106
|
+
# self.instance_eval { alias evince? return_version_of_evince } # === EnvironmentInformation.evince?
|
|
1107
|
+
# self.instance_eval { alias return_version_of_evince? return_version_of_evince } # === EnvironmentInformation.return_version_of_evince?
|
|
1108
|
+
# self.instance_eval { alias gcc? return_version_of_gcc } # === EnvironmentInformation.gcc?
|
|
1109
|
+
# self.instance_eval { alias return_information_about_the_component_called_gcc return_version_of_gcc } # === EnvironmentInformation.return_information_about_the_component_called_gcc
|
|
1110
|
+
# self.instance_eval { alias return_version_of_gcc? return_version_of_gcc } # === EnvironmentInformation.return_version_of_gcc?
|
|
1111
|
+
# self.instance_eval { alias return_version_of_R return_version_of_r } # === EnvironmentInformation.return_version_of_R
|
|
1112
|
+
# self.instance_eval { alias coreutils? return_version_of_coreutils } # === EnvironmentInformation.coreutils?
|
|
1113
|
+
# self.instance_eval { alias return_version_of_coreutils? return_version_of_coreutils } # === EnvironmentInformation.return_version_of_coreutils
|
|
1114
|
+
# self.instance_eval { alias return_version_of_diffutils? return_version_of_diffutils } # === EnvironmentInformation.return_version_of_diffutils?
|
|
1115
|
+
# self.instance_eval { alias return_version_of_libexempi return_version_of_exempi } # === EnvironmentInformation.return_version_of_libexempi
|
|
1116
|
+
# self.instance_eval { alias return_version_of_gpg return_version_of_gnupg } # === EnvironmentInformation.return_version_of_gpg
|
|
1117
|
+
# self.instance_eval { alias return_version_of_gnupg? return_version_of_gnupg } # === EnvironmentInformation.return_version_of_gnupg?
|
|
1118
|
+
# self.instance_eval { alias return_version_of_bzip return_version_of_bzip2 } # === EnvironmentInformation.return_version_of_bzip
|
|
1119
|
+
# self.instance_eval { alias return_version_of_llvm return_version_of_clang } # === EnvironmentInformation.return_version_of_llvm
|
|
1120
|
+
# self.instance_eval { alias return_clang_version return_version_of_clang } # === EnvironmentInformation.return_clang_version
|
|
1121
|
+
# self.instance_eval { alias kde5? return_version_of_kde_frameworks } # === EnvironmentInformation.kde5?
|
|
1122
|
+
# self.instance_eval { alias add_kde5_information return_version_of_kde_frameworks } # === EnvironmentInformation.add_kde5_information
|
|
1123
|
+
# self.instance_eval { alias add_kde_information return_version_of_kde_frameworks } # === EnvironmentInformation.add_kde_information
|
|
1124
|
+
# self.instance_eval { alias return_information_about_the_component_called_rubygems return_version_of_rubygems } # === EnvironmentInformation.return_information_about_the_component_called_rubygems
|
|
1125
|
+
# self.instance_eval { alias rubygems? return_version_of_rubygems } # === EnvironmentInformation.rubygems?
|
|
1126
|
+
# self.instance_eval { alias return_version_of_rubygems? return_version_of_rubygems } # === EnvironmentInformation.return_version_of_rubygems?
|
|
1127
|
+
# self.instance_eval { alias gtk3? return_version_of_gtk3 } # === EnvironmentInformation.gtk3?
|
|
1128
|
+
# self.instance_eval { alias gtk2? return_version_of_gtk2 } # === EnvironmentInformation.gtk2?
|
|
1129
|
+
|
|
1130
|
+
# ========================================================================== #
|
|
1131
|
+
# === EnvironmentInformation.start_gtk_component
|
|
1132
|
+
#
|
|
1133
|
+
# We have to rescue the code so to notify the user what exactly
|
|
1134
|
+
# may have failed.
|
|
1135
|
+
# ========================================================================== #
|
|
1136
|
+
def self.start_gtk_component
|
|
1137
|
+
begin
|
|
1138
|
+
this_file = 'environment_information/gui/gtk3/environment_information.rb'
|
|
1139
|
+
require this_file
|
|
1140
|
+
rescue LoadError => error
|
|
1141
|
+
e "An error happened - file #{sfile(this_file)} could not be found."
|
|
1142
|
+
pp error
|
|
1143
|
+
end
|
|
1144
|
+
::EnvironmentInformation.run_gtk
|
|
1145
|
+
end
|
|
1146
|
+
|
|
1147
|
+
# ========================================================================= #
|
|
1148
|
+
# === EnvironmentInformation.return_version_of_this_program
|
|
1149
|
+
#
|
|
1150
|
+
# This is the general method that will return the version of a particular
|
|
1151
|
+
# program at hand.
|
|
1152
|
+
#
|
|
1153
|
+
# The method must be able to deal with using pkg-config, but also
|
|
1154
|
+
# querying some program's version via --version, via the commandline,
|
|
1155
|
+
# Furthermore, some programs may require an ad-hoc fix.
|
|
1156
|
+
# ========================================================================= #
|
|
1157
|
+
def self.return_version_of_this_program(
|
|
1158
|
+
this_program,
|
|
1159
|
+
prefix_to_use = @prefix_to_use
|
|
1160
|
+
)
|
|
1161
|
+
prefix_to_use = prefix_to_use.dup if prefix_to_use
|
|
1162
|
+
version = nil # ← This is the default.
|
|
1163
|
+
if this_program.is_a? Array
|
|
1164
|
+
this_program = this_program.flatten.first
|
|
1165
|
+
end
|
|
1166
|
+
# ======================================================================= #
|
|
1167
|
+
# Next define a few aliases.
|
|
1168
|
+
# ======================================================================= #
|
|
1169
|
+
this_program = ::EnvironmentInformation.return_alias_to(this_program)
|
|
1170
|
+
if ARRAY_TRACKED_NON_PROGRAMS.include? this_program
|
|
1171
|
+
return ::EnvironmentInformation.send(this_program)
|
|
1172
|
+
elsif @query_to_use_for_the_individual_components.has_key? this_program.to_sym
|
|
1173
|
+
use_this_command = @query_to_use_for_the_individual_components[this_program.to_sym]
|
|
1174
|
+
case use_this_command
|
|
1175
|
+
# ===================================================================== #
|
|
1176
|
+
# === :mate_desktop
|
|
1177
|
+
#
|
|
1178
|
+
# This entry is special.
|
|
1179
|
+
# ===================================================================== #
|
|
1180
|
+
when :mate_desktop
|
|
1181
|
+
return RBT.return_mate_desktop_version_array
|
|
1182
|
+
# ===================================================================== #
|
|
1183
|
+
# === :pkgconfig
|
|
1184
|
+
#
|
|
1185
|
+
# An invocation example for this would be:
|
|
1186
|
+
#
|
|
1187
|
+
# x = EnvironmentInformation.return_version_of_this_program(:check) # => "0.15.2"
|
|
1188
|
+
#
|
|
1189
|
+
# ===================================================================== #
|
|
1190
|
+
when :pkgconfig
|
|
1191
|
+
version = ::EnvironmentInformation::Queries::PkgConfig.new(this_program).version?
|
|
1192
|
+
# ===================================================================== #
|
|
1193
|
+
# === :custom_gtk2
|
|
1194
|
+
# ===================================================================== #
|
|
1195
|
+
when :custom_gtk2
|
|
1196
|
+
version = ::EnvironmentInformation::Queries::PkgConfig.new('gtk+-2.0').version?
|
|
1197
|
+
# ===================================================================== #
|
|
1198
|
+
# === :custom_mpc
|
|
1199
|
+
#
|
|
1200
|
+
# We rely on the header called mpc.h.
|
|
1201
|
+
# ===================================================================== #
|
|
1202
|
+
when :custom_mpc
|
|
1203
|
+
version = ::EnvironmentInformation.return_version_of_mpc
|
|
1204
|
+
# ===================================================================== #
|
|
1205
|
+
# === :custom_boost
|
|
1206
|
+
# ===================================================================== #
|
|
1207
|
+
when :custom_boost
|
|
1208
|
+
version = ::EnvironmentInformation.return_version_of_boost
|
|
1209
|
+
if version.nil?
|
|
1210
|
+
register_this_component_is_missing(:boost)
|
|
1211
|
+
end
|
|
1212
|
+
# ===================================================================== #
|
|
1213
|
+
# === :version (version tag)
|
|
1214
|
+
#
|
|
1215
|
+
# This entry point is typically for "program_name --version"
|
|
1216
|
+
# entries. Some of them require custom modifications.
|
|
1217
|
+
# ===================================================================== #
|
|
1218
|
+
when :version
|
|
1219
|
+
# =================================================================== #
|
|
1220
|
+
# Next enable support for AppDir layout, where programs will
|
|
1221
|
+
# ultimately reside in the same directory.
|
|
1222
|
+
# =================================================================== #
|
|
1223
|
+
unless prefix_to_use.empty?
|
|
1224
|
+
prefix_to_use << "#{this_program.to_s.capitalize}/Current/bin/"
|
|
1225
|
+
end
|
|
1226
|
+
cmd = "#{prefix_to_use}#{this_program} --version #{ERROR_LINE}"
|
|
1227
|
+
if @debug
|
|
1228
|
+
e Colours.crimson('DEBUG for the prefix-value in use: ')+
|
|
1229
|
+
Colours.steelblue(cmd)
|
|
1230
|
+
end
|
|
1231
|
+
version = ::EnvironmentInformation::Queries::SimpleVersion.new(this_program) {{
|
|
1232
|
+
prefix_to_use: prefix_to_use
|
|
1233
|
+
}}.version?
|
|
1234
|
+
# ===================================================================== #
|
|
1235
|
+
# Next we will handle special programs, such as "swig -v" and similar.
|
|
1236
|
+
# This is done by class ComplexVersion since as of 29.08.2020.
|
|
1237
|
+
# ===================================================================== #
|
|
1238
|
+
else # else tag
|
|
1239
|
+
if use_this_command.start_with?('pkg-config')
|
|
1240
|
+
version = ::EnvironmentInformation::Queries::PkgConfig.new(this_program).version?
|
|
1241
|
+
else
|
|
1242
|
+
cmd = "#{@prefix_to_use}#{use_this_command} #{ERROR_LINE}"
|
|
1243
|
+
version = ::EnvironmentInformation::Queries::ComplexVersion.new(this_program) {{
|
|
1244
|
+
prefix_to_use: prefix_to_use
|
|
1245
|
+
}}.version?
|
|
1246
|
+
end
|
|
1247
|
+
end
|
|
1248
|
+
else
|
|
1249
|
+
e 'Not registered any key for the program: '+this_program.to_s
|
|
1250
|
+
e 'This is currently not allowed - please add this missing information.'
|
|
1251
|
+
exit
|
|
1252
|
+
end
|
|
1253
|
+
result = version
|
|
1254
|
+
if result
|
|
1255
|
+
unless result.include? COMMAND_NOT_FOUND
|
|
1256
|
+
result = result.dup if result.frozen?
|
|
1257
|
+
result.strip!
|
|
1258
|
+
end
|
|
1259
|
+
end
|
|
1260
|
+
if result and (result == 'found' or result == 'foud')
|
|
1261
|
+
register_this_component_is_missing(this_program)
|
|
1262
|
+
elsif result and result.include?(COMMAND_NOT_FOUND)
|
|
1263
|
+
register_this_component_is_missing(this_program)
|
|
1264
|
+
# ======================================================================= #
|
|
1265
|
+
# Check whether pkg-config is available or not.
|
|
1266
|
+
# ======================================================================= #
|
|
1267
|
+
elsif result and (
|
|
1268
|
+
result.include?(PKGCONFIG_COMMAND_NOT_FOUND) or
|
|
1269
|
+
result.include?(NO_SUCH_FILE_OR_DIRECTORY)
|
|
1270
|
+
)
|
|
1271
|
+
register_this_component_is_missing(this_program)
|
|
1272
|
+
elsif result.nil?
|
|
1273
|
+
register_this_component_is_missing(this_program)
|
|
1274
|
+
end
|
|
1275
|
+
return result
|
|
1276
|
+
end; self.instance_eval { alias version_for? return_version_of_this_program } # === EnvironmentInformation,version_for?
|
|
1277
|
+
|
|
1278
|
+
# ========================================================================== #
|
|
1279
|
+
# === EnvironmentInformation.return_version_of_this_program
|
|
1280
|
+
#
|
|
1281
|
+
# This method will try to use --version first.
|
|
1282
|
+
#
|
|
1283
|
+
# This will typically use the main binary at hand, which we thus expect
|
|
1284
|
+
# to respond to --version.
|
|
1285
|
+
#
|
|
1286
|
+
# Note that the method will also handle input that can NOT be generated
|
|
1287
|
+
# via --version. This is usually called a "complex" version query, as
|
|
1288
|
+
# far as the environment_information gem is concerned.
|
|
1289
|
+
#
|
|
1290
|
+
# Usage example:
|
|
1291
|
+
#
|
|
1292
|
+
# EnvironmentInformation.return_version_of_this_program(:ccache)
|
|
1293
|
+
#
|
|
1294
|
+
# ========================================================================== #
|
|
1295
|
+
def self.return_version_of_this_program(
|
|
1296
|
+
i,
|
|
1297
|
+
&block
|
|
1298
|
+
)
|
|
1299
|
+
prefix_to_use = ''.dup
|
|
1300
|
+
i = i.to_sym
|
|
1301
|
+
# ======================================================================== #
|
|
1302
|
+
# === Handle blocks given to this method next
|
|
1303
|
+
# ======================================================================== #
|
|
1304
|
+
if block_given?
|
|
1305
|
+
yielded = yield
|
|
1306
|
+
if yielded.is_a? Hash
|
|
1307
|
+
# ======================================================================== #
|
|
1308
|
+
# === :prefix_to_use
|
|
1309
|
+
# ======================================================================== #
|
|
1310
|
+
if yielded.has_key? :prefix_to_use
|
|
1311
|
+
prefix_to_use << yielded.delete(:prefix_to_use)
|
|
1312
|
+
end
|
|
1313
|
+
end
|
|
1314
|
+
end
|
|
1315
|
+
# ======================================================================== #
|
|
1316
|
+
# The next variable will store the Hash containing all individual
|
|
1317
|
+
# queries for the registered programs.
|
|
1318
|
+
#
|
|
1319
|
+
# For instance:
|
|
1320
|
+
#
|
|
1321
|
+
# :busybox=>:custom_busybox, :bzip2=>:"bzip2recover --version",
|
|
1322
|
+
# :cairo=>:pkgconfig, :ccache=>:version, :check=>:pkgconfig,
|
|
1323
|
+
# :clang=>:version, :clutter=>:"pkg-config --modversion clutter-1.0",
|
|
1324
|
+
# :lighttpd=>:version # and so forth
|
|
1325
|
+
#
|
|
1326
|
+
# ======================================================================== #
|
|
1327
|
+
# _ = ::EnvironmentInformation.query_to_use_for_the_individual_components?
|
|
1328
|
+
_ = ::EnvironmentInformation.load_file_query_to_use_for_the_individual_components.transform_keys {|entry|
|
|
1329
|
+
entry.to_sym
|
|
1330
|
+
}
|
|
1331
|
+
if _.nil?
|
|
1332
|
+
_ = ::EnvironmentInformation.load_file_query_to_use_for_the_individual_components
|
|
1333
|
+
end
|
|
1334
|
+
if _.has_key?(i) # Check whether the program is registered.
|
|
1335
|
+
result = _[i]
|
|
1336
|
+
case result.to_sym
|
|
1337
|
+
# ====================================================================== #
|
|
1338
|
+
# === :version
|
|
1339
|
+
#
|
|
1340
|
+
# This is the simplest entry point; we will try the commandline flag
|
|
1341
|
+
# "--version" here. If you have to use "-v" then use :short_version
|
|
1342
|
+
# instead.
|
|
1343
|
+
# ====================================================================== #
|
|
1344
|
+
when :version
|
|
1345
|
+
program_version = silent_sys_command("#{prefix_to_use}#{i} --version").strip
|
|
1346
|
+
# ====================================================================== #
|
|
1347
|
+
# === :short_version
|
|
1348
|
+
# ====================================================================== #
|
|
1349
|
+
when :short_version,
|
|
1350
|
+
:simple_version
|
|
1351
|
+
program_version = silent_sys_command("#{prefix_to_use}#{i} -v").strip
|
|
1352
|
+
# ====================================================================== #
|
|
1353
|
+
# === :custom_busybox
|
|
1354
|
+
# ====================================================================== #
|
|
1355
|
+
when :custom_busybox
|
|
1356
|
+
program_version = ::EnvironmentInformation.return_version_of_busybox
|
|
1357
|
+
# ====================================================================== #
|
|
1358
|
+
# === :custom_xrandr
|
|
1359
|
+
# ====================================================================== #
|
|
1360
|
+
when :custom_xrandr
|
|
1361
|
+
program_version = ::EnvironmentInformation.return_version_of_xrandr
|
|
1362
|
+
# ====================================================================== #
|
|
1363
|
+
# === :custom_xvid
|
|
1364
|
+
# ====================================================================== #
|
|
1365
|
+
when :custom_xvid
|
|
1366
|
+
program_version = ::EnvironmentInformation.return_version_of_xvid
|
|
1367
|
+
# ====================================================================== #
|
|
1368
|
+
# === :custom_boost
|
|
1369
|
+
# ====================================================================== #
|
|
1370
|
+
when :custom_boost
|
|
1371
|
+
program_version = ::EnvironmentInformation.return_version_of_boost
|
|
1372
|
+
# ====================================================================== #
|
|
1373
|
+
# === :custom_mpc
|
|
1374
|
+
# ====================================================================== #
|
|
1375
|
+
when :custom_mpc
|
|
1376
|
+
program_version = ::EnvironmentInformation.return_version_of_mpc
|
|
1377
|
+
end
|
|
1378
|
+
if program_version.include?('not found') # First check whether it was found or not.
|
|
1379
|
+
program_version = ::EnvironmentInformation::NOT_FOUND
|
|
1380
|
+
else
|
|
1381
|
+
if program_version.include? N
|
|
1382
|
+
program_version = program_version.split(N).first
|
|
1383
|
+
end
|
|
1384
|
+
if program_version.include? '--'
|
|
1385
|
+
program_version.gsub!(/--/,'') # For strace specifically.
|
|
1386
|
+
end
|
|
1387
|
+
program_version = sanitize_this_program_version(program_version)
|
|
1388
|
+
# ======================================================================== #
|
|
1389
|
+
# Next handle cases such as the following two examples:
|
|
1390
|
+
#
|
|
1391
|
+
# "ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers"
|
|
1392
|
+
# "openjdk version \"14.0.2\" 2020-07-14"
|
|
1393
|
+
# "ffmpeg version n5.1.2 Copyright (c) 2000-2022 the FFmpeg developers"
|
|
1394
|
+
#
|
|
1395
|
+
# ======================================================================== #
|
|
1396
|
+
if program_version.include? ' version '
|
|
1397
|
+
program_version = program_version.scan(
|
|
1398
|
+
/ version n?"?(\d{0,2}\.\d{1,2}\.?\d{0,2})"?/ # See: See: https://rubular.com/r/39cIQqXin2oco0
|
|
1399
|
+
).flatten.first.to_s.strip
|
|
1400
|
+
end
|
|
1401
|
+
# ======================================================================== #
|
|
1402
|
+
# Next come format-entries such as:
|
|
1403
|
+
#
|
|
1404
|
+
# "lighttpd/1.4.71 - a light and fast webserver"
|
|
1405
|
+
#
|
|
1406
|
+
# This may fail, though - see vim:
|
|
1407
|
+
#
|
|
1408
|
+
# "VIM - Vi IMproved 9.0 (2022 Jun 28, compiled Mar 15 2024 11:08:54)"
|
|
1409
|
+
#
|
|
1410
|
+
# ======================================================================== #
|
|
1411
|
+
if program_version.include? ' - '
|
|
1412
|
+
unless this_program.to_s.include?('vim')
|
|
1413
|
+
program_version = program_version.split(' - ').first.to_s
|
|
1414
|
+
end
|
|
1415
|
+
end
|
|
1416
|
+
# ======================================================================== #
|
|
1417
|
+
# Next we will specifically handle vim:
|
|
1418
|
+
# ======================================================================== #
|
|
1419
|
+
if program_version =~ / (\d{1,2}\.\d{1,2}) \(/
|
|
1420
|
+
program_version = $1.to_s.dup
|
|
1421
|
+
end
|
|
1422
|
+
if program_version.include?('[') and program_version.include?(']')
|
|
1423
|
+
program_version.gsub!(/\[.+\]/, '')
|
|
1424
|
+
end
|
|
1425
|
+
program_version.strip!
|
|
1426
|
+
if program_version.start_with? "#{i} "
|
|
1427
|
+
# For example: "ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]"
|
|
1428
|
+
program_version.sub!(/#{i} /, '')
|
|
1429
|
+
elsif program_version.start_with? "#{i.upcase} "
|
|
1430
|
+
# For example: "NASM version 2.15.04 compiled on Aug 27 2020"
|
|
1431
|
+
program_version.sub!(/#{i.upcase} /, '')
|
|
1432
|
+
end
|
|
1433
|
+
# ======================================================================== #
|
|
1434
|
+
# The next check for "Version" should come after we eliminated
|
|
1435
|
+
# the leading program name.
|
|
1436
|
+
# ======================================================================== #
|
|
1437
|
+
if program_version.include? 'Version '
|
|
1438
|
+
program_version = program_version.scan(
|
|
1439
|
+
/Version (\d{0,2}\.?\d{0,2}\.\d{0,2})/
|
|
1440
|
+
).flatten.first.to_s.dup
|
|
1441
|
+
elsif program_version.include? 'version '
|
|
1442
|
+
# This here should work for most programs, save for perl.
|
|
1443
|
+
program_version = program_version.scan(
|
|
1444
|
+
/version (\d{0,2}\.?\d{0,2}\.\d{0,2})/
|
|
1445
|
+
).flatten.first.to_s.dup
|
|
1446
|
+
end
|
|
1447
|
+
if program_version.include? ' patchlevel '
|
|
1448
|
+
# ================================================================== #
|
|
1449
|
+
# Gnuplot has this specifically: "5.4 patchlevel 0"
|
|
1450
|
+
# ================================================================== #
|
|
1451
|
+
program_version = program_version.sub(/ patchlevel /,'.').strip
|
|
1452
|
+
end
|
|
1453
|
+
# ======================================================================== #
|
|
1454
|
+
# Next we kill everything inside (). This may sometimes be
|
|
1455
|
+
# problematic, which is why this check comes quite late.
|
|
1456
|
+
# ======================================================================== #
|
|
1457
|
+
if program_version.include?('(') and program_version.include?(')')
|
|
1458
|
+
program_version.gsub!(/\(.+\)/, '')
|
|
1459
|
+
end
|
|
1460
|
+
# ======================================================================== #
|
|
1461
|
+
# Handle: "IceWM 1.8.0, Copyright 1997-2003 Marko Macek, 2001 Mathias Hasselmann."
|
|
1462
|
+
# ======================================================================== #
|
|
1463
|
+
if program_version.include?(',')
|
|
1464
|
+
program_version = program_version.split(',').first
|
|
1465
|
+
end
|
|
1466
|
+
if program_version.include?('/')
|
|
1467
|
+
# ================================================================== #
|
|
1468
|
+
# Assume something like "lighttpd/1.4.71".
|
|
1469
|
+
# ================================================================== #
|
|
1470
|
+
program_version = program_version.split('/').last
|
|
1471
|
+
end
|
|
1472
|
+
# ======================================================================== #
|
|
1473
|
+
# Next, if a '-' is included, we split it and use the last part.
|
|
1474
|
+
# This handles cases such as "valgrind-3.16.0".
|
|
1475
|
+
# ======================================================================== #
|
|
1476
|
+
if program_version.include?('-')
|
|
1477
|
+
program_version = program_version.split('-').last
|
|
1478
|
+
end
|
|
1479
|
+
# ======================================================================== #
|
|
1480
|
+
# Last but not least, for "node" specifically.
|
|
1481
|
+
# ======================================================================== #
|
|
1482
|
+
if program_version.start_with? 'v'
|
|
1483
|
+
program_version[0,1] = ''
|
|
1484
|
+
end
|
|
1485
|
+
# ======================================================================== #
|
|
1486
|
+
# Handle cases such as: "nginx/1.18.0"
|
|
1487
|
+
# ======================================================================== #
|
|
1488
|
+
if program_version.include? '/'
|
|
1489
|
+
program_version = program_version.split('/').last.strip
|
|
1490
|
+
end
|
|
1491
|
+
if program_version.include? COMMAND_NOT_FOUND
|
|
1492
|
+
program_version = nil
|
|
1493
|
+
elsif program_version.include? ' '
|
|
1494
|
+
# ================================================================== #
|
|
1495
|
+
# Assume input such as: "GNU ld (GNU Binutils) 2.35"
|
|
1496
|
+
# ================================================================== #
|
|
1497
|
+
program_version = program_version.split(' ').last
|
|
1498
|
+
end
|
|
1499
|
+
end
|
|
1500
|
+
return program_version.strip
|
|
1501
|
+
end
|
|
1502
|
+
end; self.instance_eval { alias return_version_of return_version_of_this_program } # === EnvironmentInformation.return_version_of
|
|
1503
|
+
|
|
1504
|
+
# ========================================================================== #
|
|
1505
|
+
# === EnvironmentInformation.return_simple_version_based_programs
|
|
1506
|
+
#
|
|
1507
|
+
# This method will return an Array, consisting of all files that
|
|
1508
|
+
# can be queried via a simple --version query, via the commandline.
|
|
1509
|
+
# ========================================================================== #
|
|
1510
|
+
def self.return_simple_version_based_programs(
|
|
1511
|
+
i = file_query_to_use_for_the_individual_components
|
|
1512
|
+
)
|
|
1513
|
+
dataset = YAML.load_file(i)
|
|
1514
|
+
dataset.select {|key, value|
|
|
1515
|
+
value = value.to_sym
|
|
1516
|
+
# ===================================================================== #
|
|
1517
|
+
# The next query will select only for :version entries.
|
|
1518
|
+
# ===================================================================== #
|
|
1519
|
+
value == :version
|
|
1520
|
+
}.keys
|
|
1521
|
+
end
|
|
1522
|
+
|
|
1523
|
+
# ========================================================================== #
|
|
1524
|
+
# === EnvironmentInformation.array_missing_components?
|
|
1525
|
+
# ========================================================================== #
|
|
1526
|
+
def self.array_missing_components?
|
|
1527
|
+
@array_missing_components
|
|
1528
|
+
end; self.instance_eval { alias missing_components? array_missing_components? } # === EnvironmentInformation.missing_components?
|
|
1529
|
+
self.instance_eval { alias which_components_are_missing? array_missing_components? } # === EnvironmentInformation.which_components_are_missing?
|
|
1530
|
+
|
|
1531
|
+
# ========================================================================= #
|
|
1532
|
+
# === EnvironmentInformation.return_path_to_all_programs_file
|
|
1533
|
+
# ========================================================================= #
|
|
1534
|
+
def self.return_path_to_all_programs_file
|
|
1535
|
+
"#{temp_directory?}environment_information.yml"
|
|
1536
|
+
end
|
|
1537
|
+
|
|
1538
|
+
# ========================================================================= #
|
|
1539
|
+
# === EnvironmentInformation.show_detailed_information_about_all_available_components
|
|
1540
|
+
#
|
|
1541
|
+
# This method is mostly for testing purposes only; for real use
|
|
1542
|
+
# for the project you should consider making use of
|
|
1543
|
+
# Environment.silent_run instead.
|
|
1544
|
+
#
|
|
1545
|
+
# Do note that this method will always show all available components;
|
|
1546
|
+
# if you need more fine-tuned control then you have to use the
|
|
1547
|
+
# class EnvironmentInformation instead.
|
|
1548
|
+
# ========================================================================= #
|
|
1549
|
+
def self.show_detailed_information_about_all_available_components
|
|
1550
|
+
@hash_available_programs = {} # Clear it every time this method is run.
|
|
1551
|
+
work_on_these_programs = []
|
|
1552
|
+
work_on_these_programs << tracked_components?
|
|
1553
|
+
e
|
|
1554
|
+
work_on_these_programs.each {|this_program|
|
|
1555
|
+
version_of_this_program = ::EnvironmentInformation.return_version_of_this_program(this_program)
|
|
1556
|
+
# ===================================================================== #
|
|
1557
|
+
# Do a little sanitizing next:
|
|
1558
|
+
# ===================================================================== #
|
|
1559
|
+
case this_program.to_s
|
|
1560
|
+
when 'kde_frameworks'
|
|
1561
|
+
this_program = 'KDE Frameworks'.to_sym
|
|
1562
|
+
end
|
|
1563
|
+
left_side = colourize_and_pad_the_left_side(this_program)
|
|
1564
|
+
case version_of_this_program
|
|
1565
|
+
when COMMAND_NOT_FOUND,
|
|
1566
|
+
''
|
|
1567
|
+
version_of_this_program = nil
|
|
1568
|
+
colour_for_the_right_side = :orange
|
|
1569
|
+
else
|
|
1570
|
+
colour_for_the_right_side = :notify_if_missing
|
|
1571
|
+
end
|
|
1572
|
+
# ===================================================================== #
|
|
1573
|
+
# Next register this program into the main hash.
|
|
1574
|
+
# ===================================================================== #
|
|
1575
|
+
@hash_available_programs[this_program] = version_of_this_program
|
|
1576
|
+
right_side = colourize_and_pad_the_right_side(
|
|
1577
|
+
version_of_this_program,
|
|
1578
|
+
colour_for_the_right_side
|
|
1579
|
+
)
|
|
1580
|
+
e " #{left_side} #{right_side}"
|
|
1581
|
+
}
|
|
1582
|
+
e
|
|
1583
|
+
# ======================================================================= #
|
|
1584
|
+
# Report missing programs.
|
|
1585
|
+
# ======================================================================= #
|
|
1586
|
+
_ = missing_components?
|
|
1587
|
+
unless _.empty?
|
|
1588
|
+
e 'The following components were not found:'
|
|
1589
|
+
e
|
|
1590
|
+
_.each {|this_component|
|
|
1591
|
+
e lightseagreen(" #{this_component}")
|
|
1592
|
+
}
|
|
1593
|
+
e
|
|
1594
|
+
end
|
|
1595
|
+
consider_storing_these_results_into_a_local_file
|
|
1596
|
+
end; self.instance_eval { alias test show_detailed_information_about_all_available_components } # === EnvironmentInformation.test
|
|
1597
|
+
|
|
1598
|
+
# ========================================================================= #
|
|
1599
|
+
# === EnvironmentInformation.return_array_of_outdated_programs
|
|
1600
|
+
#
|
|
1601
|
+
# This method will return all programs that are outdated - this
|
|
1602
|
+
# also includes missing programs, so the method name is a slight
|
|
1603
|
+
# misnomer.
|
|
1604
|
+
#
|
|
1605
|
+
# Usage example:
|
|
1606
|
+
#
|
|
1607
|
+
# EnvironmentInformation.initialize
|
|
1608
|
+
# array = EnvironmentInformation.return_array_of_outdated_programs
|
|
1609
|
+
#
|
|
1610
|
+
# ========================================================================= #
|
|
1611
|
+
def self.return_array_of_outdated_programs(
|
|
1612
|
+
hash = ::EnvironmentInformation.hash?
|
|
1613
|
+
)
|
|
1614
|
+
forbidden = ::EnvironmentInformation.load_file_array_tracked_non_programs
|
|
1615
|
+
# ======================================================================= #
|
|
1616
|
+
# Now find all entries that are either nil, or have a too low program
|
|
1617
|
+
# version.
|
|
1618
|
+
# ======================================================================= #
|
|
1619
|
+
array = hash.select {|key, value|
|
|
1620
|
+
if value and forbidden.include?(key) # ← we exclude entries here such as "rubygems_installation_dir".
|
|
1621
|
+
false
|
|
1622
|
+
else
|
|
1623
|
+
if value.nil? or value.include?('not found') or
|
|
1624
|
+
!(value =~ /\d+/) # ← check for at the least one number, such as "1".
|
|
1625
|
+
true
|
|
1626
|
+
else
|
|
1627
|
+
false
|
|
1628
|
+
end
|
|
1629
|
+
end
|
|
1630
|
+
}.keys
|
|
1631
|
+
# ======================================================================= #
|
|
1632
|
+
# Next, check these against the local program version:
|
|
1633
|
+
# local_program_version = key
|
|
1634
|
+
# ======================================================================= #
|
|
1635
|
+
return array
|
|
1636
|
+
end
|
|
1637
|
+
|
|
1638
|
+
# ========================================================================= #
|
|
1639
|
+
# === Environment.silent_run
|
|
1640
|
+
# ========================================================================= #
|
|
1641
|
+
def self.silent_run
|
|
1642
|
+
_ = ::EnvironmentInformation.new { :do_not_run_yet }
|
|
1643
|
+
_.be_silent
|
|
1644
|
+
_.run
|
|
1645
|
+
return _.hash?
|
|
1646
|
+
end; self.instance_eval { alias build_up_and_return_the_main_hash silent_run } # === EnvironmentInformation.build_up_and_return_the_main_hash
|
|
1647
|
+
self.instance_eval { alias initialize_hash silent_run } # === EnvironmentInformation.initialize_hash
|
|
1648
|
+
self.instance_eval { alias initialize silent_run } # === EnvironmentInformation.initialize
|
|
1649
|
+
self.instance_eval { alias run silent_run } # === EnvironmentInformation.run
|
|
1650
|
+
|
|
1651
|
+
# ========================================================================== #
|
|
1652
|
+
# === EnvironmentInformation.store_this_hash_into_a_local_file
|
|
1653
|
+
#
|
|
1654
|
+
# This method will always take the dataset stored in the main Hash when
|
|
1655
|
+
# saving the yaml file at hand.
|
|
1656
|
+
#
|
|
1657
|
+
# The file will be stored under the temp_directory.
|
|
1658
|
+
#
|
|
1659
|
+
# This variant is silent by default.
|
|
1660
|
+
# ========================================================================== #
|
|
1661
|
+
def self.store_this_hash_into_a_local_file(
|
|
1662
|
+
hash = hash_available_programs?,
|
|
1663
|
+
this_file = return_path_to_all_programs_file,
|
|
1664
|
+
be_verbose = false
|
|
1665
|
+
)
|
|
1666
|
+
unless hash.empty?
|
|
1667
|
+
what = YAML.dump(hash)
|
|
1668
|
+
e "#{rev}Storing these #{royalblue(hash.size)} "\
|
|
1669
|
+
"#{rev}components into: #{sfile(this_file)}" if be_verbose
|
|
1670
|
+
::EnvironmentInformation.write_what_into(what, this_file)
|
|
1671
|
+
end
|
|
1672
|
+
end; self.instance_eval { alias consider_storing_these_results_into_a_local_file store_this_hash_into_a_local_file } # === EnvironmentInformation.consider_storing_these_results_into_a_local_file
|
|
1673
|
+
self.instance_eval { alias store_relevant_files store_this_hash_into_a_local_file } # === EnvironmentInformation.store_relevant_files
|
|
1674
|
+
|
|
1675
|
+
# ========================================================================= #
|
|
1676
|
+
# === EnvironmentInformation.return_everything
|
|
1677
|
+
# ========================================================================= #
|
|
1678
|
+
def self.return_everything
|
|
1679
|
+
require 'environment_information/main_class/main_class.rb'
|
|
1680
|
+
_ = ::EnvironmentInformation.new(:do_not_run_yet)
|
|
1681
|
+
_.disable_colours
|
|
1682
|
+
_.be_quiet
|
|
1683
|
+
_.menu('--really-everything')
|
|
1684
|
+
_.run
|
|
1685
|
+
return _.string
|
|
1686
|
+
end
|
|
1687
|
+
|
|
1688
|
+
# ========================================================================== #
|
|
1689
|
+
# === EnvironmentInformation.sanitize_this_version_string (sanitize tag)
|
|
1690
|
+
# ========================================================================== #
|
|
1691
|
+
def self.sanitize_this_version_string(
|
|
1692
|
+
i = nil
|
|
1693
|
+
)
|
|
1694
|
+
return if i.nil?
|
|
1695
|
+
if i.frozen?
|
|
1696
|
+
i = i.dup
|
|
1697
|
+
end
|
|
1698
|
+
# ======================================================================== #
|
|
1699
|
+
# === Handle ccache next:
|
|
1700
|
+
# ======================================================================== #
|
|
1701
|
+
if i.include? 'ccache version ' # Example: ccache version 4.8.2
|
|
1702
|
+
i = i.scan(/ccache version (\d{1,2}\.\d{1,2}\.\d{1,2})/).flatten.first.to_s
|
|
1703
|
+
end
|
|
1704
|
+
# ======================================================================== #
|
|
1705
|
+
# === Handle strace next:
|
|
1706
|
+
# ======================================================================== #
|
|
1707
|
+
if i.include? 'strace -- version '
|
|
1708
|
+
i = i.split('strace -- version ').last
|
|
1709
|
+
end
|
|
1710
|
+
# ======================================================================== #
|
|
1711
|
+
# === Handle glslang next
|
|
1712
|
+
#
|
|
1713
|
+
# We must handle e. g. 'Glslang Version: 11:14.0.0'
|
|
1714
|
+
# ======================================================================== #
|
|
1715
|
+
if i.include?('Glslang Version') and i.include?(':')# e. g. for glslang.
|
|
1716
|
+
i = i.split("\n").first if i.include? "\n"
|
|
1717
|
+
i = i.split(':').last.to_s.strip
|
|
1718
|
+
end
|
|
1719
|
+
# ======================================================================== #
|
|
1720
|
+
# === HMMER: we handle hmmer next here
|
|
1721
|
+
# ======================================================================== #
|
|
1722
|
+
if i.include? '# HMMER ' # ← Specifically for "hammer", e. g. 'HMMER 3.4 (Aug 2023); http://hmmer.org/'
|
|
1723
|
+
i = i.scan(
|
|
1724
|
+
/# HMMER (\d{0,2}\.\d{0,2}\.?\d{0,2})/
|
|
1725
|
+
).flatten.first.to_s
|
|
1726
|
+
end
|
|
1727
|
+
# ======================================================================== #
|
|
1728
|
+
# === Handle xstdcmap next:
|
|
1729
|
+
# ======================================================================== #
|
|
1730
|
+
if i.include? 'xstdcmap '
|
|
1731
|
+
i = i.split('xstdcmap').last.strip
|
|
1732
|
+
end
|
|
1733
|
+
# ======================================================================== #
|
|
1734
|
+
# === Handle qpdf next:
|
|
1735
|
+
# ======================================================================== #
|
|
1736
|
+
if i.include? 'qpdf version '
|
|
1737
|
+
i = i.split('qpdf version ').last.strip
|
|
1738
|
+
end
|
|
1739
|
+
# ======================================================================== #
|
|
1740
|
+
# === Handle Swig next:
|
|
1741
|
+
# ======================================================================== #
|
|
1742
|
+
if i.include? 'SWIG Version'
|
|
1743
|
+
i = i.scan(
|
|
1744
|
+
/SWIG Version (\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
1745
|
+
).flatten.first
|
|
1746
|
+
end
|
|
1747
|
+
# ======================================================================== #
|
|
1748
|
+
# === Handle Screen next
|
|
1749
|
+
#
|
|
1750
|
+
# For: Screen version 4.09.01 (GNU) 20-Aug-23
|
|
1751
|
+
# ======================================================================== #
|
|
1752
|
+
if i.include? 'Screen version'
|
|
1753
|
+
i = i.scan(
|
|
1754
|
+
/Screen version (\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
1755
|
+
).flatten.first
|
|
1756
|
+
end
|
|
1757
|
+
# ======================================================================== #
|
|
1758
|
+
# === Handle valgrind next:
|
|
1759
|
+
# ======================================================================== #
|
|
1760
|
+
if i.include? 'valgrind-'
|
|
1761
|
+
i = i.split('-').last
|
|
1762
|
+
end
|
|
1763
|
+
# ======================================================================== #
|
|
1764
|
+
# === Handle gimp next:
|
|
1765
|
+
#
|
|
1766
|
+
# The String may look like this: 'GNU Image Manipulation Program version 2.10.36'
|
|
1767
|
+
# ======================================================================== #
|
|
1768
|
+
if i.include?('GNU Image Manipulation')
|
|
1769
|
+
i = i.scan(
|
|
1770
|
+
/GNU Image Manipulation Program version (\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
1771
|
+
).flatten.first
|
|
1772
|
+
end
|
|
1773
|
+
# ======================================================================== #
|
|
1774
|
+
# === Handle IceWM here.
|
|
1775
|
+
#
|
|
1776
|
+
# The specific substring is:
|
|
1777
|
+
#
|
|
1778
|
+
# "IceWM 3.4.7, Copyright 1997-2012 Marko Macek, 2001 Mathias Hasselmann."
|
|
1779
|
+
#
|
|
1780
|
+
# ======================================================================== #
|
|
1781
|
+
if i.include? 'IceWM '
|
|
1782
|
+
i = i.scan(
|
|
1783
|
+
/IceWM (\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
1784
|
+
).flatten.first.to_s
|
|
1785
|
+
end
|
|
1786
|
+
# ======================================================================== #
|
|
1787
|
+
# === Handle 'KDE Frameworks: 5.73.0'
|
|
1788
|
+
# ======================================================================== #
|
|
1789
|
+
if i.include? 'KDE Frameworks: '
|
|
1790
|
+
i = i.scan(
|
|
1791
|
+
/KDE Frameworks: (\d{0,2}\.\d{0,3}\.\d{0,2})/ # Must match e. g. "KDE Frameworks: 5.115.0".
|
|
1792
|
+
).flatten.first.to_s
|
|
1793
|
+
end
|
|
1794
|
+
# ======================================================================== #
|
|
1795
|
+
# === Handle 'lighttpd' next
|
|
1796
|
+
# ======================================================================== #
|
|
1797
|
+
if i.include? '- a light and fast webserver'
|
|
1798
|
+
i = i.split('- a light and fast webserver').first
|
|
1799
|
+
i = i.split('/').last if i.include?('/')
|
|
1800
|
+
end
|
|
1801
|
+
# ======================================================================== #
|
|
1802
|
+
# === Handle flatpak next:
|
|
1803
|
+
# ======================================================================== #
|
|
1804
|
+
if i.include? 'Flatpak '
|
|
1805
|
+
i = i.split('Flatpak ').last
|
|
1806
|
+
end
|
|
1807
|
+
# ======================================================================== #
|
|
1808
|
+
# === Handle xinput next:
|
|
1809
|
+
# ======================================================================== #
|
|
1810
|
+
if i.include? 'xinput version '
|
|
1811
|
+
i = i.split(' ').last
|
|
1812
|
+
end
|
|
1813
|
+
# ======================================================================== #
|
|
1814
|
+
# === Handle vim next
|
|
1815
|
+
# ======================================================================== #
|
|
1816
|
+
if i.include? 'IMproved ' # For Vim.
|
|
1817
|
+
i = i.scan(
|
|
1818
|
+
/VIM - Vi IMproved (\d{1,2}\.\d{1,2})/
|
|
1819
|
+
).flatten.first
|
|
1820
|
+
end
|
|
1821
|
+
# ======================================================================== #
|
|
1822
|
+
# === Handle xfs next:
|
|
1823
|
+
# ======================================================================== #
|
|
1824
|
+
if i.include? 'xfs_info'
|
|
1825
|
+
i.sub!(/xfs_info/,'')
|
|
1826
|
+
end
|
|
1827
|
+
# ======================================================================== #
|
|
1828
|
+
# === Handle rsync next:
|
|
1829
|
+
# ======================================================================== #
|
|
1830
|
+
if i.include? 'rsync version '
|
|
1831
|
+
i = i.split('rsync version ').last
|
|
1832
|
+
i = i.split(' ').first if i.include?(' ')
|
|
1833
|
+
end
|
|
1834
|
+
# ======================================================================== #
|
|
1835
|
+
# === Handle clang next:
|
|
1836
|
+
# ======================================================================== #
|
|
1837
|
+
if i.include? 'clang version ' # clang version 18.1.2
|
|
1838
|
+
i = i.split('clang version ').last.strip
|
|
1839
|
+
end
|
|
1840
|
+
# ======================================================================== #
|
|
1841
|
+
# === Handle git next:
|
|
1842
|
+
# ======================================================================== #
|
|
1843
|
+
if i.include? 'git version ' # git version
|
|
1844
|
+
i = i.split('git version ').last
|
|
1845
|
+
end
|
|
1846
|
+
# ======================================================================== #
|
|
1847
|
+
# === Handle gnuplot next:
|
|
1848
|
+
# ======================================================================== #
|
|
1849
|
+
if i.include? 'gnuplot ' # gnuplot version
|
|
1850
|
+
i = i.split('gnuplot ').last
|
|
1851
|
+
end
|
|
1852
|
+
# ======================================================================== #
|
|
1853
|
+
# === Handle gperf next:
|
|
1854
|
+
# ======================================================================== #
|
|
1855
|
+
if i.include? 'gperf ' # gperf version
|
|
1856
|
+
i = i.split('gperf ').last
|
|
1857
|
+
end
|
|
1858
|
+
# ======================================================================== #
|
|
1859
|
+
# === Handle re2c next:
|
|
1860
|
+
# ======================================================================== #
|
|
1861
|
+
if i.include? 're2c '
|
|
1862
|
+
i = i.split('re2c ').last
|
|
1863
|
+
end
|
|
1864
|
+
# ======================================================================== #
|
|
1865
|
+
# === Handle plzip next:
|
|
1866
|
+
# ======================================================================== #
|
|
1867
|
+
if i.include? 'plzip '
|
|
1868
|
+
i = i.split('plzip ').last
|
|
1869
|
+
end
|
|
1870
|
+
# ======================================================================== #
|
|
1871
|
+
# === Handle PHP next:
|
|
1872
|
+
# ======================================================================== #
|
|
1873
|
+
if i.include? 'PHP '
|
|
1874
|
+
i = i.scan(
|
|
1875
|
+
/PHP (\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
1876
|
+
).flatten.first
|
|
1877
|
+
end
|
|
1878
|
+
# ======================================================================== #
|
|
1879
|
+
# === Handle dhcpcd next:
|
|
1880
|
+
# ======================================================================== #
|
|
1881
|
+
if i.include? 'dhcpcd '
|
|
1882
|
+
i = i.split('dhcpcd ').last
|
|
1883
|
+
end
|
|
1884
|
+
# ======================================================================== #
|
|
1885
|
+
# === Handle bubblewrap next:
|
|
1886
|
+
# ======================================================================== #
|
|
1887
|
+
if i.include? 'bubblewrap '
|
|
1888
|
+
i = i.split('bubblewrap ').last
|
|
1889
|
+
end
|
|
1890
|
+
# ======================================================================== #
|
|
1891
|
+
# === Handle cmake next:
|
|
1892
|
+
# ======================================================================== #
|
|
1893
|
+
if i.include? 'cmake version '
|
|
1894
|
+
i = i.split('cmake version ').last
|
|
1895
|
+
elsif i.include? 'cmake '
|
|
1896
|
+
i = i.split('cmake ').last
|
|
1897
|
+
end
|
|
1898
|
+
# ======================================================================== #
|
|
1899
|
+
# === Handle flex next:
|
|
1900
|
+
# ======================================================================== #
|
|
1901
|
+
if i.include? 'flex '
|
|
1902
|
+
i = i.split('flex ').last
|
|
1903
|
+
end
|
|
1904
|
+
# ======================================================================== #
|
|
1905
|
+
# === Handle file next:
|
|
1906
|
+
# ======================================================================== #
|
|
1907
|
+
if i.include? 'file-'
|
|
1908
|
+
i = i.split('file-').last
|
|
1909
|
+
end
|
|
1910
|
+
# ======================================================================== #
|
|
1911
|
+
# === Handle gzip next:
|
|
1912
|
+
# ======================================================================== #
|
|
1913
|
+
if i.include? 'gzip '
|
|
1914
|
+
i = i.split('gzip ')[1]
|
|
1915
|
+
end
|
|
1916
|
+
# ======================================================================== #
|
|
1917
|
+
# === Handle groff next:
|
|
1918
|
+
# ======================================================================== #
|
|
1919
|
+
if i.include? 'groff '
|
|
1920
|
+
i = i.split('groff ')[1]
|
|
1921
|
+
if i.include? 'version'
|
|
1922
|
+
i = i.split('version').last.strip
|
|
1923
|
+
end
|
|
1924
|
+
end
|
|
1925
|
+
# ======================================================================== #
|
|
1926
|
+
# === Handle ethtool next:
|
|
1927
|
+
# ======================================================================== #
|
|
1928
|
+
if i.include? 'ethtool '
|
|
1929
|
+
i = i.split('ethtool ')[1]
|
|
1930
|
+
end
|
|
1931
|
+
# ======================================================================== #
|
|
1932
|
+
# === Handle tmux next:
|
|
1933
|
+
# ======================================================================== #
|
|
1934
|
+
if i.include? 'tmux '
|
|
1935
|
+
i = i.split('tmux').last.strip
|
|
1936
|
+
end
|
|
1937
|
+
# ======================================================================== #
|
|
1938
|
+
# === Handle sysstag next:
|
|
1939
|
+
# ======================================================================== #
|
|
1940
|
+
if i.include? 'sysstat version '
|
|
1941
|
+
i = i.split('sysstat version').last.to_s.strip
|
|
1942
|
+
end
|
|
1943
|
+
# ======================================================================== #
|
|
1944
|
+
# === Handle samtools next:
|
|
1945
|
+
# ======================================================================== #
|
|
1946
|
+
if i.include? 'samtools '
|
|
1947
|
+
i = i.split('samtools ').last.to_s.strip
|
|
1948
|
+
end
|
|
1949
|
+
# ======================================================================== #
|
|
1950
|
+
# === Handle the Linux kernel next
|
|
1951
|
+
# ======================================================================== #
|
|
1952
|
+
if i.start_with?('Linux ')
|
|
1953
|
+
i = i.scan(
|
|
1954
|
+
/(\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
1955
|
+
).flatten.first.to_s
|
|
1956
|
+
end
|
|
1957
|
+
# ======================================================================== #
|
|
1958
|
+
# === Handle the xz-utils next:
|
|
1959
|
+
# ======================================================================== #
|
|
1960
|
+
if i.include? 'xz (XZ Utils)'
|
|
1961
|
+
i = i.split('xz (XZ Utils)').last
|
|
1962
|
+
end
|
|
1963
|
+
# ======================================================================== #
|
|
1964
|
+
# === Handle xterm next:
|
|
1965
|
+
# ======================================================================== #
|
|
1966
|
+
if i.include? 'XTerm('
|
|
1967
|
+
i = i.split('XTerm(').last.delete(')')
|
|
1968
|
+
end
|
|
1969
|
+
# ======================================================================== #
|
|
1970
|
+
# === Handle gnuplot:
|
|
1971
|
+
# ======================================================================== #
|
|
1972
|
+
if i.include? ' patchlevel'
|
|
1973
|
+
i = i.split('patchlevel').first
|
|
1974
|
+
end
|
|
1975
|
+
# ======================================================================== #
|
|
1976
|
+
# === Handle patch next:
|
|
1977
|
+
# ======================================================================== #
|
|
1978
|
+
if i.include? 'GNU patch '
|
|
1979
|
+
i = i.split('GNU patch ').last
|
|
1980
|
+
end
|
|
1981
|
+
# ======================================================================== #
|
|
1982
|
+
# === Handle simple-scan:
|
|
1983
|
+
# ======================================================================== #
|
|
1984
|
+
if i.include? 'simple-scan '
|
|
1985
|
+
i = i.split('simple-scan').last
|
|
1986
|
+
end
|
|
1987
|
+
# ======================================================================== #
|
|
1988
|
+
# === Handle ffmpeg next:
|
|
1989
|
+
# ======================================================================== #
|
|
1990
|
+
if i.include? 'ffmpeg version'
|
|
1991
|
+
# ffmpeg version N-114276-g7f4b8d2f5e Copyright (c) 2000-2024 the FFmpeg developers
|
|
1992
|
+
i = i.scan(/ffmpeg version (.+) /).flatten.first.to_s
|
|
1993
|
+
i = i.split(' ').first if i.include? ' '
|
|
1994
|
+
if i.include? '-'
|
|
1995
|
+
i = i.scan(
|
|
1996
|
+
/-(\d{5,6})-/
|
|
1997
|
+
).flatten.first.to_s
|
|
1998
|
+
end
|
|
1999
|
+
end
|
|
2000
|
+
# ======================================================================== #
|
|
2001
|
+
# === Handle GCC next:
|
|
2002
|
+
#
|
|
2003
|
+
# The String we are looking for is like:
|
|
2004
|
+
#
|
|
2005
|
+
# "gcc version: 14.0.1 20240326 (experimental)"
|
|
2006
|
+
#
|
|
2007
|
+
# ======================================================================== #
|
|
2008
|
+
if i.include?('gcc (GCC)') or i.include?('gcc version')
|
|
2009
|
+
first_line = i.split("\n").first
|
|
2010
|
+
i = first_line.split('gcc (GCC) ').last.strip
|
|
2011
|
+
if i.include? ' '
|
|
2012
|
+
i = i.split(' ').first
|
|
2013
|
+
end
|
|
2014
|
+
end
|
|
2015
|
+
# ======================================================================== #
|
|
2016
|
+
# === Handle Lynx next
|
|
2017
|
+
# ======================================================================== #
|
|
2018
|
+
if i.include? 'Lynx Version ' # Lynx Version 2.9.0 (15 Jan 2024)
|
|
2019
|
+
i = i.scan(
|
|
2020
|
+
/Lynx Version (\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
2021
|
+
).flatten.first.to_s
|
|
2022
|
+
end
|
|
2023
|
+
# ======================================================================== #
|
|
2024
|
+
# === openjdk
|
|
2025
|
+
# ======================================================================== #
|
|
2026
|
+
if i.include? 'openjdk'
|
|
2027
|
+
i = i.scan(/openjdk version "(\d{1,2}\.\d{1,2}\.\d{1,2})"/).flatten.first
|
|
2028
|
+
end
|
|
2029
|
+
# ======================================================================== #
|
|
2030
|
+
# if i.include? 'GNOME Document Viewer'
|
|
2031
|
+
# i.sub!(/GNOME Document Viewer/,'') # For evince specifically.
|
|
2032
|
+
# end
|
|
2033
|
+
# ======================================================================== #
|
|
2034
|
+
if i.include? 'GNU'
|
|
2035
|
+
i.gsub!(/GNU/,'')
|
|
2036
|
+
end
|
|
2037
|
+
# ======================================================================== #
|
|
2038
|
+
# === Handle ruby 'ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]'
|
|
2039
|
+
# ======================================================================== #
|
|
2040
|
+
if i.include? 'ruby '
|
|
2041
|
+
i = i.scan(
|
|
2042
|
+
/^ruby (\d{1,1}\.\d{1,1}\.\d{1,1})/
|
|
2043
|
+
).flatten.first.to_s
|
|
2044
|
+
end
|
|
2045
|
+
# ======================================================================== #
|
|
2046
|
+
# === Handle 'ncurses 6.2.20200212' aka ncurses
|
|
2047
|
+
# ======================================================================== #
|
|
2048
|
+
if i.include? 'ncurses '
|
|
2049
|
+
i = i.scan(
|
|
2050
|
+
/ncurses (\d{1,1}\.\d{1,1})/
|
|
2051
|
+
).flatten.first.to_s
|
|
2052
|
+
end
|
|
2053
|
+
# ======================================================================== #
|
|
2054
|
+
# === Handle Imagemagick: 'Version: ImageMagick 7.0.10-28'
|
|
2055
|
+
# ======================================================================== #
|
|
2056
|
+
if i.include? 'Version: ImageMagick '
|
|
2057
|
+
i = i.scan(
|
|
2058
|
+
/Version: ImageMagick (\d{0,2}\.\d{0,2}\.\d{0,2}-\d{0,2})/
|
|
2059
|
+
).flatten.first.to_s.tr('-','.')
|
|
2060
|
+
end
|
|
2061
|
+
# ======================================================================== #
|
|
2062
|
+
# === Handle Qt next:
|
|
2063
|
+
# ======================================================================== #
|
|
2064
|
+
if i.include? 'uic ' # uic 5.15.12
|
|
2065
|
+
i = i.split('uic ').last
|
|
2066
|
+
elsif i.include? 'Using Qt version' # Using Qt version 6.6.3 in
|
|
2067
|
+
i = i.scan(
|
|
2068
|
+
/Using Qt version (\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
2069
|
+
).flatten.first
|
|
2070
|
+
end
|
|
2071
|
+
# ======================================================================== #
|
|
2072
|
+
# === Handle perl next:
|
|
2073
|
+
# ======================================================================== #
|
|
2074
|
+
if i.include?('This is perl') and i.include?('(v') # "This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux",
|
|
2075
|
+
# ====================================================================== #
|
|
2076
|
+
# Alternatively we could use this regex:
|
|
2077
|
+
#
|
|
2078
|
+
# /\(v(\d{0,2}\.?\d{0,2}\.\d{0,2})\)/
|
|
2079
|
+
#
|
|
2080
|
+
# ====================================================================== #
|
|
2081
|
+
i = i.scan(
|
|
2082
|
+
/\((v\d{1,2}\.\d{1,2}\.\d{1,2})\)/
|
|
2083
|
+
).flatten.first.to_s.dup
|
|
2084
|
+
end
|
|
2085
|
+
# ======================================================================== #
|
|
2086
|
+
# === Handle awk next:
|
|
2087
|
+
# ======================================================================== #
|
|
2088
|
+
if i.include? 'Awk '
|
|
2089
|
+
i = i.scan(/Awk (\d{1,2}\.\d{1,2}\.\d{1,2})/).flatten.first
|
|
2090
|
+
end
|
|
2091
|
+
# ======================================================================== #
|
|
2092
|
+
# === Handle patchelf '0.12.20200827.8d3a16e'
|
|
2093
|
+
#
|
|
2094
|
+
# This can also include output such as "patchelf 0.14.3".
|
|
2095
|
+
# ======================================================================== #
|
|
2096
|
+
if i.include? 'patchelf '
|
|
2097
|
+
i = i.scan(
|
|
2098
|
+
/^patchelf (\d{1,1}\.\d{1,2}\.?\d{0,2})/
|
|
2099
|
+
).flatten.first.to_s
|
|
2100
|
+
end
|
|
2101
|
+
# ======================================================================== #
|
|
2102
|
+
# === Work on NASM next:
|
|
2103
|
+
# ======================================================================== #
|
|
2104
|
+
if i.include? 'NASM ' # "NASM version 2.16.01 compiled on Mar 23 2024"
|
|
2105
|
+
scanned = i.scan(
|
|
2106
|
+
/NASM\s*version\s*(\d{1,2}\.\d{1,2}\.\d{1,2})/
|
|
2107
|
+
)
|
|
2108
|
+
i = scanned.flatten.first.to_s.strip
|
|
2109
|
+
end
|
|
2110
|
+
# ======================================================================== #
|
|
2111
|
+
# === Handle bzip2 next:
|
|
2112
|
+
# ======================================================================== #
|
|
2113
|
+
if i.include? 'bzip2, a block'
|
|
2114
|
+
i = i.scan(
|
|
2115
|
+
/Version (\d{1,2}\.\d{1,2}\.\d{1,2}),/
|
|
2116
|
+
).flatten.first.to_s
|
|
2117
|
+
end
|
|
2118
|
+
# ======================================================================== #
|
|
2119
|
+
# === Handle emacs next:
|
|
2120
|
+
# ======================================================================== #
|
|
2121
|
+
if i.include? 'Emacs '
|
|
2122
|
+
i.sub!(/Emacs/,'')
|
|
2123
|
+
end
|
|
2124
|
+
# ======================================================================== #
|
|
2125
|
+
# === bzip2recover
|
|
2126
|
+
# ======================================================================== #
|
|
2127
|
+
if i.include? 'extracts blocks from damag'
|
|
2128
|
+
i = i.scan(
|
|
2129
|
+
/bzip2recover (\d{0,2}\.\d{0,2}\.\d{0,2}): extracts blocks from damaged .bz2 files/
|
|
2130
|
+
).flatten.first.to_s.dup
|
|
2131
|
+
end
|
|
2132
|
+
# ======================================================================== #
|
|
2133
|
+
# === Handle Python next:
|
|
2134
|
+
# ======================================================================== #
|
|
2135
|
+
if i.include? 'Python ' # Python 3.11.7
|
|
2136
|
+
i.sub!(/Python /,'')
|
|
2137
|
+
end
|
|
2138
|
+
# ======================================================================== #
|
|
2139
|
+
# === Remove "built on linux-gnu":
|
|
2140
|
+
# ======================================================================== #
|
|
2141
|
+
if i.include? ' built on linux-gnu.'
|
|
2142
|
+
i.gsub!(/ built on linux-gnu\./, '') # Fixing wget specifically.
|
|
2143
|
+
end
|
|
2144
|
+
# ======================================================================== #
|
|
2145
|
+
# === Remove 'Wget' substring:
|
|
2146
|
+
# ======================================================================== #
|
|
2147
|
+
if i.include? 'Wget'
|
|
2148
|
+
i.sub!(/Wget/,'')
|
|
2149
|
+
i.strip!
|
|
2150
|
+
end
|
|
2151
|
+
if i.include? 'built on'
|
|
2152
|
+
i = i.split(/built on/).first
|
|
2153
|
+
end
|
|
2154
|
+
# ======================================================================== #
|
|
2155
|
+
# === Handle "Midnight Commander" next:
|
|
2156
|
+
# ======================================================================== #
|
|
2157
|
+
if i.include? 'Midnight Commander'
|
|
2158
|
+
i.gsub!(/Midnight Commander/, '')
|
|
2159
|
+
end
|
|
2160
|
+
# ======================================================================== #
|
|
2161
|
+
# === Eliminate '.git'
|
|
2162
|
+
# ======================================================================== #
|
|
2163
|
+
if i.include? '.git'
|
|
2164
|
+
i.sub!(/\.git/,'')
|
|
2165
|
+
end
|
|
2166
|
+
# ======================================================================== #
|
|
2167
|
+
# === Remove the substring 'GNU' next; this should come fairly late:
|
|
2168
|
+
# ======================================================================== #
|
|
2169
|
+
if i.include? 'GNU'
|
|
2170
|
+
i.sub!(/GNU/,'')
|
|
2171
|
+
end
|
|
2172
|
+
# ======================================================================== #
|
|
2173
|
+
# === For rsync specifically
|
|
2174
|
+
# ======================================================================== #
|
|
2175
|
+
if i.include? 'protocol version'
|
|
2176
|
+
i = i.split('protocol version').first
|
|
2177
|
+
end
|
|
2178
|
+
# ======================================================================== #
|
|
2179
|
+
# === Remove '#'
|
|
2180
|
+
# ======================================================================== #
|
|
2181
|
+
if i.include? ' #' # Handle "uname -a" aka Linux darkstar.example.net 5.4.50 #1 SMP
|
|
2182
|
+
i = i.split(' #').first.strip
|
|
2183
|
+
end
|
|
2184
|
+
if i.start_with? 'v'
|
|
2185
|
+
i = i.dup
|
|
2186
|
+
i[0,1] = ''
|
|
2187
|
+
end
|
|
2188
|
+
return i
|
|
2189
|
+
end; self.instance_eval { alias sanitize_this_program_version sanitize_this_version_string } # === EnvironmentInformation.sanitize_this_program_version
|
|
2190
|
+
|
|
2191
|
+
# ========================================================================== #
|
|
2192
|
+
# === EnvironmentInformation.return_very_silent_system_output_from (query tag)
|
|
2193
|
+
# ========================================================================== #
|
|
2194
|
+
def self.return_very_silent_system_output_from(
|
|
2195
|
+
use_this_query
|
|
2196
|
+
)
|
|
2197
|
+
@original_stderr = $stderr.clone
|
|
2198
|
+
$stderr.reopen('/dev/null', 'w')
|
|
2199
|
+
result = `#{use_this_query} 2>&1`
|
|
2200
|
+
$stderr.reopen(@original_stderr)
|
|
2201
|
+
return result
|
|
2202
|
+
end; self.instance_eval { alias silent_sys_command return_very_silent_system_output_from } # === EnvironmentInformation.silent_sys_command
|
|
2203
|
+
self.instance_eval { alias default_query return_very_silent_system_output_from } # === EnvironmentInformation.default_query
|
|
2204
|
+
self.instance_eval { alias silent_query return_very_silent_system_output_from } # === EnvironmentInformation.silent_query
|
|
2205
|
+
|
|
2206
|
+
end
|
|
2207
|
+
|
|
2208
|
+
if __FILE__ == $PROGRAM_NAME
|
|
2209
|
+
alias e puts
|
|
2210
|
+
# e EnvironmentInformation.n_subcommands?.to_s+' components are tracked.'
|
|
2211
|
+
# e EnvironmentInformation.internet_is_available?
|
|
2212
|
+
# EnvironmentInformation.e('Hello world!')
|
|
2213
|
+
# e EnvironmentInformation.return_remote_gtk2_version
|
|
2214
|
+
# EnvironmentInformation.write_what_into(ARGV, 'test_this.md')
|
|
2215
|
+
# Next test .simple_version()
|
|
2216
|
+
seek_this_program = :bison # :gnuplot # :lftp
|
|
2217
|
+
_ = EnvironmentInformation.return_version_of(seek_this_program)
|
|
2218
|
+
e _
|
|
2219
|
+
# ========================================================================== #
|
|
2220
|
+
# Next we test various individual components, stored in an Array:
|
|
2221
|
+
# ========================================================================== #
|
|
2222
|
+
array = %i(
|
|
2223
|
+
mpc
|
|
2224
|
+
gtk2
|
|
2225
|
+
linux
|
|
2226
|
+
binutils
|
|
2227
|
+
boost
|
|
2228
|
+
coreutils
|
|
2229
|
+
diffutils
|
|
2230
|
+
ffmpeg
|
|
2231
|
+
findutils
|
|
2232
|
+
java
|
|
2233
|
+
imagemagick
|
|
2234
|
+
kde_frameworks
|
|
2235
|
+
llvm
|
|
2236
|
+
ncurses
|
|
2237
|
+
nginx
|
|
2238
|
+
qt
|
|
2239
|
+
rubygems
|
|
2240
|
+
sharutils
|
|
2241
|
+
sysstat
|
|
2242
|
+
swig
|
|
2243
|
+
texinfo
|
|
2244
|
+
tmux
|
|
2245
|
+
xfsprogs
|
|
2246
|
+
xterm
|
|
2247
|
+
hmmer
|
|
2248
|
+
viennarna
|
|
2249
|
+
xstdcmap
|
|
2250
|
+
)
|
|
2251
|
+
array.each {|entry|
|
|
2252
|
+
_ = EnvironmentInformation.version_of(entry)
|
|
2253
|
+
e _
|
|
2254
|
+
}
|
|
2255
|
+
e EnvironmentInformation.return_version_of_mpc
|
|
2256
|
+
e EnvironmentInformation.return_version_of_boost
|
|
2257
|
+
EnvironmentInformation.test
|
|
2258
|
+
end # showcomponents --compare
|