/obs-service-cargo_vendor

OBS Source Service to vendor Rust dependency sources

Primary LanguagePythonGNU General Public License v2.0GPL-2.0

OBS Source Service obs-service-cargo_vendor

The authoritative source of this project is https://github.com/openSUSE/obs-service-cargo_vendor.

obs-service-cargo_vendor uses the Cargo.toml file present in a Rust application to run cargo vendor, that populates a folder with the sources of the Rust dependencies. This folder is compressed in a vendor.tar[.<tar compression>] archive, and copied in the RPM package directory source. The archive can be commited to OBS to facilitate builds of Rust application packages for openSUSE, SUSE, and numerous other distributions.

The vendored sources allow building a Rust application using cargo build, without requiring access to the network.

Usage for packagers (with SCM service)

Follow this steps when creating a new RPM package for a Rust application:

  1. Add to the _service file this snippet:
<services>
  <service name="obs_scm" mode="disabled">
    ...
  </service>
  <service name="cargo_vendor" mode="disabled">
    <param name="srcdir">projectname</param>
    <param name="update">true</param>
  </service>
</services>
  1. Run osc command locally:
$ osc service ra
  1. A set of steps is displayed from this command to guide you in modifying your .spec. An example is:
Your spec file should be modified per the following example:

---BEGIN---
%global rustflags '-Clink-arg=-Wl,-z,relro,-z,now'

Source1:    vendor.tar.zst
Source2:    cargo_config

%prep
%setup -qa1
mkdir .cargo
cp %{SOURCE2} .cargo/config

%build
RUSTFLAGS=%{rustflags} cargo build --release

%install
RUSTFLAGS=%{rustflags} cargo install --root=%{buildroot}%{_prefix} --path .
  1. Add the generated tarball to the packages sources:
$ osc add vendor.tar.zst
  1. Perform a local build to confirm the changes work as expected:
$ osc build

Manual (without SCM service)

If you are not using SCM, you can use the cargo vendor service manually.

  1. Extract your source archive into your working directory.
$ tar -xv archive.tar.zst
  1. Examine the folder name it extracted, IE archive-v1.0.0

  2. Set srcdir to match

<services>
  <service name="cargo_vendor" mode="disabled">
    <param name="srcdir">archive-v1.0.0</param>
  </service>
</services>
  1. Continue from Usage for packagers - Step 2.

Note you will not be able to have a server side cargo vendor service with this configuration, so you should keep mode="disabled"

Options

  • <param name="srcdir">projectname</param>
  • <param name="srctar">name-of-source.tar</param>

The location to search for the Cargo.toml which we will vendor from. Generally this is your project name from the SCM checkout, or the extracted archive top dir, but it may differ depending on your configuration.

You can alternately specify srctar, which we will unpack into a temp location and perform the vendor instead. This removes your need to rely on obs_scm or similar

  • <param name="compression">zst</param>

The compression to use for the vendor.tar. If the option is not supplied it will default to zst. Available compressions are those supported by tar.

  • <param name="update" />

If present, cargo update will be run before vendoring to ensure that the latest version of compatible dependencies is used.

  • <param name="tag">tagname</param>

In some rare case, you may wish to annotate your vendor.tar and cargo_config with a unique tag. Generally this happens if you are needing to create multiple vendor tars. When you specify tag the vendor routine will create vendor-{tag}.tar and cargo_config_{tag} instead.

You may also want to add additional Cargo.toml files to sync and vendor. This will fix some issues with complex projects with many subcrates that are not in match with the dependencies of the root Cargo.toml file. The first param will be assumed to be the manifest path. Subsequent cargotoml parameters are sync options.

     <!-- This will be for manifest path -->
     <param name="cargotoml">jay-config/Cargo.toml</param>
    <!-- This will be assumed to be synced and vendored -->
     <param name="cargotoml">default-config/Cargo.toml</param>
    <!-- This will be assumed to be synced and vendored -->
     <param name="cargotoml">algorithms/Cargo.toml</param>

Example

<services>
  <service name="obs_scm" mode="disabled">
    ...
  </service>
  <service name="cargo_vendor" mode="disabled">
    <param name="srcdir">projectname</param>
    <param name="compression">zst</param>
    <param name="update">true</param>
  </service>
</services>
<services>
  <service name="cargo_vendor" mode="disabled">
    <param name="srctar">projectname.tar.zst</param>
    <param name="compression">zst</param>
    <param name="update">true</param>
  </service>
</services>

Transition note

Until obs-service-cargo_vendor is available on OBS, the vendor.tar[.<tar compression>] should be committed along with the Rust application source tarball.

License

GNU General Public License v2.0 or later

Attributions

This project is a derivative work of obs-service-go_modules available at https://github.com/openSUSE/obs-service-go_modules.