1mod build;
4mod doc;
5mod fmt_project;
6mod init;
7mod plugin;
8mod serve;
9mod sourcemap;
10mod upload;
11
12use std::{borrow::Cow, env, path::Path, str::FromStr};
13
14use clap::Parser;
15use thiserror::Error;
16
17pub use self::build::BuildCommand;
18pub use self::doc::DocCommand;
19pub use self::fmt_project::FmtProjectCommand;
20pub use self::init::{InitCommand, InitKind};
21pub use self::plugin::{PluginCommand, PluginSubcommand};
22pub use self::serve::ServeCommand;
23pub use self::sourcemap::SourcemapCommand;
24pub use self::upload::UploadCommand;
25
26#[derive(Debug, Parser)]
28#[clap(name = "Rojo", version, about)]
29pub struct Options {
30 #[clap(flatten)]
31 pub global: GlobalOptions,
32
33 #[clap(subcommand)]
35 pub subcommand: Subcommand,
36}
37
38impl Options {
39 pub fn run(self) -> anyhow::Result<()> {
40 match self.subcommand {
41 Subcommand::Init(subcommand) => subcommand.run(),
42 Subcommand::Serve(subcommand) => subcommand.run(self.global),
43 Subcommand::Build(subcommand) => subcommand.run(),
44 Subcommand::Upload(subcommand) => subcommand.run(),
45 Subcommand::Sourcemap(subcommand) => subcommand.run(),
46 Subcommand::FmtProject(subcommand) => subcommand.run(),
47 Subcommand::Doc(subcommand) => subcommand.run(),
48 Subcommand::Plugin(subcommand) => subcommand.run(),
49 }
50 }
51}
52
53#[derive(Debug, Parser)]
54pub struct GlobalOptions {
55 #[clap(long("verbose"), short, global(true), parse(from_occurrences))]
57 pub verbosity: u8,
58
59 #[clap(long("color"), global(true), default_value("auto"))]
61 pub color: ColorChoice,
62}
63
64#[derive(Debug, Clone, Copy)]
65pub enum ColorChoice {
66 Auto,
67 Always,
68 Never,
69}
70
71impl FromStr for ColorChoice {
72 type Err = ColorChoiceParseError;
73
74 fn from_str(source: &str) -> Result<Self, Self::Err> {
75 match source {
76 "auto" => Ok(ColorChoice::Auto),
77 "always" => Ok(ColorChoice::Always),
78 "never" => Ok(ColorChoice::Never),
79 _ => Err(ColorChoiceParseError {
80 attempted: source.to_owned(),
81 }),
82 }
83 }
84}
85
86impl From<ColorChoice> for termcolor::ColorChoice {
87 fn from(value: ColorChoice) -> Self {
88 match value {
89 ColorChoice::Auto => termcolor::ColorChoice::Auto,
90 ColorChoice::Always => termcolor::ColorChoice::Always,
91 ColorChoice::Never => termcolor::ColorChoice::Never,
92 }
93 }
94}
95
96impl From<ColorChoice> for env_logger::WriteStyle {
97 fn from(value: ColorChoice) -> Self {
98 match value {
99 ColorChoice::Auto => env_logger::WriteStyle::Auto,
100 ColorChoice::Always => env_logger::WriteStyle::Always,
101 ColorChoice::Never => env_logger::WriteStyle::Never,
102 }
103 }
104}
105
106#[derive(Debug, Error)]
107#[error("Invalid color choice '{attempted}'. Valid values are: auto, always, never")]
108pub struct ColorChoiceParseError {
109 attempted: String,
110}
111
112#[derive(Debug, Parser)]
113pub enum Subcommand {
114 Init(InitCommand),
115 Serve(ServeCommand),
116 Build(BuildCommand),
117 Upload(UploadCommand),
118 Sourcemap(SourcemapCommand),
119 FmtProject(FmtProjectCommand),
120 Doc(DocCommand),
121 Plugin(PluginCommand),
122}
123
124pub(super) fn resolve_path(path: &Path) -> Cow<'_, Path> {
125 if path.is_absolute() {
126 Cow::Borrowed(path)
127 } else {
128 Cow::Owned(env::current_dir().unwrap().join(path))
129 }
130}