1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*!
Common types used by the `build-info` and `build-info-build` crates.

User code should not depend on this crate directly, but rather depend on `build-info` (as a `[dependency]`) and `build-info-build` (as a `[build-dependency]`).
The types provided herein are reexported by `build-info` and should be used that way.
For example, `build_info_common::BuildInfo` should be used as `build_info::BuildInfo` instead.
*/

#![forbid(unsafe_code)]

use derive_more::Display;

pub use chrono;
use chrono::{DateTime, NaiveDate, Utc};

pub use semver;
use semver::Version;

#[cfg(feature = "enable-serde")]
use serde::{Deserialize, Serialize};

#[cfg(feature = "enable-serde")]
mod versioned_string;
#[cfg(feature = "enable-serde")]
pub use versioned_string::VersionedString;

pub mod display;

/// Gets the version of the `build-info-common` crate (this crate)
pub fn crate_version() -> Version {
	Version::parse(env!("CARGO_PKG_VERSION")).unwrap()
}

/// Information about the current build
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct BuildInfo {
	/// Updated whenever `build.rs` is rerun.
	pub timestamp: DateTime<Utc>,

	/// Cargo currently supports two different build types: `"Release"` and `"Debug"`
	pub profile: String,

	/// The optimization level can be set in `Cargo.toml` for each profile
	pub optimization_level: u8,

	/// Information about the current crate
	pub crate_info: CrateInfo,

	/// Information about the compiler used.
	pub compiler: CompilerInfo,

	/// `Some` if the project is inside a check-out of a supported version control system.
	pub version_control: Option<VersionControl>,
}

/// Information about the current crate (i.e., the crate for which build information has been generated)
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct CrateInfo {
	/// The name, as defined in `Cargo.toml`.
	pub name: String,

	/// The version, as defined in `Cargo.toml`.
	pub version: Version,

	/// The authors, as defined in `Cargo.toml`.
	pub authors: Vec<String>,

	/// The license string, as defined in `Cargo.toml`.
	pub license: Option<String>,

	/// The features of this crate that are currently enabled in this configuration.
	pub enabled_features: Vec<String>,

	/// All features that are available from this crate.
	pub available_features: Vec<String>,

	/// Dependencies of this crate.
	/// Will only be filled with data if `build-info-build` has the `dependencies` feature enabled.
	pub dependencies: Vec<CrateInfo>,
}

/// `rustc` version and configuration
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct CompilerInfo {
	/// Version of the current `rustc`
	pub version: Version,

	/// Commit hash from which `rustc` was built
	pub commit_id: Option<String>,

	/// Date on which `rustc` was built
	pub commit_date: Option<NaiveDate>,

	/// Channel which was configured for this version of `rustc`
	pub channel: CompilerChannel,

	/// Identifies the host on which `rustc` was running
	pub host_triple: String,

	/// Identifies the target architecture for which the crate is being compiled
	pub target_triple: String,
}

/// `rustc` distribution channel (some compiler features are only available on specific channels)
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
#[derive(Display, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum CompilerChannel {
	Dev,
	Nightly,
	Beta,
	Stable,
}

/// Support for different version control systems
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum VersionControl {
	Git(GitInfo),
}

impl VersionControl {
	pub fn git(&self) -> Option<&GitInfo> {
		match self {
			VersionControl::Git(git) => Some(git),
			// _ => None, // Pattern currently unreachable
		}
	}
}

/**
Information about a git repository

If a git repository is detected (and, thereby, this information included), the build script will be rerun whenever the
currently checked out commit changes.
*/
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct GitInfo {
	/// Full commit hash for the currently checked out commit
	pub commit_id: String,

	/// Short commit hash for the currently checked out commit
	///
	/// The length of this string depends on the effective value of the git configuration variable `core.abbrev`, and is
	/// extended to the minimum length required for the id to be unique (at the time it was computed).
	pub commit_short_id: String,

	/// Timestamp of the currently checked out commit
	pub commit_timestamp: DateTime<Utc>,

	/// `true` iff the repository had uncommitted changes when building the project.
	pub dirty: bool,

	/// Names the branch that is currently checked out, if any
	pub branch: Option<String>,

	/// All tags that point to the current commit (e.g., `["v0.0.10", "sample@v0.0.10"]`)
	pub tags: Vec<String>,
}