1#![cfg_attr(
25 all(doc, feature = "document-features"),
26 doc = ::document_features::document_features!()
27)]
28#![cfg_attr(all(doc, feature = "document-features"), feature(doc_cfg, doc_auto_cfg))]
29#![cfg_attr(feature = "async-client", allow(unused))]
30#![deny(rust_2018_idioms)]
31#![forbid(unsafe_code)]
32
33use anyhow::bail;
34use std::str::FromStr;
35
36#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
37pub enum OutputFormat {
38 Human,
39 #[cfg(feature = "serde")]
40 Json,
41}
42
43impl OutputFormat {
44 pub fn variants() -> &'static [&'static str] {
45 &[
46 "human",
47 #[cfg(feature = "serde")]
48 "json",
49 ]
50 }
51}
52
53impl FromStr for OutputFormat {
54 type Err = String;
55
56 fn from_str(s: &str) -> Result<Self, Self::Err> {
57 let s_lc = s.to_ascii_lowercase();
58 Ok(match s_lc.as_str() {
59 "human" => OutputFormat::Human,
60 #[cfg(feature = "serde")]
61 "json" => OutputFormat::Json,
62 _ => return Err(format!("Invalid output format: '{s}'")),
63 })
64 }
65}
66
67pub mod commitgraph;
68#[cfg(feature = "corpus")]
69pub mod corpus;
70pub mod net;
71
72#[cfg(feature = "estimate-hours")]
73pub mod hours;
74pub mod index;
75pub mod mailmap;
76#[cfg(feature = "organize")]
77pub mod organize;
78pub mod pack;
79#[cfg(feature = "query")]
80pub mod query;
81pub mod repository;
82
83mod discover;
84pub use discover::discover;
85
86pub fn env(mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {
87 if format != OutputFormat::Human {
88 bail!("JSON output isn't supported");
89 }
90
91 let width = 15;
92 writeln!(
93 out,
94 "{field:>width$}: {}",
95 std::path::Path::new(gix::path::env::shell()).display(),
96 field = "shell",
97 )?;
98 writeln!(
99 out,
100 "{field:>width$}: {:?}",
101 gix::path::env::installation_config_prefix(),
102 field = "config prefix",
103 )?;
104 writeln!(
105 out,
106 "{field:>width$}: {:?}",
107 gix::path::env::installation_config(),
108 field = "config",
109 )?;
110 writeln!(
111 out,
112 "{field:>width$}: {}",
113 gix::path::env::exe_invocation().display(),
114 field = "git exe",
115 )?;
116 writeln!(
117 out,
118 "{field:>width$}: {:?}",
119 gix::path::env::system_prefix(),
120 field = "system prefix",
121 )?;
122 writeln!(
123 out,
124 "{field:>width$}: {:?}",
125 gix::path::env::core_dir(),
126 field = "core dir",
127 )?;
128 Ok(())
129}
130
131#[cfg(all(feature = "async-client", feature = "blocking-client"))]
132compile_error!("Cannot set both 'blocking-client' and 'async-client' features as they are mutually exclusive");
133
134fn is_dir_to_mode(is_dir: bool) -> gix::index::entry::Mode {
135 if is_dir {
136 gix::index::entry::Mode::DIR
137 } else {
138 gix::index::entry::Mode::FILE
139 }
140}