19 Commits

Author SHA1 Message Date
c78f9a36d9 Bump version to v1.1 2024-05-25 18:39:51 +02:00
5fd6da816f Add contribution guide in README. 2024-05-25 18:39:07 +02:00
d9d807b754 Correct name of GNU Make in README. 2024-05-25 18:29:27 +02:00
7c5f748791 Remove pacundo binary from gitignore.
No longer exists.
2024-05-25 18:28:38 +02:00
2bda4e6d7c Makefile: Fix install target. 2024-05-25 18:27:18 +02:00
795a06f4be Implement download from ArchLinux Archive. 2024-05-25 18:24:41 +02:00
e9e2737bd4 Silence ls errors.
It is expected behavior that sometimes the local file will not be found.
2024-05-25 18:17:47 +02:00
d4f0f15341 Add uninstall target for Makefile. 2024-05-25 18:01:37 +02:00
962c54b8e0 Remove perl compiling.
This is giving some weird outputs when I try running it after making the
ArchLinux package (see AUR pacundo).
2024-05-25 17:58:51 +02:00
ebdf36d3c0 Update description to include "rollback" keyword.
This is the keyword that I assume most people use when looking for this
sort of a tool. Should be helpful.

Signed-off-by: Nicolás Ortega Froysa <nicolas@ortegas.org>
2024-05-22 17:14:30 +02:00
858d44b5ca Bump version to v1.0.1
Signed-off-by: Nicolás Ortega Froysa <nicolas@ortegas.org>
2024-05-21 15:45:25 +02:00
e18136e43c Makefile: create parent directories if not exists.
Signed-off-by: Nicolas A. Ortega Froysa <nicolas.ortega@babelgroup.com>
2024-05-21 15:41:36 +02:00
d692d4aa59 Makefile: Fix PREFIX handling.
Signed-off-by: Nicolas A. Ortega Froysa <nicolas.ortega@babelgroup.com>
2024-05-21 15:41:36 +02:00
1516ce9ff3 Include section for supported AUR helpers.
Signed-off-by: Nicolás Ortega Froysa <nicolas@ortegas.org>
2024-05-07 18:07:13 +02:00
555ead272e Improve repository check.
Signed-off-by: Nicolás Ortega Froysa <nicolas@ortegas.org>
2024-05-07 18:05:11 +02:00
d616930208 Remove unnecessary sudo.
Signed-off-by: Nicolás Ortega Froysa <nicolas@ortegas.org>
2024-05-07 17:49:20 +02:00
347b49d5ee Find local package when reinstalling removed package.
Signed-off-by: Nicolás Ortega Froysa <nicolas@ortegas.org>
2024-05-02 13:36:07 +02:00
641163a495 Implement dry-run mode.
Signed-off-by: Nicolás Ortega Froysa <nicolas@ortegas.org>
2024-05-02 13:17:02 +02:00
75c663eb1e Update help information.
Signed-off-by: Nicolás Ortega Froysa <nicolas@ortegas.org>
2024-05-02 13:12:34 +02:00
5 changed files with 137 additions and 37 deletions

1
.gitignore vendored
View File

@ -1,2 +1 @@
pacundo
pacundo.1.gz

View File

@ -20,20 +20,26 @@
# 3. This notice may not be removed or altered from any source
# distribution.
PREFIX=/usr/local
pacundo: pacundo.pl
pp -o $@ $^
ifeq ($(PREFIX),)
PREFIX := /usr/local
endif
pacundo.1.gz: pacundo.1
gzip -c $^ > $@
.PHONY: install clean
.PHONY: clean doc install uninstall
clean:
$(RM) pacundo
$(RM) pacundo.1.gz
install: pacundo pacundo.1.gz
install -m 755 pacundo $(PREFIX)/bin/
doc: pacundo.1.gz
install: pacundo.1.gz
install -d $(PREFIX)/bin
install -m 755 pacundo.pl $(PREFIX)/bin/pacundo
install -d $(PREFIX)/share/man/man1
install -m 644 pacundo.1.gz $(PREFIX)/share/man/man1/
uninstall:
$(RM) $(PREFIX)/bin/pacundo
$(RM) $(PREFIX)/share/man/man1/pacundo.1.gz

View File

