rubygems-requirements-system 0.0.2 → 0.0.4

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: 598b91ef023d6606d97e7bfc74168cef0316de0897c63266c7371ef844322d6a
4
- data.tar.gz: 99fe81ea125044711118147950372853e17377a25306b09e20f9ca0f3369e43e
3
+ metadata.gz: 0271d5e7218e5a925f41e5d890ad4eed1194572fbb2a140578df4bef80bbc666
4
+ data.tar.gz: 9631386ad89e63d5534cc0e5e463aa7231f777ec3c3738c80a9dbcbedd94d779
5
5
  SHA512:
6
- metadata.gz: b0dbff35b8e7ccfd004b78bfcf26efe011afd87106c646ba02093c4c7e076f568ebc8d65b96dc3ce15d2ed739780de8504557a412f5e4a1e21a2a38c15e6f735
7
- data.tar.gz: 89933a20c0aa2129b871df4a70d445bb856258959889a225849f25030d55de60252470db5e540e3a3fd12cedc4773ca5c78712d170183aa393948267419ea2b2
6
+ metadata.gz: f3d2ac2e6e04d60114008135395b83c563251810bd5157af728dd0fd28dc1100610a7621895400f298f9ed2747122c21483ea3f43e4447ad92cde70aba7ce15f
7
+ data.tar.gz: b0679db240aa4a3c1feb263da1e36f17d2a984b7e29431e4d0159c1cfce3642e40d8498d99da652001789ead7965ee6decbbd073aecb4050bbde7c4fcf950867
data/README.md CHANGED
@@ -40,21 +40,33 @@ developers and users. If we can reduce maintenance costs for
40
40
  developers, developers can focus on new features and bug fixes than
41
41
  releases.
42
42
 
43
- ## Usage
43
+ ## Usage for users
44
44
 
45
- Add `rubygems-requirements-system` to your gem's runtime dependencies:
45
+ If you're using Bundler, add the following line to your `Gemfile`:
46
46
 
47
47
  ```ruby
48
- Gem::Specification.new do |spec|
49
- # ...
50
- spec.add_runtime_dependency("rubygems-requirements-system")
51
- # ...
52
- end
48
+ plugin "rubygems-requirements-system"
53
49
  ```
54
50
 
51
+ If you're not using Bundler, install `rubygems-requirements-system`:
52
+
53
+ ```bash
54
+ gem install rubygems-requirements-system
55
+ ```
56
+
57
+ ## Usage for developers
58
+
59
+ Add dependency information to `Gem::Specification#requirements`.
60
+
55
61
  ### Basic usage
56
62
 
57
- Add dependency information to `Gem::Specification#requirements`:
63
+ In most cases, you can just specify the followings:
64
+
65
+ 1. Package ID
66
+ 2. Platform ID
67
+ 3. Package name on the platform
68
+
69
+ See the following example:
58
70
 
59
71
  ```ruby
60
72
  Gem::Specification.new do |spec|
@@ -173,7 +185,7 @@ Gem::Specification.new do |spec|
173
185
  #
174
186
  # On Ubuntu 24.04:
175
187
  # https://packages.groonga.org/%{distribution}/groonga-apt-source-latest-%{code_name}.deb ->
176
- # https://packages.groonga.org/ubuntu/groonga-apt-source-latest-nobole.deb
188
+ # https://packages.groonga.org/ubuntu/groonga-apt-source-latest-noble.deb
177
189
  spec.requirements << "system: groonga: debian: https://packages.groonga.org/%{distribution}/groonga-apt-source-latest-%{code_name}.deb"
178
190
  # Install libgroonga-dev from the registered repository.
179
191
  spec.requirements << "system: groonga: debian: libgroonga-dev"
@@ -207,15 +219,141 @@ Gem::Specification.new do |spec|
207
219
  end
208
220
  ```
209
221
 
