rsrepo
is my personal command-line program for managing my Rust project
repositories, including generating packaging boilerplate and performing
releases. While it may in theory be suitable for general use, I make no
guarantees, nor do I intend to release it for general consumption. Use at your
own risk.
rsrepo [<global options>] <subcommand> ...
All rsrepo
subcommands other than rsrepo new
must be run inside a Cargo
package directory & Git repository (after processing the --chdir
option, if
given). Cargo workspaces are currently not supported.
Certain commands automatically edit packages' README.md
and/or CHANGELOG.md
files; these files are expected to adhere to specific formats, documented in
doc/readme-format.md
and doc/changelog-format.md
,
respectively.
-
-c <file>
,--config <file>
— Read configuration from the given file; by default, configuration is read from~/.config/rsrepo.toml
. See "Configuration File" below for more information. -
-C <dir>
,--chdir <dir>
— Change to the given directory before taking any further actions -
-l <level>
,--log-level <level>
— Set the logging level to the given value. The possible options are "OFF
", "ERROR
", "WARN
", "INFO
", "DEBUG
", and "TRACE
", all case-insensitive. The default value is "INFO
".
Various rsrepo
subcommands make use of the following external programs or
configurations:
-
Git — required by the
new
,mkgithub
, andrelease
subcommands -
pre-commit — optional dependency of the
new
subcommand; a warning will be emitted if not installed -
Cargo — required by the
release
subcommand- If using
rsrepo release
to publish a package, a Cargo registry API token must have been saved with Cargo.
- If using
-
A GitHub access token must either be set via the
GH_TOKEN
orGITHUB_TOKEN
environment variable or else have been saved withgh
in order for various commands to perform GitHub REST API requests -
The
release
subcommand creates a signed Git tag, and sogpg
(or another program specified via Git'sgpg.program
config variable) must be installed and usable
The configuration file (located at ~/.config/rsrepo.toml
by default) is a
TOML file with the following fields:
-
author
(required) — The author name to use whenrsrepo new
generatesCargo.toml
andLICENSE
files -
author-email
(required) — The author e-mail to use whenrsrepo new
generates aCargo.toml
file; this may contain a placeholder of the form{package}
, which will be replaced with the name of the package being initialized. -
github-user
— The GitHub username to use whenrsrepo new
generatesCargo.toml
andREADME.md
files and whenrsrepo mkgithub
creates a repository. If this is not set, the value is fetched via the GitHub API when needed. -
codecov-token
— Default value that thersrepo mkgithub
command should use for theCODECOV_TOKEN
secret when no value is specified on the command line or in the environment
rsrepo [<global options>] new [<options>] <directory>
Create a new Git repository at the given directory path and populate it with basic files for a new Cargo project.
The following files are created in the directory:
.github/renovate.json5
.github/workflows/test.yml
.gitignore
.pre-commit-config.yaml
(pre-commit install
is also run ifpre-commit
is installed)Cargo.toml
LICENSE
README.md
src/lib.rs
(if creating a library crate)src/main.rs
(if create a binary crate)
-
--bin
— Create a binary crate -
--copyright-year <string>
— Specify the copyright year(s) to put in theLICENSE
file; defaults to the current year -
-d <text>
,--description <text>
— Specify a description for the new package; if not specified, thedescription
field inCargo.toml
will be commented out. -
--lib
— Create a library crate. This is the default if neither--bin
nor--lib
is given. -
--msrv VERSION
— Specify the minimum supported Rust version to declare for the new package; defaults to the latest stable rustc version with the patch component removed. The version must be given as either two or three dot-separated integers. -
--name <name>
— Specify the package name to declare in theCargo.toml
file; defaults to the basename of the directory -
--repo-name <name>
— Specify the GitHub repository name (sans owner) to use in URLs in generated files; defaults to the package name
rsrepo [<global options>] mkgithub [<options>] [<name>]
Create a new GitHub repository for the project, set the local repository's
origin
remote to point to the GitHub repository, and push all branches & tags
to the remote. In addition, if the package.repository
field in the package's
Cargo.toml
is unset, it is set to the web URL of the GitHub repository; if
instead the field differs from the web URL, a warning is emitted.
The GitHub repository will be created under the user account for the GitHub access token in use. Creating a repository under an organization is currently not supported.
The package description (if any) is used as the repository description. The
package's keywords are used as the repository's topics, along with the "rust
"
topic; in addition, if the package's README.md
file has a "WIP"
repostatus.org badge, the "work-in-progress
"
topic is added. The custom labels used by the .github/renovate.json5
file
generated by rsrepo new
are created in the repository, a CODECOV_TOKEN
secret is set for GitHub Actions, automerging of PRs is enabled, and the tests
listed in the .github/workflows/test.yml
file generated by rsrepo new
are
registered as required checks for merging PRs.
The bare name of the repository to create (e.g. hello-world
, not
octocat/hello-world
or https://github.com/octocat/hello-world
) can
optionally be specified as an argument on the command line; if not given, the
repository name is determined by parsing the package.repository
field in the
Cargo.toml
file, falling back to the package name if there is no such field.
When parsing the package.repository
field, it is an error if the repository
owner given in the URL differs from the github-user
configuration value.
-
--codecov-token <secret>
— Specify the value to use for theCODECOV_TOKEN
secret. This option can be set via theCODECOV_TOKEN
environment variable, and a default value can be set via the configuration file.If no value is not set and
--no-codecov-token
is not given, a warning is emitted. -
--no-codecov-token
— Do not set theCODECOV_TOKEN
secret -
-P
,--private
— Make the new repository private
rsrepo [<global-options>] release [<options>] [<version>]
Prepare & publish a new release for a package.
The version of the release can be either specified explicitly on the command
line or (if one of --major
, --minor
, or --patch
is given) calculated by
bumping the version extracted from the most recently-created Git tag; in the
latter case, the metadata identifier (if any) is discarded from the version,
and it is an error if the bumped version is a prerelease. If no version or
bump option is given on the command line, the version declared in the
Cargo.toml
file is used after stripping any prerelease & metadata components;
it is an error if this version is less than or equal to the version of the
latest Git tag. Except when an explicit version argument is given, it is an
error for the latest Git tag to not be a Cargo semver version with optional
leading v
.
This command performs the following operations in order:
-
The version field in
Cargo.toml
is set to the release version. If the package contains a binary crate, the version inCargo.lock
is set as well. -
If
CHANGELOG.md
exists, the header for the topmost section is edited to contain the release version and the current date. It is an error if the topmost section header already contains a date. -
If the release version is not a prerelease and the
README.md
has a repostatus.org "WIP" badge, the badge is changed to "Active." -
If
publish
inCargo.toml
is notfalse
, links tocrates.io
and (if the package contains a library crate)docs.rs
are added toREADME.md
's header links. -
The copyright years in the first copyright line in
LICENSE
are updated to include all years in which commits were made to the repository, including the current year. A line is treated as a copyright line if it is of the form "Copyright YEARS AUTHOR" or "Copyright (c) YEARS AUTHOR" (optional leading whitespace allowed for both forms), where the "YEARS" component consists of year numbers, dashes, commas, and/or spaces. It is an error ifLICENSE
does not contain a copyright line. -
All changes made to tracked files in the repository are committed; the text of the most recent
CHANGELOG.md
section is included in the commit message template.- The release can be cancelled at this point by either leaving the commit message unchanged or by deleting the entire commit message.
-
The commit is tagged (as
v{version}
) and signed. -
If
publish
inCargo.toml
is notfalse
:-
Any untracked files in the repository are moved to
$GIT_WORK_TREE.stash/
, where$GIT_WORK_TREE
is the path to the toplevel of the Git repository's working tree. (Note that ".stash" is here an extension appended to the basename of the directory, not a subdirectory of$GIT_WORK_TREE
.) -
cargo publish
is run. -
Any files in
$GIT_WORK_TREE.stash/
are moved back to the Git repository, and the stash directory is deleted.
-
-
The commit & tag are pushed; it is assumed that they are pushed to GitHub.
-
If the repository does not contain a
.github/workflows/release.yml
workflow, then a GitHub release pointing to the new tag is created in the project's GitHub repository. The name of the release is the first line of the tagged commit's commit message, and its body is the rest of the commit message. If the new version is a prerelease, the GitHub release is marked as a prerelease as well.- The project's GitHub repository is identified by parsing the URL for the
local Git repository's
origin
remote.
- The project's GitHub repository is identified by parsing the URL for the
local Git repository's
-
If the repostatus.org badge in
README.md
was set to "Active" earlier, then any "work-in-progress
" topic is removed from the GitHub repository's topics, and ifpublish
inCargo.toml
is additionally notfalse
, the "available-on-crates-io
" topic is added. -
Development on the next version is started:
-
The version field in
Cargo.toml
(andCargo.lock
, if the package contains a binary crate) is set to the next minor version after the just-released version, plus a "-dev" prerelease segment. -
If a
CHANGELOG.md
file does not exist, one is created with a section for the release that was just made (with text set to "Initial release"). Either way, an empty section for the next minor version is added to the top of the changelog. In addition, a link toCHANGELOG.md
on GitHub is added toREADME.md
's header links if not already present.
-
-
--major
— Set the release's version to the next major version after the most recent Git tag -
--minor
— Set the release's version to the next minor version after the most recent Git tag -
--patch
— Set the release's version to the next micro version after the most recent Git tag
rsrepo [<global-options>] set-msrv <version>
Set the package's MSRV as declared in Cargo.toml
and README.md
's badges to
the given rustc version. A basic attempt at updating CHANGELOG.md
to mention
the change is also performed.