Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment to create an srpm output. #1967

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jordansissel
Copy link
Owner

[ Not intended for merging at this time ]

Currently only supports cpan-to-srpm

Ideas for #1954

Currently only supports cpan-to-srpm

Ideas for #1954
Copy link
Owner Author

@jordansissel jordansissel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've annotated a few areas of the prototype

# For handling conversion
require "fpm/package/cpan"

class FPM::Package::SRPM < FPM::Package
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of this file is copied directly from rpm.rb (the FPM::Package::RPM class). I'd like to reduce code duplication if we can, such as the duplicate methods for architecture, to_s, etc, and the nearly identical output method.

end

# Pick the first file found, should be a tarball.
source_archive = ::Dir.glob(File.join(input.build_path, "*")).select(&File.method(:file?)).first
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This trick is all so we can find the original source archive that came from cpan because the 'output' is not told anything about it. If we move forward, we'll want a better way to express these things from input to output conversions, such as the cpan input being able to say "My source file is /some/path/here"

# Generate an rpm spec with Source0: <source_archive>
rpmspec = template("srpm.erb").result(binding)

# Copied from rpm.rb ---
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the below is copied directly from rpm.rb with small modifications, for example invoking rpmbuild -bs to request only a source rpm.

def to_s(format=nil)
if format.nil?
format = if attributes[:rpm_dist]
"NAME-VERSION-ITERATION.DIST.src.rpm"
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is copied and slightly modified from rpm.rb where the extension is now hard-coded to '.src.rpm'

@@ -0,0 +1,233 @@
# Hello packaging friend!
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much of this file is copied and slightly modified from the original rpm.erb

<%= description.gsub(/^\s*$/, " .") %>

%prep
%autosetup -n <%= source_archive_dirname %>
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rpm assumes the source archive contains a directory that matches the same name as the package itself, such as perl-File-Temp-0.2311/, but things from cpan are more typically containing a path named after the module itself and not following redhat's naming scheme.

The source_archive_dirname is a variable that contains the first toplevel directory within the source tarball. It seems to work well enough for %autosetup and %setup to do their jobs.

%prep
%autosetup -n <%= source_archive_dirname %>

%build
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The %build section was hand-written loosely based on what the cpan input already does.

I probably still need to set -Mlocal::lib=./cpan when invoking perl, though.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notably, this specfile only works with cpan input and would fail everything else.

For this to go forward, we'd to codify the prep/build/install steps for other inputs (gem, npm, pear, etc).

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some ideas, but we'll need to study the existing inputs (rpm, deb, gem, npm, et al) to see what common elements exist between them.

make

%install
%make_install
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses rpm's %make_install macro. This will work for some projects, but not most, especially ones which don't use make

%dir <%= rpm_file_entry(path) %>
<% end -%>
<%# list only files, not directories? -%>
/
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're building an rpm from source with rpmbuild, we might be able to get away with listing / as the %files entry and including all files that end up in the %buildroot.

This is mostly a hack at this time to avoid having to do additional file list generation in this prototype.

end

def converted_from(origin)
if origin == FPM::Package::CPAN
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll probably need a mapping of { input type => instructions }, where the instructions are the appropriate %prep, %build, %install, etc steps.

I'm not sure this can be generalized to other output targets, such as Debian source packages, Arch BUILD files, FreeBSD Ports, Nix files, and other kinds of package-from-source systems. We don't have to target everything at once, but it's good to think about ways the work can be reused when targeting things besides Red Hat packages.

@NicholasBHubbard
Copy link
Contributor

Thanks for creating this prototype!

I understand now that it is possible to automatically generate build steps for certain package input types. I would like to try to extend this prototype to support another input type (Ruby gems) and another output type (deb source packages). I want to see if I can generalize the prototype so in the future FPM can support any source-based package.

Would you please give me write access to this branch?

@wbraswell
Copy link
Contributor

@jordansissel
I am in favor of @NicholasBHubbard working on this branch with you.

@jordansissel
Copy link
Owner Author

Would you please give me write access to this branch?

GitHub doesn't have access controls per branch. I'm open to working on a fork separately or we can find some other way to work on this?

@NicholasBHubbard
Copy link
Contributor

NicholasBHubbard commented Dec 4, 2022

@jordansissel: I created #1972 which is an exact copy of this prototype, and added you to my fork. We should now both be able to write to my forks "source-based-package-support" branch (which is the branch for #1972).

I am still working on making upgrades to the prototype.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants