Skip to main content

spm_swift_package/cli/
mod.rs

1pub mod cli_controller;
2pub use cli_controller::Cli;
3
4use clap::{Parser, Subcommand, ValueEnum};
5
6/// Defines :the CLI arguments accepted by the application
7/// Uses Clap to support a subcommand-based interface
8#[derive(Parser)]
9pub struct Args {
10	/// Optional subcommand that defines an alternative execution flow
11	#[command(subcommand)]
12	pub command: Option<Command>,
13}
14
15/// Represents the available CLI subcommands
16/// UI triggers the graphical mode instead of the terminal flow
17#[derive(Subcommand)]
18pub enum Command {
19	/// Runs the UI mode using the iced-based interface
20	UI,
21	/// Generates a Swift Package non-interactively (useful for CI)
22	Generate {
23		/// Name of the library/package
24		#[arg(short, long)]
25		name: String,
26		/// Target platform
27		#[arg(short, long)]
28		platform: Platform,
29		/// Test framework to use
30		#[arg(short, long, default_value = "xctest")]
31		test_framework: TestFramework,
32		/// Optional files to include (can be repeated)
33		#[arg(short, long)]
34		files: Vec<OptionalFile>,
35		/// Open the generated package in Xcode after creation
36		#[arg(long)]
37		open_xcode: bool,
38	},
39}
40
41/// Dispatches CLI arguments to the appropriate execution path
42pub async fn run(args: Args) -> Result<(), String> {
43	match args.command {
44		Some(Command::UI) => {
45			let _ = crate::ui::spm_view::run();
46			Ok(())
47		}
48		Some(Command::Generate {
49			name,
50			platform,
51			test_framework,
52			files,
53			open_xcode,
54		}) => {
55			crate::core::spm_builder::SpmBuilder::create(
56				&name,
57				&files,
58				&[platform.as_str()],
59				test_framework.as_str(),
60			)?;
61
62			println!("Package '{}' generated.", name);
63
64			if open_xcode {
65				crate::utils::xcode::open_xcode(&name)?;
66			}
67
68			Ok(())
69		}
70		None => {
71			let header = crate::header::Header::show();
72			println!("{header}");
73			Cli::execute_flow().await
74		}
75	}
76}
77
78#[derive(Clone, ValueEnum)]
79pub enum Platform {
80	Ios,
81	Macos,
82	Tvos,
83	Watchos,
84	Visionos,
85}
86
87impl Platform {
88	pub fn as_str(&self) -> &'static str {
89		match self {
90			Platform::Ios => "iOS",
91			Platform::Macos => "macOS",
92			Platform::Tvos => "tvOS",
93			Platform::Watchos => "watchOS",
94			Platform::Visionos => "visionOS",
95		}
96	}
97}
98
99#[derive(Clone, ValueEnum)]
100pub enum TestFramework {
101	Xctest,
102	SwiftTesting,
103}
104
105impl TestFramework {
106	pub fn as_str(&self) -> &'static str {
107		match self {
108			TestFramework::Xctest => "XCTest",
109			TestFramework::SwiftTesting => "Swift Testing",
110		}
111	}
112}
113
114#[derive(Clone, ValueEnum)]
115pub enum OptionalFile {
116	Changelog,
117	Readme,
118	Spi,
119	Swiftlint,
120}
121
122impl OptionalFile {
123	pub fn as_str(&self) -> &'static str {
124		match self {
125			OptionalFile::Changelog => "Changelog",
126			OptionalFile::Readme => "Readme",
127			OptionalFile::Spi => "Swift Package Index",
128			OptionalFile::Swiftlint => "SwiftLint",
129		}
130	}
131}
132
133impl AsRef<str> for OptionalFile {
134	fn as_ref(&self) -> &str {
135		self.as_str()
136	}
137}