1010/// - https://stackoverflow.com/q/43753491/3484614
1111/// - https://crates.io/crates/vergen
1212
13- extern crate datetime;
1413use std:: env;
15- use std:: io;
14+ use std:: fs:: File ;
15+ use std:: io:: { self , Write } ;
16+ use std:: path:: PathBuf ;
1617
18+ use datetime:: { LocalDateTime , ISO } ;
1719
20+
21+ /// The build script entry point.
22+ fn main ( ) -> io:: Result < ( ) > {
23+ #![ allow( clippy:: write_with_newline) ]
24+
25+ let tagline = "exa - list files on the command-line" ;
26+ let url = "https://the.exa.website/" ;
27+
28+ let ver =
29+ if is_debug_build ( ) {
30+ format ! ( "{}\n v{} \\ 1;31m(pre-release debug build!)\\ 0m\n \\ 1;4;34m{}\\ 0m" , tagline, version_string( ) , url)
31+ }
32+ else if is_development_version ( ) {
33+ format ! ( "{}\n v{} [{}] built on {} \\ 1;31m(pre-release!)\\ 0m\n \\ 1;4;34m{}\\ 0m" , tagline, version_string( ) , git_hash( ) , build_date( ) , url)
34+ }
35+ else {
36+ format ! ( "{}\n v{}\n \\ 1;4;34m{}\\ 0m" , tagline, version_string( ) , url)
37+ } ;
38+
39+ // We need to create these files in the Cargo output directory.
40+ let out = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
41+
42+ // Bland version text
43+ let mut f = File :: create ( & out. join ( "version_string.txt" ) ) ?;
44+ writeln ! ( f, "{}" , strip_codes( & ver) ) ?;
45+
46+ Ok ( ( ) )
47+ }
48+
49+ /// Removes escape codes from a string.
50+ fn strip_codes ( input : & str ) -> String {
51+ input. replace ( "\\ 0m" , "" )
52+ . replace ( "\\ 1;31m" , "" )
53+ . replace ( "\\ 1;4;34m" , "" )
54+ }
55+
56+ /// Retrieve the project’s current Git hash, as a string.
1857fn git_hash ( ) -> String {
1958 use std:: process:: Command ;
2059
@@ -25,40 +64,59 @@ fn git_hash() -> String {
2564 . stdout ) . trim ( ) . to_string ( )
2665}
2766
28- fn main ( ) {
29- write_statics ( ) . unwrap ( ) ;
30- }
31-
67+ /// Whether we should show pre-release info in the version string.
68+ ///
69+ /// Both weekly releases and actual releases are --release releases,
70+ /// but actual releases will have a proper version number.
3271fn is_development_version ( ) -> bool {
33- // Both weekly releases and actual releases are --release releases,
34- // but actual releases will have a proper version number
3572 cargo_version ( ) . ends_with ( "-pre" ) || env:: var ( "PROFILE" ) . unwrap ( ) == "debug"
3673}
3774
75+ /// Whether we are building in debug mode.
76+ fn is_debug_build ( ) -> bool {
77+ env:: var ( "PROFILE" ) . unwrap ( ) == "debug"
78+ }
79+
80+ /// Retrieves the [package] version in Cargo.toml as a string.
3881fn cargo_version ( ) -> String {
3982 env:: var ( "CARGO_PKG_VERSION" ) . unwrap ( )
4083}
4184
42- fn build_date ( ) -> String {
43- use datetime:: { LocalDateTime , ISO } ;
85+ /// Returns the version and build parameters string.
86+ fn version_string ( ) -> String {
87+ let mut ver = cargo_version ( ) ;
4488
45- let now = LocalDateTime :: now ( ) ;
46- format ! ( "{}" , now. date( ) . iso( ) )
89+ let feats = nonstandard_features_string ( ) ;
90+ if ! feats. is_empty ( ) {
91+ ver. push_str ( & format ! ( " [{}]" , & feats) ) ;
92+ }
93+
94+ ver
95+ }
96+
97+ /// Finds whether a feature is enabled by examining the Cargo variable.
98+ fn feature_enabled ( name : & str ) -> bool {
99+ env:: var ( & format ! ( "CARGO_FEATURE_{}" , name) )
100+ . map ( |e| ! e. is_empty ( ) )
101+ . unwrap_or ( false )
47102}
48103
49- fn write_statics ( ) -> io:: Result < ( ) > {
50- use std:: fs:: File ;
51- use std:: io:: Write ;
52- use std:: path:: PathBuf ;
104+ /// A comma-separated list of non-standard feature choices.
105+ fn nonstandard_features_string ( ) -> String {
106+ let mut s = Vec :: new ( ) ;
53107
54- let ver = if is_development_version ( ) {
55- format ! ( "exa v{} ({} built on {})" , cargo_version ( ) , git_hash ( ) , build_date ( ) )
108+ if feature_enabled ( "GIT" ) {
109+ s . push ( "+git" ) ;
56110 }
57111 else {
58- format ! ( "exa v{}" , cargo_version ( ) )
59- } ;
112+ s . push ( "-git" ) ;
113+ }
60114
61- let out = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
62- let mut f = File :: create ( & out. join ( "version_string.txt" ) ) ?;
63- write ! ( f, "{:?}" , ver)
115+ s. join ( ", " )
116+ }
117+
118+ /// Formats the current date as an ISO 8601 string.
119+ fn build_date ( ) -> String {
120+ let now = LocalDateTime :: now ( ) ;
121+ format ! ( "{}" , now. date( ) . iso( ) )
64122}
0 commit comments