How to release a beta version of a crate for limited public testing? - rust

I want to carefully release a new version of a crate to give users a chance to test it first. How can I release it to crates.io as a "beta"? (similar to how npm has #next tagged releases).
It's not supposed to be a breaking change, so I'm not going to increase semver-major version. I don't want it to be automatically picked when users do cargo upgrade until the beta testing period ends.
What version syntax should I use for the release?
Do I need to use any special cargo options when releasing it?
How do users use cargo/Cargo.toml to opt in into the beta version?

Semantic versioning defines the concept of a pre-release version:
A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes. Pre-release versions have a lower precedence than the associated normal version. A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92
To use this in Cargo, publish a crate of the planned version number but append a pre-release identifier. I suggest -beta.0, allowing you to easily increase if you need a second:
[package]
name = "library"
version = "0.1.1-beta.0"
To use this, you need to specifically opt into it by putting beta into the version requirement:
[dependencies]
library = "0.1.1-beta"
To test this, I:
Spun up a local crates.io server
Uploaded the crate library with version 0.1.0
Used library = "0.1.0" in a binary project app — it resolved to 0.1.0
Uploaded the crate library with version 0.1.1-beta.0
Ran cargo update in app — the version did not change.
Changed to library = "0.1.1-beta" in app, ran cargo update — the version did change.
Uploaded the crate library with version 0.1.1-beta.1
Ran cargo update in app — the version did change.

Related

How do I replace version "*" in Cargo.toml with version numbers from Cargo.lock?

When I'm developing a Rust project, I usually use foo-crate = "*" for dependency versions unless I have a reason to pick a particular version.
Before sharing a project, I want to update the "*" dependency version numbers in Cargo.toml to those found in Cargo.lock. i.e. I want the "*" version number to be replaced with what I'm successfully using in the project.
When I only have two or three dependencies, it's not a concern to do this manually.
Now, I'm regularly depending on a dozen or more crates.
Is there an automated way to move version numbers from Cargo.lock to Cargo.toml?

Pin version of a 3rd party crate dependency

I have a crate that has several dependencies that use one common dependency, same as the root project. An intersecting range, though.
I.e.,:
[dependencies]
bitcoin="0.28"
hdpath="0.6" <- this one depends on `>=0.27`
hwkey="0.1" <- this one depends on `=0.28`
And the current latest version is bitcoin:0.29.2
The current Cargo.lock file contains bitcoin:0.28.1 so it all works for all of the deps and compiles fine.
But if I try to publish the crate there is no way to enforce it using the version from Cargo.lock and it tries to use two different version of bitcoin. The latest 0.29.2 for hdpath because it allows any version, and 0.28.1 for other parts because they are not compatible with the latest one.
That obviously doesn't work because it produces incompatible data types.
Is there any way to force Cargo to disable such an upgrade and use version from the lock file?

How to use rocket on stable release of Rust

I am trying to use stable version of rustc to compile a rocket web application. rocket crate compiles fine but I would like to use a static file server from rocket_contrib. My Cargo.toml file looks like this:
[dependencies]
rocket = "0.5.0-rc.1"
[dependencies.rocket_dyn_templates]
version = "0.1.0-rc.1"
features = ["handlebars"]
[dependencies.rocket_contrib]
version = "0.4.10"
default-features = false
features = ["serve"]
I get the following error when I try to run cargo build :
Error: Pear requires a 'dev' or 'nightly' version of rustc.
Installed version: 1.52.1 (2021-05-09)
Minimum required: 1.31.0-nightly (2018-10-05)
Starting from version 0.5 of Rocket, you are not expected to use rocket_contrib, because this one was split into features which are either already in the core crate or moved to separate crates. The notes from this revision (see also issue 1659) provide a few more details:
This follows the completed graduation of stable contrib features into
core, removing 'rocket_contrib' in its entirety in favor of two new
crates. These crates are versioned independently of Rocket's core
libraries, allowing upgrades to dependencies without consideration for
versions in core libraries.
'rocket_dyn_templates' replaces the contrib 'templates' features. While
largely a 1-to-1 copy, it makes the following changes:
the 'tera_templates' feature is now 'tera'
the 'handlebars_templates' feature is now 'handlebars'
fails to compile if neither 'tera' nor 'handlebars' is enabled
'rocket_sync_db_pools' replaces the contrib 'database' features. It
makes no changes to the replaced features except that the database
attribute is properly documented at the crate root.
In short, you will need to migrate your code away from rocket_contrib. Better guidelines may become available once v0.5 is definitely released, but until then, you may look for the features once available in rocket_contrib in the core documentation and respective Cargo feature list.

Pub package update management

Am I the only one who thinks that the pub package manager is a good base but lack some basic stuff (compare to Nugget on VS)?
Installing a new package is very easy : just add a line of code in the pubspec.yaml file.
But how do you manage updates? If you do not specify a version you've got almost automatic update, and if you do, you just don't have any update at all. Is there any way you can have notification when a package update is available, and chose one by one if you update it or not, based on the changelog?
Thanks!
Dart packages use semantic versioning.
TL;DR about semver:
major = breaking changes
minor = new features
patch = bug fixes.
Combined with version constraints you can have custom behavior.
For example, the following will accept only bug fixes for the 1.0.0 version of a package named some_package:
dependencies:
some_package: ^1.0.0
Similarly, this constraint accepts all newer releases besides breaking changes:
dependencies:
some_package: '>=1.2.3 <2.0.0'
See https://dart.dev/tools/pub/dependencies#version-constraints for more information.
That plugin is exactly what I was looking for!
https://plugins.jetbrains.com/plugin/12400-flutter-pub-version-checker
Combined with the sementic versionning explained by #Remi, it's perfect 👌

How to tell Cargo to use a git repository as source for an indirect dependency instead of crates.io?

A few days ago, cross-compiling to JavaScript via Emscripten has finally hit nightly. I wanted to compile a project using glium in that manner. However, there are still many Emscripten-related bugs in many crates. While maintainers usually fix those bugs quickly, they don't necessarily release those bug fixes to crates.io immediately.
In my case, glium depends on glutin. glutin had a bug which is fixed now, but only in the git repository, not on crates.io. Note: glutin is not a direct dependency of my project; only an indirect one through glium!
How do I tell Cargo to use the glutin repository as source for glutin instead of crates.io?
You can use the [replace] section in your project's Cargo.toml. You can find the documentation about that feature here in the Cargo documentation.
In your case, glium depends on glutin 0.6.1. The version 0.6.1 on crates.io still contains the bug. So just add this to your Cargo.toml:
[replace]
"glutin:0.6.1" = { git = 'https://github.com/tomaka/glutin' }
Note however,
[...] that the replaced crate must not only have the same name but also the same version.
But even in the case of a version-mismatch (the repository already contains a newer version), you could still be in luck if the crate's maintainer creates git tags for every version (many in the Rust community do). In that case you can just specify the tag:
[replace]
"glutin:0.6.1" = {
git = 'https://github.com/tomaka/glutin'
tag = 'v0.6.1'
}
Sadly, this won't work with glutin, because the maintainer did not create tags for every version. In that case you can simply find the last commit before the version was bumped and specify it with rev = 'b4a3d0...' or specify a specific branch with the branch = '...' key.

Resources