@@ -2,45 +2,47 @@ use std::process::{Command, ExitStatus};
22use std:: env;
33use std:: os:: unix:: fs:: PermissionsExt ;
44
5- const DNF_PATH : & str = "/usr/lib/HackerOS/dnf " ;
5+ const APT_PATH : & str = "/usr/lib/HackerOS/apt " ;
66
77fn print_help ( ) {
8- println ! ( "hacker: A simple package management tool" ) ;
8+ println ! ( "hacker: A simple package management tool for Ubuntu " ) ;
99 println ! ( "Usage: hacker <command> [arguments]" ) ;
1010 println ! ( "\n Available commands:" ) ;
11- println ! ( " autoremove Remove unneeded packages" ) ;
12- println ! ( " install <packages> Install one or more packages" ) ;
13- println ! ( " remove <packages> Remove one or more packages" ) ;
14- println ! ( " list List installed packages" ) ;
15- println ! ( " search <term> Search for packages" ) ;
16- println ! ( " clean Clean package cache" ) ;
17- println ! ( " info <package> Show package information" ) ;
18- println ! ( " repolist List enabled repositories" ) ;
19- println ! ( " copr-enable <repo> Enable a COPR repository" ) ;
20- println ! ( " copr-disable <repo> Disable a COPR repository" ) ;
21- println ! ( " ? Show this help message" ) ;
11+ println ! ( " autoremove Remove unneeded packages" ) ;
12+ println ! ( " install Install one or more packages" ) ;
13+ println ! ( " remove Remove one or more packages" ) ;
14+ println ! ( " purge Remove one or more packages and their configuration files" ) ;
15+ println ! ( " list List installed packages" ) ;
16+ println ! ( " list-available List all available packages" ) ;
17+ println ! ( " list-upgradable List packages that can be upgraded" ) ;
18+ println ! ( " search Search for packages" ) ;
19+ println ! ( " clean Clean package cache" ) ;
20+ println ! ( " show Show package information" ) ;
21+ println ! ( " hold Prevent a package from being upgraded" ) ;
22+ println ! ( " unhold Allow a package to be upgraded" ) ;
23+ println ! ( " repolist List enabled repositories" ) ;
24+ println ! ( " ? Show this help message" ) ;
2225 println ! ( "\n Note: Use 'hacker-update' for system updates and upgrades." ) ;
2326}
2427
25- fn execute_dnf ( args : Vec < & str > , use_sudo : bool ) -> Result < ExitStatus , String > {
28+ fn execute_apt ( args : Vec < & str > , use_sudo : bool ) -> Result < ExitStatus , String > {
2629 let mut command = if use_sudo {
2730 let mut cmd = Command :: new ( "sudo" ) ;
28- cmd. arg ( DNF_PATH ) ;
31+ cmd. arg ( APT_PATH ) ;
2932 cmd
3033 } else {
31- Command :: new ( DNF_PATH )
34+ Command :: new ( APT_PATH )
3235 } ;
33-
3436 let output = command
35- . args ( & args)
36- . status ( )
37- . map_err ( |e| format ! ( "Failed to execute dnf : {}" , e) ) ?;
37+ . args ( & args)
38+ . status ( )
39+ . map_err ( |e| format ! ( "Failed to execute apt : {}" , e) ) ?;
3840 Ok ( output)
3941}
4042
4143fn can_run_without_sudo ( ) -> bool {
42- // Check if user has write permissions to /usr/lib/HackerOS/dnf
43- if let Ok ( metadata) = std:: fs:: metadata ( DNF_PATH ) {
44+ // Check if user has write permissions to /usr/lib/HackerOS/apt
45+ if let Ok ( metadata) = std:: fs:: metadata ( APT_PATH ) {
4446 let permissions = metadata. permissions ( ) ;
4547 let mode = permissions. mode ( ) ;
4648 // Check if executable and writable by user or group
@@ -57,13 +59,12 @@ fn main() {
5759 print_help ( ) ;
5860 std:: process:: exit ( 1 ) ;
5961 }
60-
6162 let command = & args[ 1 ] ;
6263 let use_sudo = !can_run_without_sudo ( ) ;
6364
6465 match command. as_str ( ) {
6566 "autoremove" => {
66- match execute_dnf ( vec ! [ "autoremove" , "-y" ] , use_sudo) {
67+ match execute_apt ( vec ! [ "autoremove" , "-y" ] , use_sudo) {
6768 Ok ( status) if status. success ( ) => println ! ( "Autoremove completed successfully" ) ,
6869 Ok ( _) => println ! ( "Autoremove failed" ) ,
6970 Err ( e) => println ! ( "Error: {}" , e) ,
@@ -75,9 +76,9 @@ fn main() {
7576 std:: process:: exit ( 1 ) ;
7677 }
7778 let packages = & args[ 2 ..] ;
78- let mut dnf_args = vec ! [ "install" , "-y" ] ;
79- dnf_args . extend ( packages. iter ( ) . map ( |s| s. as_str ( ) ) ) ;
80- match execute_dnf ( dnf_args , use_sudo) {
79+ let mut apt_args = vec ! [ "install" , "-y" ] ;
80+ apt_args . extend ( packages. iter ( ) . map ( |s| s. as_str ( ) ) ) ;
81+ match execute_apt ( apt_args , use_sudo) {
8182 Ok ( status) if status. success ( ) => println ! ( "Package(s) {} installed successfully" , packages. join( " " ) ) ,
8283 Ok ( _) => println ! ( "Failed to install package(s) {}" , packages. join( " " ) ) ,
8384 Err ( e) => println ! ( "Error: {}" , e) ,
@@ -89,80 +90,108 @@ fn main() {
8990 std:: process:: exit ( 1 ) ;
9091 }
9192 let packages = & args[ 2 ..] ;
92- let mut dnf_args = vec ! [ "remove" , "-y" ] ;
93- dnf_args . extend ( packages. iter ( ) . map ( |s| s. as_str ( ) ) ) ;
94- match execute_dnf ( dnf_args , use_sudo) {
93+ let mut apt_args = vec ! [ "remove" , "-y" ] ;
94+ apt_args . extend ( packages. iter ( ) . map ( |s| s. as_str ( ) ) ) ;
95+ match execute_apt ( apt_args , use_sudo) {
9596 Ok ( status) if status. success ( ) => println ! ( "Package(s) {} removed successfully" , packages. join( " " ) ) ,
9697 Ok ( _) => println ! ( "Failed to remove package(s) {}" , packages. join( " " ) ) ,
9798 Err ( e) => println ! ( "Error: {}" , e) ,
9899 }
99100 }
101+ "purge" => {
102+ if args. len ( ) < 3 {
103+ println ! ( "Error: At least one package name required for purge" ) ;
104+ std:: process:: exit ( 1 ) ;
105+ }
106+ let packages = & args[ 2 ..] ;
107+ let mut apt_args = vec ! [ "purge" , "-y" ] ;
108+ apt_args. extend ( packages. iter ( ) . map ( |s| s. as_str ( ) ) ) ;
109+ match execute_apt ( apt_args, use_sudo) {
110+ Ok ( status) if status. success ( ) => println ! ( "Package(s) {} purged successfully" , packages. join( " " ) ) ,
111+ Ok ( _) => println ! ( "Failed to purge package(s) {}" , packages. join( " " ) ) ,
112+ Err ( e) => println ! ( "Error: {}" , e) ,
113+ }
114+ }
100115 "list" => {
101- match execute_dnf ( vec ! [ "list" , "installed" ] , use_sudo) {
116+ match execute_apt ( vec ! [ "list" , "-- installed" ] , use_sudo) {
102117 Ok ( status) if status. success ( ) => println ! ( "Listed installed packages" ) ,
103118 Ok ( _) => println ! ( "Failed to list packages" ) ,
104119 Err ( e) => println ! ( "Error: {}" , e) ,
105120 }
106121 }
122+ "list-available" => {
123+ match execute_apt ( vec ! [ "list" ] , use_sudo) {
124+ Ok ( status) if status. success ( ) => println ! ( "Listed available packages" ) ,
125+ Ok ( _) => println ! ( "Failed to list available packages" ) ,
126+ Err ( e) => println ! ( "Error: {}" , e) ,
127+ }
128+ }
129+ "list-upgradable" => {
130+ match execute_apt ( vec ! [ "list" , "--upgradable" ] , use_sudo) {
131+ Ok ( status) if status. success ( ) => println ! ( "Listed upgradable packages" ) ,
132+ Ok ( _) => println ! ( "Failed to list upgradable packages" ) ,
133+ Err ( e) => println ! ( "Error: {}" , e) ,
134+ }
135+ }
107136 "search" => {
108137 if args. len ( ) < 3 {
109138 println ! ( "Error: Search term required" ) ;
110139 std:: process:: exit ( 1 ) ;
111140 }
112141 let term = & args[ 2 ] ;
113- match execute_dnf ( vec ! [ "search" , term] , use_sudo) {
142+ match execute_apt ( vec ! [ "search" , term] , use_sudo) {
114143 Ok ( status) if status. success ( ) => println ! ( "Search completed" ) ,
115144 Ok ( _) => println ! ( "Search failed" ) ,
116145 Err ( e) => println ! ( "Error: {}" , e) ,
117146 }
118147 }
119148 "clean" => {
120- match execute_dnf ( vec ! [ "clean" , "all "] , use_sudo) {
149+ match execute_apt ( vec ! [ "clean" ] , use_sudo) {
121150 Ok ( status) if status. success ( ) => println ! ( "Package cache cleaned successfully" ) ,
122151 Ok ( _) => println ! ( "Failed to clean package cache" ) ,
123152 Err ( e) => println ! ( "Error: {}" , e) ,
124153 }
125154 }
126- "info " => {
155+ "show " => {
127156 if args. len ( ) < 3 {
128- println ! ( "Error: Package name required for info " ) ;
157+ println ! ( "Error: Package name required for show " ) ;
129158 std:: process:: exit ( 1 ) ;
130159 }
131160 let package = & args[ 2 ] ;
132- match execute_dnf ( vec ! [ "info " , package] , use_sudo) {
161+ match execute_apt ( vec ! [ "show " , package] , use_sudo) {
133162 Ok ( status) if status. success ( ) => println ! ( "Package information displayed" ) ,
134163 Ok ( _) => println ! ( "Failed to display package information" ) ,
135164 Err ( e) => println ! ( "Error: {}" , e) ,
136165 }
137166 }
138- "repolist" => {
139- match execute_dnf ( vec ! [ "repolist" ] , use_sudo) {
140- Ok ( status) if status. success ( ) => println ! ( "Repository list displayed" ) ,
141- Ok ( _) => println ! ( "Failed to display repository list" ) ,
142- Err ( e) => println ! ( "Error: {}" , e) ,
143- }
144- }
145- "copr-enable" => {
167+ "hold" => {
146168 if args. len ( ) < 3 {
147- println ! ( "Error: COPR repository name required" ) ;
169+ println ! ( "Error: Package name required for hold " ) ;
148170 std:: process:: exit ( 1 ) ;
149171 }
150- let repo = & args[ 2 ] ;
151- match execute_dnf ( vec ! [ "copr " , "enable" , repo ] , use_sudo) {
152- Ok ( status) if status. success ( ) => println ! ( "COPR repository {} enabled " , repo ) ,
153- Ok ( _) => println ! ( "Failed to enable COPR repository {}" , repo ) ,
172+ let package = & args[ 2 ] ;
173+ match execute_apt ( vec ! [ "hold " , package ] , use_sudo) {
174+ Ok ( status) if status. success ( ) => println ! ( "Package {} set to hold " , package ) ,
175+ Ok ( _) => println ! ( "Failed to hold package {}" , package ) ,
154176 Err ( e) => println ! ( "Error: {}" , e) ,
155177 }
156178 }
157- "copr-disable " => {
179+ "unhold " => {
158180 if args. len ( ) < 3 {
159- println ! ( "Error: COPR repository name required" ) ;
181+ println ! ( "Error: Package name required for unhold " ) ;
160182 std:: process:: exit ( 1 ) ;
161183 }
162- let repo = & args[ 2 ] ;
163- match execute_dnf ( vec ! [ "copr" , "disable" , repo] , use_sudo) {
164- Ok ( status) if status. success ( ) => println ! ( "COPR repository {} disabled" , repo) ,
165- Ok ( _) => println ! ( "Failed to disable COPR repository {}" , repo) ,
184+ let package = & args[ 2 ] ;
185+ match execute_apt ( vec ! [ "unhold" , package] , use_sudo) {
186+ Ok ( status) if status. success ( ) => println ! ( "Package {} set to unhold" , package) ,
187+ Ok ( _) => println ! ( "Failed to unhold package {}" , package) ,
188+ Err ( e) => println ! ( "Error: {}" , e) ,
189+ }
190+ }
191+ "repolist" => {
192+ match execute_apt ( vec ! [ "-o" , "Debug::pkgProblemResolver=yes" , "update" ] , use_sudo) {
193+ Ok ( status) if status. success ( ) => println ! ( "Repository list refreshed (use 'less /etc/apt/sources.list' for details)" ) ,
194+ Ok ( _) => println ! ( "Failed to refresh repository list" ) ,
166195 Err ( e) => println ! ( "Error: {}" , e) ,
167196 }
168197 }
0 commit comments