@ -11,13 +11,13 @@ to boot from a USB depending on just how broken it is).
- Perl 5
- `File::ReadBackwards` module
- PAR Packager (for compiling)
- GNU Makefile
- cURL
- GNU Make
You can install these packages with the following command:
```console
# pacman -S perl perl-file-readbackwards perl-par-packer
# pacman -S perl perl-file-readbackwards curl
```
### Compiling & Installing
@ -45,6 +45,30 @@ There are two modes for undoing pacman transactions:
Look at the man-page (`man pacundo`) for more information.
### Supported AUR Helpers
- [yay](https://github.com/Jguer/yay)
## Contributing
If you find any issues, feel free to report them on GitHub or send me an E-Mail
(see my website/profile for the address). I will add these issues to my personal
Gitea page and (unless specified otherwise) mention you as the person who found
the issue.
For patches/pull requests, if you open a PR on GitHub I will likely not merge
directly but instead apply the patches locally (via Git patches, conserving
authorship), push them to my Gitea repository, which will finally be mirrored to
GitHub. However, you can save me a bit of work by just sending me the Git
patches directly (via E-Mail).
If you're looking for a way to contribute, there are a few to-do items within
the code which you can find using `grep`:
```console
# grep -n "TODO" pacundo.pl
```
## License
This project is licensed under the terms & conditions of the Zlib license.

View File

@ -1,6 +1,6 @@
.TH PACUNDO "1" "April 2024" "pacundo 1.0" "User Commands"
.TH PACUNDO "1" "April 2024" "pacundo 1.1" "User Commands"
.SH "NAME"
pacundo - A time machine to return your ArchLinux machine back to a working state.
pacundo - A time machine to roll back your ArchLinux machine to a working state.
.SH "SYNOPSIS"
.B pacundo
[\fI\-i\fR|\fI\-r\fR] [\fI\-t\fR <\fInum\fR>] [\fI\-d\fR]
@ -21,19 +21,22 @@ is especially helpful if the last update broke your system for some reason.
.SH "OPTIONS"
.TP
\fB\-i\fR
Interactively select the transactions to undo (default behavior)
Enter interactive mode to select package operations to undo (default behavior)
.TP
\fB\-r\fR
Non-interactively undo transactions
Non-interactively undo entire transactions
.TP
\fB\-t\fR <\fInum\fR>
Select number of transactions to include (default: 1)
Specify the number of transactions to include (default: 1)
.TP
\fB\-d\fR
Dry run, i.e. don't actually do anything
.TP
\fB\-h\fR
Show help information
Show this help information
.TP
\fB\-v\fR
Show program version
Print program version
.SH "AUTHOR"
Written by Nicolás A. Ortega Froysa.

View File

@ -29,7 +29,7 @@ use feature qw(signatures);
use Getopt::Std;
use File::ReadBackwards;
my $VERSION = '1.0';
my $VERSION = '1.1';
my $PROG_NAME = 'pacundo';
sub print_version() {
@ -39,7 +39,7 @@ sub print_version() {
sub print_help() {
&print_version();
print("A time machine to return your ArchLinux machine back to a working state.
print("A time machine to roll back your ArchLinux machine to a working state.
USAGE:
$PROG_NAME [-i|-r] [-t <num>] [-d]
@ -47,9 +47,9 @@ USAGE:
$PROG_NAME -v
OPTIONS:
-i Enter interactive mode to select packages to downgrade [default behavior]
-r Automatically downgrade all packages from last upgrade
-t <num> Specify the number of transactions to include for undoing selection [default 1]
-i Enter interactive mode to select package operations to undo (default behavior)
-r Non-interactively undo entire transactions
-t <num> Specify the number of transactions to include (default: 1)
-d Dry run, i.e. don't actually do anything
-h Show this help information
-v Print program version\n");
@ -169,7 +169,8 @@ sub get_pkgmgr() {
my %pkgmgr = (
name => $mgr,
bin => $mgr_bin,
search => "$sudo $mgr_bin -Ss",
search => "$mgr_bin -Ss",
info => "$mgr_bin -Si",
install_remote => "$sudo $mgr_bin -S",
install_local => "$sudo $mgr_bin -U",
remove => "$sudo $mgr_bin -R",
@ -178,17 +179,72 @@ sub get_pkgmgr() {
return \%pkgmgr;
}
sub find_local_pkg($pkgmgr, $pkg_name, $pkg_ver) {
sub find_local_pkg($pkgmgr, $pkg_name, $pkg_ver='') {
my $pkg_file = '';
my $aur_dir = "$ENV{'XDG_CACHE_HOME'}/yay/$pkg_name";
my $pkg_pat;
my $repo = `$pkgmgr->{info} $pkg_name | awk '{ if (\$1 == "Repository") print \$3; }'`;;
chomp($repo);
if ($pkgmgr->{name} eq 'yay' && -d $aur_dir) {
$pkg_file = `ls $aur_dir/$pkg_name-$pkg_ver-*.pkg.tar.zst | tail -n1`;
if ($pkg_ver ne '') {
$pkg_pat = "$pkg_name-$pkg_ver-*.pkg.tar.zst";
} else {
$pkg_file = `ls /var/cache/pacman/pkg/$pkg_name-$pkg_ver-*.pkg.tar.zst | tail -n1`;
$pkg_pat = "$pkg_name-*.pkg.tar.zst";
}
if ($repo eq 'aur') {
my $aur_dir;
if ($pkgmgr->{name} eq 'yay') {
$aur_dir = "$ENV{'XDG_CACHE_HOME'}/yay/$pkg_name";
} else {
return '';
}
$pkg_file = `ls $aur_dir/$pkg_pat 2> /dev/null | tail -n1`;
} else {
$pkg_file = `ls /var/cache/pacman/pkg/$pkg_pat 2> /dev/null | tail -n1`;
}
chomp($pkg_file);
return $pkg_file;
}
sub find_remote_archive($pkgmgr, $pkg_name, $pkg_ver) {
my $repo = `$pkgmgr->{info} $pkg_name | awk '{ if (\$1 == "Repository") print \$3; }'`;;
chomp($repo);
# TODO: look through git history for version.
if ($repo eq 'aur') {
return '';
}
# TODO: Probably a better way of managing architectures. There should be a
# way of getting the architecture of the package.
my @archs = (`uname -m`, 'any');
my $ala_url = "https://archive.archlinux.org/packages/" .
substr($pkg_name,0,1) . "/" . $pkg_name;
my $pkg_file = '';
foreach my $arch (@archs) {
chomp($arch);
my $filename = "$pkg_name-$pkg_ver-$arch.pkg.tar.zst";
my $pkg_url = "$ala_url/$filename";
my $output_file = "/tmp/$filename";
my $resp = `curl -Lo $output_file -s -w '%{http_code}\n' $pkg_url`;
chomp($resp);
if ($resp eq '200') {
system("curl -Lo $output_file.sig -s $pkg_url.sig");
$pkg_file = $output_file;
last;
} else {
unlink $output_file;
}
}
if ($pkg_file ne '') {
print("Downloaded from archive: $pkg_file\n");
}
return $pkg_file;
}
@ -227,18 +283,30 @@ foreach my $tx (@undo_txs) {
if ($tx->{action} eq 'installed') {
$remove_pkgs .= "$tx->{pkg_name} ";
} elsif ($tx->{action} eq 'removed') {
# TODO: install local package if available
$remote_install_pkgs .= "$tx->{pkg_name} ";
} else {
my $pkg_file = &find_local_pkg($pkgmgr, $tx->{pkg_name}, $tx->{oldver});
my $pkg_file = &find_local_pkg($pkgmgr, $tx->{pkg_name});
if ($pkg_file eq '') {
$remote_install_pkgs .= "$tx->{pkg_name} ";
} else {
$local_install_pkgs .= "$pkg_file ";
}
} else {
my $pkg_file = &find_local_pkg($pkgmgr, $tx->{pkg_name}, $tx->{oldver});
$pkg_file = &find_remote_archive($pkgmgr, $tx->{pkg_name}, $tx->{oldver}) if ($pkg_file eq '');
if ($pkg_file ne '') {
$local_install_pkgs .= "$pkg_file ";
} else {
print(STDERR "Unable to find $tx->{pkg_name} $tx->{pkg_ver}");
}
}
}
system("$pkgmgr->{remove} $remove_pkgs") if ($remove_pkgs ne '');
system("$pkgmgr->{install_remote} $remote_install_pkgs") if ($remote_install_pkgs ne '');
system("$pkgmgr->{install_local} $local_install_pkgs") if ($local_install_pkgs ne '');
if ($dry_run) {
print("$pkgmgr->{remove} $remove_pkgs\n") if ($remove_pkgs ne '');
print("$pkgmgr->{install_remote} $remote_install_pkgs\n") if ($remote_install_pkgs ne '');
print("$pkgmgr->{install_local} $local_install_pkgs\n") if ($local_install_pkgs ne '');
} else {
system("$pkgmgr->{remove} $remove_pkgs") if ($remove_pkgs ne '');
system("$pkgmgr->{install_remote} $remote_install_pkgs") if ($remote_install_pkgs ne '');
system("$pkgmgr->{install_local} $local_install_pkgs") if ($local_install_pkgs ne '');
}