210
- ## Requirements
222
+ ### Install repositories
223
+
224
+ You can install APT/Yum repositories by specifying metadata.
225
+
226
+ You need to specify multiple metadata for one repository. So you need
227
+ to use multiple `spec.requirements` for one repository. Here is the
228
+ syntax for one repository:
229
+
230
+ ```ruby
231
+ spec.requirements << "system: #{package}: #{platform}: repository: #{key1}: #{value1}"
232
+ spec.requirements << "system: #{package}: #{platform}: repository: #{key2}: #{value2}"
233
+ # ...
234
+ ```
235
+
236
+ You must specify at least `id` as `key`. For example:
237
+
238
+ ```
239
+ spec.requirements << "system: libpq: debian: repository: id: pgdg"
240
+ ```
241
+
242
+ You can start another repository metadata by starting `id` metadata
243
+ for another repository:
244
+
245
+ ```ruby
246
+ spec.requirements << "system: #{package}: #{platform}: repository: id: repository1"
247
+ spec.requirements << "system: #{package}: #{platform}: repository: #{key1_1}: #{value1_1}"
248
+ spec.requirements << "system: #{package}: #{platform}: repository: #{key1_2}: #{value1_2}"
249
+ # ...
250
+ spec.requirements << "system: #{package}: #{platform}: repository: id: repository2"
251
+ spec.requirements << "system: #{package}: #{platform}: repository: #{key2_1}: #{value2_1}"
252
+ spec.requirements << "system: #{package}: #{platform}: repository: #{key2_2}: #{value2_2}"
253
+ # ...
254
+ ```
255
+
256
+ Here are metadata for a APT repository:
257
+
258
+ * `compoennts`: Optional. The default is `main`.
259
+ * `signed-by`: Optional. The URL of armored keyring that is used for
260
+ signing this repository.
261
+ * `suites`: Optional. The default is `%{code_name}`.
262
+ * `types`: Optional. The default is `deb`.
263
+ * `uris`: Required. The URLs that provide this repository.
264
+
265
+ See also: https://wiki.debian.org/SourcesList
266
+
267
+ Here are metadata for a Yum repository:
268
+
269
+ * `baseurl`: Required. The base URL that provides this repository.
270
+ * `gpgkey`: Optional. The URL of GPG key that is used for signing this
271
+ repository.
272
+ * `name`: Optional. The name of this repository.
273
+
274
+ See also: TODO: Is there any URL that describes the specification of
275
+ `.repo` file?
276
+
277
+ You can use placeholder for metadata values with `%{KEY}` format.
278
+
279
+ Here are available placeholders:
280
+
281
+ `debian` family platforms:
282
+
283
+ * `distribution`: The `ID` value in `/etc/os-release`. It's `debian`,
284
+ `ubuntu` and so on.
285
+ * `code_name`: The `VERSION_CODENAME` value in `/etc/os-release`. It's
286
+ `bookworm`, `noble` and so on.
287
+ * `version`: The `VERSION_ID` value in `/etc/os-release`. It's `12`,
288
+ `24.04` and so on.
289
+
290
+ `fedora` family platforms:
291
+
292
+ * `distribution`: The `ID` value in `/etc/os-release`. It's `fedora`,
293
+ `rhel`, `almalinux` and so on.
294
+ * `major_version`: The major part of `VERSION_ID` value in
295
+ `/etc/os-release`. It's `41`, `9` and so on.
296
+ * `version`: The `VERSION_ID` value in `/etc/os-release`. It's `41`,
297
+ `9.5` and so on.
298
+
299
+ Here is an example that uses this feature for adding a new repository:
300
+
301
+ ```ruby
302
+ Gem::Specification.new do |spec|
303
+ # ...
304
+
305
+ # Install PostgreSQL's APT repository on Debian family platforms.
306
+ #
307
+ # %{code_name} is placeholders.
308
+ #
309
+ # On Debian GNU/Linux bookworm:
310
+ # %{code_name}-pgdg ->
311
+ # bookworm-pgdg
312
+ #
313
+ # On Ubuntu 24.04:
314
+ # %{code_name}-pgdg ->
315
+ # noble-pgdg
316
+ spec.requirements << "system: libpq: debian: repository: id: pgdg"
317
+ spec.requirements << "system: libpq: debian: repository: uris: https://apt.postgresql.org/pub/repos/apt"
318
+ spec.requirements << "system: libpq: debian: repository: signed-by: https://www.postgresql.org/media/keys/ACCC4CF8.asc"
319
+ spec.requirements << "system: libpq: debian: repository: suites: %{code_name}-pgdg"
320
+ spec.requirements << "system: libpq: debian: repository: components: main"
321
+ # Install libpq-dev from the registered repository.
322
+ spec.requirements << "system: libpq: debian: libpq-dev"
323
+
324
+ # Install PostgreSQL's Yum repository on RHEL family platforms:
325
+ spec.requirements << "system: libpq: rhel: repository: id: pgdg17"
326
+ spec.requirements << "system: libpq: rhel: repository: name: PostgreSQL 17 $releasever - $basearch"
327
+ spec.requirements << "system: libpq: rhel: repository: baseurl: https://download.postgresql.org/pub/repos/yum/17/redhat/rhel-$releasever-$basearch"
328
+ spec.requirements << "system: libpq: rhel: repository: gpgkey: https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL"
329
+ # You can disable built-in "postgresql" module by "module: disable:
330
+ # postgresql".
331
+ spec.requirements << "system: libpq: rhel: module: disable: postgresql"
332
+ # Install postgresql17-devel from the registered repository. But
333
+ # users can't find "libpq.pc" provided by postgresql17-devel without
334
+ # PKG_CONFIG_PATH=/usr/pgsql-17/lib/pkgconfig ...
335
+ spec.requirements << "system: libpq: rhel: postgresql17-devel"
336
+
337
+ # ...
338
+ end
339
+ ```
340
+
341
+ ## Configurations
342
+
343
+ ### Disable
344
+
345
+ If you want to install system packages automatically, you need to
346
+ install rubygems-requirements-system gem explicitly (opt-in). You can
347
+ disable rubygems-requirements-system gem even when you install this
348
+ explicitly:
211
349
 
212
- RubyGems 3.5.0 or later is required. RubyGems can load installed
213
- plugin immediately since 3.5.0.
350
+ 1. Set `RUBYGEMS_REQUIREMENTS_SYSTEM=false`
351
+ 2. Add the following configuration to `~/.gemrc`:
214
352
 
215
- If `gem install glib2` installs rubygems-requirements-system gem as a
216
- dependency, old RubyGems doesn't use a RubyGems plugin in
217
- rubygems-requirements-system gem while installing glib2 gem. So glib2
218
- gem dependencies aren't installed automatically.
353
+ ```yaml
354
+ requirements_system:
355
+ enabled: false
356
+ ```
219
357
 
220
358
  ## History
221
359
 
data/Rakefile CHANGED
@@ -16,6 +16,8 @@
16
16
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
 
18
18
  require "bundler/gem_helper"
19
+ require "json"
20
+ require "open-uri"
19
21
 
20
22
  base_dir = File.dirname(__FILE__)
21
23
  helper = Bundler::GemHelper.new(base_dir)
@@ -24,6 +26,35 @@ def helper.version_tag
24
26
  end
25
27
  helper.install
26
28
 
29
+ def github_api(path)
30
+ URI("https://api.github.com/#{path}").open do |response|
31
+ JSON.parse(response.read)
32
+ end
33
+ end
34
+
35
+ def github_content(repository, tag, path, &block)
36
+ uri = "https://raw.githubusercontent.com/#{repository}/" +
37
+ "refs/tags/#{tag}/#{path}"
38
+ URI(uri).open(&block)
39
+ end
40
+
41
+ namespace :vendor do
42
+ namespace :pkg_config do
43
+ desc "Update vendored pkg-config"
44
+ task :update do
45
+ latest = github_api("repos/ruby-gnome/pkg-config/releases/latest")
46
+ github_content("ruby-gnome/pkg-config",
47
+ latest["tag_name"],
48
+ "lib/pkg-config.rb") do |response|
49
+ output_path = "lib/rubygems-requirements-system/pkg-config.rb"
50
+ File.open(output_path, "w") do |output|
51
+ IO.copy_stream(response, output)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
27
58
  release_task = Rake.application["release"]
28
59
  # We use Trusted Publishing.
29
60
  release_task.prerequisites.delete("build")
data/doc/text/news.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # News
2
2
 
3
+ ## 0.0.4 - 2025-03-05
4
+
5
+ ### Improvements
6
+
7
+ * Bundled `pkg-config` gem.
8
+
9
+ * Changed to opt-in style. Each user must install this gem
10
+ explicitly.
11
+
12
+ * Added support for Bundler.
13
+
14
+ ## 0.0.3 - 2025-01-13
15
+
16
+ ### Improvements
17
+
18
+ * Added support for opt-out.
19
+
20
+ * debian: Added support for adding APT repository by raw metadata.
21
+
22
+ * fedora: Added support for adding Yum repository by raw metadata.
23
+
24
+ * fedora: Added support for enabling/disabling module.
25
+
3
26
  ## 0.0.2 - 2025-01-08
4
27
 
5
28
  ### Improvements
@@ -15,42 +15,18 @@
15
15
 
16
16
  require "shellwords"
17
17
 
18
- require "pkg-config"
19
-
20
18
  require_relative "version"
21
19
 
22
20
  require_relative "platform"
21
+ require_relative "requirements-parser"
23
22
 
24
23
  module RubyGemsRequirementsSystem
