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

feat(zk_toolbox): Verbose version message #2884

Merged
merged 2 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions zk_toolbox/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions zk_toolbox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"crates/types",
"crates/zk_inception",
"crates/zk_supervisor",
"crates/git_version_macro",
]
resolver = "2"

Expand All @@ -25,6 +26,7 @@ keywords = ["zk", "cryptography", "blockchain", "ZKStack", "ZKsync"]
common = { path = "crates/common" }
config = { path = "crates/config" }
types = { path = "crates/types" }
git_version_macro = { path = "crates/git_version_macro" }

# ZkSync deps
zksync_config = { path = "../core/lib/config" }
Expand All @@ -37,6 +39,7 @@ zksync_protobuf = "=0.1.1"
# External dependencies
anyhow = "1.0.82"
clap = { version = "4.4", features = ["derive", "wrap_help", "string"] }
chrono = "0.4"
slugify-rs = "0.0.3"
cliclack = "0.2.5"
console = "0.15.8"
Expand Down
1 change: 1 addition & 0 deletions zk_toolbox/crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ url.workspace = true
xshell.workspace = true
thiserror.workspace = true
strum.workspace = true
git_version_macro.workspace = true
1 change: 1 addition & 0 deletions zk_toolbox/crates/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub mod files;
pub mod forge;
pub mod git;
pub mod server;
pub mod version;
pub mod wallets;

