Skip to content

Commit

Permalink
Showcase dynamic build requires
Browse files Browse the repository at this point in the history
Since Fedora 31 it's possible to use Dynamic BuildRequires[1]. This
removes the need to change the spec file all the time to keep in sync
with the Foreman repo itself.

Once EL 8 support is dropped, the legacy way can be dropped. Until then
it's hidden behind conditionals so at least EL 9 is up to date.

In a proper implementation we would have tooling that's usable in all
package, like a foreman-packaging RPM with reusable scripts and macros.

[1]: https://fedoraproject.org/wiki/Changes/DynamicBuildRequires
  • Loading branch information
ekohl committed Mar 5, 2024
1 parent 212285e commit 3c51fa5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
16 changes: 15 additions & 1 deletion packages/foreman/foreman/foreman.spec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
%global dynflow_sidekiq_service_name dynflow-sidekiq@
%global rake /usr/bin/rake

%global release 2
%global release 3
%global prereleasesource develop
%global prerelease %{?prereleasesource}

Expand All @@ -17,6 +17,7 @@ Group: Applications/System
License: GPLv3+ with exceptions
URL: https://theforeman.org
Source0: https://downloads.theforeman.org/%{name}/%{name}-%{version}%{?prerelease:-}%{?prerelease}.tar.bz2
Source1: gen-gem-buildreqs
Source3: %{name}.logrotate
Source4: %{name}.cron.d
Source5: %{name}.tmpfiles
Expand Down Expand Up @@ -116,6 +117,7 @@ Requires: (rubygem(rss) or ruby-default-gems < 3.0)
BuildRequires: (rubygem(rexml) or ruby-default-gems < 3.0)
Requires: (rubygem(rexml) or ruby-default-gems < 3.0)

%if 0%{?fedora} < 31 && 0%{?rhel} < 9
# start specfile default BuildRequires
BuildRequires: (rubygem(rails) >= 6.1.6 with rubygem(rails) < 6.2.0)
BuildRequires: (rubygem(rest-client) >= 2.0.0 with rubygem(rest-client) < 3)
Expand Down Expand Up @@ -161,6 +163,7 @@ BuildRequires: (rubygem(graphql) >= 1.13.0 with rubygem(graphql) < 1.14.0)
BuildRequires: rubygem(graphql-batch)
BuildRequires: rubygem(activerecord-nulldb-adapter)
# end specfile default BuildRequires
%endif

# assets
BuildRequires: nodejs-packaging
Expand Down Expand Up @@ -196,6 +199,7 @@ BuildRequires: (npm(os-browserify) >= 0.3.0 with npm(os-browserify) < 1.0.0)
BuildRequires: (npm(react-intl) >= 2.8.0 with npm(react-intl) < 3.0.0)
# end package.json dependencies BuildRequires

%if 0%{?fedora} < 31 && 0%{?rhel} < 9
# start specfile assets BuildRequires
BuildRequires: (rubygem(jquery-ui-rails) >= 6.0 with rubygem(jquery-ui-rails) < 7.0)
BuildRequires: (rubygem(patternfly-sass) >= 3.59.4 with rubygem(patternfly-sass) < 3.60.0)
Expand All @@ -210,7 +214,14 @@ BuildRequires: (rubygem(coffee-rails) >= 5.0.0 with rubygem(coffee-rails) < 5.1.
# start specfile facter BuildRequires
BuildRequires: rubygem(facter)
# end specfile facter BuildRequires
%else
# Tools needed by the script
BuildRequires: rubygems(bundler)

%generate_buildrequires
# Generate rubygem BuildRequires using a script that uses bundler
%{SOURCE1}
%endif

%package cli
Summary: Foreman CLI
Expand Down Expand Up @@ -861,6 +872,9 @@ exit 0
%systemd_postun %{name}.socket

%changelog
* Mon Mar 04 2024 Ewoud Kohl van Wijngaarden <[email protected]> - 3.11.0-0.3.develop
- Use generated build dependencies if available

* Mon Mar 04 2024 Evgeni Golov - 3.11.0-0.2.develop
- Update GEM Requiremens

Expand Down
48 changes: 48 additions & 0 deletions packages/foreman/foreman/gen-gem-buildreqs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env ruby
require 'optparse'
require 'bundler'

options = {}
OptionParser.new do |opts|
opts.on('--gemfile GEMFILE', 'Path to Gemfile')
opts.on('--groups', 'Bundler groups to include')
end.parse!(into: options)

FILENAME = options.fetch(:gemfile, 'Gemfile')
INCLUDED_GROUPS = options.fetch(:groups, 'default:assets:facter').split(':').map(&:to_sym)

unless File.file?(FILENAME)
STDERR.puts "File #{FILENAME} is not an existing file"
exit 1
end

bundler = Dir.chdir(File.dirname(FILENAME)) do
Bundler.load
end

bundler.dependencies.each do |dependency|
next unless (dependency.groups & INCLUDED_GROUPS).any?

name = "rubygem(#{dependency.name})"

reqs = []
dependency.requirement.requirements.each do |op, version|
if op == '~>'
reqs << "#{name} >= #{version}" << "#{name} < #{version.bump}.0"
elsif op == '>=' && version.to_s == '0'
# No real requirement, handled elsewhere
elsif op != '!=' # != is not supported in RPM
reqs << "#{name} #{op} #{version}"
end
end

requirement = case reqs.size
when 0
name
when 1
reqs.first
else
"(#{reqs.join(' with ')})"
end
puts requirement
end

0 comments on commit 3c51fa5

Please sign in to comment.