Merge branch 'master' into 'master'
Change argument parsing to use clap v3 derive syntax See merge request crystal/programs/jade!1axtloss/rework-partitioning
commit
d23b17cb2f
@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DiscordProjectSettings">
|
||||||
|
<option name="show" value="PROJECT_FILES" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="CPP_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/jade.iml" filepath="$PROJECT_DIR$/.idea/jade.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,189 @@
|
|||||||
|
use clap::{ArgEnum, Args, Parser, Subcommand};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
#[clap(name="jade", version=env!("CARGO_PKG_VERSION"), about=env!("CARGO_PKG_DESCRIPTION"), author=env!("CARGO_PKG_AUTHORS"))]
|
||||||
|
pub struct Opt {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
pub command: Command,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
pub enum Command {
|
||||||
|
/// Partition the install destination
|
||||||
|
#[clap(name = "partition")]
|
||||||
|
Partition(PartitionArgs),
|
||||||
|
|
||||||
|
/// Install base packages
|
||||||
|
#[clap(name = "install-base")]
|
||||||
|
InstallBase,
|
||||||
|
|
||||||
|
/// Generate fstab file for mounting partitions
|
||||||
|
#[clap(name = "genfstab")]
|
||||||
|
GenFstab,
|
||||||
|
|
||||||
|
/// Setup timeshift
|
||||||
|
#[clap(name = "setup-timeshift")]
|
||||||
|
SetupTimeshift,
|
||||||
|
|
||||||
|
/// Install the bootloader
|
||||||
|
#[clap(name = "bootloader")]
|
||||||
|
Bootloader {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
subcommand: BootloaderSubcommand,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Set locale stuff
|
||||||
|
#[clap(name = "locale")]
|
||||||
|
Locale(LocaleArgs),
|
||||||
|
|
||||||
|
/// Set networking stuff
|
||||||
|
#[clap(name = "networking")]
|
||||||
|
Networking(NetworkingArgs),
|
||||||
|
|
||||||
|
/// Configure users and passwords
|
||||||
|
#[clap(name = "users")]
|
||||||
|
Users {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
subcommand: UsersSubcommand,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Install the nix package manager
|
||||||
|
#[clap(name = "nix")]
|
||||||
|
Nix,
|
||||||
|
|
||||||
|
/// Read jade installation config
|
||||||
|
#[clap(name = "config")]
|
||||||
|
Config {
|
||||||
|
/// The config to read
|
||||||
|
config: PathBuf,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Install a graphical desktop setup
|
||||||
|
#[clap(name = "desktops")]
|
||||||
|
Desktops {
|
||||||
|
/// The desktop setup to use
|
||||||
|
#[clap(arg_enum)]
|
||||||
|
desktop: DesktopSetup,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
pub struct PartitionArgs {
|
||||||
|
/// If jade should automatically partition (mode = auto)
|
||||||
|
/// or the user manually partitioned it (mode = manual)
|
||||||
|
#[clap(arg_enum)]
|
||||||
|
pub mode: PartitionMode,
|
||||||
|
|
||||||
|
/// The device to partition
|
||||||
|
#[clap(required_if_eq("mode", "PartitionMode::Manual"))]
|
||||||
|
pub device: PathBuf,
|
||||||
|
|
||||||
|
/// If the install destination should be partitioned with EFI
|
||||||
|
#[clap(long)]
|
||||||
|
pub efi: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, ArgEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum PartitionMode {
|
||||||
|
#[clap(name = "auto")]
|
||||||
|
Auto,
|
||||||
|
#[clap(name = "manual")]
|
||||||
|
Manual,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
pub enum BootloaderSubcommand {
|
||||||
|
/// Install grub in efi mode
|
||||||
|
#[clap(name = "grub-efi")]
|
||||||
|
GrubEfi {
|
||||||
|
/// The directory to install the EFI bootloader to
|
||||||
|
efidir: PathBuf,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// Install grub in legacy (BIOS) mode
|
||||||
|
#[clap(name = "grub-legacy")]
|
||||||
|
GrubLegacy {
|
||||||
|
/// The device to install the bootloader to
|
||||||
|
device: PathBuf,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
pub struct LocaleArgs {
|
||||||
|
/// The keyboard layout to use
|
||||||
|
pub keyboard: String,
|
||||||
|
|
||||||
|
/// The timezone to use
|
||||||
|
pub timezone: String,
|
||||||
|
|
||||||
|
/// The locales to set
|
||||||
|
pub locales: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
pub struct NetworkingArgs {
|
||||||
|
/// The hostname to assign to the system
|
||||||
|
pub hostname: String,
|
||||||
|
|
||||||
|
/// Whether ipv6 should be enabled
|
||||||
|
#[clap(long)]
|
||||||
|
pub ipv6: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
pub enum UsersSubcommand {
|
||||||
|
/// Create a new user
|
||||||
|
#[clap(name="new-user", aliases=&["newUser"])]
|
||||||
|
NewUser(NewUserArgs),
|
||||||
|
|
||||||
|
/// Set the password of the root user
|
||||||
|
#[clap(name="root-password", aliases=&["root-pass", "rootPass"])]
|
||||||
|
RootPass {
|
||||||
|
/// The password to set. NOTE: Takes hashed password, use `openssl passwd -1 <password>` to generate the hash.
|
||||||
|
password: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
pub struct NewUserArgs {
|
||||||
|
/// The name of the user to create
|
||||||
|
pub username: String,
|
||||||
|
|
||||||
|
/// If the user should have root privileges
|
||||||
|
#[clap(long, aliases=&["has-root"])]
|
||||||
|
pub hasroot: bool,
|
||||||
|
|
||||||
|
/// The password to set. NOTE: Takes hashed password, use `openssl passwd -1 <password>` to generate the hash.
|
||||||
|
/// When not providing a password openssl jumps into an interactive masked input mode allowing you to hide your password
|
||||||
|
/// from the terminal history.
|
||||||
|
pub password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, ArgEnum, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum DesktopSetup {
|
||||||
|
#[clap(name = "onyx")]
|
||||||
|
Onyx,
|
||||||
|
|
||||||
|
#[clap(name = "gnome")]
|
||||||
|
Gnome,
|
||||||
|
|
||||||
|
#[clap(name = "kde", aliases = ["plasma"])]
|
||||||
|
Kde,
|
||||||
|
|
||||||
|
#[clap(name = "budgie")]
|
||||||
|
Budgie,
|
||||||
|
|
||||||
|
#[clap(name = "cinnamon")]
|
||||||
|
Cinnamon,
|
||||||
|
|
||||||
|
#[clap(name = "mate")]
|
||||||
|
Mate,
|
||||||
|
|
||||||
|
#[clap(name = "xfce")]
|
||||||
|
Xfce,
|
||||||
|
|
||||||
|
#[clap(name = "enlightenment")]
|
||||||
|
Enlightenment,
|
||||||
|
}
|
@ -1,213 +1,62 @@
|
|||||||
|
mod args;
|
||||||
mod functions;
|
mod functions;
|
||||||
mod internal;
|
mod internal;
|
||||||
|
|
||||||
|
use crate::args::{BootloaderSubcommand, Command, Opt, UsersSubcommand};
|
||||||
use crate::functions::*;
|
use crate::functions::*;
|
||||||
use clap::{App, Arg, SubCommand};
|
use clap::Parser;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let app = App::new("jade")
|
let opt: Opt = Opt::parse();
|
||||||
.version(env!("CARGO_PKG_VERSION"))
|
match opt.command {
|
||||||
.about(env!("CARGO_PKG_DESCRIPTION"))
|
Command::Partition(args) => {
|
||||||
.author(env!("CARGO_PKG_AUTHORS"))
|
partition::partition(args.device, args.mode, args.efi);
|
||||||
.subcommand(
|
}
|
||||||
SubCommand::with_name("partition")
|
Command::InstallBase => {
|
||||||
.about("Partition the install destination")
|
base::install_base_packages();
|
||||||
.arg(
|
}
|
||||||
Arg::with_name("mode")
|
Command::GenFstab => {
|
||||||
.help("If jade should automatically partition (mode = auto) or the user manually partitioned it (mode = manual)")
|
base::genfstab();
|
||||||
.possible_values(&["auto", "manual"])
|
}
|
||||||
.required(true),
|
Command::SetupTimeshift => base::setup_timeshift(),
|
||||||
)
|
Command::Bootloader { subcommand } => match subcommand {
|
||||||
.arg(
|
BootloaderSubcommand::GrubEfi { efidir } => {
|
||||||
Arg::with_name("device")
|
base::install_bootloader_efi(efidir);
|
||||||
.help("The device to partition")
|
}
|
||||||
.required_if("mode", "auto"),
|
BootloaderSubcommand::GrubLegacy { device } => {
|
||||||
)
|
base::install_bootloader_legacy(device);
|
||||||
.arg(
|
}
|
||||||
Arg::with_name("efi")
|
},
|
||||||
.help("If the install destination should be partitioned with EFI")
|
Command::Locale(args) => {
|
||||||
.long("efi")
|
locale::set_locale(args.locales.join(" "));
|
||||||
.takes_value(false),
|
locale::set_keyboard(&args.keyboard);
|
||||||
),
|
locale::set_timezone(&args.timezone);
|
||||||
)
|
}
|
||||||
.subcommand(
|
Command::Networking(args) => {
|
||||||
SubCommand::with_name("install-base")
|
if args.ipv6 {
|
||||||
.about("Install base packages")
|
network::create_hosts();
|
||||||
)
|
network::enable_ipv6()
|
||||||
.subcommand(
|
} else {
|
||||||
SubCommand::with_name("genfstab")
|
network::create_hosts();
|
||||||
.about("Generate fstab")
|
}
|
||||||
)
|
network::set_hostname(&args.hostname);
|
||||||
.subcommand(
|
}
|
||||||
SubCommand::with_name("setup-timeshift")
|
Command::Users { subcommand } => match subcommand {
|
||||||
.about("Setup timeshift")
|
UsersSubcommand::NewUser(args) => {
|
||||||
)
|
users::new_user(&args.username, args.hasroot, &args.password);
|
||||||
.subcommand(
|
}
|
||||||
SubCommand::with_name("bootloader")
|
UsersSubcommand::RootPass { password } => {
|
||||||
.about("Install bootloader")
|
users::root_pass(&password);
|
||||||
.subcommand(
|
}
|
||||||
SubCommand::with_name("grub-efi")
|
},
|
||||||
.about("Install grub-efi")
|
Command::Nix => {
|
||||||
.arg(
|
base::install_homemgr();
|
||||||
Arg::with_name("efidir")
|
|
||||||
.help("The directory to install the EFI bootloader to")
|
|
||||||
.required(true),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("grub-legacy")
|
|
||||||
.about("Install grub-legacy")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("device")
|
|
||||||
.help("The device to install the bootloader to")
|
|
||||||
.required(true),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("locale")
|
|
||||||
.about("Set locale stuff")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("keyboard")
|
|
||||||
.help("The keyboard layout to use")
|
|
||||||
.required(true),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("timezone")
|
|
||||||
.help("The timezone to use")
|
|
||||||
.required(true),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("locales")
|
|
||||||
.help("The locales to set")
|
|
||||||
.multiple(true)
|
|
||||||
.index(3)
|
|
||||||
.required(true),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("networking")
|
|
||||||
.about("Set networking stuff")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("hostname")
|
|
||||||
.help("The hostname to use")
|
|
||||||
.required(true),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("ipv6")
|
|
||||||
.help("Wether ipv6 should be enabled")
|
|
||||||
.short("i6")
|
|
||||||
.long("ipv6")
|
|
||||||
.takes_value(false),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("users")
|
|
||||||
.about("Configure users")
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("newUser")
|
|
||||||
.about("Create a new user")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("username")
|
|
||||||
.help("The username to create")
|
|
||||||
.required(true),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("hasroot")
|
|
||||||
.help("If the user should have root privileges")
|
|
||||||
.required(true),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("password")
|
|
||||||
.help("The password to set. NOTE: Takes hashed password, use `openssl passwd -1 <password>` to generate the hash.")
|
|
||||||
.required(true),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("rootPass")
|
|
||||||
.about("Set the root password")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("rootPass")
|
|
||||||
.help("The password to set. NOTE: Takes hashed password, use `openssl passwd -1 <password>` to generate the hash._")
|
|
||||||
.required(true),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("nix")
|
|
||||||
.about("Install nix"),
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("config")
|
|
||||||
.about("read a jade installation config")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("config")
|
|
||||||
.help("The config to read")
|
|
||||||
.required(true),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.subcommand(
|
|
||||||
SubCommand::with_name("desktops")
|
|
||||||
.about("Graphical stuff (Desktop environment and Display Manager)")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("desktopsetup")
|
|
||||||
.help("The desktop setup to use")
|
|
||||||
.required(true),
|
|
||||||
),
|
|
||||||
).get_matches();
|
|
||||||
|
|
||||||
if let Some(app) = app.subcommand_matches("partition") {
|
|
||||||
partition::partition(
|
|
||||||
app.value_of("device").unwrap(),
|
|
||||||
app.value_of("mode").unwrap(),
|
|
||||||
app.is_present("efi"),
|
|
||||||
);
|
|
||||||
} else if let Some(app) = app.subcommand_matches("locale") {
|
|
||||||
locale::set_locale(
|
|
||||||
app.values_of("locales")
|
|
||||||
.unwrap()
|
|
||||||
.collect::<Vec<&str>>()
|
|
||||||
.join(" "),
|
|
||||||
);
|
|
||||||
locale::set_keyboard(app.value_of("keyboard").unwrap());
|
|
||||||
locale::set_timezone(app.value_of("timezone").unwrap());
|
|
||||||
} else if let Some(app) = app.subcommand_matches("networking") {
|
|
||||||
if app.is_present("ipv6") {
|
|
||||||
network::create_hosts();
|
|
||||||
network::enable_ipv6()
|
|
||||||
} else {
|
|
||||||
network::create_hosts()
|
|
||||||
}
|
}
|
||||||
network::set_hostname(app.value_of("hostname").unwrap())
|
Command::Config { config } => {
|
||||||
} else if let Some(app) = app.subcommand_matches("users") {
|
crate::internal::config::read_config(config);
|
||||||
if let Some(app) = app.subcommand_matches("newUser") {
|
|
||||||
users::new_user(
|
|
||||||
app.value_of("username").unwrap(),
|
|
||||||
app.value_of("hasroot").unwrap().parse::<bool>().unwrap(),
|
|
||||||
app.value_of("password").unwrap(),
|
|
||||||
);
|
|
||||||
} else if let Some(app) = app.subcommand_matches("rootPass") {
|
|
||||||
users::root_pass(app.value_of("rootPass").unwrap());
|
|
||||||
}
|
}
|
||||||
} else if let Some(app) = app.subcommand_matches("desktops") {
|
Command::Desktops { desktop } => {
|
||||||
desktops::choose_pkgs(app.value_of("desktopsetup").unwrap());
|
desktops::install_desktop_setup(desktop);
|
||||||
} else if let Some(app) = app.subcommand_matches("bootloader") {
|
|
||||||
if let Some(app) = app.subcommand_matches("grub-efi") {
|
|
||||||
base::install_bootloader_efi(app.value_of("efidir").unwrap());
|
|
||||||
} else if let Some(app) = app.subcommand_matches("grub-legacy") {
|
|
||||||
base::install_bootloader_legacy(app.value_of("device").unwrap());
|
|
||||||
}
|
}
|
||||||
} else if app.subcommand_matches("install-base").is_some() {
|
|
||||||
base::install_base_packages();
|
|
||||||
} else if app.subcommand_matches("genfstab").is_some() {
|
|
||||||
base::genfstab();
|
|
||||||
} else if app.subcommand_matches("setup-timeshift").is_some() {
|
|
||||||
base::setup_timeshift();
|
|
||||||
} else if app.subcommand_matches("nix").is_some() {
|
|
||||||
base::install_homemgr();
|
|
||||||
} else if let Some(app) = app.subcommand_matches("config") {
|
|
||||||
crate::internal::config::read_config(app.value_of("config").unwrap());
|
|
||||||
} else {
|
|
||||||
println!("{}", app.usage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue