rust-cli / team

CLI working group
https://rust-cli.github.io/book
MIT License
298 stars 34 forks source link

Bash-friendly way to query cargo metadata (package version) #33

Open kornelski opened 6 years ago

kornelski commented 6 years ago

Related to #8

I package my apps with a bash script sort of like this:

cargo build --release
tar cjf app-$VERSION.tar.gz target/release/app
rsync etc.

The problematic part is $VERSION. I would like to read the version from Cargo.toml, but can't without string manipulation in bash (yuck!)

I'd be great if there was something like cargo metadata --query package.version that outputs nothing by the given Cargo.toml key.

epage commented 6 years ago

Is your need as much about querying the version or just streamlining creating tarballs of your application?

I'm working on https://github.com/crate-ci/meta/issues/1 which should help with tarballing. My goal is to have a prototype of cargo-tarball in the next two weeks.

ashutoshrishi commented 5 years ago

Not too advanced at using awk but this works for me:

awk -F ' = ' '$1 ~ /version/ { gsub(/[\"]/, "", $2); printf("%s",$2) }' Cargo.toml

I use it in a Makefile as:

PKG_VERSION = $(shell awk -F ' = ' '$$1 ~ /version/ { gsub(/[\"]/, "", $$2); printf("%s",$$2) }' Cargo.toml)
ltfschoen commented 1 year ago

Not too advanced at using awk but this works for me:

awk -F ' = ' '$1 ~ /version/ { gsub(/[\"]/, "", $2); printf("%s",$2) }' Cargo.toml

I use it in a Makefile as:

PKG_VERSION = $(shell awk -F ' = ' '$$1 ~ /version/ { gsub(/[\"]/, "", $$2); printf("%s ",$$2) }' Cargo.toml)

i had to use a double backslash and remove the space around the equal sign as below to get it to not error

PKG_VERSION=$(awk -F ' = ' '$$1 ~ /version/ { gsub(/[\\"]/, "", $$2); printf("%s",$$2) }' Cargo.toml)
echo $PKG_VERSION

otherwise i'd get error awk: cmd. line:1: warning: regexp escape sequence\"' is not a known regexp operator

but i was using this Cargo.toml file, where there's also a a [dependencies] section that may be using the following syntax kobold = { version = 0.5.0, ... }, so it actually stored more than i wanted as shown below:

version = 0.1.0 kobold = { version = 0.5.0, git = https://github.com/maciejhirsz/kobold.git, rev = 53eacf69d2ea3f25a47e58a3ccd11dcaf73d48bf } 

but when i only want the version = 0.1.0 part

and some Cargo.toml files choose to use the following format to list their [dependencies] rather than kobold = { version = "0.5.0", ... }:

[dependencies.kobold]
version = "0.5.0"
...

and the order that [package] and [dependences] appear in the Cargo.toml file might vary

ltfschoen commented 1 year ago
tar cjf app-$VERSION.tar.gz 

i wrote this script https://github.com/ltfschoen/kobold-test/blob/master/set_cargo_package_version.sh that finds the line number of [package] where ever the user has put it in the Cargo.toml file (i.e. incase its after [dependencies] since that might also have instances of version), then i just find the line number of the first version that occurs after the line number of [package], and then i remove the version, =, and whitespace with xargs, leaving you with just the version number, and then i set it as an environment variable of the calling shell if you run the script so you can use the value

cargo build --release
# run this script to set the environment variable CARGO_PACKAGE_VERSION of the calling shell with the value of the [package] version (assuming its not a workspace Cargo.toml file that does not have it.
. ./set_cargo_package_version.sh
tar cjf app-$CARGO_PACKAGE_VERSION.tar.gz target/release/app
rsync etc.

if you've got a simple Cargo.toml file that doesn't have other version's in the first column, then i think you can just do:

adt-get install jq
jq '.name' $PWD/Cargo.toml | sed 's/\"//g'