-
Notifications
You must be signed in to change notification settings - Fork 98
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
refactor(build script): rewrite the main build script #2319
Changes from 6 commits
2fab6c0
2522712
25c8578
ffa03c7
5f4d0f6
aca6c66
9aaa9ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is re-written from scratch, I suggest you to review this by opening the file directly as the diff view will make it likely impossible to understand the logic. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,114 +1,47 @@ | ||
use chrono::DateTime; | ||
use gstuff::slurp; | ||
use chrono::Utc; | ||
use regex::Regex; | ||
use std::fs; | ||
use std::io::Write; | ||
use std::path::{Path, PathBuf}; | ||
use std::process::Command; | ||
use std::str::from_utf8; | ||
use std::{env, process::Command}; | ||
|
||
fn path2s(path: PathBuf) -> String { | ||
path.to_str() | ||
.unwrap_or_else(|| panic!("Non-stringy path {:?}", path)) | ||
.into() | ||
} | ||
|
||
/// AtomicDEX's root. | ||
fn root() -> PathBuf { | ||
let super_net = Path::new(env!("CARGO_MANIFEST_DIR")); | ||
let super_net = match super_net.canonicalize() { | ||
Ok(p) => p, | ||
Err(err) => panic!("Can't canonicalize {:?}: {}", super_net, err), | ||
}; | ||
// On Windows we're getting these "\\?\" paths from canonicalize but they aren't any good for CMake. | ||
if cfg!(windows) { | ||
let s = path2s(super_net); | ||
let stripped = match s.strip_prefix(r"\\?\") { | ||
Some(stripped) => stripped, | ||
None => &s, | ||
}; | ||
Path::new(stripped).into() | ||
} else { | ||
super_net | ||
} | ||
} | ||
|
||
/// This function ensures that we have the “MM_VERSION” and “MM_DATETIME” variables during the build. | ||
/// | ||
/// The build script will usually help us by putting the MarketMaker version into the “MM_VERSION” file | ||
/// and the corresponding ISO 8601 time into the “MM_DATETIME” file | ||
/// | ||
/// For the nightly builds the version contains the short commit hash. | ||
/// | ||
/// We're also trying to get the hash and the time from Git. | ||
/// | ||
/// Git information isn't always available during the build (for instance, when a build server is used, | ||
/// we might skip synchronizing the Git repository there), | ||
/// but if it is, then we're going to check if the “MM_DATETIME” and the Git data match. | ||
fn mm_version() -> String { | ||
// Reading version of `mm2_bin_lib` from cargo manifest | ||
let mut version = env!("CARGO_PKG_VERSION").to_owned(); | ||
|
||
let mm_version_p = root().join("../../MM_VERSION"); | ||
let v_file = String::from_utf8(slurp(&mm_version_p)).unwrap(); | ||
fn crate_version() -> &'static str { env!("CARGO_PKG_VERSION") } | ||
|
||
// if there is MM_VERSION file, that means CI wants to put a tag to version | ||
if !v_file.is_empty() { | ||
version = format!("{}_{}", version, v_file.trim()); | ||
fn version_tag() -> Result<String, String> { | ||
if let Ok(tag) = env::var("KDF_BUILD_TAG") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not important |
||
return Ok(tag); | ||
} | ||
// put commit tag to the version | ||
else { | ||
let mut command = Command::new("git"); | ||
command.arg("log").arg("--pretty=format:%h").arg("-n1"); | ||
if let Ok(go) = command.output() { | ||
if go.status.success() { | ||
let commit_hash = from_utf8(&go.stdout).unwrap().trim().to_string(); | ||
if !Regex::new(r"^\w+$").unwrap().is_match(&commit_hash) { | ||
panic!("{}", commit_hash) | ||
} | ||
|
||
version = format!("{version}_{commit_hash}"); | ||
} | ||
} | ||
let output = Command::new("git") | ||
.args(["log", "--pretty=format:%h", "-n1"]) | ||
.output() | ||
.map_err(|e| format!("Failed to run git command: {e}\nSet `KDF_BUILD_TAG` manually instead.",))?; | ||
|
||
let commit_hash = String::from_utf8(output.stdout) | ||
.map_err(|e| format!("Invalid UTF-8 sequence: {e}"))? | ||
.trim() | ||
.to_string(); | ||
|
||
if !Regex::new(r"^\w+$") | ||
.expect("Failed to compile regex") | ||
.is_match(&commit_hash) | ||
{ | ||
return Err(format!("Invalid tag: {commit_hash}")); | ||
} | ||
|
||
println!("cargo:rustc-env=MM_VERSION={}", version); | ||
|
||
let mut dt_git = None; | ||
let mut command = Command::new("git"); | ||
command.arg("log").arg("--pretty=format:%cI").arg("-n1"); // ISO 8601 | ||
if let Ok(go) = command.output() { | ||
if go.status.success() { | ||
let got = from_utf8(&go.stdout).unwrap().trim(); | ||
let _dt_check = DateTime::parse_from_rfc3339(got).unwrap(); | ||
dt_git = Some(got.to_string()); | ||
} | ||
} | ||
Ok(commit_hash) | ||
} | ||
|
||
let mm_datetime_p = root().join("../../MM_DATETIME"); | ||
let dt_file = String::from_utf8(slurp(&mm_datetime_p)).unwrap(); | ||
let mut dt_file = dt_file.trim().to_string(); | ||
if let Some(ref dt_git) = dt_git { | ||
if dt_git[..] != dt_file[..] { | ||
// Create or update the “MM_DATETIME” file in order to appease the Cargo dependency management. | ||
let mut mm_datetime_f = fs::File::create(&mm_datetime_p).unwrap(); | ||
mm_datetime_f.write_all(dt_git.as_bytes()).unwrap(); | ||
dt_file = dt_git.to_string(); | ||
} | ||
} | ||
fn version() -> Result<String, String> { version_tag().map(|tag| format!("{}_{}", crate_version(), tag)) } | ||
|
||
println!("cargo:rustc-env=MM_DATETIME={}", dt_file); | ||
fn build_datetime() -> String { Utc::now().to_rfc3339() } | ||
|
||
version | ||
fn set_build_variables() -> Result<(), String> { | ||
println!("cargo:rustc-env=KDF_VERSION={}", version()?); | ||
println!("cargo:rustc-env=KDF_DATETIME={}", build_datetime()); | ||
Ok(()) | ||
} | ||
|
||
fn main() { | ||
println!("cargo:rerun-if-env-changed=MANUAL_MM_VERSION"); | ||
println!("cargo:rerun-if-changed=../../MM_VERSION"); | ||
println!("cargo:rerun-if-changed=../../MM_DATETIME"); | ||
if std::env::var("MANUAL_MM_VERSION").is_err() { | ||
// This allows build script to run even if no source code files change as rerun-if-changed checks for a file that doesn't exist | ||
println!("cargo:rerun-if-changed=NON_EXISTING_FILE"); | ||
} | ||
mm_version(); | ||
println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION"); | ||
println!("cargo:rerun-if-env-changed=KDF_BUILD_TAG"); | ||
|
||
set_build_variables().expect("Failed to set build variables"); | ||
} | ||
shamardy marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to revise our docs... This is extremely outdated.