2017-05-03 6 views
6

मैं गिट रिपॉजिटरी में एक जंग परियोजना होस्ट करता हूं और मैं इसे कुछ कमांड पर संस्करण प्रिंट करना चाहता हूं। मैं प्रोग्राम में संस्करण कैसे शामिल कर सकता हूं? मैंने सोचा था कि निर्माण स्क्रिप्ट वातावरण चर जो इस परियोजना का संयोजित करते समय इस्तेमाल किया जा सकता सेट कर सकते हैं कि, लेकिन यह काम नहीं करता है:गस्ट प्रतिबद्ध हैश को जंग प्रोग्राम में स्ट्रिंग के रूप में शामिल करें

build.rs:

use std::env; 

fn get_git_hash() -> Option<String> { 
    use std::process::Command; 

    let branch = Command::new("git") 
         .arg("rev-parse") 
         .arg("--abbrev-ref") 
         .arg("HEAD") 
         .output(); 
    if let Ok(branch_output) = branch { 
     let branch_string = String::from_utf8_lossy(&branch_output.stdout); 
     let commit = Command::new("git") 
          .arg("rev-parse") 
          .arg("--verify") 
          .arg("HEAD") 
          .output(); 
     if let Ok(commit_output) = commit { 
      let commit_string = String::from_utf8_lossy(&commit_output.stdout); 

      return Some(format!("{}, {}", 
         branch_string.lines().next().unwrap_or(""), 
         commit_string.lines().next().unwrap_or(""))) 
     } else { 
      panic!("Can not get git commit: {}", commit_output.unwrap_err()); 
     } 
    } else { 
     panic!("Can not get git branch: {}", branch.unwrap_err()); 
    } 
    None 
} 

fn main() { 
    if let Some(git) = get_git_hash() { 
     env::set_var("GIT_HASH", git); 
    } 
} 

src/main.rs:

pub const GIT_HASH: &'static str = env!("GIT_HASH"); 

fm main() { 
    println!("Git hash: {}", GIT_HASH); 
} 

त्रुटि संदेश:

error: environment variable `GIT_HASH` not defined 
    --> src/main.rs:10:25 
    | 
10 | pub const GIT_HASH: &'static str = env!("GIT_HASH"); 
    | 
             ^^^^^^^^^^^^^^^^ 

क्या संकलन समय पर ऐसे डेटा को पास करने का कोई तरीका है? यदि पर्यावरण चर के साथ नहीं है तो मैं बिल्ड स्क्रिप्ट और स्रोत कोड के बीच संवाद कैसे कर सकता हूं? मैं केवल कुछ फाइलों को डेटा लिखने के बारे में सोच सकता हूं, लेकिन मुझे लगता है कि यह इस मामले के लिए अधिक है।

उत्तर

6

मैं केवल कुछ फ़ाइल में डेटा लिखने के बारे में सोच सकता हूं, लेकिन मुझे लगता है कि यह इस मामले के लिए अधिक है।

कि दुर्भाग्यपूर्ण है, क्योंकि वह यह ऐसा करने का एकमात्र तरीका है। पर्यावरण चर काम नहीं कर सकते क्योंकि पर्यावरण में परिवर्तन अन्य, गैर-बाल प्रक्रियाओं में "रिसाव" नहीं कर सकता है।

सरल चीजों के लिए, आप सशर्त संकलन झंडे को परिभाषित करने के लिए कार्गो को निर्देश दे सकते हैं, लेकिन वे स्ट्रिंग [1] को संवाद करने के लिए पर्याप्त शक्तिशाली नहीं हैं।

बिल्ड स्क्रिप्ट से कोड उत्पन्न करने का विवरण code generation section of the Cargo documentation में विस्तृत है।


[1]: मेरा मतलब है, जब तक आप 160 config झंडे में हैश को तोड़ने का मन है और फिर उन्हें स्रोत में फिर से कोडांतरण संकलित किया जा रहा है, लेकिन यह भी अधिक overkill है।

+0

मुझे कॉन्फ़िगर ध्वज संस्करण का एक उदाहरण देखना अच्छा लगेगा। हालांकि एक गिट हैश को केवल 40 वर्ण होने की जरूरत है। – Shepmaster

+1

** अन्य, गैर-बाल प्रक्रियाओं में ** मुझे लगता है कि यहां महसूस करने की महत्वपूर्ण बात है। बिल्ड स्क्रिप्ट लाइब्रेरी के संकलन से पहले * * * * के आसपास * चलाया जाता है। – Shepmaster

+2

@ शेमपस्टर: एक ध्वज केवल आपको एक बिट देता है, हालांकि। आपके पास '# [cfg (bit_0)] const का कुछ है BIT_0: u8 = 1; # [सीएफजी (नहीं (bit_0))] const BIT_0: u8 = 0; '160 बार। मैं * पिछले कुछ में अतीत में कुछ भी कर सकता हूं ... \ ** सीटी * \ * –

6

पहले से ही मौजूदा क्रेट vergen है जो बिल्ड स्क्रिप्ट में गिट प्रतिबद्धता की गणना कर सकता है। @DK's answer वर्णित है, बिल्ड स्क्रिप्ट जंग 1.19 से पहले पर्यावरण चर को संशोधित नहीं कर सकती है, इसलिए vergen अभी भी OUT_DIR (i.e. vergen में परिणाम लिखकर काम करता है, अभी भी ओपी के प्रश्न को हल नहीं करेगा, लेकिन इसका उपयोग करना आसान होना चाहिए)।


उपयोग:

# Cargo.toml 
... 
[build-dependencies] 
vergen = "0.1" 
// build.rs 
extern crate vergen; 
use vergen::*; 
fn main() { 
    vergen(SHORT_SHA | COMMIT_DATE).unwrap(); 
} 
mod version { 
    include!(concat!(env!("OUT_DIR"), "/version.rs")); 
} 
fn main() { 
    println!("commit: {} {}", version::commit_date(), version::short_sha()); 
    // output something like: 
    //  commit: 2017-05-03 a29c7e5 
} 
8

के बाद से जंग 1.19 (कार्गो 0.20।0), https://github.com/rust-lang/cargo/pull/3929 करने के लिए धन्यवाद, अब आप एक संकलन समय वातावरण चर (env!(…)) rustc के लिए और परिभाषित कर सकते हैं के माध्यम से rustdoc:

println!("cargo:rustc-env=KEY=value"); 

तो ओपी के कार्यक्रम के रूप में लिखा जा सकता है:

// build.rs 
use std::process::Command; 
fn main() { 
    // note: add error checking yourself. 
    let output = Command::new("git").args(&["rev-parse", "HEAD"]).output().unwrap(); 
    let git_hash = String::from_utf8(output.stdout).unwrap(); 
    println!("cargo:rustc-env=GIT_HASH={}", git_hash); 
} 
// main.rs 
fn main() { 
    println!("{}", env!("GIT_HASH")); 
    // output something like: 
    // 7480b50f3c75eeed88323ec6a718d7baac76290d 
} 

ध्यान दें कि यदि आप अभी भी 1.18 या उससे नीचे का समर्थन करना चाहते हैं तो भी आप इसका उपयोग नहीं कर सकते हैं।

संबंधित मुद्दे