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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 22a3a8081ff1e94f151748798d5ef76a8486e443bba0fb1eff8beba737117ceb
4
- data.tar.gz: 6fd217d604fa0ca5e14d46621579c4def3ee907e729fd5c49d5b158db37bc436
3
+ metadata.gz: 8f87b213f67bfe68b6caa65cc7d6f5f26afcd296be4c8175ab6c60e34ce5a6e0
4
+ data.tar.gz: fcb778b18e788a332e523f299f9af433997c42cad62bcf132b6c6451fc902f81
5
5
  SHA512:
6
- metadata.gz: 7d38029bf367d24f6dca168d661a75fe5b1571f9e41bbde5d9aaeed641bcbf9ef45c7e3035969a72edf3b30faf89e3aa5693d66e6be2c5b96dee1bf7a7f0beb6
7
- data.tar.gz: 76f55fc9787328c0892da26a4f623c424d1d8cbdae9787fe8d5864bbe0fae0880707bcb41c32eab003ccdb2abca35c1ac3e9b749c3893a18c0ecec007b28d89b
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
@@ -1,5 +1,11 @@
1
1
  # News
2
2
 
3
+ ## 0.0.8 - 2025-04-05
4
+
5
+ ### Improvements
6
+
7
+ * Added support for an executable as a dependency.
8
+
3
9
  ## 0.0.7 - 2025-03-22
4
10
 
5
11
  ### Fixes
@@ -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
- include Gem::UserInteraction
35
-
36
- def initialize(gemspec)
35
+ def initialize(gemspec, ui)
37
36
  @gemspec = gemspec
38
- @platform = Platform.detect
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
- class << self
19
- def parse(input)
20
- new(*input.split(/\s*(==|>=|>|<=|<)\s*/, 3))
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
- def valid?
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
- include Gem::UserInteraction
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 = "requirements: system: #{package_label}: #{action}"
126
- say("#{prefix}: Start")
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
- say("#{prefix}: #{result_message}")
146
+ @ui.info("#{prefix}: #{result_message}")
146
147
 
147
148
  unless succeeded
148
149
  escaped_command_line = command_line.collect do |part|
149
- Shellwords.escape(part)
150
+ Shellwobrds.escape(part)
150
151
  end
151
- alert_warning("#{prefix}: Failed.")
152
- alert_warning("Run the following command " +
153
- "to #{action} required system package: " +
154
- escaped_command_line.join(" "))
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(:packages, :system_packages) do
17
+ Requirement = Struct.new(:dependencies, :system_packages) do
18
18
  def satisfied?
19
- packages.any? do |package|
20
- installed?(package)
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
- all_packages_set = {}
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, raw_packages, platform, system_package = components
36
+ id, raw_dependencies, platform, system_package = components
35
37
  next unless id == "system"
36
38
 
37
- packages = parse_packages(raw_packages)
38
- next if packages.empty?
39
+ dependencies = parse_dependencies(raw_dependencies)
40
+ next if dependencies.empty?
39
41
 
40
- all_packages_set[packages] = true
42
+ all_dependencies_set[dependencies] = true
41
43
 
42
44
  next unless @platform.target?(platform)
43
- requirements[packages] ||= []
44
- requirements[packages] << system_package
45
+ requirements[dependencies] ||= []
46
+ requirements[dependencies] << system_package
45
47
  end
46
- (all_packages_set.keys - requirements.keys).each do |not_used_packages|
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[not_used_packages] = system_packages
55
+ requirements[not_used_deps] = system_packages
50
56
  end
51
- requirements.collect do |packages, system_packages|
57
+ requirements.collect do |dependencies, system_packages|
52
58
  system_packages = detect_system_repositories(system_packages)
53
- Requirement.new(packages, system_packages)
59
+ Requirement.new(dependencies, system_packages)
54
60
  end
55
61
  end
56
62
 
57
63
  private
58
- def parse_packages(raw_packages)
59
- packages = raw_packages.split(/\s*\|\s*/).collect do |raw_package|
60
- Package.parse(raw_package)
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
- # Ignore this requirement if any invalid package is included.
63
- # We must not report an error for this because
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
- # warning instead.
68
- packages.each do |package|
69
- unless package.valid?
70
- # TODO: Report a warning
71
- return []
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
@@ -14,5 +14,5 @@
14
14
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
16
  module RubyGemsRequirementsSystem
17
- VERSION = "0.0.7"
17
+ VERSION = "0.0.8"
18
18
  end
@@ -19,6 +19,7 @@ Gem.pre_install do |gem_installer|
19
19
 
20
20
  require_relative "rubygems-requirements-system/installer"
21
21
 
22
- installer = RubyGemsRequirementsSystem::Installer.new(gem_installer.spec)
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
- installer = RubyGemsRequirementsSystem::Installer.new(gem_installer.spec)
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.7
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-03-22 00:00:00.000000000 Z
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