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
/*!
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.
*/

pub use chrono::{DateTime, TimeZone, Utc};
use derive_more::Display;
pub use semver::{Identifier, Version};
#[cfg(feature = "enable-serde")]
use serde::{Deserialize, Serialize};

pub fn crate_version() -> Version {
	Version::parse(env!("CARGO_PKG_VERSION")).unwrap()
}

/// Used internally to ensure that `build-info` and `build-info-build` use the same version of `build-info-common`.
#[cfg(feature = "enable-serde")]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct VersionedString {
	pub version: Version,
	pub string: String,
}

#[cfg(feature = "enable-serde")]
impl VersionedString {
	pub fn build_info_common_versioned(string: String) -> Self {
		Self {
			version: crate_version(),
			string,
		}
	}

	pub fn check(&self) -> bool {
		self.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>,

	/// 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>,
}

/// Used internally by the function that is generated by `build_info::build_info!`
#[doc(hidden)]
pub fn nanos_to_utc(nanos: i64) -> DateTime<Utc> {
	Utc.timestamp_nanos(nanos)
}

/// 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>,
}

/// `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<String>,

	/// 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, 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),
}

/**
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 {
	/// Currently checked out git commit hash
	pub commit_id: String,

	/// `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., `["refs/tags/v0.0.10", "refs/tags/sample@v0.0.10"]`)
	pub tags: Vec<String>,
}