1#![doc = include_str!("../README.md")]
2
3use base64::{Engine, engine::general_purpose::STANDARD};
4use bitwarden_cli::install_color_eyre;
5use clap::{CommandFactory, Parser};
6use clap_complete::Shell;
7use color_eyre::eyre::Result;
8use tracing_subscriber::{
9 EnvFilter, prelude::__tracing_subscriber_SubscriberExt as _, util::SubscriberInitExt as _,
10};
11
12use crate::{command::*, render::CommandResult};
13
14mod admin_console;
15mod auth;
16mod command;
17mod platform;
18mod render;
19mod tools;
20mod vault;
21
22#[tokio::main(flavor = "current_thread")]
23async fn main() -> Result<()> {
24 let filter = EnvFilter::builder()
29 .with_default_directive(
30 option_env!("RUST_LOG")
31 .unwrap_or("info")
32 .parse()
33 .expect("should provide valid log level at compile time."),
34 )
35 .from_env_lossy();
38
39 tracing_subscriber::registry()
40 .with(tracing_subscriber::fmt::layer().with_writer(std::io::stderr))
41 .with(filter)
42 .init();
43
44 let cli = Cli::parse();
45 install_color_eyre(cli.color)?;
46 let render_config = render::RenderConfig::new(&cli);
47
48 let Some(command) = cli.command else {
49 let mut cmd = Cli::command();
50 cmd.print_help()?;
51 return Ok(());
52 };
53
54 let result = process_commands(command, cli.session).await;
55
56 render_config.render_result(result)
58}
59
60async fn process_commands(command: Commands, _session: Option<String>) -> CommandResult {
61 let client = bitwarden_pm::PasswordManagerClient::new(None);
72
73 match command {
74 Commands::Login(args) => args.run().await,
76 Commands::Logout => todo!(),
77 Commands::Register(register) => register.run().await,
78
79 Commands::Unlock(_args) => todo!(),
81
82 Commands::Sync { .. } => todo!(),
84
85 Commands::Encode => {
86 let input = std::io::read_to_string(std::io::stdin())?;
87 let encoded = STANDARD.encode(input);
88 Ok(encoded.into())
89 }
90
91 Commands::Config { command } => command.run().await,
92
93 Commands::Update { .. } => todo!(),
94
95 Commands::Completion { shell } => {
96 let Some(shell) = shell.or_else(Shell::from_env) else {
97 return Ok(
98 "Couldn't autodetect a valid shell. Run `bw completion --help` for more info."
99 .into(),
100 );
101 };
102
103 let mut cmd = Cli::command();
104 let name = cmd.get_name().to_string();
105 clap_complete::generate(shell, &mut cmd, name, &mut std::io::stdout());
106 Ok(().into())
107 }
108
109 Commands::Status => todo!(),
110
111 Commands::Item { command: _ } => todo!(),
113 Commands::Template { command } => command.run(),
114
115 Commands::List => todo!(),
116 Commands::Get => todo!(),
117 Commands::Create => todo!(),
118 Commands::Edit => todo!(),
119 Commands::Delete => todo!(),
120 Commands::Restore => todo!(),
121 Commands::Move => todo!(),
122
123 Commands::Confirm { .. } => todo!(),
125
126 Commands::Generate(arg) => arg.run(&client),
128 Commands::Import => todo!(),
129 Commands::Export => todo!(),
130 Commands::Share => todo!(),
131 Commands::Send => todo!(),
132 Commands::Receive => todo!(),
133 }
134}