commit 8571dd64f07a29c5f46b8d3cbce6bb8fdaa39010 Author: amy Date: Tue Nov 30 20:22:34 2021 +0100 initial commit diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..94f09d5 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,115 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "libc" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "nix" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "pkg-config" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" + +[[package]] +name = "pkg-warner" +version = "0.1.0" +dependencies = [ + "nix", + "sqlite", + "toml", +] + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" + +[[package]] +name = "sqlite" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1a534c07ec276fbbe0e55a1c00814d8563da3a2f4d9d9d4c802bd1278db6a" +dependencies = [ + "libc", + "sqlite3-sys", +] + +[[package]] +name = "sqlite3-src" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a260b07ce75a0644c6f5891f34f46db9869e731838e95293469ab17999abcfa3" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "sqlite3-sys" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04d2f028faeb14352df7934b4771806f60d61ce61be1928ec92396d7492e2e54" +dependencies = [ + "libc", + "sqlite3-src", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..bf467d1 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "pkg-warner" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +toml = "*" +sqlite = "*" +nix = "*" \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8189bf5 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +debug: + cargo build + ln -sf target/debug/pkg-warner . +release: + cargo build --release + ln -sf target/release/pkg-warner . +clean: + rm -rf target/ Cargo.lock pkg-warner +install: + cargo build --release + sudo cp target/release/pkg-warner /usr/bin/pkg-warner + sudo touch /etc/package_managers.toml diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b6720c5 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,174 @@ +use toml::{Value, toml}; +use std::{fs, env}; +use std::io::Write; + +pub fn help() { + println!("Usage: + -h, help: Show this help message + -v, version: Show version + -i, init: Initialize the database + -c, create-script: create the scripts for the warnings + -w , warning : Show the warning for specified package manager + "); +} + +pub fn create_database() { + let homepath = env::var("HOME").unwrap(); + let file = "/usr/share/pkg_warner/pkg_mngrs.db".to_string(); + if !std::path::Path::new(&"/usr/share/pkg_warner/").is_dir() { + let _cdar = fs::create_dir_all("/usr/share/pkg_warner/".to_string()); + match _cdar { + Ok(_) => { + println!("Created path for database (previously missing)"); + } + Err(_) => { + println!("Couldn't create path for database (/usr/share/pkg_warner)") + } + } + } + let connection = sqlite::open(file).unwrap(); + let result = connection + .execute( + " + CREATE TABLE pkg_mngrs (mngr TEXT, distro TEXT); + ", + ); + match result { + Ok(_) => { + println!("Created database"); + } + Err(_) => { + println!("Couldn't create database"); + } + } +} + +pub fn add_mngrs(pkg_managers: Vec>, proper_manager: String) { + let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db".to_string()).unwrap(); + for entry in pkg_managers { + println!("Don't use {}! {} is used on {}, here you use {}!", entry[0], entry[0], entry[1], proper_manager); + let result = connection.execute(format!( + " + INSERT INTO pkg_mngrs (mngr, distro) VALUES (\"{}\", \"{}\"); + ", entry[0], entry[1] + )); + match result { + Ok(_) => { + println!("Added {} to database", entry[0]); + } + Err(_) => { + println!("Couldn't add {} to database", entry[0]); + } + } + } +} + +pub fn create_script() { + let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db").unwrap(); + let result = connection.iterate( + format!("SELECT mngr FROM pkg_mngrs WHERE mngr IS NOT \"proper_manager\";"), + |pairs| { + for &(_column, value) in pairs.iter() { + writeln!(&mut fs::File::create(format!("/usr/bin/{}",value.unwrap())).unwrap(), "#!/usr/bin/env bash\n pkg-warner -w {}", value.unwrap()).unwrap(); + } + true + }, + ); + match result { + Ok(_) => {} + Err(_) => println!("Couldn't get value from database"), + } + +} + +pub fn warn(proper_manager: String, package_manager: String) { + let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db".to_string()).unwrap(); + let mut warned = false; + let result = connection.iterate( + format!("SELECT distro FROM pkg_mngrs WHERE mngr = \"{}\";", package_manager), + |pairs| { + for &(_column, value) in pairs.iter() { + if !warned { + println!("{} is used on {}! Please use {} instead!", package_manager, value.unwrap(), proper_manager); + warned = true; + } + } + true + }, + ); + match result { + Ok(_) => {} + Err(_) => println!("Couldn't get value from database"), + } +} + +fn main() { + + let args: Vec = env::args().skip(1).collect(); + if args.is_empty() { + help(); + return; + } + + let oper = &args[0]; + + if !nix::unistd::Uid::effective().is_root() && oper != "-w" { + println!("You need to be root to run this program"); + return; + } + + let file = "/usr/share/pkg_warner/pkg_mngrs.db".to_string(); + if !std::path::Path::new(&file).exists() { + create_database(); + } + + let file = format!("/etc/package_managers.toml"); + let mut database = String::new(); + database = fs::read_to_string(file).expect("Unable to read file"); + let db_parsed = database.parse::().expect("Unable to parse database"); + let mut pkg_managers: Vec> = Vec::new(); + for entry in db_parsed.as_table() { + for (key, value) in &*entry { + let mut tempvec = Vec::new(); + tempvec.push(key.to_string()); + tempvec.push(value.to_string().replace("distro = ", "").replace("\n","").replace("\"","")); + pkg_managers.push(tempvec); + } + } + + let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db").unwrap(); + let mut proper_manager = String::new(); + let mut found = false; + let result = connection.iterate( + format!("SELECT distro FROM pkg_mngrs WHERE mngr = \"proper_manager\";"), + |pairs| { + for &(_column, value) in pairs.iter() { + if !found { + proper_manager.push_str(value.unwrap()); + found = true; + } + } + true + }, + ); + + match oper.as_str() { + "-i" | "init" => { + create_database(); + add_mngrs(pkg_managers, proper_manager); + create_script(); + } + "-a" | "add" => { + add_mngrs(pkg_managers, proper_manager); + } + "-c" | "create-script" => { + create_script(); + } + "-w" | "warning" => { + warn(proper_manager, args[1].to_string()); + } + _ => { + help(); + } + } +} \ No newline at end of file