rubygems-requirements-system 0.0.7 → 0.0.8
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 +31 -1
- data/doc/text/news.md +6 -0
- data/lib/rubygems-requirements-system/executable.rb +24 -0
- data/lib/rubygems-requirements-system/installer.rb +5 -5
- data/lib/rubygems-requirements-system/package.rb +7 -8
- data/lib/rubygems-requirements-system/platform/base.rb +11 -10
- data/lib/rubygems-requirements-system/platform.rb +3 -3
- data/lib/rubygems-requirements-system/requirement.rb +3 -15
- data/lib/rubygems-requirements-system/requirements-parser.rb +56 -24
- data/lib/rubygems-requirements-system/ui.rb +44 -0
- data/lib/rubygems-requirements-system/version.rb +1 -1
- data/lib/rubygems_plugin.rb +2 -1
- data/plugins.rb +2 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f87b213f67bfe68b6caa65cc7d6f5f26afcd296be4c8175ab6c60e34ce5a6e0
|
4
|
+
data.tar.gz: fcb778b18e788a332e523f299f9af433997c42cad62bcf132b6c6451fc902f81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c59501b4dd04061d6ae9551569462619aeef6764f506edb1c1be42958499d3737dd45381eece9012c57837e16d063ba61825349e697dc0ec4ee230466afd3987
|
7
|
+
data.tar.gz: 2b25b9acf564e5d02c26052e6a199711865c0c84d26bee7468dd7c3553c872f82fb165aa1ff16d51e0c9638eb978fd43fac192dd099334eb69b90e371bb98a77
|
data/README.md
CHANGED
@@ -62,7 +62,7 @@ Add dependency information to `Gem::Specification#requirements`.
|
|
62
62
|
|
63
63
|
In most cases, you can just specify the followings:
|
64
64
|
|
65
|
-
1. Package ID
|
65
|
+
1. Package ID as dependency
|
66
66
|
2. Platform ID
|
67
67
|
3. Package name on the platform
|
68
68
|
|
@@ -338,6 +338,36 @@ Gem::Specification.new do |spec|
|
|
338
338
|
end
|
339
339
|
```
|
340
340
|
|
341
|
+
### Executable dependency
|
342
|
+
|
343
|
+
Dependency (the `DEPENDENCY` part in `system: DEPENDENCY: ...`) is
|
344
|
+
package ID of pkg-config by default. But you can use an executable as
|
345
|
+
dependency. For example, [graphviz
|
346
|
+
gem](https://rubygems.org/gems/graphviz) uses the `dot` command. It
|
347
|
+
means that the `dot` command is a runtime dependency of graphviz gem.
|
348
|
+
|
349
|
+
We can use rubygems-requirements-system for this use case. We can use
|
350
|
+
`executable(name)` for the `DEPENDENCY` part:
|
351
|
+
|
352
|
+
```ruby
|
353
|
+
Gem::Specification.new do |spec|
|
354
|
+
# ...
|
355
|
+
|
356
|
+
# Install dot before this gem is installed.
|
357
|
+
spec.requirements << "system: executable(dot): alt_linux: graphviz"
|
358
|
+
spec.requirements << "system: executable(dot): arch_linux: graphviz"
|
359
|
+
spec.requirements << "system: executable(dot): conda: graphviz"
|
360
|
+
spec.requirements << "system: executable(dot): debian: graphviz"
|
361
|
+
spec.requirements << "system: executable(dot): gentoo_linux: media-gfx/graphviz"
|
362
|
+
spec.requirements << "system: executable(dot): homebrew: graphviz"
|
363
|
+
spec.requirements << "system: executable(dot): macports: graphviz"
|
364
|
+
spec.requirements << "system: executable(dot): rhel: graphviz"
|
365
|
+
|
366
|
+
# ...
|
367
|
+
end
|
368
|
+
```
|
369
|
+
|
370
|
+
|
341
371
|
## Configurations
|
342
372
|
|
343
373
|
### Disable
|
data/doc/text/news.md
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright (C) 2025 Ruby-GNOME Project Team
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require_relative "executable-finder"
|
17
|
+
|
18
|
+
module RubyGemsRequirementsSystem
|
19
|
+
Executable = Struct.new(:name) do
|
20
|
+
def installed?
|
21
|
+
ExecutableFinder.exist?(name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -19,6 +19,7 @@ require_relative "version"
|
|
19
19
|
|
20
20
|
require_relative "platform"
|
21
21
|
require_relative "requirements-parser"
|
22
|
+
require_relative "ui"
|
22
23
|
|
23
24
|
module RubyGemsRequirementsSystem
|
24
25
|
pkg_config_rb = File.join(__dir__, "pkg-config.rb")
|
@@ -31,17 +32,16 @@ module RubyGemsRequirementsSystem
|
|
31
32
|
end
|
32
33
|
|
33
34
|
class Installer
|
34
|
-
|
35
|
-
|
36
|
-
def initialize(gemspec)
|
35
|
+
def initialize(gemspec, ui)
|
37
36
|
@gemspec = gemspec
|
38
|
-
@
|
37
|
+
@ui = UI.new(ui)
|
38
|
+
@platform = Platform.detect(@ui)
|
39
39
|
end
|
40
40
|
|
41
41
|
def install
|
42
42
|
return true unless enabled?
|
43
43
|
|
44
|
-
parser = RequirementsParser.new(@gemspec.requirements, @platform)
|
44
|
+
parser = RequirementsParser.new(@gemspec.requirements, @platform, @ui)
|
45
45
|
requirements = parser.parse
|
46
46
|
requirements.all? do |requirement|
|
47
47
|
next true if requirement.satisfied?
|
@@ -15,16 +15,15 @@
|
|
15
15
|
|
16
16
|
module RubyGemsRequirementsSystem
|
17
17
|
Package = Struct.new(:id, :operator, :required_version) do
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def installed?
|
19
|
+
package_config = PKGConfig.package_config(id)
|
20
|
+
begin
|
21
|
+
package_config.cflags
|
22
|
+
rescue PackageConfig::NotFoundError
|
23
|
+
return false
|
21
24
|
end
|
22
|
-
end
|
23
25
|
|
24
|
-
|
25
|
-
return false if id.empty?
|
26
|
-
return false if operator and required_version.nil?
|
27
|
-
true
|
26
|
+
satisfied?(package_config.version)
|
28
27
|
end
|
29
28
|
|
30
29
|
def satisfied?(target_version)
|
@@ -15,7 +15,6 @@
|
|
15
15
|
|
16
16
|
require "fileutils"
|
17
17
|
require "open-uri"
|
18
|
-
require "rubygems/user_interaction"
|
19
18
|
require "tempfile"
|
20
19
|
|
21
20
|
require_relative "../executable-finder"
|
@@ -24,7 +23,9 @@ require_relative "../os-release"
|
|
24
23
|
module RubyGemsRequirementsSystem
|
25
24
|
module Platform
|
26
25
|
class Base
|
27
|
-
|
26
|
+
def initialize(ui)
|
27
|
+
@ui = ui
|
28
|
+
end
|
28
29
|
|
29
30
|
def target?(platform)
|
30
31
|
raise NotImpelementedError
|
@@ -122,8 +123,8 @@ module RubyGemsRequirementsSystem
|
|
122
123
|
else
|
123
124
|
package_label = package
|
124
125
|
end
|
125
|
-
prefix = "
|
126
|
-
|
126
|
+
prefix = "#{package_label}: #{action}"
|
127
|
+
@ui.info("#{prefix}: Start")
|
127
128
|
failed_to_get_super_user_priviledge = false
|
128
129
|
if have_priviledge?
|
129
130
|
succeeded = system(*command_line)
|
@@ -142,16 +143,16 @@ module RubyGemsRequirementsSystem
|
|
142
143
|
else
|
143
144
|
result_message = succeeded ? "succeeded" : "failed"
|
144
145
|
end
|
145
|
-
|
146
|
+
@ui.info("#{prefix}: #{result_message}")
|
146
147
|
|
147
148
|
unless succeeded
|
148
149
|
escaped_command_line = command_line.collect do |part|
|
149
|
-
|
150
|
+
Shellwobrds.escape(part)
|
150
151
|
end
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
152
|
+
@ui.error("#{prefix}: Failed.")
|
153
|
+
@ui.error("Run the following command " +
|
154
|
+
"to #{action} required system package: " +
|
155
|
+
escaped_command_line.join(" "))
|
155
156
|
end
|
156
157
|
succeeded
|
157
158
|
end
|
@@ -22,11 +22,11 @@ module RubyGemsRequirementsSystem
|
|
22
22
|
PLATFORM_CLASSES << platform_class
|
23
23
|
end
|
24
24
|
|
25
|
-
def detect
|
25
|
+
def detect(ui)
|
26
26
|
PLATFORM_CLASSES.reverse_each do |platform_class|
|
27
|
-
return platform_class.new if platform_class.current_platform?
|
27
|
+
return platform_class.new(ui) if platform_class.current_platform?
|
28
28
|
end
|
29
|
-
Unknown.new
|
29
|
+
Unknown.new(ui)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -14,23 +14,11 @@
|
|
14
14
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
15
|
|
16
16
|
module RubyGemsRequirementsSystem
|
17
|
-
Requirement = Struct.new(:
|
17
|
+
Requirement = Struct.new(:dependencies, :system_packages) do
|
18
18
|
def satisfied?
|
19
|
-
|
20
|
-
installed?
|
19
|
+
dependencies.any? do |dependency|
|
20
|
+
dependency.installed?
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
24
|
-
private
|
25
|
-
def installed?(package)
|
26
|
-
package_config = PKGConfig.package_config(package.id)
|
27
|
-
begin
|
28
|
-
package_config.cflags
|
29
|
-
rescue PackageConfig::NotFoundError
|
30
|
-
return false
|
31
|
-
end
|
32
|
-
|
33
|
-
package.satisfied?(package_config.version)
|
34
|
-
end
|
35
23
|
end
|
36
24
|
end
|
@@ -13,65 +13,97 @@
|
|
13
13
|
# You should have received a copy of the GNU Lesser General Public License
|
14
14
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
15
|
|
16
|
+
require_relative "executable"
|
16
17
|
require_relative "package"
|
17
18
|
require_relative "requirement"
|
18
19
|
require_relative "system-repository"
|
19
20
|
|
20
21
|
module RubyGemsRequirementsSystem
|
21
22
|
class RequirementsParser
|
22
|
-
def initialize(gemspec_requirements, platform)
|
23
|
+
def initialize(gemspec_requirements, platform, ui)
|
23
24
|
@gemspec_requirements = gemspec_requirements
|
24
25
|
@platform = platform
|
26
|
+
@ui = ui
|
25
27
|
end
|
26
28
|
|
27
29
|
def parse
|
28
|
-
|
30
|
+
all_dependencies_set = {}
|
29
31
|
requirements = {}
|
30
32
|
@gemspec_requirements.each do |gemspec_requirement|
|
31
33
|
components = gemspec_requirement.split(/:\s*/, 4)
|
32
34
|
next unless components.size == 4
|
33
35
|
|
34
|
-
id,
|
36
|
+
id, raw_dependencies, platform, system_package = components
|
35
37
|
next unless id == "system"
|
36
38
|
|
37
|
-
|
38
|
-
next if
|
39
|
+
dependencies = parse_dependencies(raw_dependencies)
|
40
|
+
next if dependencies.empty?
|
39
41
|
|
40
|
-
|
42
|
+
all_dependencies_set[dependencies] = true
|
41
43
|
|
42
44
|
next unless @platform.target?(platform)
|
43
|
-
requirements[
|
44
|
-
requirements[
|
45
|
+
requirements[dependencies] ||= []
|
46
|
+
requirements[dependencies] << system_package
|
45
47
|
end
|
46
|
-
(
|
48
|
+
(all_dependencies_set.keys - requirements.keys).each do |not_used_deps|
|
49
|
+
not_used_packages = not_used_deps.select do |dependency|
|
50
|
+
dependency.is_a?(Package)
|
51
|
+
end
|
52
|
+
next if not_used_packages.empty?
|
47
53
|
system_packages = @platform.default_system_packages(not_used_packages)
|
48
54
|
next if system_packages.nil?
|
49
|
-
requirements[
|
55
|
+
requirements[not_used_deps] = system_packages
|
50
56
|
end
|
51
|
-
requirements.collect do |
|
57
|
+
requirements.collect do |dependencies, system_packages|
|
52
58
|
system_packages = detect_system_repositories(system_packages)
|
53
|
-
Requirement.new(
|
59
|
+
Requirement.new(dependencies, system_packages)
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
57
63
|
private
|
58
|
-
def
|
59
|
-
|
60
|
-
|
64
|
+
def parse_dependencies(raw_dependencies)
|
65
|
+
dependencies = []
|
66
|
+
raw_dependencies.split(/\s*\|\s*/).each do |raw_dependency|
|
67
|
+
match_data = /\A([^(]+)\((.+)\)\z/.match(raw_dependency)
|
68
|
+
if match_data
|
69
|
+
type = match_data[1]
|
70
|
+
value = match_data[2]
|
71
|
+
else
|
72
|
+
type = "pkgconfig"
|
73
|
+
value = raw_dependency
|
74
|
+
end
|
75
|
+
dependency = parse_dependency(type, value, raw_dependency)
|
76
|
+
next if dependency.nil?
|
77
|
+
dependencies << dependency
|
61
78
|
end
|
62
|
-
|
63
|
-
|
79
|
+
dependencies
|
80
|
+
end
|
81
|
+
|
82
|
+
def parse_dependency(type, value, raw_dependency)
|
83
|
+
# We must not report an error for invalid dependency because
|
64
84
|
# Gem::Specification#requirements is a free form
|
65
85
|
# configuration. So there are configuration values that use
|
66
|
-
# "system: ..." but not for this plugin. We can report a
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
86
|
+
# "system: ..." but not for this plugin. We can report a warning
|
87
|
+
# instead.
|
88
|
+
case type
|
89
|
+
when "executable"
|
90
|
+
Executable.new(value)
|
91
|
+
when "pkgconfig"
|
92
|
+
id, operator, required_version = value.split(/\s*(==|>=|>|<=|<)\s*/, 3)
|
93
|
+
if id.empty?
|
94
|
+
@ui.warn("Ignore invalid package: no ID: #{raw_dependency}")
|
95
|
+
return nil
|
96
|
+
end
|
97
|
+
if operator and required_version.nil?
|
98
|
+
@ui.warn("Ignore invalid package: " +
|
99
|
+
"no required version with operator: #{raw_dependency}")
|
100
|
+
return nil
|
72
101
|
end
|
102
|
+
Package.new(id, operator, required_version)
|
103
|
+
else
|
104
|
+
@ui.warn("Ignore unsupported type: #{type}: #{raw_dependency}")
|
105
|
+
nil
|
73
106
|
end
|
74
|
-
packages
|
75
107
|
end
|
76
108
|
|
77
109
|
def detect_system_repositories(original_system_packages)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright (C) 2025 Ruby-GNOME Project Team
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
module RubyGemsRequirementsSystem
|
17
|
+
class UI
|
18
|
+
def initialize(ui)
|
19
|
+
@ui = ui
|
20
|
+
end
|
21
|
+
|
22
|
+
def debug(message)
|
23
|
+
log(:debug, message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def info(message)
|
27
|
+
log(:info, message)
|
28
|
+
end
|
29
|
+
|
30
|
+
def warn(message)
|
31
|
+
log(:warn, message)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def log(level, message)
|
36
|
+
message = "requirements: system: #{message}"
|
37
|
+
if @ui.respond_to?(level)
|
38
|
+
@ui.__send__(level, message)
|
39
|
+
else
|
40
|
+
@ui.say(message)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/rubygems_plugin.rb
CHANGED
@@ -19,6 +19,7 @@ Gem.pre_install do |gem_installer|
|
|
19
19
|
|
20
20
|
require_relative "rubygems-requirements-system/installer"
|
21
21
|
|
22
|
-
|
22
|
+
ui = Gem.ui
|
23
|
+
installer = RubyGemsRequirementsSystem::Installer.new(gem_installer.spec, ui)
|
23
24
|
installer.install
|
24
25
|
end
|
data/plugins.rb
CHANGED
@@ -20,7 +20,8 @@ Bundler::Plugin::API.hook(Bundler::Plugin::Events::GEM_BEFORE_INSTALL_ALL) do |d
|
|
20
20
|
|
21
21
|
require_relative "lib/rubygems-requirements-system/installer"
|
22
22
|
|
23
|
-
|
23
|
+
ui = Bundler.ui
|
24
|
+
installer = RubyGemsRequirementsSystem::Installer.new(gem_installer.spec, ui)
|
24
25
|
installer.install
|
25
26
|
end
|
26
27
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubygems-requirements-system
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sutou Kouhei
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-04-05 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: |-
|
13
13
|
Users need to install system packages to install an extension library
|
@@ -29,6 +29,7 @@ files:
|
|
29
29
|
- doc/text/lgpl-3.txt
|
30
30
|
- doc/text/news.md
|
31
31
|
- lib/rubygems-requirements-system/executable-finder.rb
|
32
|
+
- lib/rubygems-requirements-system/executable.rb
|
32
33
|
- lib/rubygems-requirements-system/installer.rb
|
33
34
|
- lib/rubygems-requirements-system/os-release.rb
|
34
35
|
- lib/rubygems-requirements-system/package.rb
|
@@ -55,6 +56,7 @@ files:
|
|
55
56
|
- lib/rubygems-requirements-system/requirement.rb
|
56
57
|
- lib/rubygems-requirements-system/requirements-parser.rb
|
57
58
|
- lib/rubygems-requirements-system/system-repository.rb
|
59
|
+
- lib/rubygems-requirements-system/ui.rb
|
58
60
|
- lib/rubygems-requirements-system/version.rb
|
59
61
|
- lib/rubygems_plugin.rb
|
60
62
|
- plugins.rb
|