Compare commits

...

15 Commits

Author SHA1 Message Date
Jeevitha Kannan K S
42deb2e5b2
Merge 4f5030c359 into 8ea3da9843 2024-11-07 01:59:32 +00:00
Jeevitha Kannan K S
4f5030c359
Merge branch 'main' into automation 2024-11-07 07:29:25 +05:30
Jeevitha Kannan K S
8ea3da9843
Remove dependabot ignores (#806) 2024-11-06 16:30:40 -06:00
Jeevitha Kannan K S
176b19d692
Use ratatui bundled crossterm (#805) 2024-11-06 16:29:52 -06:00
Jeevitha Kannan K S
98e2f83f43
feat: Add arch nvidia installation script (#797)
* Add arch nvidia script

* Update model fetching

* chore: formatting, git as dep

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2024-11-06 16:28:36 -06:00
Adam Perkowski
9d1dc35f43
📃 feat: Linux Neptune (Valve's kernel for SteamDeck) installation (#683)
* Linux Neptune installation script

* fixed some stuff that's not supposed to be here

Co-authored-by: nnyyxxxx <nnyyxxxx@users.noreply.github.com>

* fix repo check

* added audio patches

https://github.com/ChrisTitusTech/linutil/issues/269#issuecomment-2380379049

* add linux neptune to docs (userguide)

* steamdeck precondition

Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>

* precondition fix

* another precondition fix

---------

Co-authored-by: nnyyxxxx <nnyyxxxx@users.noreply.github.com>
Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
Co-authored-by: Chris Titus <contact@christitus.com>
2024-11-06 16:20:16 -06:00
Jeevitha Kannan K S
1234edd466
Change numlock description (#790) 2024-11-06 16:11:31 -06:00
leventbesli
d1a1812709
feat: btrfs assistant & grub-btrfs (#789)
* Btrfs Assistant(+snapper), grub-btrfs Setup added

Adds fedora-btrfs-assistant.sh, updates tab_data and documentation.

* updated doc, ta_data and sh

* enable grub-btrfsd service added

* updated some wording in notices.

* updated wording and add prompts for actions

* added fix for a possible grub error

also some more enhancements and wording improvements.

* user action removed

reinstall snapper action removed because removing and reinstalling snapper is a very unlikely action. and also snapper can't handle ./snapsots folder in the disk after reinstalling: "creating btrfs subvolume .snapshots failed since it already exists".

* firs snapshot order changed

home snapshot taken first because it's config can be saved to first root snapshot.

* better explanations in user prompts

* improved y/n loop

* formatting improvements

* formatting improvement

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* formatting improvement

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* Update task list

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* removed a inline comment

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* removed an unnececary inline comment

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* removed an unnececary inline comment

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* improved sed -i

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* improved sed -i

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* improved sed -i

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* newlines removed from tab_data.toml

Co-authored-by: Nyx <nnyyxxxx@protonmail.com>

* btrfs detection moved to toml

Co-authored-by: Nyx <nnyyxxxx@protonmail.com>

* data.preconditions added - escalation tool used

* $PACKAGER replaced with dnf

* re-added packager

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* re-added packager

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>

* usergide updated with docgen

* typo fix

---------

Co-authored-by: Adam Perkowski <adas1per@protonmail.com>
Co-authored-by: Nyx <nnyyxxxx@protonmail.com>
2024-11-06 16:05:26 -06:00
Albert de Palo Hardvendel
f2a1766289
Added support for installing podman (#787)
* Added support for installing podman

* removed llm comment

* Added podman to userguide

* Added support for install pythona and pip in case of missing. changed pip install to rootless install

* changed installing podman-compose with pip to packagemanager

* Update core/tabs/applications-setup/podman-setup.sh

Only install Podman if it is not installed already.

Co-authored-by: nyx <nnyyxxxx@protonmail.com>

* Update core/tabs/applications-setup/podman-setup.sh

Only install podman-compose if it is not installed already.

Co-authored-by: nyx <nnyyxxxx@protonmail.com>

* added podman-compose install option

* split podman install into podman and podman-compose

* Update core/tabs/applications-setup/podman-setup.sh

Co-authored-by: nyx <nnyyxxxx@protonmail.com>

* Update core/tabs/applications-setup/podman-setup.sh

Co-authored-by: nyx <nnyyxxxx@protonmail.com>

* Update core/tabs/applications-setup/podman-compose-setup.sh

Co-authored-by: nyx <nnyyxxxx@protonmail.com>

* Update core/tabs/applications-setup/podman-compose-setup.sh

Co-authored-by: nyx <nnyyxxxx@protonmail.com>

* Update core/tabs/applications-setup/podman-compose-setup.sh

Removed redundant quotes

Co-authored-by: JEEVITHA KANNAN K S <ksjeevithakannan123@gmail.com>

* Update core/tabs/applications-setup/podman-setup.sh

Removed redundant quotes

Co-authored-by: JEEVITHA KANNAN K S <ksjeevithakannan123@gmail.com>

---------

Co-authored-by: nyx <nnyyxxxx@protonmail.com>
Co-authored-by: JEEVITHA KANNAN K S <ksjeevithakannan123@gmail.com>
Co-authored-by: Chris Titus <contact@christitus.com>
2024-11-06 16:03:50 -06:00
Liam
6728e7ee9b
refact: Handle temporary directories entirely within core (#754)
* refactor: Handle temporary directories entirely within core

* fix (xtask): Handle modified tablist struct

* refactor (xtask): Apply Clippy suggested changes

* Fix size_bypass

---------

Co-authored-by: Chris Titus <contact@christitus.com>
2024-11-06 15:28:17 -06:00
Jeevitha Kannan K S
9de3c9af19
Merge remote-tracking branch 'upstream/main' into automation 2024-11-06 21:52:51 +05:30
JEEVITHA KANNAN K S
2e05a0c587
update roadmap 2024-11-01 20:30:13 +05:30
JEEVITHA KANNAN K S
ee601dcb0e
Merge remote-tracking branch 'upstream/main' into automation 2024-11-01 20:29:48 +05:30
Adam Perkowski
eb9c13c941 docs: add configuration to the manpage & README 2024-10-30 00:35:13 +01:00
Jeevitha Kannan K S
6cabee6d72
feat: Add automation based on config file 2024-10-28 08:43:14 +05:30
27 changed files with 638 additions and 62 deletions

View File

@ -7,11 +7,4 @@ updates:
- package-ecosystem: "github-actions" - package-ecosystem: "github-actions"
directory: "/" directory: "/"
schedule: schedule:
interval: "weekly" interval: "weekly"
ignore:
- dependency-name: "actions/stale"
versions: '>= 9'
- dependency-name: "actions/setup-python"
versions: '> 4'
- dependency-name: "crossterm"
versions: '> 0.27.0'

1
Cargo.lock generated
View File

@ -435,7 +435,6 @@ dependencies = [
"ansi-to-tui", "ansi-to-tui",
"anstyle", "anstyle",
"clap", "clap",
"crossterm",
"ego-tree", "ego-tree",
"linutil_core", "linutil_core",
"oneshot", "oneshot",

View File

@ -72,6 +72,28 @@ Note that crates installed using `cargo install` require manual updating with `c
</details> </details>
## Configuration
Linutil supports configuration through a TOML config file. Path to the file can be specified with `--config` (or `-c`).
Available options:
- `auto_execute` - a list of commands to execute automatically (can be combined with `--skip-confirmation`)
Example config:
```toml
# example_config.toml
auto_execute = [
"Fastfetch",
"Alacritty",
"Kitty"
]
```
```bash
linutil --config /path/to/example_config.toml
```
## 💖 Support ## 💖 Support
If you find Linutil helpful, please consider giving it a ⭐️ to show your support! If you find Linutil helpful, please consider giving it a ⭐️ to show your support!

28
core/src/config.rs Normal file
View File

@ -0,0 +1,28 @@
use serde::Deserialize;
use std::path::Path;
use std::process;
#[derive(Deserialize)]
pub struct Config {
pub auto_execute: Vec<String>,
}
impl Config {
pub fn from_file(path: &Path) -> Self {
let content = match std::fs::read_to_string(path) {
Ok(content) => content,
Err(e) => {
eprintln!("Failed to read config file {}: {}", path.display(), e);
process::exit(1);
}
};
match toml::from_str(&content) {
Ok(config) => config,
Err(e) => {
eprintln!("Failed to parse config file: {}", e);
process::exit(1);
}
}
}
}

View File

@ -1,6 +1,7 @@
use std::{ use std::{
fs::File, fs::File,
io::{BufRead, BufReader, Read}, io::{BufRead, BufReader, Read},
ops::{Deref, DerefMut},
os::unix::fs::PermissionsExt, os::unix::fs::PermissionsExt,
path::{Path, PathBuf}, path::{Path, PathBuf},
rc::Rc, rc::Rc,
@ -14,8 +15,34 @@ use temp_dir::TempDir;
const TAB_DATA: Dir = include_dir!("$CARGO_MANIFEST_DIR/tabs"); const TAB_DATA: Dir = include_dir!("$CARGO_MANIFEST_DIR/tabs");
pub fn get_tabs(validate: bool) -> (TempDir, Vec<Tab>) { // Allow the unused TempDir to be stored for later destructor call
let (temp_dir, tab_files) = TabList::get_tabs(); #[allow(dead_code)]
pub struct TabList(pub Vec<Tab>, TempDir);
// Implement deref to allow Vec<Tab> methods to be called on TabList
impl Deref for TabList {
type Target = Vec<Tab>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for TabList {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl IntoIterator for TabList {
type Item = Tab;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
pub fn get_tabs(validate: bool) -> TabList {
let (temp_dir, tab_files) = TabDirectories::get_tabs();
let tabs: Vec<_> = tab_files let tabs: Vec<_> = tab_files
.into_iter() .into_iter()
@ -50,11 +77,11 @@ pub fn get_tabs(validate: bool) -> (TempDir, Vec<Tab>) {
if tabs.is_empty() { if tabs.is_empty() {
panic!("No tabs found"); panic!("No tabs found");
} }
(temp_dir, tabs) TabList(tabs, temp_dir)
} }
#[derive(Deserialize)] #[derive(Deserialize)]
struct TabList { struct TabDirectories {
directories: Vec<PathBuf>, directories: Vec<PathBuf>,
} }
@ -246,9 +273,9 @@ fn is_executable(path: &Path) -> bool {
.unwrap_or(false) .unwrap_or(false)
} }
impl TabList { impl TabDirectories {
fn get_tabs() -> (TempDir, Vec<PathBuf>) { fn get_tabs() -> (TempDir, Vec<PathBuf>) {
let temp_dir = TempDir::new().unwrap(); let temp_dir = TempDir::with_prefix("linutil_scripts").unwrap();
TAB_DATA TAB_DATA
.extract(&temp_dir) .extract(&temp_dir)
.expect("Failed to extract the saved directory"); .expect("Failed to extract the saved directory");

View File

@ -1,3 +1,4 @@
mod config;
mod inner; mod inner;
use std::rc::Rc; use std::rc::Rc;
@ -5,7 +6,8 @@ use std::rc::Rc;
use ego_tree::Tree; use ego_tree::Tree;
use std::path::PathBuf; use std::path::PathBuf;
pub use inner::get_tabs; pub use config::Config;
pub use inner::{get_tabs, TabList};
#[derive(Clone, Hash, Eq, PartialEq)] #[derive(Clone, Hash, Eq, PartialEq)]
pub enum Command { pub enum Command {
@ -33,3 +35,16 @@ pub struct ListNode {
pub task_list: String, pub task_list: String,
pub multi_select: bool, pub multi_select: bool,
} }
impl Tab {
pub fn find_command(&self, name: &str) -> Option<Rc<ListNode>> {
self.tree.root().descendants().find_map(|node| {
let value = node.value();
if value.name == name && !node.has_children() {
Some(value.clone())
} else {
None
}
})
}
}

View File

@ -0,0 +1,33 @@
#!/bin/sh -e
. ../common-script.sh
installPodmanCompose() {
if ! command_exists podman-compose; then
printf "%b\n" "${YELLOW}Installing Podman Compose...${RC}"
case "$PACKAGER" in
apt-get|nala)
"$ESCALATION_TOOL" "$PACKAGER" install -y podman-compose
;;
zypper)
"$ESCALATION_TOOL" "$PACKAGER" --non-interactive install podman-compose
;;
pacman)
"$ESCALATION_TOOL" "$PACKAGER" -S --noconfirm --needed podman-compose
;;
dnf)
"$ESCALATION_TOOL" "$PACKAGER" install -y podman-compose
;;
*)
printf "%b\n" "${RED}Unsupported package manager: ${PACKAGER}${RC}"
exit 1
;;
esac
else
printf "%b\n" "${GREEN}Podman Compose is already installed.${RC}"
fi
}
checkEnv
checkEscalationTool
installPodmanCompose

View File

@ -0,0 +1,33 @@
#!/bin/sh -e
. ../common-script.sh
installPodman() {
if ! command_exists podman; then
printf "%b\n" "${YELLOW}Installing Podman...${RC}"
case "$PACKAGER" in
apt-get|nala)
"$ESCALATION_TOOL" "$PACKAGER" install -y podman
;;
zypper)
"$ESCALATION_TOOL" "$PACKAGER" --non-interactive install podman
;;
pacman)
"$ESCALATION_TOOL" "$PACKAGER" -S --noconfirm --needed podman
;;
dnf)
"$ESCALATION_TOOL" "$PACKAGER" install -y podman
;;
*)
printf "%b\n" "${RED}Unsupported package manager: ${PACKAGER}${RC}"
exit 1
;;
esac
else
printf "%b\n" "${GREEN}Podman is already installed.${RC}"
fi
}
checkEnv
checkEscalationTool
installPodman

View File

@ -228,6 +228,18 @@ description = "Docker is an open platform that uses OS-level virtualization to d
script = "docker-setup.sh" script = "docker-setup.sh"
task_list = "I SS" task_list = "I SS"
[[data]]
name = "Podman"
description = "Podman is a daemon-less open platform that uses OS-level virtualization to deliver software in packages called containers."
script = "podman-setup.sh"
task_list = "I SS"
[[data]]
name = "Podman-compose"
description = "Podman Compose is a tool for defining and running multi-container applications using Podman."
script = "podman-compose-setup.sh"
task_list = "I SS"
[[data]] [[data]]
name = "DWM-Titus" name = "DWM-Titus"
description = "DWM is a dynamic window manager for X.\nIt manages windows in tiled, monocle and floating layouts.\nAll of the layouts can be applied dynamically, optimising the environment for the application in use and the task performed.\nThis command installs and configures DWM and a desktop manager.\nThe list of patches applied can be found in CTT's DWM repository\nhttps://github.com/ChrisTitusTech/dwm-titus" description = "DWM is a dynamic window manager for X.\nIt manages windows in tiled, monocle and floating layouts.\nAll of the layouts can be applied dynamically, optimising the environment for the application in use and the task performed.\nThis command installs and configures DWM and a desktop manager.\nThe list of patches applied can be found in CTT's DWM repository\nhttps://github.com/ChrisTitusTech/dwm-titus"

View File

@ -0,0 +1,60 @@
#!/bin/sh -e
. ../../common-script.sh
setUpRepos() {
if ! grep -q "^\s*\[jupiter-staging\]" /etc/pacman.conf; then
printf "%b\n" "${CYAN}Adding jupiter-staging to pacman repositories...${RC}"
echo "[jupiter-staging]" | "$ESCALATION_TOOL" tee -a /etc/pacman.conf
echo "Server = https://steamdeck-packages.steamos.cloud/archlinux-mirror/\$repo/os/\$arch" | "$ESCALATION_TOOL" tee -a /etc/pacman.conf
echo "SigLevel = Never" | "$ESCALATION_TOOL" tee -a /etc/pacman.conf
fi
if ! grep -q "^\s*\[holo-staging\]" /etc/pacman.conf; then
printf "%b\n" "${CYAN}Adding holo-staging to pacman repositories...${RC}"
echo "[holo-staging]" | "$ESCALATION_TOOL" tee -a /etc/pacman.conf
echo "Server = https://steamdeck-packages.steamos.cloud/archlinux-mirror/\$repo/os/\$arch" | "$ESCALATION_TOOL" tee -a /etc/pacman.conf
echo "SigLevel = Never" | "$ESCALATION_TOOL" tee -a /etc/pacman.conf
fi
}
installKernel() {
if ! "$PACKAGER" -Q | grep -q "\blinux-neptune"; then
printf "%b\n" "${CYAN}Installing linux-neptune..."
"$ESCALATION_TOOL" "$PACKAGER" -Syyu --noconfirm
"$ESCALATION_TOOL" "$PACKAGER" -S --noconfirm linux-neptune linux-neptune-headers steamdeck-dsp jupiter-staging/alsa-ucm-conf
"$ESCALATION_TOOL" mkinitcpio -P
else
printf "%b\n" "${GREEN}linux-neptune detected. Skipping installation.${RC}"
fi
if [ -f /etc/default/grub ]; then
printf "%b\n" "${CYAN}Updating GRUB...${RC}"
if ! grep -q '^UPDATEDEFAULT=' /etc/default/grub; then
echo 'UPDATEDEFAULT=yes' | "$ESCALATION_TOOL" tee -a /etc/default/grub
else
"$ESCALATION_TOOL" sed -i 's/^UPDATEDEFAULT=.*/UPDATEDEFAULT=yes/' /etc/default/grub
fi
if [ -f /boot/grub/grub.cfg ]; then
"$ESCALATION_TOOL" grub-mkconfig -o /boot/grub/grub.cfg
else
printf "%b\n" "${RED}GRUB configuration file not found. Run grub-mkconfig manually.${RC}"
fi
else
printf "%b\n" "${RED}GRUB not detected. Manually set your bootloader to use linux-neptune.${RC}"
fi
}
copyFirmwareFiles() {
printf "%b\n" "${CYAN}Copying firmware files...${RC}"
"$ESCALATION_TOOL" mkdir -p /usr/lib/firmware/cirrus
"$ESCALATION_TOOL" cp /usr/lib/firmware/cs35l41-dsp1-spk-cali.bin /usr/lib/firmware/cirrus/
"$ESCALATION_TOOL" cp /usr/lib/firmware/cs35l41-dsp1-spk-cali.wmfw /usr/lib/firmware/cirrus/
"$ESCALATION_TOOL" cp /usr/lib/firmware/cs35l41-dsp1-spk-prot.bin /usr/lib/firmware/cirrus/
"$ESCALATION_TOOL" cp /usr/lib/firmware/cs35l41-dsp1-spk-prot.wmfw /usr/lib/firmware/cirrus/
}
checkEnv
checkEscalationTool
setUpRepos
installKernel
copyFirmwareFiles

View File

@ -0,0 +1,120 @@
#!/bin/sh -e
. ../../common-script.sh
LIBVA_DIR="$HOME/.local/share/linutil/libva"
MPV_CONF="$HOME/.config/mpv/mpv.conf"
installDeps() {
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm base-devel dkms ninja meson git
installed_kernels=$("$PACKAGER" -Q | grep -E '^linux(| |-rt|-rt-lts|-hardened|-zen|-lts)[^-headers]' | cut -d ' ' -f 1)
for kernel in $installed_kernels; do
header="${kernel}-headers"
printf "%b\n" "${CYAN}Installing headers for $kernel...${RC}"
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm "$header"
done
}
checkNvidiaHardware() {
# Refer https://nouveau.freedesktop.org/CodeNames.html for model code names
model=$(lspci -k | grep -A 2 -E "(VGA|3D)" | grep NVIDIA | sed 's/.*Corporation //;s/ .*//' | cut -c 1-2)
case "$model" in
GM | GP | GV) return 1 ;;
TU | GA | AD) return 0 ;;
*) printf "%b\n" "${RED}Unsupported hardware." && exit 1 ;;
esac
}
checkIntelHardware() {
model=$(grep "model name" /proc/cpuinfo | head -n 1 | cut -d ':' -f 2 | cut -c 2-3)
[ "$model" -ge 11 ]
}
promptUser() {
printf "%b" "Do you want to $1 ? [y/N]:"
read -r confirm
[ "$confirm" = "y" ] || [ "$confirm" = "Y" ]
}
setKernelParam() {
PARAMETER="$1"
if grep -q "$PARAMETER" /etc/default/grub; then
printf "%b\n" "${YELLOW}NVIDIA modesetting is already enabled in GRUB.${RC}"
else
"$ESCALATION_TOOL" sed -i "/^GRUB_CMDLINE_LINUX_DEFAULT=/ s/\"$/ $PARAMETER\"/" /etc/default/grub
printf "%b\n" "${CYAN}Added $PARAMETER to /etc/default/grub.${RC}"
"$ESCALATION_TOOL" grub-mkconfig -o /boot/grub/grub.cfg
fi
}
setupHardwareAcceleration() {
if ! command_exists grub-mkconfig; then
printf "%b\n" "${RED}Currently hardware acceleration is only available with GRUB.${RC}"
return
fi
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm libva-nvidia-driver
mkdir -p "$HOME/.local/share/linutil"
if [ -d "$LIBVA_DIR" ]; then
rm -rf "$LIBVA_DIR"
fi
printf "%b\n" "${YELLOW}Cloning libva from https://github.com/intel/libva in ${LIBVA_DIR}${RC}"
git clone --branch=v2.22-branch --depth=1 https://github.com/intel/libva "$LIBVA_DIR"
mkdir -p "$LIBVA_DIR/build"
cd "$LIBVA_DIR/build" && arch-meson .. -Dwith_legacy=nvctrl && ninja
"$ESCALATION_TOOL" ninja install
"$ESCALATION_TOOL" sed -i '/^MOZ_DISABLE_RDD_SANDBOX/d' "/etc/environment"
"$ESCALATION_TOOL" sed -i '/^LIBVA_DRIVER_NAME/d' "/etc/environment"
printf "LIBVA_DRIVER_NAME=nvidia\nMOZ_DISABLE_RDD_SANDBOX=1" | "$ESCALATION_TOOL" tee -a /etc/environment >/dev/null
printf "%b\n" "${GREEN}Hardware Acceleration setup completed successfully.${RC}"
if promptUser "enable Hardware Acceleration in MPV player"; then
mkdir -p "$HOME/.config/mpv"
if [ -f "$MPV_CONF" ]; then
sed -i '/^hwdec/d' "$MPV_CONF"
fi
printf "hwdec=auto" | tee -a "$MPV_CONF" >/dev/null
printf "%b\n" "${GREEN}MPV Hardware Acceleration enabled successfully.${RC}"
fi
}
installDriver() {
# Refer https://wiki.archlinux.org/title/NVIDIA for open-dkms or dkms driver selection
if checkNvidiaHardware && promptUser "install nvidia's open source drivers"; then
printf "%b\n" "${YELLOW}Installing nvidia open source driver...${RC}"
installDeps
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm nvidia-open-dkms nvidia-utils
else
printf "%b\n" "${YELLOW}Installing nvidia proprietary driver...${RC}"
installDeps
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm nvidia-dkms nvidia-utils
fi
if checkIntelHardware; then
setKernelParam "ibt=off"
fi
# Refer https://wiki.archlinux.org/title/NVIDIA/Tips_and_tricks#Preserve_video_memory_after_suspend
setKernelParam "nvidia.NVreg_PreserveVideoMemoryAllocations=1"
"$ESCALATION_TOOL" systemctl enable nvidia-suspend.service nvidia-hibernate.service nvidia-resume.service
printf "%b\n" "${GREEN}Driver installed successfully.${RC}"
if promptUser "setup Hardware Acceleration"; then
setupHardwareAcceleration
fi
printf "%b\n" "${GREEN}Please reboot your system for the changes to take effect.${RC}"
}
checkEnv
checkEscalationTool
installDriver

View File

@ -0,0 +1,168 @@
#!/bin/sh -e
. ../../common-script.sh
# This script automates the installation and root and home snapshot configuration of Snapper and installs Grub-Btrfs on Fedora.
# Also installs python3-dnf-plugin-snapper package for automatic snapshots after dnf commands.
# Install Btrfs-Assistant/snapper and dependencies
installBtrfsStack() {
if ! command_exists btrfs-assistant; then
printf "%b\n" "${YELLOW}==========================================${RC}"
printf "%b\n" "${YELLOW}Installing Btrfs Assistant with snapper...${RC}"
printf "%b\n" "${YELLOW}==========================================${RC}"
case "$PACKAGER" in
dnf)
"$ESCALATION_TOOL" "$PACKAGER" install -y btrfs-assistant python3-dnf-plugin-snapper
;;
*)
printf "%b\n" "${RED}Unsupported package manager: ""$PACKAGER""${RC}"
exit 1
;;
esac
else
printf "%b\n" "${GREEN}Btrfs Assistant is already installed.${RC}"
fi
}
# Create first snapper config for root and home and create new manual snapshots
configureSnapper() {
printf "%b\n" "${YELLOW}===========================================================================${RC}"
printf "%b\n" "${YELLOW}Creating snapper root(/) and /home config and taking the first snapshots...${RC}"
printf "%b\n" "${YELLOW}===========================================================================${RC}"
"$ESCALATION_TOOL" snapper -c home create-config /home && "$ESCALATION_TOOL" snapper -c home create --description "First home Snapshot"
"$ESCALATION_TOOL" snapper -c root create-config / && "$ESCALATION_TOOL" snapper -c root create --description "First root Snapshot"
printf "%b\n" "${YELLOW}Updating timeline settings...${RC}"
# Modifyling default timeline root config
"$ESCALATION_TOOL" sed -i'' '
s/^TIMELINE_LIMIT_HOURLY="[^"]*"/TIMELINE_LIMIT_HOURLY="1"/;
s/^TIMELINE_LIMIT_DAILY="[^"]*"/TIMELINE_LIMIT_DAILY="2"/;
s/^TIMELINE_LIMIT_WEEKLY="[^"]*"/TIMELINE_LIMIT_WEEKLY="1"/;
s/^TIMELINE_LIMIT_MONTHLY="[^"]*"/TIMELINE_LIMIT_MONTHLY="0"/;
s/^TIMELINE_LIMIT_YEARLY="[^"]*"/TIMELINE_LIMIT_YEARLY="0"/
' /etc/snapper/configs/root
# Modifyling default timeline for home config
"$ESCALATION_TOOL" sed -i'' '
s/^TIMELINE_LIMIT_HOURLY="[^"]*"/TIMELINE_LIMIT_HOURLY="2"/;
s/^TIMELINE_LIMIT_DAILY="[^"]*"/TIMELINE_LIMIT_DAILY="1"/;
s/^TIMELINE_LIMIT_WEEKLY="[^"]*"/TIMELINE_LIMIT_WEEKLY="0"/;
s/^TIMELINE_LIMIT_MONTHLY="[^"]*"/TIMELINE_LIMIT_MONTHLY="1"/;
s/^TIMELINE_LIMIT_YEARLY="[^"]*"/TIMELINE_LIMIT_YEARLY="0"/
' /etc/snapper/configs/home
printf "%b\n" "${GREEN}Snapper configs and first snapshots created.${RC}"
}
# Starting services
serviceStartEnable() {
printf "%b\n" "${YELLOW}==================================================================================${RC}"
printf "%b\n" "${YELLOW}Starting and enabling snapper-timeline.timer and snapper-cleanup.timer services...${RC}"
printf "%b\n" "${YELLOW}==================================================================================${RC}"
"$ESCALATION_TOOL" systemctl enable --now snapper-timeline.timer
"$ESCALATION_TOOL" systemctl enable --now snapper-cleanup.timer
printf "%b\n" "${GREEN}Snapper services started and enabled.${RC}"
}
# Ask user if they want to install grub-btrfs
askInstallGrubBtrfs() {
printf "%b\n" "${YELLOW}=====================================${RC}"
printf "%b\n" "${YELLOW}(optional) grub-btrfs installation...${RC}"
printf "%b\n" "${YELLOW}=====================================${RC}"
printf "%b\n" "${YELLOW}You can skip installing grub-btrfs and use only Btrfs Assistant GUI or snapper CLI.${RC}"
printf "%b\n" "${CYAN}Notice: grub-btrfs may cause problems with booting into snapshots and other OSes on systems with secure boot/tpm. You will be asked to apply mitigation for this issue in next step.${RC}"
while true; do
printf "%b" "${YELLOW}Do you want to install grub-btrfs? Press (y) for yes, (n) for no, (f) to apply tpm mitigation to already installed grub-btrfs: ${RC}"
read -r response
case "$response" in
[yY]*)
installGrubBtrfs
break
;;
[nN]*)
printf "%b\n" "${GREEN}Skipping grub-btrfs installation.${RC}"
break
;;
[fF]*)
mitigateTpmError
break
;;
*)
printf "%b\n" "${RED}Invalid input. Please enter 'y' for yes, 'n' for no, or (f) to apply tpm mitigation to already installed grub-btrfs.${RC}"
;;
esac
done
}
# Install grub-btrfs
installGrubBtrfs() {
# Check if the grub-btrfs dir exists before attempting to clone into it.
printf "%b\n" "${YELLOW}Downloading grub-btrfs and installing dependencies...${RC}"
if [ -d "$HOME/grub-btrfs" ]; then
rm -rf "$HOME/grub-btrfs"
fi
"$ESCALATION_TOOL" "$PACKAGER" install -y make git inotify-tools
cd "$HOME" && git clone https://github.com/Antynea/grub-btrfs
printf "%b\n" "${YELLOW}Installing grub-btrfs...${RC}"
cd "$HOME/grub-btrfs"
printf "%b\n" "${YELLOW}Modifying grub-btrfs configuration for Fedora...${RC}"
sed -i'' '/#GRUB_BTRFS_SNAPSHOT_KERNEL/a GRUB_BTRFS_SNAPSHOT_KERNEL_PARAMETERS="systemd.volatile=state"' config
sed -i'' '/#GRUB_BTRFS_GRUB_DIRNAME/a GRUB_BTRFS_GRUB_DIRNAME="/boot/grub2"' config
sed -i'' '/#GRUB_BTRFS_MKCONFIG=/a GRUB_BTRFS_MKCONFIG=/sbin/grub2-mkconfig' config
sed -i'' '/#GRUB_BTRFS_SCRIPT_CHECK=/a GRUB_BTRFS_SCRIPT_CHECK=grub2-script-check' config
"$ESCALATION_TOOL" make install
printf "%b\n" "${YELLOW}Updating grub configuration and enabling grub-btrfsd service...${RC}"
"$ESCALATION_TOOL" grub2-mkconfig -o /boot/grub2/grub.cfg && "$ESCALATION_TOOL" systemctl enable --now grub-btrfsd.service
printf "%b\n" "${YELLOW}Cleaning up installation files...${RC}"
cd .. && rm -rf "$HOME/grub-btrfs"
printf "%b\n" "${GREEN}Grub-btrfs installed and service enabled.${RC}"
printf "%b\n" "${CYAN}Notice: To perform a system recovery via grub-btrfs, perform a restore operation with Btrfs Assistant GUI after booting into the snapshot.${RC}"
mitigateTpmError
}
mitigateTpmError() {
printf "%b\n" "${YELLOW}===============================================${RC}"
printf "%b\n" "${YELLOW}Mitigation for 'tpm.c:150:unknown TPM error'...${RC}"
printf "%b\n" "${YELLOW}===============================================${RC}"
printf "%b\n" "${YELLOW}Some systems with secure boot/tpm may encounter 'tpm.c:150:unknown TPM error' when booting into snapshots.${RC}"
printf "%b\n" "${YELLOW}If you encounter this issue, you can come back later and apply this mitigation or you can apply it now.${RC}"
while true; do
printf "%b\n" "${YELLOW}Do you want to apply the TPM error mitigation? (y/n): ${RC}"
read -r response
case "$response" in
[yY]*)
printf "%b\n" "${YELLOW}Creating /etc/grub.d/02_tpm file...${RC}"
echo '#!/bin/sh' | "$ESCALATION_TOOL" tee /etc/grub.d/02_tpm > /dev/null
echo 'echo "rmmod tpm"' | "$ESCALATION_TOOL" tee -a /etc/grub.d/02_tpm > /dev/null
"$ESCALATION_TOOL" chmod +x /etc/grub.d/02_tpm # makes the file executable
"$ESCALATION_TOOL" grub2-mkconfig -o /boot/grub2/grub.cfg # updates grub config
printf "%b\n" "${GREEN}Mitigation applied and grub config updated.${RC}"
break
;;
[nN]*)
printf "%b\n" "${GREEN}Skipping TPM error mitigation.${RC}"
break
;;
*)
printf "%b\n" "${RED}Invalid input. Please enter 'y' for yes or 'n' for no.${RC}"
;;
esac
done
}
# Post install information
someNotices() {
printf "%b\n" "${YELLOW}================================NOTICES================================${RC}"
printf "%b\n" "${YELLOW}Notice: You can manage snapshots from GUI with Btrfs Assistant or CLI with snapper.${RC}"
printf "%b\n" "${YELLOW}Notice: You may change (Hourly, daily, weekly, monthly, yearly) timeline settings with Btrfs Assistant GUI.${RC}"
printf "%b\n" "${RED}Notice: If you used the default Fedora disk partitioning during OS installation, the /boot configured as an separate EXT4 partition. Therefore, it cannot be included in root snapshots. Backup separately...${RC}"
printf "%b\n" "${YELLOW}================================NOTICES================================${RC}"
printf "%b\n" "${GREEN}Setup process completed.${RC}"
}
checkEnv
checkEscalationTool
installBtrfsStack
configureSnapper
serviceStartEnable
askInstallGrubBtrfs
someNotices

View File

@ -15,6 +15,23 @@ script = "arch/server-setup.sh"
task_list = "SI D" task_list = "SI D"
multi_select = false multi_select = false
[[data.entries]]
name ="Linux Neptune for SteamDeck"
description = "Valve's fork of Linux Kernel for the SteamDeck"
script = "arch/linux-neptune.sh"
task_list = "I PFM K"
[[data.entries.preconditions]]
matches = true
data = { file = "/sys/devices/virtual/dmi/id/board_vendor" }
values = [ "Valve" ]
[[data.entries]]
name = "Nvidia Drivers && Hardware Acceleration"
description = "This script installs and configures nvidia drivers with Hardware Acceleration."
script = "arch/nvidia-drivers.sh"
task_list = "I FM SS"
[[data.entries]] [[data.entries]]
name = "Paru AUR Helper" name = "Paru AUR Helper"
description = "Paru is your standard pacman wrapping AUR helper with lots of features and minimal interaction. To know more about AUR helpers visit: https://wiki.archlinux.org/title/AUR_helpers" description = "Paru is your standard pacman wrapping AUR helper with lots of features and minimal interaction. To know more about AUR helpers visit: https://wiki.archlinux.org/title/AUR_helpers"
@ -71,6 +88,17 @@ description = "Enables Virtualization through dnf"
script = "fedora/virtualization.sh" script = "fedora/virtualization.sh"
task_list = "I" task_list = "I"
[[data.entries]]
name = "Btrfs Assistant, Snapper Config, grub-btrfs"
description = "Installs Btrfs Assistant, Snapper, dnf snapper plugin and takes the first root(/) and /home snapshots. Enables snapper-timeline and snapper-cleanup services. Installs Grub-Btrfs. Notice: To perform a system recovery via grub-btrfs, perform a restore operation with Btrfs Assistant GUI after booting into the snapshot. Notice: If you used the default Fedora disk partitioning during OS installation, the /boot configured as an separate EXT4 partition. Therefore, it cannot be included in root snapshots. Backup separately."
script = "fedora/fedora-btrfs-assistant.sh"
task_list = "I PFM SS"
[[data.preconditions]]
matches = true
data = "command_exists"
values = [ "btrfs" ]
[[data]] [[data]]
name = "Build Prerequisites" name = "Build Prerequisites"
description = "This script is designed to handle the installation of various software dependencies across different Linux distributions" description = "This script is designed to handle the installation of various software dependencies across different Linux distributions"

View File

@ -2,11 +2,6 @@
. ../common-script.sh . ../common-script.sh
# setleds can be used in all distros
# This method works by calling a script using systemd service
# Create a script to toggle numlock
create_file() { create_file() {
printf "%b\n" "Creating script..." printf "%b\n" "Creating script..."
"$ESCALATION_TOOL" tee "/usr/local/bin/numlock" >/dev/null <<'EOF' "$ESCALATION_TOOL" tee "/usr/local/bin/numlock" >/dev/null <<'EOF'
@ -21,7 +16,6 @@ EOF
"$ESCALATION_TOOL" chmod +x /usr/local/bin/numlock "$ESCALATION_TOOL" chmod +x /usr/local/bin/numlock
} }
# Create a systemd service to run the script on boot
create_service() { create_service() {
printf "%b\n" "Creating service..." printf "%b\n" "Creating service..."
"$ESCALATION_TOOL" tee "/etc/systemd/system/numlock.service" >/dev/null <<'EOF' "$ESCALATION_TOOL" tee "/etc/systemd/system/numlock.service" >/dev/null <<'EOF'
@ -39,7 +33,6 @@ EOF
} }
numlockSetup() { numlockSetup() {
# Check if the script and service files exists
if [ ! -f "/usr/local/bin/numlock" ]; then if [ ! -f "/usr/local/bin/numlock" ]; then
create_file create_file
fi fi

View File

@ -136,7 +136,7 @@ task_list = "I FM"
[[data]] [[data]]
name = "Numlock on Startup" name = "Numlock on Startup"
description = "This utility is designed to configure auto enabling of numlock on boot" description = "This utility is designed to enable Num Lock at boot, rather than within desktop environments like KDE or GNOME"
script = "numlock.sh" script = "numlock.sh"
task_list = "PFM SS" task_list = "PFM SS"

View File

@ -13,7 +13,7 @@
## Milestones ## Milestones
### Q4 2024 ### Q4 2024
- [x] Finish the foundation of the project's CLI - [x] Finish the foundation of the project's CLI
- [ ] Implement CLI arguments and configuration support - [x] Implement CLI arguments and configuration support
- [ ] Add an option for logging script executions - [ ] Add an option for logging script executions
### Q1 2025 ### Q1 2025

View File

@ -56,6 +56,9 @@ All of the layouts can be applied dynamically, optimising the environment for th
This command installs and configures DWM and a desktop manager. This command installs and configures DWM and a desktop manager.
The list of patches applied can be found in CTT's DWM repository The list of patches applied can be found in CTT's DWM repository
https://github.com/ChrisTitusTech/dwm-titus https://github.com/ChrisTitusTech/dwm-titus
- **Docker**: Docker is an open platform that uses OS-level virtualization to deliver software in packages called containers.
- **Podman**: Podman is a daemon-less open platform that uses OS-level virtualization to deliver software in packages called containers.
- **Podman-compose**: Podman Compose is a tool for defining and running multi-container applications using Podman.
- **Fastfetch**: Fastfetch is a neofetch-like tool for fetching system information and displaying it prettily. It is written mainly in C, with performance and customizability in mind. This command installs fastfetch and configures from CTT's mybash repository. https://github.com/ChrisTitusTech/mybash - **Fastfetch**: Fastfetch is a neofetch-like tool for fetching system information and displaying it prettily. It is written mainly in C, with performance and customizability in mind. This command installs fastfetch and configures from CTT's mybash repository. https://github.com/ChrisTitusTech/mybash
- **Flatpak / Flathub**: Flatpak is a universal application sandbox for Linux that uses isolated packages from Flathub to prevent conflicts and system alterations, while alleviating dependency concerns. This command installs Flatpak and adds the Flathub repository - **Flatpak / Flathub**: Flatpak is a universal application sandbox for Linux that uses isolated packages from Flathub to prevent conflicts and system alterations, while alleviating dependency concerns. This command installs Flatpak and adds the Flathub repository
- **Grub Theme**: Installs ChrisTitusTech's Top 5 Bootloader Themes script to allow for easy customization of GRUB. - **Grub Theme**: Installs ChrisTitusTech's Top 5 Bootloader Themes script to allow for easy customization of GRUB.
@ -83,6 +86,8 @@ https://github.com/ChrisTitusTech/dwm-titus
### Arch Linux ### Arch Linux
- **Arch Server Setup**: This command installs a minimal arch server setup under 5 minutes. - **Arch Server Setup**: This command installs a minimal arch server setup under 5 minutes.
- **Linux Neptune for SteamDeck**: Valve's fork of Linux Kernel for the SteamDeck
- **Nvidia Drivers && Hardware Acceleration**: This script installs and configures nvidia drivers with Hardware Acceleration.
- **Paru AUR Helper**: Paru is your standard pacman wrapping AUR helper with lots of features and minimal interaction. To know more about AUR helpers visit: https://wiki.archlinux.org/title/AUR_helpers - **Paru AUR Helper**: Paru is your standard pacman wrapping AUR helper with lots of features and minimal interaction. To know more about AUR helpers visit: https://wiki.archlinux.org/title/AUR_helpers
- **Yay AUR Helper**: Yet Another Yogurt - An AUR Helper Written in Go. To know more about AUR helpers visit: https://wiki.archlinux.org/title/AUR_helpers - **Yay AUR Helper**: Yet Another Yogurt - An AUR Helper Written in Go. To know more about AUR helpers visit: https://wiki.archlinux.org/title/AUR_helpers
@ -94,6 +99,7 @@ https://github.com/ChrisTitusTech/dwm-titus
- **RPM Fusion**: RPM Fusion provides software that the Fedora Project or Red Hat doesn't want to ship. That software is provided as precompiled RPMs for all current Fedora versions and current Red Hat Enterprise Linux or clones versions; you can use the RPM Fusion repositories with tools like yum and PackageKit. For more information visit: https://rpmfusion.org/ - **RPM Fusion**: RPM Fusion provides software that the Fedora Project or Red Hat doesn't want to ship. That software is provided as precompiled RPMs for all current Fedora versions and current Red Hat Enterprise Linux or clones versions; you can use the RPM Fusion repositories with tools like yum and PackageKit. For more information visit: https://rpmfusion.org/
- **Upgrade to a New Fedora Release**: Upgrades system to the next Fedora release - **Upgrade to a New Fedora Release**: Upgrades system to the next Fedora release
- **Virtualization**: Enables Virtualization through dnf - **Virtualization**: Enables Virtualization through dnf
- **Btrfs Assistant, Snapper Config, grub-btrfs**: Installs Btrfs Assistant, Snapper, dnf snapper plugin and takes the first root(/) and /home snapshots. Enables snapper-timeline and snapper-cleanup services. Installs Grub-Btrfs. Notice: To perform a system recovery via grub-btrfs, perform a restore operation with Btrfs Assistant GUI after booting into the snapshot. Notice: If you used the default Fedora disk partitioning during OS installation, the /boot configured as an separate EXT4 partition. Therefore, it cannot be included in root snapshots. Backup separately.
- **Build Prerequisites**: This script is designed to handle the installation of various software dependencies across different Linux distributions - **Build Prerequisites**: This script is designed to handle the installation of various software dependencies across different Linux distributions
- **Full System Cleanup**: This script is designed to remove unnecessary packages, clean old cache files, remove temporary files, and to empty the trash. - **Full System Cleanup**: This script is designed to remove unnecessary packages, clean old cache files, remove temporary files, and to empty the trash.
- **Full System Update**: This command updates your system to the latest packages available for your distro - **Full System Update**: This command updates your system to the latest packages available for your distro
@ -124,7 +130,7 @@ https://github.com/ChrisTitusTech/dwm-titus
- **Auto Mount Drive**: This utility is designed to help with automating the process of mounting a drive on to your system. - **Auto Mount Drive**: This utility is designed to help with automating the process of mounting a drive on to your system.
- **Bluetooth Manager**: This utility is designed to manage bluetooth in your system - **Bluetooth Manager**: This utility is designed to manage bluetooth in your system
- **Numlock on Startup**: This utility is designed to configure auto enabling of numlock on boot - **Numlock on Startup**: This utility is designed to enable Num Lock at boot, rather than within desktop environments like KDE or GNOME
- **Ollama**: This utility is designed to manage ollama in your system - **Ollama**: This utility is designed to manage ollama in your system
- **Service Manager**: This utility is designed to manage services in your system - **Service Manager**: This utility is designed to manage services in your system
- **WiFi Manager**: This utility is designed to manage wifi in your system - **WiFi Manager**: This utility is designed to manage wifi in your system

View File

@ -22,6 +22,10 @@ curl -fsSL https://christitus.com/linux | sh
curl -fsSL https://christitus.com/linuxdev | sh curl -fsSL https://christitus.com/linuxdev | sh
.SH OPTIONS .SH OPTIONS
.TP
\fB\-c\fR, \fB\-\-config\fR \fI<path>\fR
Path to the configuration file.
.TP .TP
\fB\-t\fR, \fB\-\-theme\fR \fI<theme>\fR \fB\-t\fR, \fB\-\-theme\fR \fI<theme>\fR
Set the theme to use in the TUI. Set the theme to use in the TUI.

View File

@ -15,7 +15,6 @@ tips = ["rand"]
[dependencies] [dependencies]
clap = { version = "4.5.20", features = ["derive"] } clap = { version = "4.5.20", features = ["derive"] }
crossterm = "0.28.1"
ego-tree = { workspace = true } ego-tree = { workspace = true }
oneshot = "0.1.8" oneshot = "0.1.8"
portable-pty = "0.8.1" portable-pty = "0.8.1"

View File

@ -2,8 +2,8 @@ use std::borrow::Cow;
use crate::{float::FloatContent, hint::Shortcut}; use crate::{float::FloatContent, hint::Shortcut};
use crossterm::event::{KeyCode, KeyEvent};
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent},
layout::Alignment, layout::Alignment,
prelude::*, prelude::*,
widgets::{Block, Borders, Clear, List}, widgets::{Block, Borders, Clear, List},

View File

@ -1,8 +1,8 @@
use crate::{state::ListEntry, theme::Theme}; use crate::{state::ListEntry, theme::Theme};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use ego_tree::NodeId; use ego_tree::NodeId;
use linutil_core::Tab; use linutil_core::Tab;
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent, KeyModifiers},
layout::{Position, Rect}, layout::{Position, Rect},
style::{Color, Style}, style::{Color, Style},
text::Span, text::Span,

View File

@ -1,5 +1,5 @@
use crossterm::event::{KeyCode, KeyEvent};
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent},
layout::{Constraint, Direction, Layout, Rect}, layout::{Constraint, Direction, Layout, Rect},
Frame, Frame,
}; };

View File

@ -8,9 +8,8 @@ use crate::{float::FloatContent, hint::Shortcut};
use linutil_core::Command; use linutil_core::Command;
use crossterm::event::{KeyCode, KeyEvent};
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent},
layout::Rect, layout::Rect,
style::{Style, Stylize}, style::{Style, Stylize},
text::Line, text::Line,

View File

@ -9,23 +9,30 @@ mod theme;
use std::{ use std::{
io::{self, stdout}, io::{self, stdout},
path::PathBuf,
time::Duration, time::Duration,
}; };
use crate::theme::Theme; use crate::theme::Theme;
use clap::Parser; use clap::Parser;
use crossterm::{
event::{self, DisableMouseCapture, Event, KeyEventKind}, use ratatui::{
style::ResetColor, backend::CrosstermBackend,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, crossterm::{
ExecutableCommand, event::{self, DisableMouseCapture, Event, KeyEventKind},
style::ResetColor,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
},
Terminal,
}; };
use ratatui::{backend::CrosstermBackend, Terminal};
use state::AppState; use state::AppState;
// Linux utility toolbox // Linux utility toolbox
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
struct Args { struct Args {
#[arg(short, long, help = "Path to the configuration file")]
config: Option<PathBuf>,
#[arg(short, long, value_enum)] #[arg(short, long, value_enum)]
#[arg(default_value_t = Theme::Default)] #[arg(default_value_t = Theme::Default)]
#[arg(help = "Set the theme to use in the application")] #[arg(help = "Set the theme to use in the application")]
@ -41,7 +48,12 @@ struct Args {
fn main() -> io::Result<()> { fn main() -> io::Result<()> {
let args = Args::parse(); let args = Args::parse();
let mut state = AppState::new(args.theme, args.override_validation, args.size_bypass); let mut state = AppState::new(
args.config,
args.theme,
args.override_validation,
args.size_bypass,
);
stdout().execute(EnterAlternateScreen)?; stdout().execute(EnterAlternateScreen)?;
enable_raw_mode()?; enable_raw_mode()?;

View File

@ -1,11 +1,11 @@
use crate::{float::FloatContent, hint::Shortcut}; use crate::{float::FloatContent, hint::Shortcut};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use linutil_core::Command; use linutil_core::Command;
use oneshot::{channel, Receiver}; use oneshot::{channel, Receiver};
use portable_pty::{ use portable_pty::{
ChildKiller, CommandBuilder, ExitStatus, MasterPty, NativePtySystem, PtySize, PtySystem, ChildKiller, CommandBuilder, ExitStatus, MasterPty, NativePtySystem, PtySize, PtySystem,
}; };
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent, KeyModifiers},
layout::{Rect, Size}, layout::{Rect, Size},
style::{Color, Style, Stylize}, style::{Color, Style, Stylize},
text::{Line, Span}, text::{Line, Span},

View File

@ -7,20 +7,20 @@ use crate::{
running_command::RunningCommand, running_command::RunningCommand,
theme::Theme, theme::Theme,
}; };
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
use ego_tree::NodeId; use ego_tree::NodeId;
use linutil_core::{ListNode, Tab}; use linutil_core::{Config, ListNode, TabList};
#[cfg(feature = "tips")] #[cfg(feature = "tips")]
use rand::Rng; use rand::Rng;
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers},
layout::{Alignment, Constraint, Direction, Flex, Layout}, layout::{Alignment, Constraint, Direction, Flex, Layout},
style::{Style, Stylize}, style::{Style, Stylize},
text::{Line, Span, Text}, text::{Line, Span, Text},
widgets::{Block, Borders, List, ListState, Paragraph}, widgets::{Block, Borders, List, ListState, Paragraph},
Frame, Frame,
}; };
use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use temp_dir::TempDir;
const MIN_WIDTH: u16 = 100; const MIN_WIDTH: u16 = 100;
const MIN_HEIGHT: u16 = 25; const MIN_HEIGHT: u16 = 25;
@ -31,6 +31,7 @@ D - disk modifications (ex. partitioning) (privileged)
FI - flatpak installation FI - flatpak installation
FM - file modification FM - file modification
I - installation (privileged) I - installation (privileged)
K - kernel modifications (privileged)
MP - package manager actions MP - package manager actions
SI - full system installation SI - full system installation
SS - systemd actions (privileged) SS - systemd actions (privileged)
@ -40,14 +41,12 @@ P* - privileged *
"; ";
pub struct AppState { pub struct AppState {
/// This must be passed to retain the temp dir until the end of the program
_temp_dir: TempDir,
/// Selected theme /// Selected theme
theme: Theme, theme: Theme,
/// Currently focused area /// Currently focused area
pub focus: Focus, pub focus: Focus,
/// List of tabs /// List of tabs
tabs: Vec<Tab>, tabs: TabList,
/// Current tab /// Current tab
current_tab: ListState, current_tab: ListState,
/// This stack keeps track of our "current directory". You can think of it as `pwd`. but not /// This stack keeps track of our "current directory". You can think of it as `pwd`. but not
@ -87,12 +86,18 @@ enum SelectedItem {
} }
impl AppState { impl AppState {
pub fn new(theme: Theme, override_validation: bool, size_bypass: bool) -> Self { pub fn new(
let (temp_dir, tabs) = linutil_core::get_tabs(!override_validation); config_path: Option<PathBuf>,
theme: Theme,
override_validation: bool,
size_bypass: bool,
) -> Self {
let tabs = linutil_core::get_tabs(!override_validation);
let root_id = tabs[0].tree.root().id(); let root_id = tabs[0].tree.root().id();
let auto_execute_commands = config_path.map(|path| Config::from_file(&path).auto_execute);
let mut state = Self { let mut state = Self {
_temp_dir: temp_dir,
theme, theme,
focus: Focus::List, focus: Focus::List,
tabs, tabs,
@ -109,9 +114,31 @@ impl AppState {
}; };
state.update_items(); state.update_items();
if let Some(auto_execute_commands) = auto_execute_commands {
state.handle_initial_auto_execute(&auto_execute_commands);
}
state state
} }
fn handle_initial_auto_execute(&mut self, auto_execute_commands: &[String]) {
self.selected_commands = auto_execute_commands
.iter()
.filter_map(|name| self.tabs.iter().find_map(|tab| tab.find_command(name)))
.collect();
if !self.selected_commands.is_empty() {
let cmd_names: Vec<_> = self
.selected_commands
.iter()
.map(|node| node.name.as_str())
.collect();
let prompt = ConfirmPrompt::new(&cmd_names);
self.focus = Focus::ConfirmationPrompt(Float::new(Box::new(prompt), 40, 40));
}
}
fn get_list_item_shortcut(&self) -> Box<[Shortcut]> { fn get_list_item_shortcut(&self) -> Box<[Shortcut]> {
if self.selected_item_is_dir() { if self.selected_item_is_dir() {
Box::new([Shortcut::new("Go to selected dir", ["l", "Right", "Enter"])]) Box::new([Shortcut::new("Go to selected dir", ["l", "Right", "Enter"])])

View File

@ -11,7 +11,7 @@ pub fn userguide() -> Result<String, DynError> {
let mut md = String::new(); let mut md = String::new();
md.push_str("<!-- THIS FILE IS GENERATED BY cargo xtask docgen -->\n# Walkthrough\n"); md.push_str("<!-- THIS FILE IS GENERATED BY cargo xtask docgen -->\n# Walkthrough\n");
let tabs = linutil_core::get_tabs(false).1; let tabs = linutil_core::get_tabs(false);
for tab in tabs { for tab in tabs {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
@ -24,7 +24,7 @@ pub fn userguide() -> Result<String, DynError> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
println!(" Directory: {}", entry.name); println!(" Directory: {}", entry.name);
if entry.name != "root".to_string() { if entry.name != "root" {
md.push_str(&format!("\n### {}\n\n", entry.name)); md.push_str(&format!("\n### {}\n\n", entry.name));
} }
@ -36,18 +36,16 @@ pub fn userguide() -> Result<String, DynError> {
current_dir current_dir
)); ));
} */ // Commenting this for now, might be a good idea later } */ // Commenting this for now, might be a good idea later
} else { } else if !entry.description.is_empty() {
if !entry.description.is_empty() { #[cfg(debug_assertions)]
#[cfg(debug_assertions)] println!(" Entry: {}", entry.name);
println!(" Entry: {}", entry.name); #[cfg(debug_assertions)]
#[cfg(debug_assertions)] println!(" Description: {}", entry.description);
println!(" Description: {}", entry.description);
md.push_str(&format!("- **{}**: {}\n", entry.name, entry.description)); md.push_str(&format!("- **{}**: {}\n", entry.name, entry.description));
} /* else { } /* else {
md.push_str(&format!("- **{}**\n", entry.name)); md.push_str(&format!("- **{}**\n", entry.name));
} */ // https://github.com/ChrisTitusTech/linutil/pull/753 } */ // https://github.com/ChrisTitusTech/linutil/pull/753
}
} }
} }