pub use prerequisites::{
Expand Down
24 changes: 24 additions & 0 deletions zk_toolbox/crates/common/src/version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const GIT_VERSION: &str = git_version_macro::build_git_revision!();
const GIT_BRANCH: &str = git_version_macro::build_git_branch!();
const GIT_SUBMODULES: &[(&str, &str)] = git_version_macro::build_git_submodules!();
popzxc marked this conversation as resolved.
Show resolved Hide resolved
const BUILD_TIMESTAMP: &str = git_version_macro::build_timestamp!();

/// Returns a multi-line version message that includes:
/// - provided crate version
/// - git revision
/// - git branch
/// - git submodules
/// - build timestamp
pub fn version_message(crate_version: &str) -> String {
let mut version = format!("v{}-{}\n", crate_version, GIT_VERSION);
version.push_str(&format!("Branch: {}\n", GIT_BRANCH));
#[allow(clippy::const_is_empty)] // Proc-macro generated.
if !GIT_SUBMODULES.is_empty() {
version.push_str("Submodules:\n");
for (name, rev) in GIT_SUBMODULES {
version.push_str(&format!(" - {}: {}\n", name, rev));
}
}
version.push_str(&format!("Build timestamp: {}\n", BUILD_TIMESTAMP));
version
}
17 changes: 17 additions & 0 deletions zk_toolbox/crates/git_version_macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "git_version_macro"
edition = "2021"
description = "Procedural macro to generate metainformation about build in compile time"
version.workspace = true
homepage.workspace = true
license.workspace = true
authors.workspace = true
exclude.workspace = true
repository.workspace = true
keywords.workspace = true

[lib]
proc-macro = true

[dependencies]
chrono.workspace = true
81 changes: 81 additions & 0 deletions zk_toolbox/crates/git_version_macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
extern crate proc_macro;
use std::{process::Command, str::FromStr};

use proc_macro::TokenStream;

/// Outputs the current date and time as a string literal.
/// Can be used to include the build timestamp in the binary.
#[proc_macro]
pub fn build_timestamp(_item: TokenStream) -> TokenStream {
let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
encode_as_str(&now)
}

/// Outputs the current git branch as a string literal.
#[proc_macro]
pub fn build_git_branch(_item: TokenStream) -> TokenStream {
let out = run_cmd("git", &["rev-parse", "--abbrev-ref", "HEAD"]);
encode_as_str(&out)
}

/// Outputs the current git commit hash as a string literal.
#[proc_macro]
pub fn build_git_revision(_item: TokenStream) -> TokenStream {
let out = run_cmd("git", &["rev-parse", "--short", "HEAD"]);
encode_as_str(&out)
}

/// Creates a slice of `&[(&str, &str)]` tuples that correspond to
/// the submodule name -> revision.
/// Results in an empty list if there are no submodules or if
/// the command fails.
#[proc_macro]
pub fn build_git_submodules(_item: TokenStream) -> TokenStream {
let Some(out) = run_cmd_opt("git", &["submodule", "status"]) else {
return TokenStream::from_str("&[]").unwrap();
};
let submodules = out
.lines()
.filter_map(|line| {
let parts: Vec<&str> = line.split_whitespace().collect();
// Index 0 is commit hash, index 1 is the path to the folder, and there
// may be some metainformation after that.
if parts.len() >= 2 {
let folder_name = parts[1].split('/').last().unwrap_or(parts[1]);
Some((folder_name, parts[0]))
} else {
None
}
})
.collect::<Vec<_>>();
let submodules = submodules
.iter()
.map(|(name, rev)| format!("(\"{}\", \"{}\")", name, rev))
.collect::<Vec<_>>()
.join(", ");
TokenStream::from_str(format!("&[{}]", submodules).as_str())
.unwrap_or_else(|_| panic!("Unable to encode submodules: {}", submodules))
}

/// Tries to run the command, only returns `Some` if the command
/// succeeded and the output was valid utf8.
fn run_cmd(cmd: &str, args: &[&str]) -> String {
run_cmd_opt(cmd, args).unwrap_or("unknown".to_string())
}

fn run_cmd_opt(cmd: &str, args: &[&str]) -> Option<String> {
let output = Command::new(cmd).args(args).output().ok()?;
if output.status.success() {
String::from_utf8(output.stdout)
.ok()
.map(|s| s.trim().to_string())
} else {
None
}
}

/// Encodes string as a literal.
fn encode_as_str(s: &str) -> TokenStream {
TokenStream::from_str(format!("\"{}\"", s).as_str())
.unwrap_or_else(|_| panic!("Unable to encode string: {}", s))
}
11 changes: 9 additions & 2 deletions zk_toolbox/crates/zk_inception/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use common::{
config::{global_config, init_global_config, GlobalConfig},
error::log_error,
init_prompt_theme, logger,
version::version_message,
};
use config::EcosystemConfig;
use xshell::Shell;
Expand All @@ -26,7 +27,10 @@ mod messages;
mod utils;

#[derive(Parser, Debug)]
#[command(version, about)]
#[command(
version = version_message(env!("CARGO_PKG_VERSION")),
about
)]
struct Inception {
#[command(subcommand)]
command: InceptionSubcommands,
Expand Down Expand Up @@ -86,13 +90,16 @@ struct InceptionGlobalArgs {
async fn main() -> anyhow::Result<()> {
human_panic::setup_panic!();

// We must parse arguments before printing the intro, because some autogenerated
// Clap commands (like `--version` would look odd otherwise).
EmilLuta marked this conversation as resolved.
Show resolved Hide resolved
let inception_args = Inception::parse();

init_prompt_theme();

logger::new_empty_line();
logger::intro();

let shell = Shell::new().unwrap();
let inception_args = Inception::parse();

init_global_config_inner(&shell, &inception_args.global)?;

Expand Down
12 changes: 9 additions & 3 deletions zk_toolbox/crates/zk_supervisor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use common::{
config::{global_config, init_global_config, GlobalConfig},
error::log_error,
init_prompt_theme, logger,
version::version_message,
};
use config::EcosystemConfig;
use messages::{
Expand All @@ -25,7 +26,10 @@ mod defaults;
mod messages;

#[derive(Parser, Debug)]
#[command(version, about)]
#[command(
version = version_message(env!("CARGO_PKG_VERSION")),
about
)]
struct Supervisor {
#[command(subcommand)]
command: SupervisorSubcommands,
Expand Down Expand Up @@ -73,14 +77,16 @@ struct SupervisorGlobalArgs {
async fn main() -> anyhow::Result<()> {
human_panic::setup_panic!();

// We must parse arguments before printing the intro, because some autogenerated
// Clap commands (like `--version` would look odd otherwise).
let args = Supervisor::parse();

init_prompt_theme();

logger::new_empty_line();
logger::intro();

let shell = Shell::new().unwrap();
let args = Supervisor::parse();

init_global_config_inner(&shell, &args.global)?;

if !global_config().ignore_prerequisites {
Expand Down
Loading