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