plat4m 1.0.0
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +11 -0
- data/lib/plat4m/pkgman.rb +60 -0
- data/lib/plat4m/sniff/darwin.rb +206 -0
- data/lib/plat4m/sniff/freebsd.rb +51 -0
- data/lib/plat4m/sniff/linux.rb +260 -0
- data/lib/plat4m/sniff/windows.rb +55 -0
- data/lib/plat4m/system.rb +179 -0
- data/lib/plat4m/version.rb +13 -0
- data/lib/plat4m.rb +15 -0
- metadata +55 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9df6b644a5e122916e8230965e4e4999441bd067706d2679e905008f0000c0f8
|
4
|
+
data.tar.gz: 0efb88c4163e04fef3499e3f542d9a003ffb7fdd28ced4ff0db4a1d8fb3aa8d8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e7101d9e5feba298a1b945b010996a7d48f26d3267f31da53b041cf5b4e936eeff29ed8e5ff6277d6548c5d4efda9de05b2779000d3100d611474a99196c5bd7
|
7
|
+
data.tar.gz: d8c7db00c80acc09fe3308b04a33a522263ffe71b40b01096ab5da4614b9b0486c349907d9f66a440feb738e82ef15e96f10f146a93b451f9f2c970450213e1a
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2024 Martin Corino
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
[](LICENSE)
|
2
|
+
[](https://badge.fury.io/rb/plat4m)
|
3
|
+
|
4
|
+
# Plat4m
|
5
|
+
|
6
|
+
Plat4m is a simple runtime system platform scouting and support library specially intended to
|
7
|
+
be used with other Ruby projects to provide light weight runtime system detection and provide
|
8
|
+
support for simple system package management (install/uninstall) support.
|
9
|
+
|
10
|
+
Plat4m is definitely not intended as a full fledged runtime system detection system and/or a
|
11
|
+
complete system management solution.
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m PkgManager
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
class PkgManager
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@has_sudo = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def installed?(pkg)
|
17
|
+
raise NoMethodError
|
18
|
+
end
|
19
|
+
|
20
|
+
def select_uninstalled(*pkgs)
|
21
|
+
pkgs.flatten.select { |pkg| !installed?(pkg) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def available?(pkg)
|
25
|
+
raise NoMethodError
|
26
|
+
end
|
27
|
+
|
28
|
+
def select_available(*pkgs)
|
29
|
+
pkgs.flatten.select { |pkg| available?(pkg) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def make_install_command(*pkgs)
|
33
|
+
raise NoMethodError
|
34
|
+
end
|
35
|
+
|
36
|
+
def install(*pkgs, silent: false)
|
37
|
+
cmd = make_install_command
|
38
|
+
silent ? system("#{cmd} >/dev/null 2>&1") : system(cmd)
|
39
|
+
end
|
40
|
+
|
41
|
+
def make_uninstall_command(*pkgs)
|
42
|
+
raise NoMethodError
|
43
|
+
end
|
44
|
+
|
45
|
+
def uninstall(*pkgs, silent: false)
|
46
|
+
cmd = make_uninstall_command
|
47
|
+
silent ? system("#{cmd} >/dev/null 2>&1") : system(cmd)
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_root?
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
def has_sudo?
|
55
|
+
@has_sudo
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m Linux sniffer
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
module Sniffer
|
11
|
+
|
12
|
+
module Darwin
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def detect_system
|
17
|
+
# determine system platform
|
18
|
+
System.new(System::Platform.new(arch: get_arch, cpus: get_cpu_count),
|
19
|
+
System::OS.new(id: :darwin, **get_distro))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def get_arch
|
25
|
+
arch, _ = RbConfig::CONFIG['arch'].split('-')
|
26
|
+
arch = 'x86' if arch =~ /i\d86/
|
27
|
+
arch
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_cpu_count
|
31
|
+
(system('command -v nproc > /dev/null 2>&1') ? `nproc` : `getconf _NPROCESSORS_ONLN`).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_distro
|
35
|
+
distro = {
|
36
|
+
distro: 'macosx'
|
37
|
+
}
|
38
|
+
ver = `sw_vers --productVersion`.strip
|
39
|
+
distro[:release] = ver.split('.').first
|
40
|
+
distro[:version] = ver
|
41
|
+
distro[:pkgman] = MacPkgManager.new
|
42
|
+
distro
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_macports?
|
46
|
+
if @has_macports.nil?
|
47
|
+
@has_macports = system('command -v port>/dev/null')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_homebrew?
|
52
|
+
if @has_homebrew.nil?
|
53
|
+
@has_homebrew = system('command -v brew>/dev/null')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
class MacPkgManager < PkgManager
|
60
|
+
|
61
|
+
def initialize
|
62
|
+
super
|
63
|
+
@has_sudo = system('command -v sudo > /dev/null')
|
64
|
+
@has_macports = system('command -v port>/dev/null')
|
65
|
+
@has_homebrew = system('command -v brew>/dev/null')
|
66
|
+
end
|
67
|
+
|
68
|
+
def installed?(pkg)
|
69
|
+
pkg_manager.installed?(pkg)
|
70
|
+
end
|
71
|
+
|
72
|
+
def available?(pkg)
|
73
|
+
pkg_manager.available?(pkg)
|
74
|
+
end
|
75
|
+
|
76
|
+
def make_install_command(*pkgs)
|
77
|
+
pkg_manager.make_install_command(*pkgs)
|
78
|
+
end
|
79
|
+
|
80
|
+
def make_uninstall_command(*pkgs)
|
81
|
+
pkg_manager.make_uninstall_command(*pkgs)
|
82
|
+
end
|
83
|
+
|
84
|
+
def macports?
|
85
|
+
MacPorts === pkg_manager
|
86
|
+
end
|
87
|
+
|
88
|
+
def homebrew?
|
89
|
+
Homebrew === pkg_manager
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def is_root?
|
95
|
+
`id -u 2>/dev/null`.chomp == '0'
|
96
|
+
end
|
97
|
+
|
98
|
+
def has_macports?
|
99
|
+
if @has_macports.nil?
|
100
|
+
@has_macports = system('command -v port>/dev/null')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def has_homebrew?
|
105
|
+
if @has_homebrew.nil?
|
106
|
+
@has_homebrew = system('command -v brew>/dev/null')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Homebrew < PkgManager
|
111
|
+
|
112
|
+
def initialize(owner)
|
113
|
+
super()
|
114
|
+
@owner = owner
|
115
|
+
@has_sudo = @owner.has_sudo?
|
116
|
+
end
|
117
|
+
|
118
|
+
def installed?(pkg)
|
119
|
+
`brew list -1 --formula`.strip.split("\n").include?(pkg) ||
|
120
|
+
`brew list -1 --cask`.strip.split("\n").include?(pkg)
|
121
|
+
end
|
122
|
+
|
123
|
+
def available?(pkg)
|
124
|
+
system(%Q[brew search "/^#{pkg}$/" >/dev/null 2>&1])
|
125
|
+
end
|
126
|
+
|
127
|
+
def make_install_command(*pkgs)
|
128
|
+
"brew install -q #{pkgs.join(' ')}"
|
129
|
+
end
|
130
|
+
|
131
|
+
def make_uninstall_command(*pkgs)
|
132
|
+
"brew uninstall -q #{pkgs.join(' ')}"
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
class MacPorts < PkgManager
|
138
|
+
|
139
|
+
def initialize(owner)
|
140
|
+
super()
|
141
|
+
@owner = owner
|
142
|
+
@has_sudo = @owner.has_sudo?
|
143
|
+
@privileged = File.stat(`which port`.strip).uid == 0
|
144
|
+
end
|
145
|
+
|
146
|
+
def installed?(pkg)
|
147
|
+
!(`port -q installed #{pkg}`.strip.empty?)
|
148
|
+
end
|
149
|
+
|
150
|
+
def available?(pkg)
|
151
|
+
!(`port -q search --exact #{pkg}`.strip.empty?)
|
152
|
+
end
|
153
|
+
|
154
|
+
def make_install_command(*pkgs)
|
155
|
+
auth_cmd("port install #{pkgs.join(' ')}")
|
156
|
+
end
|
157
|
+
|
158
|
+
def make_uninstall_command(*pkgs)
|
159
|
+
auth_cmd("port uninstall #{pkgs.join(' ')}")
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def is_root?
|
165
|
+
@owner.is_root?
|
166
|
+
end
|
167
|
+
|
168
|
+
def auth_cmd(cmd)
|
169
|
+
raise "Cannot find 'sudo' for command [#{cmd}]" unless !@privileged || is_root? || @has_sudo
|
170
|
+
(!@privileged || is_root?) ? cmd : "sudo #{cmd}"
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
def pkg_manager
|
176
|
+
unless @pkg_manager
|
177
|
+
# # Has Ruby been installed through MacPorts?
|
178
|
+
# if has_macports? &&
|
179
|
+
# expand('port -q installed installed').strip.split("\n").find { |ln| ln.strip =~ /\Aruby\d+\s/ }
|
180
|
+
# @pkg_manager = MacPorts.new
|
181
|
+
|
182
|
+
# re we running without root privileges and have Homebrew installed?
|
183
|
+
# (Ruby may be installed using Homebrew itself or using a Ruby version manager like RVM)
|
184
|
+
if !is_root? && has_homebrew?
|
185
|
+
@pkg_manager = Homebrew.new(self)
|
186
|
+
|
187
|
+
# or do we have MacPorts (running either privileged or not).
|
188
|
+
elsif has_macports?
|
189
|
+
@pkg_manager = MacPorts.new(self)
|
190
|
+
|
191
|
+
else
|
192
|
+
raise RuntimeError, 'Unable to determine package manager to use!'
|
193
|
+
end
|
194
|
+
end
|
195
|
+
@pkg_manager
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
self.sniffers[:darwin] = Sniffer::Darwin
|
205
|
+
|
206
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m Freebsd sniffer
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
module Sniffer
|
11
|
+
|
12
|
+
module Freebsd
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def detect_system
|
17
|
+
# determine system platform
|
18
|
+
System.new(System::Platform.new(arch: get_arch, cpus: get_cpu_count),
|
19
|
+
System::OS.new(id: :freebsd, **get_distro))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def get_arch
|
25
|
+
arch, _ = RbConfig::CONFIG['arch'].split('-')
|
26
|
+
arch = 'x86' if arch =~ /i\d86/
|
27
|
+
arch
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_cpu_count
|
31
|
+
(system('command -v nproc > /dev/null 2>&1') ? `nproc` : `getconf NPROCESSORS_ONLN`).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_distro
|
35
|
+
distro = {
|
36
|
+
distro: 'freebsd'
|
37
|
+
}
|
38
|
+
distro[:release] = 0
|
39
|
+
distro[:pkgman] = nil
|
40
|
+
distro
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
self.sniffers[:freebsd] = Sniffer::Freebsd
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,260 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m Linux sniffer
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
module Sniffer
|
11
|
+
|
12
|
+
module Linux
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def detect_system
|
17
|
+
# determine system platform
|
18
|
+
System.new(System::Platform.new(arch: get_arch, cpus: get_cpu_count),
|
19
|
+
System::OS.new(id: :linux, **get_distro))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def get_arch
|
25
|
+
arch, _ = RbConfig::CONFIG['arch'].split('-')
|
26
|
+
arch = 'x86' if arch =~ /i\d86/
|
27
|
+
arch
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_cpu_count
|
31
|
+
(system('command -v nproc > /dev/null 2>&1') ? `nproc` : `getconf _NPROCESSORS_ONLN`).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_distro
|
35
|
+
distro = if File.file?('/etc/os-release') # works with most (if not all) recent distro releases
|
36
|
+
data = File.readlines('/etc/os-release').reduce({}) do |hash, line|
|
37
|
+
val, var = line.split('=')
|
38
|
+
hash[val] = var.strip.gsub(/(\A")|("\Z)/, '')
|
39
|
+
hash
|
40
|
+
end
|
41
|
+
{
|
42
|
+
variant: if data['ID_LIKE']
|
43
|
+
data['ID_LIKE'].split.first.to_sym
|
44
|
+
elsif File.file?('/etc/redhat-release')
|
45
|
+
:rhel
|
46
|
+
elsif File.file?('/etc/SUSE-brand') || File.file?('/etc/SuSE-release')
|
47
|
+
:suse
|
48
|
+
elsif File.file?('/etc/debian_version')
|
49
|
+
:debian
|
50
|
+
else
|
51
|
+
data['ID'].to_sym
|
52
|
+
end,
|
53
|
+
distro: data['ID'].downcase,
|
54
|
+
release: data['VERSION_ID']
|
55
|
+
}
|
56
|
+
elsif File.file?('/etc/redhat-release')
|
57
|
+
data = File.read('/etc/redhat-release').strip
|
58
|
+
{
|
59
|
+
variant: :rhel,
|
60
|
+
distro: data.split.shift.downcase,
|
61
|
+
release: data =~ /\d+(\.\d+)*/ ? $~[0] : ''
|
62
|
+
}
|
63
|
+
elsif File.file?('/etc/SUSE-brand') || File.file?('/etc/SuSE-release')
|
64
|
+
data = File.readlines(File.file?('/etc/SUSE-brand') ? '/etc/SUSE-brand' : '/etc/SuSE-release')
|
65
|
+
{
|
66
|
+
variant: :suse,
|
67
|
+
distro: data.shift.split.shift.downcase,
|
68
|
+
release: (data.find { |s| s.strip =~ /\AVERSION\s*=/ } || '').split('=').last || ''
|
69
|
+
}
|
70
|
+
elsif File.file?('/etc/debian_version')
|
71
|
+
{
|
72
|
+
variant: :debian,
|
73
|
+
distro: 'generic',
|
74
|
+
release: File.read('/etc/debian_version').strip.split('.').shift
|
75
|
+
}
|
76
|
+
else
|
77
|
+
{
|
78
|
+
}
|
79
|
+
end
|
80
|
+
distro[:pkgman] = case distro[:variant]
|
81
|
+
when :debian
|
82
|
+
Apt.new(distro)
|
83
|
+
when :rhel
|
84
|
+
Dnf.new(distro)
|
85
|
+
when :suse
|
86
|
+
Zypper.new(distro)
|
87
|
+
when :arch
|
88
|
+
Pacman.new(distro)
|
89
|
+
end
|
90
|
+
distro
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
class NixManager < PkgManager
|
96
|
+
|
97
|
+
def initialize(_distro)
|
98
|
+
super()
|
99
|
+
@has_sudo = system('command -v sudo > /dev/null')
|
100
|
+
end
|
101
|
+
|
102
|
+
def make_install_command(*pkgs)
|
103
|
+
auth_cmd(get_install_command(*pkgs))
|
104
|
+
end
|
105
|
+
|
106
|
+
def make_uninstall_command(*pkgs)
|
107
|
+
auth_cmd(get_uninstall_command(*pkgs))
|
108
|
+
end
|
109
|
+
|
110
|
+
protected
|
111
|
+
|
112
|
+
def get_install_command(*pkgs)
|
113
|
+
raise NoMethodError
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_uninstall_command(*pkgs)
|
117
|
+
raise NoMethodError
|
118
|
+
end
|
119
|
+
|
120
|
+
def is_root?
|
121
|
+
`id -u 2>/dev/null`.chomp == '0'
|
122
|
+
end
|
123
|
+
|
124
|
+
def auth_cmd(cmd)
|
125
|
+
raise "Cannot find 'sudo' for command [#{cmd}]" unless is_root? || has_sudo?
|
126
|
+
is_root? ? cmd : "sudo #{cmd}"
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
class Apt < NixManager
|
132
|
+
|
133
|
+
def installed?(pkg)
|
134
|
+
# get architecture
|
135
|
+
system("dpkg-query -s \"#{pkg}:#{pkg_arch}\" >/dev/null 2>&1") ||
|
136
|
+
system("dpkg-query -s \"#{pkg}:all\" >/dev/null 2>&1") ||
|
137
|
+
(`dpkg-query -s \"#{pkg}\" 2>/dev/null`.strip =~ /Architecture: (#{pkg_arch}|all)/)
|
138
|
+
end
|
139
|
+
|
140
|
+
def available?(pkg)
|
141
|
+
apt_cache.include?(pkg)
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def apt_cmd(cmd)
|
147
|
+
"DEBIAN_FRONTEND=noninteractive apt-get -q -o=Dpkg::Use-Pty=0 #{cmd}"
|
148
|
+
end
|
149
|
+
|
150
|
+
def get_install_command(*pkgs)
|
151
|
+
apt_cmd("install -y #{pkgs.flatten.join(' ')}")
|
152
|
+
end
|
153
|
+
|
154
|
+
def get_uninstall_command(*pkgs)
|
155
|
+
apt_cmd("remove -y #{pkgs.flatten.join(' ')}")
|
156
|
+
end
|
157
|
+
|
158
|
+
def update_pkgs
|
159
|
+
system(auth_cmd(apt_cmd('update')))
|
160
|
+
end
|
161
|
+
|
162
|
+
def apt_cache
|
163
|
+
unless @apt_cache
|
164
|
+
update_pkgs
|
165
|
+
@apt_cache = `apt-cache pkgnames`.chomp.split("\n").collect { |s| s.strip }
|
166
|
+
end
|
167
|
+
@apt_cache
|
168
|
+
end
|
169
|
+
|
170
|
+
def pkg_arch
|
171
|
+
@pkg_arch ||= `dpkg --print-architecture`.strip
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
class Dnf < NixManager
|
177
|
+
|
178
|
+
def installed?(pkg)
|
179
|
+
system("dnf list installed #{pkg} >/dev/null 2>&1")
|
180
|
+
end
|
181
|
+
|
182
|
+
def available?(pkg)
|
183
|
+
!!(`dnf repoquery --info #{pkg} 2>/dev/null`.strip =~ /Name\s*:\s*#{pkg}/)
|
184
|
+
end
|
185
|
+
|
186
|
+
protected
|
187
|
+
|
188
|
+
def dnf_cmd(cmd)
|
189
|
+
"dnf #{cmd}"
|
190
|
+
end
|
191
|
+
|
192
|
+
def get_install_command(*pkgs)
|
193
|
+
dnf_cmd("install -y #{pkgs.flatten.join(' ')}")
|
194
|
+
end
|
195
|
+
|
196
|
+
def get_uninstall_command(*pkgs)
|
197
|
+
dnf_cmd("remove -y #{pkgs.flatten.join(' ')}")
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
class Zypper < NixManager
|
203
|
+
|
204
|
+
def installed?(pkg)
|
205
|
+
system("rpm -q --whatprovides #{pkg} >/dev/null 2>&1")
|
206
|
+
end
|
207
|
+
|
208
|
+
def available?(pkg)
|
209
|
+
system("zypper -x -t package #{pkg} >/dev/null 2>&1")
|
210
|
+
end
|
211
|
+
|
212
|
+
protected
|
213
|
+
|
214
|
+
def zypper_cmd(cmd)
|
215
|
+
"zypper -t -i #{cmd}"
|
216
|
+
end
|
217
|
+
|
218
|
+
def get_install_command(*pkgs)
|
219
|
+
zypper_cmd("install -y #{pkgs.flatten.join(' ')}")
|
220
|
+
end
|
221
|
+
|
222
|
+
def get_uninstall_command(*pkgs)
|
223
|
+
zypper_cmd("remove -y #{pkgs.flatten.join(' ')}")
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
|
228
|
+
class Pacman < NixManager
|
229
|
+
|
230
|
+
def installed?(pkg)
|
231
|
+
system("pacman -Qq #{pkg} >/dev/null 2>&1")
|
232
|
+
end
|
233
|
+
|
234
|
+
def available?(pkg)
|
235
|
+
system(%Q[pacman -Ss "^#{pkg}$" >/dev/null 2>&1])
|
236
|
+
end
|
237
|
+
|
238
|
+
protected
|
239
|
+
|
240
|
+
def pacman_cmd(cmd)
|
241
|
+
"pacman --noconfirm #{cmd}"
|
242
|
+
end
|
243
|
+
|
244
|
+
def get_install_command(*pkgs)
|
245
|
+
pacman_cmd("-S --needed #{ pkgs.join(' ') }")
|
246
|
+
end
|
247
|
+
|
248
|
+
def get_uninstall_command(*pkgs)
|
249
|
+
pacman_cmd("-Rsu #{pkgs.flatten.join(' ')}")
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
self.sniffers[:linux] = Sniffer::Linux
|
259
|
+
|
260
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m Windows sniffer
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
module Sniffer
|
11
|
+
|
12
|
+
module Windows
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def detect_system
|
17
|
+
# determine system platform
|
18
|
+
System.new(System::Platform.new(arch: get_arch, cpus: get_cpu_count),
|
19
|
+
System::OS.new(id: :windows, **get_distro))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def get_arch
|
25
|
+
arch, _ = RbConfig::CONFIG['arch'].split('-')
|
26
|
+
arch = 'x86' if arch =~ /i\d86/
|
27
|
+
arch
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_cpu_count
|
31
|
+
ENV['NUMBER_OF_PROCESSORS'].to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_distro
|
35
|
+
distro = {
|
36
|
+
distro: 'windows'
|
37
|
+
}
|
38
|
+
# the 'ver' command returns something like "Microsoft Windows [Version xx.xx.xx.xx]"
|
39
|
+
match = `ver`.strip.match(/\[(.*)\]/)
|
40
|
+
ver = match[1].split.last
|
41
|
+
distro[:release] = ver.split('.').shift
|
42
|
+
distro[:version] = ver
|
43
|
+
distro[:pkgman] = nil
|
44
|
+
distro
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
self.sniffers[:windows] = Sniffer::Darwin
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m System class
|
6
|
+
|
7
|
+
|
8
|
+
module Plat4m
|
9
|
+
|
10
|
+
# Instances of this class identify a system and provide access to system management support.
|
11
|
+
class System
|
12
|
+
|
13
|
+
# Provides information about the hardware platform.
|
14
|
+
class Platform
|
15
|
+
|
16
|
+
def initialize(arch: nil, cpus: nil)
|
17
|
+
@arch = arch
|
18
|
+
@bits = @arch.to_s =~ /64/ ? 64 : 32
|
19
|
+
@cpus = cpus
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :arch, :bits, :cpus
|
23
|
+
|
24
|
+
def complete?
|
25
|
+
::String === @arch && !@arch.empty? &&
|
26
|
+
::Integer === cpus && @cpus>0
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"[#{@arch}: #{@bits}bits, #{cpus} cpu]"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
# Provides information about the operating system.
|
36
|
+
class OS
|
37
|
+
|
38
|
+
def initialize(id: nil, distro: nil, variant: nil, release: nil, pkgman: nil, **other)
|
39
|
+
@id = id
|
40
|
+
@distro = distro
|
41
|
+
@variant = variant
|
42
|
+
@release = release
|
43
|
+
@pkgman = pkgman
|
44
|
+
@other = other
|
45
|
+
@other.each_key do |key|
|
46
|
+
unless self.method(key.to_sym)
|
47
|
+
singleton_class.class_eval <<~__CODE
|
48
|
+
define_method(:#{key}) do
|
49
|
+
@other['#{key}']
|
50
|
+
end
|
51
|
+
__CODE
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_reader :id, :distro, :release, :pkgman
|
57
|
+
|
58
|
+
def variant
|
59
|
+
@variant || @distro
|
60
|
+
end
|
61
|
+
|
62
|
+
alias :distribution :distro
|
63
|
+
|
64
|
+
def complete?
|
65
|
+
::Symbol === @id &&
|
66
|
+
::String === @distro && !@distro.empty?
|
67
|
+
::String === @release && !@release.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
def is_root?
|
71
|
+
@pkgman ? @pkgman.is_root? : false
|
72
|
+
end
|
73
|
+
|
74
|
+
def has_sudo?
|
75
|
+
@pkgman ? @pkgman.has_sudo? : false
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_s
|
79
|
+
"#{@distro}-#{@release}[#{@id}#{@variant ? " #{@variant}" : ''}}]"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
def initialize(platform, os)
|
85
|
+
unless platform && platform.complete? && os && os.complete?
|
86
|
+
raise "Invalid system specification [#{os} @ #{platform}]"
|
87
|
+
end
|
88
|
+
@platform = platform
|
89
|
+
@os = os
|
90
|
+
end
|
91
|
+
|
92
|
+
attr_reader :platform, :os
|
93
|
+
|
94
|
+
def kind
|
95
|
+
"#{@platform.arch}-#{@os.id}"
|
96
|
+
end
|
97
|
+
|
98
|
+
def intel?
|
99
|
+
@platform.arch =~ /x86/
|
100
|
+
end
|
101
|
+
|
102
|
+
def arm?
|
103
|
+
@platform.arch =~ /arm/
|
104
|
+
end
|
105
|
+
|
106
|
+
def bits
|
107
|
+
@platform.bits
|
108
|
+
end
|
109
|
+
|
110
|
+
def cpu_count
|
111
|
+
@platform.cpus
|
112
|
+
end
|
113
|
+
|
114
|
+
def linux?
|
115
|
+
@os.id == :linux
|
116
|
+
end
|
117
|
+
|
118
|
+
def windows?
|
119
|
+
@os.id == :windows
|
120
|
+
end
|
121
|
+
|
122
|
+
def darwin?
|
123
|
+
@os.id == :darwin
|
124
|
+
end
|
125
|
+
|
126
|
+
def macosx?
|
127
|
+
darwin? && @os.distro == 'MacOSX'
|
128
|
+
end
|
129
|
+
alias :osx? :macosx?
|
130
|
+
|
131
|
+
def freebsd?
|
132
|
+
@os.id == :freebsd
|
133
|
+
end
|
134
|
+
|
135
|
+
def dev_null
|
136
|
+
windows? ? 'NUL' : '/dev/null'
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
class << self
|
142
|
+
|
143
|
+
# Returns System instance for current system.
|
144
|
+
def current
|
145
|
+
@current ||= detect_current
|
146
|
+
end
|
147
|
+
|
148
|
+
# System sniffer registry.
|
149
|
+
def sniffers
|
150
|
+
@sniffers ||= {}
|
151
|
+
end
|
152
|
+
|
153
|
+
def detect_current
|
154
|
+
case RbConfig::CONFIG['host_os']
|
155
|
+
when /linux/
|
156
|
+
sniffers[:linux].detect_system
|
157
|
+
when /darwin/
|
158
|
+
sniffers[:darwin].detect_system
|
159
|
+
when /freebsd/
|
160
|
+
sniffers[:freebsd].detect_system
|
161
|
+
else
|
162
|
+
if ENV['OS'] =~ /windows/i
|
163
|
+
sniffers[:windows].detect_system
|
164
|
+
else
|
165
|
+
raise "Unknown system!"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
private :detect_current
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
require_relative 'pkgman'
|
176
|
+
require_relative 'sniff/darwin'
|
177
|
+
require_relative 'sniff/linux'
|
178
|
+
require_relative 'sniff/windows'
|
179
|
+
require_relative 'sniff/freebsd'
|
data/lib/plat4m.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Copyright (c) 2023 M.J.N. Corino, The Netherlands
|
2
|
+
#
|
3
|
+
# This software is released under the MIT license.
|
4
|
+
#
|
5
|
+
# Plat4m loader
|
6
|
+
|
7
|
+
|
8
|
+
# Plat4m provides methods and classes to scout the details of the computer system and
|
9
|
+
# support system management tasks.
|
10
|
+
module Plat4m
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
require_relative 'plat4m/version'
|
15
|
+
require_relative 'plat4m/system'
|
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: plat4m
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Corino
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-02-20 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Plat4m is a simple runtime system platform scouting and support library.
|
14
|
+
email: mcorino@m2c-software.nl
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- LICENSE
|
20
|
+
- README.md
|
21
|
+
- lib/plat4m.rb
|
22
|
+
- lib/plat4m/pkgman.rb
|
23
|
+
- lib/plat4m/sniff/darwin.rb
|
24
|
+
- lib/plat4m/sniff/freebsd.rb
|
25
|
+
- lib/plat4m/sniff/linux.rb
|
26
|
+
- lib/plat4m/sniff/windows.rb
|
27
|
+
- lib/plat4m/system.rb
|
28
|
+
- lib/plat4m/version.rb
|
29
|
+
homepage: https://github.com/mcorino/plat4m
|
30
|
+
licenses:
|
31
|
+
- MIT
|
32
|
+
metadata:
|
33
|
+
bug_tracker_uri: https://github.com/mcorino/plat4m/issues
|
34
|
+
homepage_uri: https://github.com/mcorino/plat4m
|
35
|
+
github_repo: https://github.com/mcorino/plat4m
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '2.5'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
requirements: []
|
51
|
+
rubygems_version: 3.5.3
|
52
|
+
signing_key:
|
53
|
+
specification_version: 4
|
54
|
+
summary: Runtime system detection.
|
55
|
+
test_files: []
|