diff options
author | Arun Raghavan <arun@asymptotic.io> | 2020-04-05 17:38:52 +0300 |
---|---|---|
committer | Arun Raghavan <arun@arunraghavan.net> | 2020-04-05 22:10:47 +0300 |
commit | dc3c8fd0494056ae5e5f87aa716b4c3866af6591 (patch) | |
tree | 3226cac3439fd29b7b02f6456f3162d6a3d1e00a /version-helper/src | |
parent | 205b6040fbb918c0fa736874b09f8e3f3f261e44 (diff) |
Drop gst-plugin- prefix in plugin directory name
Diffstat (limited to 'version-helper/src')
-rw-r--r-- | version-helper/src/git.rs | 41 | ||||
-rw-r--r-- | version-helper/src/lib.rs | 91 |
2 files changed, 132 insertions, 0 deletions
diff --git a/version-helper/src/git.rs b/version-helper/src/git.rs new file mode 100644 index 000000000..2bd188dc5 --- /dev/null +++ b/version-helper/src/git.rs @@ -0,0 +1,41 @@ +use std::path::Path; +use std::process::Command; + +pub fn repo_hash<P: AsRef<Path>>(path: P) -> Option<(String, String)> { + let git_path = path.as_ref().to_str(); + let mut args = match git_path { + Some(path) => vec!["-C", path], + None => vec![], + }; + args.extend(&["log", "-1", "--format=%h_%cd", "--date=short"]); + let output = Command::new("git").args(&args).output().ok()?; + if !output.status.success() { + return None; + } + let output = String::from_utf8(output.stdout).ok()?; + let output = output.trim_end_matches('\n'); + let mut s = output.split('_'); + let hash = s.next()?; + let date = s.next()?; + + let hash = if dirty(path) { + format!("{}+", hash) + } else { + hash.into() + }; + + Some((hash, date.into())) +} + +fn dirty<P: AsRef<Path>>(path: P) -> bool { + let path = path.as_ref().to_str(); + let mut args = match path { + Some(path) => vec!["-C", path], + None => vec![], + }; + args.extend(&["ls-files", "-m"]); + match Command::new("git").args(&args).output() { + Ok(modified_files) => !modified_files.stdout.is_empty(), + Err(_) => false, + } +} diff --git a/version-helper/src/lib.rs b/version-helper/src/lib.rs new file mode 100644 index 000000000..fc85fb700 --- /dev/null +++ b/version-helper/src/lib.rs @@ -0,0 +1,91 @@ +// Copyright (C) 2019 Sajeer Ahamed <ahamedsajeer.15.15@cse.mrt.ac.lk> +// Copyright (C) 2019 Sebastian Dröge <sebastian@centricular.com> +// +// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT> + +//! Extracts release for [GStreamer](https://gstreamer.freedesktop.org) plugin metadata +//! +//! See [`get_info`](fn.get_info.html) for details. +//! +//! This function is supposed to be used as follows in the `build.rs` of a crate that implements a +//! plugin: +//! +//! ```rust,ignore +//! extern crate gst_plugin_version_helper; +//! +//! gst_plugin_version_helper::get_info(); +//! ``` +//! +//! Inside `lib.rs` of the plugin, the information provided by `get_info` are usable as follows: +//! +//! ```rust,ignore +//! gst_plugin_define!( +//! the_plugin_name, +//! env!("CARGO_PKG_DESCRIPTION"), +//! plugin_init, +//! concat!(env!("CARGO_PKG_VERSION"), "-", env!("COMMIT_ID")), +//! "The Plugin's License", +//! env!("CARGO_PKG_NAME"), +//! env!("CARGO_PKG_NAME"), +//! env!("CARGO_PKG_REPOSITORY"), +//! env!("BUILD_REL_DATE") +//! ); +//! ``` + +mod git; + +use chrono::TimeZone; +use std::convert::TryInto; +use std::time::SystemTime; +use std::{env, fs, path}; + +/// Extracts release for GStreamer plugin metadata +/// +/// Release information is first tried to be extracted from a git repository at the same +/// place as the `Cargo.toml`, or one directory up to allow for Cargo workspaces. If no +/// git repository is found, we assume this is a release. +/// +/// - If extracted from a git repository, sets the `COMMIT_ID` environment variable to the short +/// commit id of the latest commit and the `BUILD_REL_DATE` environment variable to the date of the +/// commit. +/// +/// - If not, `COMMIT_ID` will be set to the string `RELEASE` and the +/// `BUILD_REL_DATE` variable will be set to the mtime of `Cargo.toml`. +/// +/// - If neither is possible, `COMMIT_ID` is set to the string `UNKNOWN` and `BUILD_REL_DATE` to the +/// current date. +/// +pub fn get_info() { + let crate_dir = + path::PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set")); + let mut repo_dir = crate_dir.clone(); + + // First check for a git repository in the manifest directory and if there + // is none try one directory up in case we're in a Cargo workspace + let git_info = git::repo_hash(&repo_dir).or_else(move || { + repo_dir.pop(); + git::repo_hash(&repo_dir) + }); + + // If there is a git repository, extract the version information from there. + // Otherwise assume this is a release and use Cargo.toml mtime as date. + let (commit_id, commit_date) = git_info.unwrap_or_else(|| { + let date = cargo_mtime_date(crate_dir).expect("Failed to get Cargo.toml mtime"); + ("RELEASE".into(), date) + }); + + println!("cargo:rustc-env=COMMIT_ID={}", commit_id); + println!("cargo:rustc-env=BUILD_REL_DATE={}", commit_date); +} + +fn cargo_mtime_date(crate_dir: path::PathBuf) -> Option<String> { + let mut cargo_toml = crate_dir; + cargo_toml.push("Cargo.toml"); + + let metadata = fs::metadata(&cargo_toml).ok()?; + let mtime = metadata.modified().ok()?; + let unix_time = mtime.duration_since(SystemTime::UNIX_EPOCH).ok()?; + let dt = chrono::Utc.timestamp(unix_time.as_secs().try_into().ok()?, 0); + + Some(dt.format("%Y-%m-%d").to_string()) +} |