25
- Package = Struct.new(:id, :operator, :version) do
26
- def valid?
27
- return false if id.empty?
28
- return false if operator and version.nil?
29
- true
30
- end
31
- end
32
-
33
- Requirement = Struct.new(:packages, :system_packages) do
34
- def satisfied?
35
- packages.any? do |package|
36
- installed?(package)
37
- end
38
- end
39
-
40
- private
41
- def installed?(package)
42
- package_config = PKGConfig.package_config(package.id)
43
- begin
44
- package_config.cflags
45
- rescue PackageConfig::NotFoundError
46
- return false
47
- end
48
-
49
- return true if package.version.nil?
50
-
51
- current_version = Gem::Version.new(package_config.version)
52
- required_version = Gem::Version.new(package.version)
53
- current_version.__send__(package.operator, required_version)
24
+ pkg_config_rb = File.join(__dir__, "pkg-config.rb")
25
+ load(pkg_config_rb, self)
26
+ unless const_defined?(:PKGConfig)
27
+ # Ruby < 3.1
28
+ File.open(pkg_config_rb) do |pkg_config_rb_file|
29
+ module_eval(pkg_config_rb_file.read, pkg_config_rb)
54
30
  end
55
31
  end
56
32
 
@@ -63,7 +39,10 @@ module RubyGemsRequirementsSystem
63
39
  end
64
40
 
65
41
  def install
66
- requirements = parse_requirements(@gemspec.requirements)
42
+ return true unless enabled?
43
+
44
+ parser = RequirementsParser.new(@gemspec.requirements, @platform)
45
+ requirements = parser.parse
67
46
  requirements.all? do |requirement|
68
47
  next true if requirement.satisfied?
69
48
  @platform.install(requirement)
@@ -71,52 +50,21 @@ module RubyGemsRequirementsSystem
71
50
  end
72
51
 
73
52
  private
74
- def parse_requirements(gemspec_requirements)
75
- all_packages_set = {}
76
- requirements = {}
77
- gemspec_requirements.each do |gemspec_requirement|
78
- components = gemspec_requirement.split(/: +/, 4)
79
- next unless components.size == 4
80
-
81
- id, raw_packages, platform, system_package = components
82
- next unless id == "system"
83
-
84
- packages = parse_packages(raw_packages)
85
- next if packages.empty?
86
-
87
- all_packages_set[packages] = true
88
-
89
- next unless @platform.target?(platform)
90
- requirements[packages] ||= []
91
- requirements[packages] << system_package
92
- end
93
- (all_packages_set.keys - requirements.keys).each do |not_used_packages|
94
- system_packages = @platform.default_system_packages(not_used_packages)
95
- next if system_packages.nil?
96
- requirements[not_used_packages] = system_packages
97
- end
98
- requirements.collect do |packages, system_packages|
99
- Requirement.new(packages, system_packages)
53
+ def enabled?
54
+ case ENV["RUBYGEMS_REQUIREMENTS_SYSTEM"]
55
+ when "0", "no", "NO", "false", "FALSE"
56
+ return false
100
57
  end
101
- end
102
58
 
103
- def parse_packages(raw_packages)
104
- packages = raw_packages.split(/\s*\|\s*/).collect do |raw_package|
105
- Package.new(*raw_package.split(/\s*(==|!=|>=|>|<=|<)\s*/, 3))
106
- end
107
- # Ignore this requirement if any invalid package is included.
108
- # We must not report an error for this because
109
- # Gem::Specification#requirements is a free form
110
- # configuration. So there are configuration values that use
111
- # "system: ..." but not for this plugin. We can report a
112
- # warning instead.
113
- packages.each do |package|
114
- unless package.valid?
115
- # TODO: Report a warning
116
- return []
117
- end
59
+ requirements_system = Gem.configuration["requirements_system"] || {}
60
+ case requirements_system["enabled"]
61
+ when false
62
+ return false
63
+ when "false" # "true"/"false" isn't converted to boolean with old RubyGems
64
+ return false
118
65
  end
119
- packages
66
+
67
+ true
120
68
  end
121
69
  end
122
70
  end
@@ -34,7 +34,7 @@ module RubyGemsRequirementsSystem
34
34
  end
35
35
 
36
36
  def id_like
37
- (self["ID_LIKE"] || "").split(/ /)
37
+ (self["ID_LIKE"] || "").split(/\s+/)
38
38
  end
39
39
 
40
40
  def version
@@ -14,4 +14,25 @@
14
14
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
15
 
16
16
  module RubyGemsRequirementsSystem
17
+ Package = Struct.new(:id, :operator, :required_version) do
18
+ class << self
19
+ def parse(input)
20
+ new(*input.split(/\s*(==|>=|>|<=|<)\s*/, 3))
21
+ end
22
+ end
23
+
24
+ def valid?
25
+ return false if id.empty?
26
+ return false if operator and required_version.nil?
27
+ true
28
+ end
29
+
30
+ def satisfied?(target_version)
31
+ return true if required_version.nil?
32
+
33
+ target = Gem::Version.new(target_version)
34
+ required = Gem::Version.new(required_version)
35
+ target.__send__(operator, required)
36
+ end
37
+ end
17
38
  end