inspect_git/
inspect_git.rs1#[cfg(unix)]
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 use ic_host_process::provenance::{
6 IgnoreSubmodules, StatusOptions, UntrackedFiles, capture_git,
7 };
8 use ic_host_process::tool::{AdmittedTool, ExecutionContext, OutputLimits, ToolSpec};
9
10 use std::{ffi::OsString, io, path::PathBuf, time::Duration};
11
12 let invalid = |message| io::Error::new(io::ErrorKind::InvalidInput, message);
13 let mut args = std::env::args_os().skip(1);
14 let mut required = || {
15 args.next().ok_or_else(|| invalid(
16 "usage: inspect_git TOOL SHA256 VERSION WORKDIR MAX_TOOL_BYTES MAX_STDOUT_BYTES MAX_STDERR_BYTES TIMEOUT_MS UNTRACKED SUBMODULES",
17 ))
18 };
19 let executable = PathBuf::from(required()?);
20 let digest = required()?
21 .into_string()
22 .map_err(|_| invalid("digest must be UTF-8"))?
23 .parse()?;
24 let version = required()?
25 .into_string()
26 .map_err(|_| invalid("version must be UTF-8"))?;
27 let directory = PathBuf::from(required()?);
28 let mut number = || -> Result<u64, Box<dyn std::error::Error>> {
29 Ok(required()?
30 .to_str()
31 .ok_or_else(|| invalid("limits must be UTF-8"))?
32 .parse()?)
33 };
34 let executable_bytes = number()?;
35 let limits = OutputLimits {
36 stdout: ic_host_process::tool::OutputLimit::Terminate(usize::try_from(number()?)?),
37 stderr: ic_host_process::tool::OutputLimit::Terminate(usize::try_from(number()?)?),
38 timeout: Some(Duration::from_millis(number()?)),
39 };
40 let untracked = match required()?.to_str() {
41 Some("no") => UntrackedFiles::No,
42 Some("normal") => UntrackedFiles::Normal,
43 Some("all") => UntrackedFiles::All,
44 _ => return Err(invalid("untracked must be no, normal or all").into()),
45 };
46 let ignore_submodules = match required()?.to_str() {
47 Some("none") => IgnoreSubmodules::None,
48 Some("untracked") => IgnoreSubmodules::Untracked,
49 Some("dirty") => IgnoreSubmodules::Dirty,
50 Some("all") => IgnoreSubmodules::All,
51 _ => return Err(invalid("submodules must be none, untracked, dirty or all").into()),
52 };
53 if args.next().is_some() {
54 return Err(invalid("unexpected argument").into());
55 }
56 let context = ExecutionContext {
59 current_dir: &directory,
60 environment: &[],
61 };
62 let git = AdmittedTool::admit(
63 &ToolSpec {
64 executable: &executable,
65 sha256: digest,
66 executable_bytes,
67 version_arguments: &[OsString::from("--version")],
68 version_identity: &version,
69 },
70 &context,
71 limits,
72 )?;
73 let observed = capture_git(
74 &git,
75 &context,
76 StatusOptions {
77 untracked,
78 ignore_submodules,
79 },
80 limits,
81 )?;
82 println!("revision={}", observed.revision);
83 println!("tree={}", observed.tree);
84 println!("dirty={}", observed.is_dirty());
85 println!("status_bytes={}", observed.status_identity.bytes);
86 println!("status_sha256={}", observed.status_identity.sha256);
87 Ok(())
88}
89
90#[cfg(not(unix))]
91fn main() -> Result<(), std::io::Error> {
92 Err(std::io::Error::new(
93 std::io::ErrorKind::Unsupported,
94 "Git observations require a supported Unix host",
95 ))
96}