diff --git a/.travis.yml b/.travis.yml index 8afdb05..60beeeb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ perl: - "5.22" - "5.24" - "5.26" +# - "5.28" before_install: - sudo apt-get -qq update diff --git a/INSTALL.md b/INSTALL.md index 289e75f..d684474 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -38,7 +38,7 @@ You can also look for information at: ## LICENSE AND COPYRIGHT -Copyright (C) 2016-2017 Giuseppe Di Terlizzi +Copyright (C) 2016-2018 Giuseppe Di Terlizzi This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/LICENSE.md b/LICENSE.md index 54126d2..77e39eb 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (C) 2016-2017 Giuseppe Di Terlizzi +Copyright (C) 2016-2018 Giuseppe Di Terlizzi This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/MANIFEST b/MANIFEST index 7f93da4..d9687a3 100644 --- a/MANIFEST +++ b/MANIFEST @@ -22,7 +22,7 @@ etc/repos.d/extra/csb.repo etc/repos.d/extra/ktown.repo etc/repos.d/extra/microlinux.repo etc/repos.d/extra/msb.repo -etc/repos.d/extra/README.md +etc/repos.d/extra/ponce.repo etc/repos.d/extra/repo.sample etc/repos.d/extra/rlworkman.repo etc/repos.d/extra/salix.repo @@ -30,6 +30,7 @@ etc/repos.d/extra/slacke18.repo etc/repos.d/extra/slackers.repo etc/repos.d/extra/slackonly.repo etc/repos.d/extra/slacky.repo +etc/repos.d/extra/slint.repo etc/repos.d/extra/studioware.repo etc/repos.d/slackware.repo etc/slackman-cron.conf @@ -39,9 +40,7 @@ etc/slackman.cron etc/slackman.logrotate INSTALL.md lib/Slackware/SlackMan.pm -lib/Slackware/SlackMan/Base.pm lib/Slackware/SlackMan/Command.pm -lib/Slackware/SlackMan/Command/About.pm lib/Slackware/SlackMan/Command/Clean.pm lib/Slackware/SlackMan/Command/Config.pm lib/Slackware/SlackMan/Command/DB.pm @@ -82,6 +81,7 @@ t/00-load.t t/01-package-info.t t/02-variables.t t/03-config.t +t/10-slackman.t t/99-fake-root.t t/manifest.t t/pod-coverage.t diff --git a/Makefile.PL b/Makefile.PL index c688b39..8143542 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -3,7 +3,7 @@ use strict; use warnings; use ExtUtils::MakeMaker; -use lib qw(/usr/share/slackman/lib); +use lib qw(/usr/share/slackman/lib/perl5); WriteMakefile( NAME => 'Slackware::SlackMan', @@ -23,6 +23,7 @@ WriteMakefile( PREREQ_PM => { 'DBD::SQLite' => '0', 'Net::DBus' => '0', + 'HTTP::Tiny' => '0', }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Slackware-Slackman-*' }, diff --git a/RELEASE.md b/RELEASE.md index d52f715..49e0787 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,32 @@ # SlackMan - Slackware Package Manager ChangeLog +## [v1.4.0] + +This release introduce the automatic detection of Slackware `-current` release using the new `/etc/slackware-version` format (eg. `14.2+`). Added parsing of Slackware Announce in ChangeLog. General optimizations and reduced the `slackman` command startup by ~0.3 second. Improved download information (added speed, ETA, etc). Added information of supported arch in all `.repo` config file. + +## Added + + * Added `--terse` option for display only a single description line when install or upgrade package + * Added `slackman clean removed` command for delete removed packages and scripts file in pkgtools directory (`/var/log/removed_{packages,scripts}`) + * Added new entry for `00-default.renames` file + * Added `--format` option for `slackman list` commands + * Added support for Slint repository (`slint.repo`) + * Added supported arch in `.repo` files + * Accept multiple `--exclude` option for `slackman install` and `slackman upgrade` commands + * #11 - Added automatic detection of Slackware-current (since **14.2+** release) + * #12 - Added `org.LotarProject.SlackMan.Announces` D-Bus method to retrieve ChangeLog announces + * #12 - Added `slackman changelog --announces` option to retrieve Slackware ChangeLog announces + * #13 - Added `arch` config option in `.repo` files with supported repository arch + +## Changed + + * Re-added `HTTP::Tiny` support with check of SSL Perl modules (`IO::Socket::SSL` and `Net::SSLeay`) + * Optimization for `slackman.bash` completion file + * Changed location of required Perl module in `@INC` + * Load `Net::DBus` module when necessary (this reduce `slackman` command startup by ~0.3 second) + * slackman-libsupport.SlackBuild` file now use `cpanm` for download and build the required Perl modules + + ## [v1.3.0] This release introduce new options (`--local` for install or upgrade from local package) and new feature (`.renames` configuration file). Now SlackMan use cURL command for download th packages and repository metadata. Added new D-Bus methods and signals and improved `slackman-notifier` client. @@ -141,9 +168,11 @@ This release introduce new features, new commands & params and new DBus service * [v1.0.0] [Develop]: https://github.com/LotarProject/slackman/compare/master...develop +[v1.4.0]: https://github.com/LotarProject/slackman/compare/v1.3.0...v1.4.0 [v1.3.0]: https://github.com/LotarProject/slackman/compare/v1.2.1...v1.3.0 [v1.2.1]: https://github.com/LotarProject/slackman/compare/v1.2.0...v1.2.1 [v1.2.0]: https://github.com/LotarProject/slackman/compare/v1.1.1...v1.2.0 +[v1.1.2]: https://github.com/LotarProject/slackman/compare/v1.1.1...v1.1.2 [v1.1.1]: https://github.com/LotarProject/slackman/compare/v1.1.0...v1.1.1 [v1.1.0]: https://github.com/LotarProject/slackman/compare/v1.0.4...v1.1.0 [v1.0.4]: https://github.com/LotarProject/slackman/compare/v1.0.3...v1.0.4 diff --git a/TODO.md b/TODO.md index b961fb6..0e2a94e 100644 --- a/TODO.md +++ b/TODO.md @@ -1,12 +1,13 @@ # SlackMan TODO - [ ] Check dependencies command (eg. `slackman check-deps PACKAGE`) - - [ ] Add rule in `.repo` file for 32-bit or ARM directory variant (i386, i486, i586, i686, x86, armv5, armv7, armel, etc.) - - [ ] Add rule in `.repo` file to allow the repository only for particular arch (eg. `slackware:multilib` is only for `x86_64` arch) - [ ] Remove package and all "directed" dependencies (`slackman remove routersploit --remove-dependencies`) - [ ] Display installed date in `slackman history` for packages installed and removed (never upgraded). Now dsplay only the removed date - [ ] Add option `--append` (or `-A`) for `slackman config` and `slackman repo config` for append a text in config file - [ ] Notify the user of changed or installed `/etc/rc.d` + - [ ] Follow logger category for logging + - [ ] Plugin system (via hooks / events) + ## SlackMan 1.1 @@ -45,3 +46,14 @@ - [x] Add local package install/upgrade using `--local FILE` option (eg. `slackman install --local /tmp/foo-1.2-noarch-1`) - [x] Add option `d` in answer when using `slackman install` & `slackman upgrade` commands for download the packages (eg. `Perform upgrade of selected packages? [Y/N/d]`) - [x] Increase SlackMan bootstrap and module loading + + +## SlackMan 1.4 + + - [x] #11 - Use `/etc/slackware-version` to automatically detect Slackware -current (post 14.2) + - [x] #11 - Add `--terse` options for `slackman` command + - [x] #12 - Parse announces in ChangeLog + - [x] #12 - Add option for display the announces (eg. `slackman changelog --announces`) or create new command (eg. `slackman announces`) + - [x] #12 - Expose a new D-Bus methods to retrieve the announces (eg. `org.LotarProject.SlackMan.Announces`) + - [x] #13 - Add `arch` config option in `.repo` file with supported repository arch + diff --git a/VERSION b/VERSION index 18fa8e7..0d0c52f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.3.0 +v1.4.0 diff --git a/bin/slackman b/bin/slackman index b0d5b87..e32d313 100755 --- a/bin/slackman +++ b/bin/slackman @@ -10,7 +10,7 @@ unless ($< == 0) { exit(1); } -use lib qw(/usr/share/slackman/lib); +use lib qw(/usr/share/slackman/lib/perl5); require Slackware::SlackMan::Command; @@ -138,7 +138,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/dbus/dbus-pkgtools b/dbus/dbus-pkgtools index 1f1f9fb..1251ae0 100644 --- a/dbus/dbus-pkgtools +++ b/dbus/dbus-pkgtools @@ -3,7 +3,7 @@ use strict; use warnings; -use lib qw(/usr/share/slackman-libsupport/lib); +use lib qw(/usr/share/slackman/lib/perl5); use Net::DBus; diff --git a/dbus/org.lotarproject.SlackMan.7.pod b/dbus/org.lotarproject.SlackMan.7.pod index e9d8fb9..1ebc164 100644 --- a/dbus/org.lotarproject.SlackMan.7.pod +++ b/dbus/org.lotarproject.SlackMan.7.pod @@ -4,8 +4,8 @@ B - D-Bus interface for L Package Manage =head1 DESCRIPTION -The SlackMan service is accessed through the D-Bus object at /org/lotarproject/SlackMan. -Which provides the following interface. +The SlackMan service is accessed through the D-Bus object at C +which provides the following interface. =head1 METHODS @@ -13,6 +13,10 @@ Which provides the following interface. ChangeLog ( in: 's' I, out 'a{saa{ss}}' ) +=head2 Announce + +Announce ( in: 's' I, out 'a{saa{ss}}' ) + =head2 CheckUpgrade CheckUpgrade ( out 'a{sa{ss}}' ) @@ -75,6 +79,12 @@ slackware (out 's') Return the Slackware version (eg. I<14.2> or I) +=head2 isCurrent + +isCurrent (out 'b') + +Return I if this is I + =head1 SIGNALS =head2 PackageInstalled @@ -116,7 +126,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/dbus/slackman-notifier b/dbus/slackman-notifier index 67d2453..585ad99 100755 --- a/dbus/slackman-notifier +++ b/dbus/slackman-notifier @@ -5,7 +5,7 @@ use warnings FATAL => 'all'; use 5.010; -use lib qw(/usr/share/slackman/lib); +use lib qw(/usr/share/slackman/lib/perl5); use Net::DBus; use Net::DBus::Reactor; @@ -19,7 +19,7 @@ use Slackware::SlackMan; use Slackware::SlackMan::Config qw(:all); use Slackware::SlackMan::Utils qw(:all); -my $VERSION = "v1.3.0"; +my $VERSION = "v1.4.0"; my $options = {}; GetOptions( $options, @@ -180,14 +180,60 @@ sub check_upgrade { return unless ($upgrades_body); notify({ - 'icon' => '/usr/share/slackman/slackware.png', - 'summary' => 'Slackware Packages Upgrade', + 'icon' => 'system-software-update', + 'summary' => 'Slackware Package Updates Available', 'body' => $upgrades_body, }); } +sub check_announces { + + logger->info('Get new ChangeLog Announce items from SlackMan D-Bus service'); + + my $announces = dbus_slackman->Announce( undef ); # Get ChangeLog Announces for all repositories + my $max_timestamp = 0; # Max ChangeLog entry timestamp + my $announce_body = ''; + + return unless ( keys %{$announces} ); + + foreach my $repo (keys %{$announces}) { + + foreach ( @{$announces->{$repo}} ) { + + my $announce = $_->{'announce'}; + $announce =~ s/\n/ /gm; + + $announce_body .= "$repo repository\n"; + $announce_body .= sprintf("%s\n", datetime_h(timestamp_to_time($_->{'timestamp'}))); + $announce_body .= "$announce\n"; + $announce_body .= sprintf("\n%s\n", "-"x32); + + $max_timestamp = timestamp_to_time($_->{'timestamp'}) if ($max_timestamp < timestamp_to_time($_->{'timestamp'})); + + } + + } + + my $current_last_update = $cfg->get('last_update.announce') || 0; + + return unless ($max_timestamp > $current_last_update); + + $cfg->set('last_update.announce', $max_timestamp); + $cfg->save(); + + return unless ($announce_body); + + notify({ + 'icon' => '/usr/share/slackman/slackware.png', + 'summary' => 'Slackware ChangeLog Announces', + 'body' => $announce_body, + }); + +} + + sub check_changelogs { logger->info('Get new ChangeLog items from SlackMan D-Bus service'); @@ -272,8 +318,7 @@ sub check_security_advisories { my $description = $changelog->{'description'}; $description = "\n$description" if ($description); - $security_fix_body .= sprintf("\n%s\n ● %s\n%s\n", - "-"x32, $package, $description); + $security_fix_body .= sprintf(" ● %s\n%s\n", $package, $description); } @@ -300,6 +345,11 @@ sub action_notifier { sleep(5); + # Check latest Slackware ChangeLog Announces from all Slackware repository + check_announces(); + + sleep(5); + # Check latest Slackware ChangeLogs from all Slackware repository check_changelogs(); @@ -321,7 +371,7 @@ sub action_listner { sub _notify { - my ($action, $package) = @_; + my ($action, $icon, $package) = @_; my $body = ''; @@ -334,38 +384,43 @@ sub action_listner { } else { my $pkg_info = get_package_info($_); - $body .= sprintf(" ● %s (%s)\n", $pkg_info->{'name'} || $_, $pkg_info->{'version'} || ''); + + $body .= sprintf(" ● %s (%s-%s)\n", + $pkg_info->{'name'} || $_, + $pkg_info->{'version'} || '', + $pkg_info->{'build'} || '' + ); } } notify ({ - 'icon' => '/usr/share/slackman/slackware.png', - 'summary' => "Slackware - $action packages", + 'icon' => $icon, + 'summary' => "$action Slackware Package", 'body' => $body }); } - sub _notify_installed { _notify('Installed', @_) }; - sub _notify_upgraded { _notify('Upgraded', @_) }; - sub _notify_removed { _notify('Removed', @_) }; + sub _notify_installed { _notify('Installed', 'system-software-install', @_) }; + sub _notify_upgraded { _notify('Upgraded', 'system-software-update', @_) }; + sub _notify_removed { _notify('Removed', 'system-software-update', @_) }; - logger->debug('Listening to "org.lotarproject.SlackMan.PackageInstalled" signal'); + logger->debug('Listen "org.lotarproject.SlackMan.PackageInstalled" signal'); $SlackMan->connect_to_signal('PackageInstalled', \&_notify_installed); - logger->debug('Listening to "org.lotarproject.SlackMan.PackageUpgraded" signal'); + logger->debug('Listen "org.lotarproject.SlackMan.PackageUpgraded" signal'); $SlackMan->connect_to_signal('PackageUpgraded', \&_notify_upgraded); - logger->debug('Listening to "org.lotarproject.SlackMan.PackageRemoved" signal'); + logger->debug('Listen "org.lotarproject.SlackMan.PackageRemoved" signal'); $SlackMan->connect_to_signal('PackageRemoved', \&_notify_removed); - logger->debug('Listening to "org.lotarproject.SlackMan.UpdatedChangeLog" signal'); + logger->debug('Listen "org.lotarproject.SlackMan.UpdatedChangeLog" signal'); $SlackMan->connect_to_signal('UpdatedChangeLog', sub { check_changelogs; check_security_advisories }); - logger->debug('Listening to "org.lotarproject.SlackMan.UpdatedPackages" signal'); + logger->debug('Listen "org.lotarproject.SlackMan.UpdatedPackages" signal'); $SlackMan->connect_to_signal('UpdatedPackages', sub { check_upgrade() }); @@ -386,6 +441,7 @@ sub create_user_config { 'last_update' => { 'changelog' => 0, 'security_fix' => 0, + 'announce' => 0, } }; @@ -424,7 +480,7 @@ slackman-notifier - SlackMan Notification Tool B is user-space utility to receive a desktop notification via D-Bus (using B service) for Slackware Security -Advisories, ChangeLogs, new packages upgrade and post-install/upgrade/remove summary. +Advisories, Announces, ChangeLogs, new packages upgrade and post-install/upgrade/remove summary. =head1 OPTIONS @@ -448,7 +504,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/dbus/slackman-service b/dbus/slackman-service index a100568..803f7b9 100755 --- a/dbus/slackman-service +++ b/dbus/slackman-service @@ -5,7 +5,7 @@ use strict; use warnings; -use lib qw(/usr/share/slackman/lib); +use lib qw(/usr/share/slackman/lib/perl5); use Getopt::Long qw(:config); use Pod::Usage; @@ -88,7 +88,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/docs/dbus.md b/docs/dbus.md index b7c03d5..43ee5e3 100644 --- a/docs/dbus.md +++ b/docs/dbus.md @@ -16,6 +16,7 @@ This section describe the `org.lotarproject.SlackMan` D-Bus interface (methods, /** Methods */ arrayOfString ChangeLog(string repo_id); + arrayOfString Announce(string repo_id); arrayOfString SecurityFix(); arrayOfString PackageInfo(string package_name); @@ -35,6 +36,7 @@ This section describe the `org.lotarproject.SlackMan` D-Bus interface (methods, readonly attribute string slackware; readonly attribute string version; + readonly attribute boolean isCurrent; /** Signals */ @@ -76,6 +78,10 @@ This section describe the `org.lotarproject.SlackMan` D-Bus interface (methods, + + + + @@ -138,6 +144,7 @@ This section describe the `org.lotarproject.SlackMan` D-Bus interface (methods, + @@ -158,6 +165,17 @@ Argument | Type | Description `repo_id` | STRING | Repository ID +##### org.lotarproject.SlackMan.Announce + +Return last ChangeLog Annouce entries from all Slackware Changelog repositories + + ARRAY of DICT org.lotarproject.SlackMan.Announce ( in STRING repo_id ) + +Argument | Type | Description +-----------|--------|------------ +`repo_id` | STRING | Repository ID + + ##### org.lotarproject.SlackMan.SecurityFix Return last packages whit Security Fix from all Slackware Changelog repositories @@ -364,6 +382,10 @@ Advisories, ChangeLogs and new packages upgrade. ![Slackware Security notification](images/dbus-notification-slackware-security.png) +**Slackware ChangeLog Announces** + +![Slackware Security notification](images/dbus-notification-slackware-announces.png) + **Slackware Upgrade** ![Slackware Security notification](images/dbus-notification-slackware-upgrade.png) diff --git a/docs/repo.md b/docs/repo.md index c3ac889..081ba01 100644 --- a/docs/repo.md +++ b/docs/repo.md @@ -7,8 +7,9 @@ SlackMan support different Slackware repository including: - Slackware stable and **-current** - SlackOnly - Slackers (Conraid) + - Ponce (Matteo Bernardini) - Slacky (Italian Slackware Community) - - AlienBob (and **restricted** repository) + - AlienBob (with **restricted** repository) - Robby Workman - ktown (KDE5) - Cinnamon SlackBuilds @@ -41,9 +42,9 @@ Follow this easy steps: ``` [packages] - name=My personal repository - enabled=true - mirror=http://example.org/my-personal-repository + name = My personal repository + enabled = true + mirror = http://example.org/my-personal-repository ``` - Update the repository metadata using `slackman update --repo custom:packages` @@ -60,14 +61,14 @@ This is a sample .repo configuration # Short description of repository # - name=My local repository + name = My local repository # Enable or disable repository # true - enabled # false - disabeld # - enabled=false + enabled = false # Mirror URL @@ -82,45 +83,68 @@ This is a sample .repo configuration # Remote URL: https://example.org/slackware/ # Local: file:///srv/slackware/ # - mirror=https://example.org/slackware/ + mirror = https://example.org/slackware/ + + + # Supported Architectures (optional) + # + # Specify the repository arch support (default is: x86,x86_64,arm). + # + # NOTE: Prepend "!" to disable the arch. + # + # Example: + # + # Enable "only" "x86_64": + # + # arch = x86_64 + # + # Enable "x86" and "x86_64" and disable "arm": + # + # arch = x86,x86_64,!arm + # + # Override $arch variable: + # + # arch =x86:i486,x86_64 + # + arch = x86,x86_64,arm # Priority (optional) # # Specify repository priority (default is 0 - "zero") # - priority=1 + priority = 1 # Exclude packages (optional) # # Specify excluded packages for update or install (default "none") # - exclude=kernel-*,kde-l10n-*,calligra-l10n-* + exclude = kernel-*,kde-l10n-*,calligra-l10n-* # Override metadata URLs if the file is in another location # GPG-KEY file URL # - gpgkey=$mirror/GPG-KEY + gpgkey = $mirror/GPG-KEY # Packages file URL # - packages=$mirror/PACKAGES.TXT + packages = $mirror/PACKAGES.TXT # Filelist file URL # - filelist=$mirror/FILELIST.TXT + filelist = $mirror/FILELIST.TXT # Changelog file URL # - changelog=$mirror/ChangeLog.txt + changelog = $mirror/ChangeLog.txt # Manifest file URL # - manifest=$mirror/MANIFEST.bz2 + manifest = $mirror/MANIFEST.bz2 # Checksums file URL # - checksums=$mirror/CHECKSUMS.md5 + checksums = $mirror/CHECKSUMS.md5 diff --git a/etc/renames.d/00-default.renames b/etc/renames.d/00-default.renames index 54d5663..e0161e1 100644 --- a/etc/renames.d/00-default.renames +++ b/etc/renames.d/00-default.renames @@ -21,3 +21,7 @@ #tetex = texlive + +# Wireless Tools (renamed in Slackware 15.0) + +Wireless-tools = wireless-tools diff --git a/etc/repos.d/extra/README.md b/etc/repos.d/extra/README.md deleted file mode 100644 index 955b16e..0000000 --- a/etc/repos.d/extra/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Extra SlackMan repository - -SlackMan support different Slackware repository: - - - Slackware stable and **-current** - - SlackOnly - - Slackers (Conraid) - - Slacky (Italian Slackware Community) - - AlienBob (and **restricted** repository) - - Robby Workman - - ktown (KDE5) - - Cinnamon SlackBuilds - - MATE SlackBuilds - - Salix - - Microlinux - - Studioware - - ... and more - -## Install new repository - -Copy your preferred repository in `/etc/slackman/repos.d` directory or use -`slackman repo add REPOSITORY-FILE` command: - - # slackman repo add /etc/slackman/repos.d/extra/slackonly.repo - -## Enable a repository - -To enable the repository edit `.repo` file and change `enable` flag from `false` -to `true` or use `slackman repo enable REPOSITORY` command. - -## Create manually a new .repo file - -You can create a new **.repo** file for all compatible Slackware repository. -Follow this easy steps: - - * Create new text file with **.repo** (eg. **custom.repo** ) extension into `/etc/slackman/repos.d` directory - * Copy and paste the below text into new **.repo** file - - [packages] - name=My personal repository - enabled=true - mirror=http://example.org/my-personal-repository - - * Update the repository metadata using `slackman update --repo custom:packages` - * Enjoy! - -**NOTE** SlackMan provide a sample repository file `/etc/slackman/repos.d/extra/repo.sample`. diff --git a/etc/repos.d/extra/alienbob.repo b/etc/repos.d/extra/alienbob.repo index b24d266..c995847 100644 --- a/etc/repos.d/extra/alienbob.repo +++ b/etc/repos.d/extra/alienbob.repo @@ -7,6 +7,7 @@ [packages] name = AlienBob SlackBuilds enabled = false +arch = x86,x86_64 mirror = http://bear.alienbase.nl/mirrors/people/alien/sbrepos/$release/$arch/ changelog = http://bear.alienbase.nl/mirrors/people/alien/sbrepos/ChangeLog.txt priority = 1 @@ -14,6 +15,7 @@ priority = 1 [restricted] name = AlienBob Restricted SlackBuilds enabled = false +arch = x86,x86_64 mirror = http://bear.alienbase.nl/mirrors/people/alien/restricted_sbrepos/$release/$arch/ changelog = http://bear.alienbase.nl/mirrors/people/alien/restricted_sbrepos/ChangeLog.txt priority = 2 diff --git a/etc/repos.d/extra/csb.repo b/etc/repos.d/extra/csb.repo index 3a6d64f..cad3a42 100644 --- a/etc/repos.d/extra/csb.repo +++ b/etc/repos.d/extra/csb.repo @@ -17,5 +17,6 @@ [packages] name = Cinnamon SlackBuilds (CSB) enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/csb/$release.real/$arch.family/ changelog = http://slackware.uk/csb/ChangeLog.txt diff --git a/etc/repos.d/extra/ktown.repo b/etc/repos.d/extra/ktown.repo index 1670898..e5e1e82 100644 --- a/etc/repos.d/extra/ktown.repo +++ b/etc/repos.d/extra/ktown.repo @@ -8,7 +8,17 @@ [packages] name = KDE5 ktown packages enabled = false +arch = x86,x86_64 mirror = http://bear.alienbase.nl/mirrors/alien-kde/$release/latest/$arch.family/ changelog = http://bear.alienbase.nl/mirrors/alien-kde/ChangeLog.txt priority = 1 exclude = kde-l10n-*,calligra-l10n-* + +[testing] +name = KDE5 ktown testing +enabled = false +arch = x86,x86_64 +mirror = http://bear.alienbase.nl/mirrors/alien-kde/$release/testing/$arch.family/ +changelog = http://bear.alienbase.nl/mirrors/alien-kde/ChangeLog.txt +priority = 1 +exclude = kde-l10n-*,calligra-l10n-* diff --git a/etc/repos.d/extra/microlinux.repo b/etc/repos.d/extra/microlinux.repo index 7059949..b24bca8 100644 --- a/etc/repos.d/extra/microlinux.repo +++ b/etc/repos.d/extra/microlinux.repo @@ -17,14 +17,17 @@ [desktop] name = Microlinux Enterprise - Desktop enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/microlinux/desktop-$release.real-${arch.bit}bit/ [extras] name = Microlinux Enterprise - Extras enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/microlinux/extras-$release.real-${arch.bit}bit/ [server] name = Microlinux Enterprise - Server enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/microlinux/server-$release.real-${arch.bit}bit/ diff --git a/etc/repos.d/extra/msb.repo b/etc/repos.d/extra/msb.repo index b6f619f..65290dd 100644 --- a/etc/repos.d/extra/msb.repo +++ b/etc/repos.d/extra/msb.repo @@ -32,42 +32,49 @@ [latest] name = MATE SlackBuilds (MSB) - latest enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/msb/$release/latest/$arch/ changelog = http://slackware.uk/msb/ChangeLog.txt [1.18] name = MATE SlackBuilds (MSB) - 1.18 enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/msb/$release/1.18/$arch/ changelog = http://slackware.uk/msb/ChangeLog.txt [1.16] name = MATE SlackBuilds (MSB) - 1.16 enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/msb/$release/1.16/$arch/ changelog = http://slackware.uk/msb/ChangeLog.txt [1.14] name = MATE SlackBuilds (MSB) - 1.14 enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/msb/$release/1.14/$arch/ changelog = http://slackware.uk/msb/ChangeLog.txt [1.12] name = MATE SlackBuilds (MSB) - 1.12 enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/msb/$release/1.12/$arch/ changelog = http://slackware.uk/msb/ChangeLog.txt [1.10] name = MATE SlackBuilds (MSB) - 1.10 enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/msb/$release/1.10/$arch/ changelog = http://slackware.uk/msb/ChangeLog.txt [1.8] name = MATE SlackBuilds (MSB) - 1.8 enabled = false +arch = x86,x86_64 mirror = http://slackware.uk/msb/$release/1.8/$arch/ changelog = http://slackware.uk/msb/ChangeLog.txt @@ -76,3 +83,4 @@ name = MATE SlackBuilds (MSB) - 1.6 enabled = false mirror = http://slackware.uk/msb/$release/1.6/$arch/ changelog = http://slackware.uk/msb/ChangeLog.txt + diff --git a/etc/repos.d/extra/ponce.repo b/etc/repos.d/extra/ponce.repo new file mode 100644 index 0000000..def982e --- /dev/null +++ b/etc/repos.d/extra/ponce.repo @@ -0,0 +1,14 @@ +# Ponce (Matteo Bernardini Slackware Repository) + +# Home-Page: http://slackware.ponce.cc/blog/ + +[packages] +name = Ponce Slackware$release.suffix-$release packages +enabled = false +mirror = http://ponce.cc/slackware/slackware$release.suffix-$release/packages/ + +[lxde] +name = Ponce LXDE Slackware$release.suffix-$release packages +enabled = false +mirror = http://ponce.cc/slackware/slackware$release.suffix-$release/lxde + diff --git a/etc/repos.d/extra/repo.sample b/etc/repos.d/extra/repo.sample index 3ae6faf..ee8d4b7 100644 --- a/etc/repos.d/extra/repo.sample +++ b/etc/repos.d/extra/repo.sample @@ -1,15 +1,42 @@ +# This is a sample repository configuration file +# +# For more information see slackman.repo(5) man page + [repository-id] # Short description of repository # -name=My local repository +name = My local repository # Enable or disable repository # true - enabled # false - disabeld # -enabled=false +enabled = false + + +# Arch support +# +# Specify the repository arch support (default is: x86,x86_64,arm). +# +# NOTE: Prepend "!" to disable the arch. +# +# Example: +# +# Enable "only" x86_64: +# +# arch = x86_64 +# +# Enable "x86" and "x86_64" and disable "arm": +# +# arch = x86,x86_64,!arm +# +# Override $arch variable: +# +# arch =x86:i486,x86_64 +# +arch = x86,x86_64,arm # Mirror URL @@ -24,45 +51,45 @@ enabled=false # Remote URL: https://example.org/slackware/ # Local: file:///srv/slackware/ # -mirror=https://example.org/slackware/ +mirror = https://example.org/slackware/ # Priority (optional) # # Specify repository priority (default is 0 - "zero") # -priority=1 +priority = 1 # Exclude packages (optional) # # Specify excluded packages for update or install (default "none") # -exclude=kernel-*,kde-l10n-*,calligra-l10n-* +exclude = kernel-*,kde-l10n-*,calligra-l10n-* # Override metadata URLs if the file is in another location # GPG-KEY file URL # -gpgkey=$mirror/GPG-KEY +gpgkey = $mirror/GPG-KEY # Packages file URL # -packages=$mirror/PACKAGES.TXT +packages = $mirror/PACKAGES.TXT # Filelist file URL # -filelist=$mirror/FILELIST.TXT +filelist = $mirror/FILELIST.TXT # Changelog file URL # -changelog=$mirror/ChangeLog.txt +changelog = $mirror/ChangeLog.txt # Manifest file URL # -manifest=$mirror/MANIFEST.bz2 +manifest = $mirror/MANIFEST.bz2 # Checksums file URL # -checksums=$mirror/CHECKSUMS.md5 +checksums = $mirror/CHECKSUMS.md5 diff --git a/etc/repos.d/extra/rlworkman.repo b/etc/repos.d/extra/rlworkman.repo index 42b7169..2036731 100644 --- a/etc/repos.d/extra/rlworkman.repo +++ b/etc/repos.d/extra/rlworkman.repo @@ -9,6 +9,7 @@ [packages] name = Robby Workman's Slackware Packages enabled = false +arch = x86:i486,x86_64,arm mirror = http://slackware.uk/people/rlworkman/$release.real/$arch/ changelog = http://slackware.uk/people/rlworkman/$release.real/ChangeLog.txt packages = http://slackware.uk/people/rlworkman/$release.real/PACKAGES.TXT diff --git a/etc/repos.d/extra/salix.repo b/etc/repos.d/extra/salix.repo index 199da2e..0648ac0 100644 --- a/etc/repos.d/extra/salix.repo +++ b/etc/repos.d/extra/salix.repo @@ -12,9 +12,11 @@ [packages] name = Salix packages enabled = false -mirror = http://slackware.uk/salix/$arch.family/$release.real/ +arch = x86:i486,x86_64,arm +mirror = http://slackware.uk/salix/$arch/$release.real/ [extra] name = Salix extra enabled = false -mirror = http://slackware.uk/salix/$arch.family/extra-$release.real/ +arch = x86:i486,x86_64,arm +mirror = http://slackware.uk/salix/$arch/extra-$release.real/ diff --git a/etc/repos.d/extra/slacke18.repo b/etc/repos.d/extra/slacke18.repo index d74a1f7..fed780c 100644 --- a/etc/repos.d/extra/slacke18.repo +++ b/etc/repos.d/extra/slacke18.repo @@ -10,4 +10,5 @@ [packages] name = Slackware Enlightenment DR18 (E18) Packages enabled = false +arch = x86,x86_64,arm mirror = https://ngc891.blogdns.net/pub/slacke18/slackware$release.suffix-$release.real/ diff --git a/etc/repos.d/extra/slackers.repo b/etc/repos.d/extra/slackers.repo index 50a2957..dbb4e41 100644 --- a/etc/repos.d/extra/slackers.repo +++ b/etc/repos.d/extra/slackers.repo @@ -1,6 +1,9 @@ # Slackers (Conraid's Repository for Slackware64 current) +# Home-Page: http://slack.conraid.net/ + [packages] name = Slackers (Conraid's Repository for Slackware64 current) +arch = x86_64 enabled = false mirror = http://slack.conraid.net/repository/slackware64-current/ diff --git a/etc/repos.d/extra/slackonly.repo b/etc/repos.d/extra/slackonly.repo index 7662bb4..562113e 100644 --- a/etc/repos.d/extra/slackonly.repo +++ b/etc/repos.d/extra/slackonly.repo @@ -14,4 +14,5 @@ [packages] name = SlackOnly SlackBuilds enabled = false +arch = x86,x86_64 mirror = https://packages.slackonly.com/pub/packages/$release-$arch/ diff --git a/etc/repos.d/extra/slacky.repo b/etc/repos.d/extra/slacky.repo index fb2a943..19c76ca 100644 --- a/etc/repos.d/extra/slacky.repo +++ b/etc/repos.d/extra/slacky.repo @@ -5,4 +5,5 @@ [packages] name = Italian Slackware Community enabled = false +arch = x86,x86_64 mirror = http://repository.slacky.eu/slackware{$release.suffix}-{$release.real}/ diff --git a/etc/repos.d/extra/slint.repo b/etc/repos.d/extra/slint.repo new file mode 100644 index 0000000..6a75d64 --- /dev/null +++ b/etc/repos.d/extra/slint.repo @@ -0,0 +1,22 @@ +# Slint + +# Originally the Slackware Internationalization project, Slint is now a Linux +# distribution derived from Slackware and Salix. It is polyglot, versatile, +# beginner friendly, and accessible for the visually impaired. A full Slint +# installation is functional out of the box and can be tailored to fit most +# computing requirements. + +# Home-Page: http://slint.fr + +[14.2] +arch = x86:i586,x86_64,!arm +name = Slint 14.2 +enabled = false +mirror = http://slackware.uk/slint/$arch/slint-14.2/ + +[14.2.1] +arch = x86:i586,x86_64,!arm +name = Slint 14.2.1 +enabled = false +mirror = http://slackware.uk/slint/$arch/slint-14.2.1/ + diff --git a/etc/repos.d/extra/studioware.repo b/etc/repos.d/extra/studioware.repo index 852fea0..4a1ac1e 100644 --- a/etc/repos.d/extra/studioware.repo +++ b/etc/repos.d/extra/studioware.repo @@ -14,4 +14,5 @@ [packages] name = Studioware enabled = false +arch = x64-64 mirror = http://slackware.uk/studioware/$release.real/ diff --git a/etc/repos.d/slackware.repo b/etc/repos.d/slackware.repo index 1f93d0d..855feef 100644 --- a/etc/repos.d/slackware.repo +++ b/etc/repos.d/slackware.repo @@ -7,7 +7,7 @@ # - pasture # - extra # - testing -# - multilib (only for x86-64 arch) +# - multilib (only for x86_64 arch) # # NOTE: patches, pasture, extra and testing ChangeLog are included in main # Slackware "packages" repository @@ -70,6 +70,7 @@ priority = -1 [multilib] name = Slackware64-$release (MultiLib) enabled = false +arch = x86_64 mirror = http://www.slackware.com/~alien/multilib/$release/ changelog = http://www.slackware.com/~alien/multilib/ChangeLog.txt gpgkey = http://www.slackware.com/~alien/multilib/GPG-KEY diff --git a/etc/slackman.bash b/etc/slackman.bash index b5d5b49..bbe3218 100644 --- a/etc/slackman.bash +++ b/etc/slackman.bash @@ -55,33 +55,33 @@ __slackman_list_config() { } __slackman_list_installed_packages() { - echo $(slackman list installed | grep ":" | awk '{ print $1 }') + echo $(slackman list installed --format=tsv | tail -n +2 | awk '{ print $1 }') } __slackman_list_packages() { - echo $(slackman list packages | grep ":" | awk '{ print $1 }') + echo $(slackman list packages --format=tsv | tail -n +2 | awk '{ print $1 }' | sort -u) } __slackman_list_no_installed_packages() { - echo $(slackman list packages --exclude-installed | grep ":" | awk '{ print $1 }') + echo $(slackman list packages --exclude-installed --format=tsv | tail -n +2 | awk '{ print $1 }' | sort -u) } __slackman_list_repos() { - local slackman_cmd="slackman repo list --color=never" + local slackman_cmd="slackman list repo --format=tsv | tail -n +2" case "$1" in enabled) - echo $($slackman_cmd | grep -i enabled | grep ":" | awk '{ print $1 }') + echo $($slackman_cmd | grep -i enabled | awk '{ print $1 }') ;; disabled) - echo $($slackman_cmd | grep -i disabled | grep ":" | awk '{ print $1 }') + echo $($slackman_cmd | grep -i disabled | awk '{ print $1 }') ;; *) - echo $($slackman_cmd | grep ":" | awk '{ print $1 }') + echo $($slackman_cmd | awk '{ print $1 }') esac return @@ -160,6 +160,22 @@ _slackman_repo() { } +_slackman_list_packages() { + + local slackman_options="--repo" + + __slackman_complete_options "$cur" "$prev" && return + + if [[ "$cur" == -* ]]; then + COMPREPLY=( $( compgen -W "$slackman_options" -- "$cur" ) ) + return 0 + fi + + __slackman_complete_options "$cur" "$prev" && return + +} + + _slackman_log() { local subcommands="help clean tail" @@ -208,7 +224,7 @@ _slackman_update() { _slackman_upgrade() { - local slackman_options="--repo --exclude --no-priority --no-excludes --download-only --summary --no-deps --category --no-gpg-check --no-md5-check --local" + local slackman_options="--repo --exclude --no-priority --no-excludes --download-only --summary --no-deps --category --no-gpg-check --no-md5-check --local --terse" __slackman_complete_options "$cur" "$prev" && return @@ -217,6 +233,11 @@ _slackman_upgrade() { return 0 fi + if [[ "$prev" == "--local" ]]; then + _filedir 't[bglx]z' + return 0 + fi + COMPREPLY=( $(compgen -W "$(__slackman_list_installed_packages "$@")" -- "$cur") ) __ltrim_colon_completions "$cur" @@ -225,7 +246,7 @@ _slackman_upgrade() { _slackman_changelog() { - local slackman_options="--repo --limit --details --security-fix --before --after --cve" + local slackman_options="--repo --limit --details --security-fix --before --after --cve --announces" __slackman_complete_options "$cur" "$prev" && return @@ -239,7 +260,7 @@ _slackman_changelog() { _slackman_install() { - local slackman_options="--repo --exclude --no-excludes --download-only --new-packages --no-deps --category --no-gpg-check --no-md5-check --local" + local slackman_options="--repo --exclude --no-excludes --download-only --new-packages --no-deps --category --no-gpg-check --no-md5-check --local --terse" __slackman_complete_options "$cur" "$prev" && return @@ -248,6 +269,11 @@ _slackman_install() { return 0 fi + if [[ "$prev" == "--local" ]]; then + _filedir 't[bglx]z' + return 0 + fi + COMPREPLY=( $(compgen -W "$(__slackman_list_no_installed_packages "$@")" -- "$cur") ) __ltrim_colon_completions "$cur" @@ -258,7 +284,7 @@ _slackman_install() { _slackman_reinstall() { - local slackman_options="--repo --exclude --no-excludes --download-only --category --no-gpg-check --no-md5-check" + local slackman_options="--repo --exclude --no-excludes --download-only --category --no-gpg-check --no-md5-check --terse" __slackman_complete_options "$cur" "$prev" && return @@ -308,7 +334,7 @@ _slackman_help() { _slackman_list() { - local slackman_options="--exclude-installed --after --before" + local slackman_options="--exclude-installed --after --before --format" __slackman_complete_options "$cur" "$prev" && return diff --git a/etc/slackman.cron b/etc/slackman.cron index f989cf0..7300f20 100644 --- a/etc/slackman.cron +++ b/etc/slackman.cron @@ -13,7 +13,7 @@ UPDATE_MANIFEST_METADATA="no" DOWNLOAD_UPGRADED_PACKAGES="no" if [ -f /etc/slackman/slackman-cron.conf ]; then - source /etc/slackman/slackman-cron.conf + . /etc/slackman/slackman-cron.conf fi if [ "$UPDATE_METADATA" == "yes" ]; then diff --git a/lib/Slackware/SlackMan.pm b/lib/Slackware/SlackMan.pm index ca57700..a86ca68 100644 --- a/lib/Slackware/SlackMan.pm +++ b/lib/Slackware/SlackMan.pm @@ -13,7 +13,7 @@ BEGIN { @ISA = qw(Exporter); - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @EXPORT_OK = (); @EXPORT = qw( $slackman_opts @@ -68,7 +68,7 @@ if ($root ne '' && ! -d $root) { } unless (-f $config_file) { - print "Configuration file '$config_file' not found!\n"; + print "SlackMan configuration file '$config_file' not found!\n"; exit(255); } @@ -82,9 +82,17 @@ $slackman_conf->{'directory'}->{'repos'} ||= "$root/etc/slackman/repos.d"; $slackman_conf->{'directory'}->{'renames'} ||= "$root/etc/slackman/renames.d"; $slackman_conf->{'directory'}->{'log'} ||= "$root/var/log"; $slackman_conf->{'directory'}->{'lib'} ||= "$root/var/lib/slackman"; +$slackman_conf->{'directory'}->{'libexec'} ||= "$root/usr/libexec/slackman"; $slackman_conf->{'directory'}->{'cache'} ||= "$root/var/cache/slackman"; $slackman_conf->{'directory'}->{'lock'} ||= "$root/var/lock"; +# Set Slackware pkgtools directories +$slackman_conf->{'pkgtools'}->{'packages'} = "$root/var/log/packages"; +$slackman_conf->{'pkgtools'}->{'scripts'} = "$root/var/log/scripts"; +$slackman_conf->{'pkgtools'}->{'setup'} = "$root/var/log/setup"; +$slackman_conf->{'pkgtools'}->{'removed-packages'} = "$root/var/log/removed_packages"; +$slackman_conf->{'pkgtools'}->{'removed-scripts'} = "$root/var/log/removed_scripts"; + # Set default logger values $slackman_conf->{'logger'}->{'level'} ||= 'debug'; $slackman_conf->{'logger'}->{'file'} ||= $slackman_conf->{'directory'}->{'log'} . '/slackman.log'; @@ -203,7 +211,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/Command.pm b/lib/Slackware/SlackMan/Command.pm index 66af8a9..671877c 100644 --- a/lib/Slackware/SlackMan/Command.pm +++ b/lib/Slackware/SlackMan/Command.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw( run @@ -29,6 +29,7 @@ use IO::Handle; use Term::ANSIColor qw(color colored :constants); use Text::Wrap; use Pod::Usage; +use HTTP::Tiny; use Slackware::SlackMan; use Slackware::SlackMan::Utils qw(:all); @@ -48,6 +49,7 @@ use Getopt::Long qw(:config no_pass_through); GetOptions( $slackman_opts, 'after=s', + 'announces', 'before=s', 'category=s', 'cve=s', @@ -57,8 +59,9 @@ GetOptions( $slackman_opts, 'details', 'download-only', 'exclude-installed', - 'exclude|x=s', + 'exclude|x=s@', 'force|f', + 'format=s', 'help|h', 'limit=i', 'local', @@ -78,12 +81,16 @@ GetOptions( $slackman_opts, 'show-files', 'summary', 'tag=s', + 'terse', 'version', 'yes|y', ); +# Set default format to "default" +$slackman_opts->{'format'} ||= 'default'; -$slackman_opts->{'color'} ||= 'always'; # Color output is always enabled +# Color output is always enabled +$slackman_opts->{'color'} ||= 'always'; # Options Alias $slackman_opts->{'category'} = $slackman_opts->{'series'} if ($slackman_opts->{'series'}); @@ -120,6 +127,21 @@ $SIG{INT} = sub { sub run { + my ($ssl_check, $ssl_reason) = HTTP::Tiny->can_ssl; + + unless ($ssl_check) { + + $ssl_reason =~ s/^/ - /gm; + + print "Problem with SSL support for HTTP::Tiny module:\n\n"; + print "$ssl_reason\n"; + print "Please install the required modules and execute this command again.\n\n"; + + exit(100); + + } + + my @lock_commands = qw(update install upgrade remove reinstall clean); my @skip_lock = qw(log.tail); @@ -165,6 +187,26 @@ sub run { } + # Set TERSE env for pkgtools + $ENV{TERSE} = 1 if ($slackman_opts->{'terse'}); + + # Check output format (default, csv or tsv) + if ($slackman_opts->{'format'}) { + + my $format = $slackman_opts->{'format'}; + + unless (grep(/^$format$/, qw(csv tsv default))) { + print colored('WARNING', 'yellow bold') . " Invalid output format (allowed: default, csv, tsv)\n\n"; + exit(1); + } + + # Disable colors for csv and tsv output format + if ($format ne 'default') { + $ENV{ANSI_COLORS_DISABLED} = 1; + } + + } + # Commands dispatch table my $commands_dispatcher = { 'version' => \&show_version, @@ -323,7 +365,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/Command/Clean.pm b/lib/Slackware/SlackMan/Command/Clean.pm index 01acf0d..6c14566 100644 --- a/lib/Slackware/SlackMan/Command/Clean.pm +++ b/lib/Slackware/SlackMan/Command/Clean.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw(); %EXPORT_TAGS = ( @@ -35,6 +35,7 @@ use constant COMMANDS_DISPATCHER => { 'clean' => \&call_clean_help, 'clean.help' => \&call_clean_help, + 'clean.removed' => \&call_clean_removed, 'clean.cache' => \&call_clean_cache, 'clean.db' => \&call_clean_db, 'clean.metadata' => \&call_clean_metadata, @@ -80,6 +81,27 @@ sub call_clean_all { } +sub call_clean_removed { + + my $slackware_removed_packages_dir = $slackman_conf->{'pkgtools'}->{'removed-packages'}; + my $slackware_removed_scripts_dir = $slackman_conf->{'pkgtools'}->{'removed-scripts'}; + + exit(0) unless(confirm("Do you want remove Slackware log files placed in $slackware_removed_packages_dir and $slackware_removed_scripts_dir ? [Y/N]")); + + logger->debug(qq/Delete removed packages in "$slackware_removed_packages_dir"/); + + STDOUT->printflush("\nDelete removed packages in $slackware_removed_packages_dir... "); + unlink glob "$slackware_removed_packages_dir/*"; + STDOUT->printflush(colored("done\n", 'green')); + + logger->debug(qq/Delete removed scripts in "$slackware_removed_scripts_dir"/); + + STDOUT->printflush("\nDelete removed scripts in $slackware_removed_scripts_dir... "); + unlink glob "$slackware_removed_scripts_dir/*"; + STDOUT->printflush(colored("done\n", 'green')); + +} + sub call_clean_db { my $lib_dir = $slackman_conf->{'directory'}->{'lib'}; @@ -131,6 +153,7 @@ slackman-clean - Clean and control SlackMan cache slackman clean cache slackman clean metadata slackman clean db + slackman clean removed slackman clean all slackman clean help @@ -143,6 +166,7 @@ B clean and control SlackMan cache. slackman clean cache Clean cache package download directory slackman clean metadata Clean database metadata (packages, changelog, manifest) slackman clean db Clean database file + slackman clean removed Delete Slackware removed packages and scripts log from pkgtools log directory slackman clean all Clean database file and cache directory slackman clean help Display clean command help usage @@ -169,7 +193,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/lib/Slackware/SlackMan/Command/Config.pm b/lib/Slackware/SlackMan/Command/Config.pm index 9fb3247..32347d4 100644 --- a/lib/Slackware/SlackMan/Command/Config.pm +++ b/lib/Slackware/SlackMan/Command/Config.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw(); %EXPORT_TAGS = ( @@ -151,7 +151,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/lib/Slackware/SlackMan/Command/DB.pm b/lib/Slackware/SlackMan/Command/DB.pm index 62599ca..b50c12e 100644 --- a/lib/Slackware/SlackMan/Command/DB.pm +++ b/lib/Slackware/SlackMan/Command/DB.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw(); %EXPORT_TAGS = ( @@ -86,17 +86,18 @@ sub call_db_info { my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($db_path); - print sprintf("%-20s %s\n", 'Path:', $db_path); - print sprintf("%-20s %.1f M\n", 'Size:', ($size/1024/1024)); + print sprintf("%-15s : %s\n", 'Database Path', $db_path); + print sprintf("%-15s : %.1f M\n", 'Database Size', filesize_h($size, 1)); + print sprintf("%-15s : %s\n", 'Last modified', time_to_timestamp($mtime)); my $user_version = ($dbh->selectrow_arrayref('PRAGMA user_version', undef))->[0]; - print sprintf("%-20s %s\n", 'Schema Version:', $user_version); + print sprintf("%-15s : %s\n", 'Schema Version', $user_version); my $quick_check = ($dbh->selectrow_arrayref('PRAGMA quick_check', undef))->[0]; - print sprintf("%-20s %s\n", 'Quick check:', uc($quick_check)); + print sprintf("%-15s : %s\n", 'Quick check', uc($quick_check)); my $integrity_check = ($dbh->selectrow_arrayref('PRAGMA integrity_check', undef))->[0]; - print sprintf("%-20s %s\n", 'Integrity check:', uc($integrity_check)); + print sprintf("%-15s : %s\n", 'Integrity check', uc($integrity_check)); } @@ -151,7 +152,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/lib/Slackware/SlackMan/Command/List.pm b/lib/Slackware/SlackMan/Command/List.pm index 9aa6d34..0c4e3d8 100644 --- a/lib/Slackware/SlackMan/Command/List.pm +++ b/lib/Slackware/SlackMan/Command/List.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw(); %EXPORT_TAGS = ( @@ -81,32 +81,39 @@ sub call_list_obsoletes { my $obsolete_rows = package_list_obsoletes($slackman_opts->{'repo'}); my $num_rows = scalar keys %$obsolete_rows; - print "\nObsolete package(s)\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-30s %-25s %-15s %-25s %-15s %-25s\n", "Package", "ChangeLog Repository", "Version", "Obsolete from", "Actual Version", "Installed at"); - print sprintf("%s\n", "-"x132); - unless ($num_rows) { print "\nNo obsolete packages found!\n\n"; exit(0); } my @obsolete = (); + my @rows = (); foreach(keys %$obsolete_rows) { my $row = $obsolete_rows->{$_}; - print sprintf("%-30s %-25s %-15s %-25s %-15s %-25s\n", - $row->{changelog_name}, $row->{changelog_repository}, - $row->{changelog_version}, $row->{changelog_timestamp}, - $row->{installed_version}, $row->{installed_timestamp}); + push(@rows, [ + $row->{changelog_name}, + $row->{changelog_repository}, + $row->{changelog_version}, + $row->{changelog_timestamp}, + $row->{installed_version}, + $row->{installed_timestamp} + ]); push(@obsolete, $row->{changelog_name}); } - print "\n\n"; + print "\nObsolete package(s)\n\n" if ($slackman_opts->{'format'} eq 'default'); + + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Package', 'ChangeLog Repository', 'Version', 'Obsolete from', 'Actual Version', 'Installed at' ], + 'format' => $slackman_opts->{'format'}, + }); return (@obsolete); @@ -117,14 +124,19 @@ sub call_list_variables { my @variables = ( 'arch', 'arch.bit', 'arch.family', 'release', 'release.real', 'release.suffix' ); - print "\n"; - print sprintf("%-20s %s\n", "Variable", "Value"); - print sprintf("%s\n", "-"x40); + my @rows = (); foreach (@variables) { - print sprintf("%-20s %s\n", "$_", parse_variables("\$$_")); + push(@rows, [ $_, parse_variables("\$$_") ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Variable', 'Value' ], + 'format' => $slackman_opts->{'format'}, + }); + print "\n"; exit(0); @@ -133,27 +145,33 @@ sub call_list_variables { sub call_list_orphan { - print "\nOrphan package(s)\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-40s %-10s\t%-25s %-10s %-25s %s\n", "Name", "Arch", "Version", "Tag", "Installed", "Size"); - print sprintf("%s\n", "-"x132); + print "\nOrphan package(s)\n\n" if ($slackman_opts->{'format'} eq 'default'); my $rows_ref = package_list_orphan(); + my @rows = (); foreach (sort keys %$rows_ref) { my $row = $rows_ref->{$_}; - print sprintf("%-40s %-10s\t%-25s %-10s %-25s %s\n", + push(@rows, [ $row->{name}, $row->{arch}, $row->{version}, $row->{tag}, + filesize_h(($row->{size_compressed} * 1024), 1, 1), $row->{timestamp}, - filesize_h(($row->{size_compressed} * 1024), 1, 1)); + ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Tag', 'Size', 'Installed/Upgraded at' ], + 'format' => $slackman_opts->{'format'}, + }); + exit(0); } @@ -162,27 +180,33 @@ sub call_list_installed { my (@search) = @_; - print "\nInstalled packages\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-40s %-10s\t%-25s %-15s %-10s %s\n", "Name", "Arch", "Version", "Tag", "Size", "Installed/Upgraded at"); - print sprintf("%s\n", "-"x132); + print "\nInstalled packages\n\n" if ($slackman_opts->{'format'} eq 'default'); my $rows_ref = package_list_installed(@search); + my @rows = (); foreach (sort keys %$rows_ref) { my $row = $rows_ref->{$_}; - print sprintf("%-40s %-10s\t%-25s %-15s %-10s %s\n", + push(@rows, [ $row->{'name'}, $row->{'arch'}, ( $row->{'version'} . '-' . $row->{'build'} ), $row->{'tag'}, filesize_h(($row->{'size_compressed'} * 1024), 1, 1), - $row->{'timestamp'}); + $row->{'timestamp'} + ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Tag', 'Size', 'Installed/Upgraded at' ], + 'format' => $slackman_opts->{'format'}, + }); + exit(0); } @@ -190,10 +214,7 @@ sub call_list_installed { sub call_list_upgraded { - print "\nUpgraded packages\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-40s %-10s\t%-25s %-15s %-10s %s\n", "Name", "Arch", "Version", "Tag", "Size", "Timestamp"); - print sprintf("%s\n", "-"x132); + print "\nUpgraded packages\n\n" if ($slackman_opts->{'format'} eq 'default'); my @query_filters; @@ -209,18 +230,28 @@ sub call_list_upgraded { my $sth = $dbh->prepare($query); $sth->execute(); + my @rows = (); + while (my $row = $sth->fetchrow_hashref()) { - print sprintf("%-40s %-10s\t%-25s %-15s %-10s %s\n", + push(@rows, [ $row->{name}, $row->{arch}, "$row->{version}-$row->{build}", $row->{tag}, filesize_h(($row->{size_compressed} * 1024), 1, 1), - $row->{'timestamp'}); + $row->{'timestamp'} + ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Tag', 'Size', 'Timestamp' ], + 'format' => $slackman_opts->{'format'}, + }); + exit(0); } @@ -228,10 +259,7 @@ sub call_list_upgraded { sub call_list_removed { - print "\nRemoved packages\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-40s %-10s\t%-25s %-15s %-10s %s\n", "Name", "Arch", "Version", "Tag", "Size", "Timestamp"); - print sprintf("%s\n", "-"x132); + print "\nRemoved packages\n\n" if ($slackman_opts->{'format'} eq 'default'); my @query_filters; @@ -247,19 +275,28 @@ sub call_list_removed { my $sth = $dbh->prepare($query); $sth->execute(); + my @rows = (); while (my $row = $sth->fetchrow_hashref()) { - print sprintf("%-40s %-10s\t%-25s %-15s %-10s %s\n", + push(@rows, [ $row->{name}, $row->{arch}, "$row->{version}-$row->{build}", $row->{tag}, filesize_h(($row->{size_compressed} * 1024), 1, 1), - $row->{'timestamp'}); + $row->{'timestamp'} + ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Tag', 'Size', 'Timestamp' ], + 'format' => $slackman_opts->{'format'}, + }); + exit(0); } @@ -268,10 +305,7 @@ sub call_list_packages { my (@search) = @_; - print "\nAvailable packages\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-40s %-10s\t%-25s %-10s %-25s %s\n", "Name", "Arch", "Version", "Tag", "Repository", "Size"); - print sprintf("%s\n", "-"x132); + print "\nAvailable packages\n\n" if ($slackman_opts->{'format'} eq 'default'); my $option_repo = $slackman_opts->{'repo'}; @@ -306,18 +340,28 @@ sub call_list_packages { my $sth = $dbh->prepare($query); $sth->execute(); + my @rows = (); + while (my $row = $sth->fetchrow_hashref()) { - print sprintf("%-40s %-10s\t%-25s %-10s %-25s %s\n", + push(@rows, [ $row->{name}, $row->{arch}, "$row->{version}-$row->{build}", $row->{tag}, $row->{repository}, - filesize_h(($row->{size_compressed} * 1024), 1, 1)); + filesize_h(($row->{size_compressed} * 1024), 1, 1) + ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Tag', 'Repository', 'Size' ], + 'format' => $slackman_opts->{'format'}, + }); + exit(0); } @@ -371,6 +415,7 @@ B display information of: --version Display version information -c, --config=FILE Configuration file --color=[always|auto|never] Colorize the output + --format=[default|csv|tsv] Output format for list =head1 SEE ALSO @@ -387,7 +432,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/lib/Slackware/SlackMan/Command/Log.pm b/lib/Slackware/SlackMan/Command/Log.pm index c34d716..a4134b5 100644 --- a/lib/Slackware/SlackMan/Command/Log.pm +++ b/lib/Slackware/SlackMan/Command/Log.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw(); %EXPORT_TAGS = ( @@ -88,6 +88,8 @@ sub call_log_tail { my $log_file = $slackman_conf->{'logger'}->{'file'}; + exit(1) unless (-e $log_file); + system("tail -f $log_file"); exit(0); @@ -142,7 +144,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/lib/Slackware/SlackMan/Command/Package.pm b/lib/Slackware/SlackMan/Command/Package.pm index 27af048..ea79a73 100644 --- a/lib/Slackware/SlackMan/Command/Package.pm +++ b/lib/Slackware/SlackMan/Command/Package.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw(); %EXPORT_TAGS = ( @@ -125,39 +125,51 @@ sub call_package_info { my $row = $installed_rows->{$_}; my $description = $row->{description}; - my $pkg_description = ''; - - LINE: foreach my $line ( split(/\n/, $description ) ) { - $pkg_description .= sprintf("%s\n%-15s : ", trim($line), ' '); - } push @packages_installed, $row->{name}; my $pkg_dependency = $dbh->selectrow_hashref('SELECT * FROM packages WHERE package LIKE ?', undef, $row->{'package'}.'%'); - print sprintf("%-15s : %s\n", 'Name', $row->{name}); - print sprintf("%-15s : %s\n", 'Arch', $row->{arch}); - print sprintf("%-15s : %s\n", 'Tag', $row->{tag}) if ($row->{tag}); - print sprintf("%-15s : %s\n", 'Version', $row->{version}); - print sprintf("%-15s : %s\n", 'Size', filesize_h(($row->{size_uncompressed} * 1024), 1)); - print sprintf("%-15s : %s\n", 'Download Size', filesize_h(($row->{size_compressed} * 1024), 1)); - print sprintf("%-15s : %s\n", 'Require', $pkg_dependency->{'required'}) if ($pkg_dependency->{'required'}); - print sprintf("%-15s : %s\n", 'Summary', $pkg_description); + my @rows = (); + + push(@rows, [ 'Name', $row->{name} ]); + push(@rows, [ 'Arch', $row->{arch} ]); + push(@rows, [ 'Tag', $row->{tag} ]) if ($row->{tag}); + push(@rows, [ 'Version', $row->{version} ]); + push(@rows, [ 'Size', filesize_h(($row->{size_uncompressed} * 1024), 1) ]); + push(@rows, [ 'Download Size', filesize_h(($row->{size_compressed} * 1024), 1) ]); + push(@rows, [ 'Require', $pkg_dependency->{'required'} ]) if ($pkg_dependency->{'required'}); + + my $skip_summary_column = 0; + + LINE: foreach my $line ( split(/\n/, $description ) ) { + push(@rows, [ (($skip_summary_column++) ? '' : 'Summary'), trim($line) ]); + } + + push(@rows, [ '', '' ]); if ($slackman_opts->{'show-files'}) { - print sprintf("\n%-15s :\n\n", 'File lists'); + my $skip_first_column = 0; - my $package_meta = package_metadata(file_read("/var/log/packages/".$row->{'package'})); + my $package_meta = package_metadata(file_read($slackman_conf->{'pkgtools'}->{'packages'} . '/' . $row->{'package'})); foreach (@{$package_meta->{'file_list'}}) { next if (/^(install|\.\/)/); - print sprintf("%-5s /%s\n", ' ', $_); + my $file = $_; + $file = "/$file" unless ($file =~ /^\//); + push(@rows, [ (($skip_first_column++) ? '' : 'File list'), $file ]); } } - print sprintf("\n%s\n\n", "-"x80); + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' : ' }, + 'widths' => [ undef, 1 ], + }); + + print sprintf("%s\n\n", "-"x80); } @@ -177,39 +189,51 @@ sub call_package_info { my $row = $available_rows->{$_}; my $description = $row->{description}; - my $pkg_description = ''; + + my @rows = (); + + push(@rows, [ 'Name', $row->{name} ]); + push(@rows, [ 'Arch', $row->{arch} ]); + push(@rows, [ 'Tag', $row->{tag} ]) if ($row->{tag}); + push(@rows, [ 'Category', $row->{category} ]) if ($row->{category}); + push(@rows, [ 'Version', $row->{version} ]); + push(@rows, [ 'Size', filesize_h(($row->{size_uncompressed} * 1024), 1) ]); + push(@rows, [ 'Download Size', filesize_h(($row->{size_compressed} * 1024), 1) ]); + push(@rows, [ 'Require', $row->{required} ]) if ($row->{required}); + push(@rows, [ 'Repo', $row->{repository} ]); + + my $skip_summary_column = 0; LINE: foreach my $line ( split(/\n/, $description ) ) { - $pkg_description .= sprintf("%s\n%-15s : ", trim($line), ' '); + push(@rows, [ (($skip_summary_column++) ? '' : 'Summary'), trim($line) ]); } - print sprintf("%-15s : %s\n", 'Name', $row->{name}); - print sprintf("%-15s : %s\n", 'Arch', $row->{arch}); - print sprintf("%-15s : %s\n", 'Tag', $row->{tag}) if ($row->{tag}); - print sprintf("%-15s : %s\n", 'Category', $row->{category}) if ($row->{category}); - print sprintf("%-15s : %s\n", 'Version', $row->{version}); - print sprintf("%-15s : %s\n", 'Size', filesize_h(($row->{size_uncompressed} * 1024), 1)); - print sprintf("%-15s : %s\n", 'Download Size', filesize_h(($row->{size_compressed} * 1024), 1)); - print sprintf("%-15s : %s\n", 'Require', $row->{required}) if ($row->{required}); - print sprintf("%-15s : %s\n", 'Repo', $row->{repository}); - print sprintf("%-15s : %s\n", 'Summary', $pkg_description); + push(@rows, [ '', '' ]); if ($slackman_opts->{'show-files'}) { - print sprintf("\n%-15s :\n\n", 'File lists'); - my $sth = $dbh->prepare('SELECT * FROM manifest WHERE package = ? ORDER BY files'); $sth->execute($row->{'package'}); my $row = $sth->fetchrow_hashref(); + my $skip_first_column = 0; + foreach ( split(/\n/, $row->{'files'}) ) { - print sprintf("%-5s /%s\n", ' ', $_); + my $file = $_; + $file = "/$file" unless ($file =~ /^\//); + push(@rows, [ (($skip_first_column++) ? '' : 'File list'), $file ]); } } - print sprintf("\n%s\n\n", "-"x80); + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' : ' }, + 'widths' => [ undef, 1 ], + }); + + print sprintf("%s\n\n", "-"x80); } @@ -246,10 +270,7 @@ sub call_package_reinstall { _check_last_metadata_update(); - print "\nReinstall package(s)\n\n"; - print sprintf("%s\n", "-"x80); - print sprintf("%-25s %-20s %-10s %s\n", "Package", "Version", "Tag", "Installed"); - print sprintf("%s\n", "-"x80); + my @table1 = (); foreach (@packages) { @@ -257,29 +278,32 @@ sub call_package_reinstall { if ($pkg) { push(@is_installed, $pkg); - print sprintf("%-25s %-20s %-10s %s\n", $_, "$pkg->{version}-$pkg->{build}", $pkg->{tag}, $pkg->{timestamp}); + push(@table1, [ $_, $pkg->{'version'} . '-' . $pkg->{'build'}, $pkg->{'tag'}, $pkg->{'timestamp'} ]); } else { - print sprintf("%-25s not installed\n", $_); + push(@table1, [ $_, 'not installed' ]); } } + print "\nReinstall package(s)\n\n"; + + print table({ + 'rows' => \@table1, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Version', 'Tag', 'Installed' ], + }); + exit(0) unless(@is_installed); print "\n\n"; - unless ($slackman_opts->{'yes'}) { - exit(0) unless(confirm("Are you sure? [Y/N]")); - } - my @filters = (); my @filter_packages = (); - foreach (@is_installed) { - push(@filter_packages, sprintf('( package LIKE "%s%%" )', $_->{'package'})); - } + push(@filter_packages, sprintf('( name IN ("%s"))', join('", "', map { $_->{'name'} } @is_installed))); + push(@filter_packages, sprintf('( category = "%s" )', $slackman_opts->{'category'})), if ($slackman_opts->{'category'}); - push(@filters, sprintf('( %s )', join(' OR ', @filter_packages))); + push(@filters, sprintf('( %s )', join(' AND ', @filter_packages))); # Filter repository push(@filters, repo_option_to_sql()); @@ -287,7 +311,65 @@ sub call_package_reinstall { my $query = 'SELECT * FROM packages WHERE ' . join(' AND ', @filters); my $rows = $dbh->selectall_hashref($query, 'id', undef); - @packages_to_downloads = values(%$rows); + if ($slackman_opts->{'category'}) { + + my @table_category = (); + + foreach (keys %{$rows}) { + my $row = $rows->{$_}; + push(@table_category, [ $row->{'name'}, $row->{'version'} . '-' . $row->{'build'}, $row->{'tag'}, $row->{'repository'} ]); + } + + print "\nCategory Package(s)\n\n"; + + print table({ + 'rows' => \@table_category, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Version', 'Tag', 'Repository' ], + }); + + print "\n"; + + exit(0) unless(confirm("Are you sure? [Y/N]")); + + @packages_to_downloads = values(%$rows); + + } else { + + my @table_found_packages = (); + my $pkg_id = 0; + my @packages = (); + + foreach (keys %{$rows}) { + + my $row = $rows->{$_}; + push(@packages, $row); + + push(@table_found_packages, [ ++$pkg_id, $row->{'name'}, $row->{'version'} . '-' . $row->{'build'}, $row->{'tag'}, $row->{'repository'} ]); + + } + + if ($pkg_id == 0) { + print "No package found!\n\n"; + exit(1); + } + + print "\nFound Package(s)\n\n"; + + print table({ + 'rows' => \@table_found_packages, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ '#', 'Name', 'Version', 'Tag', 'Repository' ], + }); + + print "\n"; + + my $pkg_id_regex = "([1-$pkg_id])"; + my $choice = confirm_choice("Select package number [1-$pkg_id] ?", qr/$pkg_id_regex/); + + @packages_to_downloads = $packages[$choice-1]; + + } exit(0) unless (@packages_to_downloads); @@ -330,7 +412,13 @@ sub call_package_remove { _check_package_duplicates(); - my @is_installed = (); + my @is_installed = (); + my @table = (); + my $filter = ''; + my @packages_in = (); + my @packages_like = (); + + print "Remove package(s)\n\n"; if ($slackman_opts->{'obsolete-packages'}) { @@ -341,36 +429,58 @@ sub call_package_remove { if ($slackman_opts->{'category'}) { - my $packages_ref = $dbh->selectall_hashref('SELECT name FROM packages WHERE category = ?', 'name', undef, $slackman_opts->{'category'}); + my $category = $dbh->selectall_hashref('SELECT name FROM packages WHERE category = ?', 'name', undef, $slackman_opts->{'category'}); - @packages = sort keys %$packages_ref; + @packages = sort keys %{$category}; - } + exit(0) unless (@packages); - print "Remove package(s)\n\n"; - print sprintf("%s\n", "-"x80); - print sprintf("%-25s %-20s %-10s %s\n", "Package", "Version", "Tag", "Installed"); - print sprintf("%s\n", "-"x80); + } - foreach (@packages) { + foreach my $pkg (@packages) { - if ($_ =~ /^(aaa\_(base|elflibs|terminfo)|slackman)/) { - print sprintf("%-25s Never remove this package !!!\n", $_); + if ($pkg =~ /\*/) { + $pkg =~ s/\*/%/g; + push(@packages_like, qq/name LIKE "$pkg"/); } else { + push(@packages_in, $pkg); + } + + } + + $filter .= '('; + $filter .= sprintf('name IN ("%s")', join('","', @packages_in)) if (@packages_in); + $filter .= ' OR ' if (@packages_in && @packages_like); + $filter .= sprintf('(%s)', join(' OR ', @packages_like)) if (@packages_like); + $filter .= ') AND status = "installed"'; + + my $installed_packages = $dbh->selectall_hashref("SELECT * FROM history WHERE $filter ORDER BY name", 'name', undef); - my $pkg = package_info($_); + foreach (sort keys %{$installed_packages}) { - if ($pkg) { - print sprintf("%-25s %-20s %-10s %s\n", $_, "$pkg->{version}-$pkg->{build}", $pkg->{'tag'}, $pkg->{'timestamp'}); - push(@is_installed, $_); - } else { - print sprintf("%-55s %s\n", $_, colored('not installed', 'red bold')); - } + my $pkg = $installed_packages->{$_}; + if ($pkg->{'name'} =~ /^(aaa\_(base|elflibs|terminfo)|slackman)$/) { + push(@table, [ $pkg->{'name'}, colored('Don\'t remove this package', 'RED') ]); + } else { + push(@table , [ $pkg->{'name'}, "$pkg->{version}-$pkg->{build}", $pkg->{'tag'}, $pkg->{'timestamp'} ]); + push(@is_installed, $pkg->{'name'}); } } + if (@table) { + + print table({ + 'rows' => \@table, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Package', 'Version', 'Tag', 'Installed' ], + }); + + } else { + print 'Package not found!'; + } + print "\n\n"; } @@ -383,9 +493,7 @@ sub call_package_remove { } foreach my $package_path (@is_installed) { - package_remove($package_path); - } # Send the list of removed packages via D-Bus @@ -470,12 +578,8 @@ sub call_package_install { if (scalar keys %$packages_to_install) { print "Package(s) to install\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-30s %-8s %-40s %-40s %s\n", - 'Name', 'Arch', 'Version', 'Repository', 'Size'); - - print sprintf("%s\n", "-"x132); + my @rows = (); foreach (sort keys %$packages_to_install) { @@ -484,15 +588,21 @@ sub call_package_install { $total_uncompressed_size += $pkg->{size_uncompressed}; $total_compressed_size += $pkg->{size_compressed}; - print sprintf("%-30s %-8s %-40s %-40s %s\n", + push(@rows, [ $pkg->{name}, $pkg->{arch}, $pkg->{version}, $pkg->{repository}, filesize_h(($pkg->{size_compressed} * 1024), 1, 1) - ); + ]); push(@packages_to_downloads, $pkg); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Repository', 'Size' ], + }); + } if (scalar keys %$dependency_pkgs) { @@ -500,12 +610,7 @@ sub call_package_install { print "\n\n"; print "Required package(s) to install\n\n"; - print sprintf("%s\n", "-"x132); - - print sprintf("%-30s %-8s %-20s %-20s %-40s %s\n", - 'Name', 'Arch', 'Version', 'Needed by', 'Repository', 'Size'); - - print sprintf("%s\n", "-"x132); + my @rows = (); foreach (sort keys %$dependency_pkgs) { @@ -515,14 +620,20 @@ sub call_package_install { $total_uncompressed_size += $pkg->{size_uncompressed}; $total_compressed_size += $pkg->{size_compressed}; - print sprintf("%-30s %-8s %-20s %-20s %-40s %s\n", + push(@rows, [ $pkg->{name}, $pkg->{arch}, $pkg->{version}, $needed_by, $pkg->{repository}, filesize_h(($pkg->{size_compressed} * 1024), 1, 1) - ); + ]); push(@packages_to_downloads, $pkg); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Needed by', 'Repository', 'Size' ], + }); + } unless (scalar keys %$packages_to_install) { @@ -646,16 +757,12 @@ sub call_package_search { my $sth = $dbh->prepare($query); $sth->execute($search, $search, $search, $search); - my $rows = 0; - - print sprintf("%s\n", "-"x132); - print sprintf("%-80s %-15s %-8s %-10s %s\n", - 'Name', 'Version', 'Arch', 'Status', 'Repository'); - print sprintf("%s\n", "-"x132); + my $n_rows = 0; + my @rows = (); while (my $row = $sth->fetchrow_hashref()) { - $rows++; + $n_rows++; my $name = $row->{'name'}; my $summary = $row->{'summary'}; @@ -663,17 +770,29 @@ sub call_package_search { $summary =~ s/^$name//; $summary =~ s/^\s+//; - print sprintf("%-80s %-15s %-8s %-10s %s\n", + push(@rows , [ "$name $summary", $row->{'version'}, $row->{'arch'}, colored(sprintf('%-10s', $row->{'status'} ||' '), 'green'), $row->{'repository'} - ); + ]); + + } + + if ($n_rows > 0) { + + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Version', 'Arch', 'Status', 'Repository' ], + 'widths' => [ 0, 0, 0, 10, 0 ] + }); } - unless ($rows) { + + unless ($n_rows) { print "Package not found!\n"; exit(255); } @@ -701,11 +820,9 @@ sub call_package_history { exit 1; } - my $row_pattern = "%-10s %-20s %-10s %-25s %-20s %-25s\n"; + my @table = (); print sprintf("History of @{[ BOLD ]}%s@{[ RESET ]} package:\n\n", $package); - print sprintf($row_pattern, "Status", "Version", "Tag", "Timestamp", "Previous", "Upgraded"); - print sprintf("%s\n", "-"x132); my $prev_version = ''; my $prev_status = ''; @@ -728,18 +845,19 @@ sub call_package_history { $prev_version = '' if ($status_history eq 'removed'); $prev_version = '' if ($status_history eq 'installed'); - print sprintf( - $row_pattern, - $status_history, $version, - $tag, $timestamp, - $prev_version, $upgraded - ); + push(@table, [ $status_history, $version, $tag, $timestamp, $prev_version, $upgraded ]); $prev_version = $version; $prev_status = $status; } + print table({ + 'rows' => \@table, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Status', 'Version', 'Tag', 'Timestamp', 'Previous', 'Upgraded' ], + }); + print "\n"; exit(0); @@ -822,12 +940,8 @@ sub call_package_upgrade { if (scalar keys %$packages_to_update) { print "Package(s) to upgrade\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-30s %-8s %-40s %-40s %s\n", - 'Name', 'Arch', 'Version', 'Repository', 'Size'); - - print sprintf("%s\n", "-"x132); + my @rows = (); foreach (sort keys %$packages_to_update) { @@ -840,20 +954,26 @@ sub call_package_upgrade { my $pkg_size = filesize_h(($pkg->{'size_compressed'} * 1024), 1, 1); # Detect renamed package name - if ($pkg->{'new_name'} ne $pkg->{'old_name'}) { + if ( ( defined($pkg->{'new_name'}) && defined($pkg->{'old-name'}) ) + && ( $pkg->{'new_name'} ne $pkg->{'old_name'}) ) { $pkg_name = sprintf("%s -> %s", $pkg->{'old_name'}, $pkg->{'new_name'}); } $total_uncompressed_size += $pkg->{'size_uncompressed'}; $total_compressed_size += $pkg->{'size_compressed'}; - print sprintf("%-30s %-8s %-40s %-40s %s\n", - $pkg_name, $pkg_arch, $pkg_version, $pkg_repository, $pkg_size); + push(@rows, [ $pkg_name, $pkg_arch, $pkg_version, $pkg_repository, $pkg_size ]); push(@packages_to_downloads, $pkg); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Repository', 'Size' ], + }); + } if (scalar keys %$packages_to_install) { @@ -861,12 +981,7 @@ sub call_package_upgrade { print "\n\n"; print "Required package(s) to install\n\n"; - print sprintf("%s\n", "-"x132); - - print sprintf("%-30s %-8s %-9s %-20s %-40s %s\n", - 'Name', 'Arch', 'Version', 'Needed by', 'Repository', 'Size'); - - print sprintf("%s\n", "-"x132); + my @rows = (); foreach (sort keys %$packages_to_install) { @@ -876,14 +991,22 @@ sub call_package_upgrade { $total_uncompressed_size += $pkg->{size_uncompressed}; $total_compressed_size += $pkg->{size_compressed}; - print sprintf("%-30s %-8s %-9s %-20s %-40s %s\n", + push(@rows, [ $pkg->{name}, $pkg->{arch}, $pkg->{version}, $needed_by, $pkg->{repository}, filesize_h(($pkg->{size_uncompressed} * 1024), 1, 1) - ); + ]); push(@packages_to_downloads, $pkg); + } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Name', 'Arch', 'Version', 'Needed by', 'Repository', 'Size' ], + }); + + } unless (scalar keys %$packages_to_update) { @@ -996,6 +1119,23 @@ sub call_package_file_search { } +sub _changelog_announces { + + my $announces = package_changelog_announces(); + + foreach my $row ( @{$announces} ) { + + print sprintf("%s (%s)\n\n%s\n\n\n", + $row->{'timestamp'}, + colored($row->{'repository'}, 'BOLD'), + wrap(" ", " ", $row->{'announce'}) + ); + + } + +} + + sub call_package_changelog { my ($package) = @_; @@ -1006,24 +1146,37 @@ sub call_package_changelog { exit(1); } + if ($slackman_opts->{'announces'}) { + _changelog_announces(); + exit(0); + } + unless ($slackman_opts->{'details'}) { - print sprintf("%-60s %-20s %-1s %-10s %-20s %s\n", "Package", "Version", " ", "Status", "Timestamp", "Repository"); - print sprintf("%s\n", "-"x132); + my @rows = (); foreach my $row ( @{$changelogs} ) { - print sprintf("%-60s %-20s %-1s %-10s %-20s %s\n", + push(@rows, [ ($row->{'package'} || ''), ($row->{'version'} || ''), - ($row->{'security_fix'} ? "@{[ BLINK ]}@{[ RED ]}!@{[ RESET ]}" : ''), ($row->{'status'} || ''), ($row->{'timestamp'} || ''), ($row->{'repository'} || ''), - ); + ($row->{'security_fix'} ? colored('!', 'RED') : ''), + ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Package', 'Version', 'Status', 'Timestamp', 'Repository', '' ], + 'widths' => [ 0, 0, 0, 0, 0, 1 ] + }); + + exit(0); + } if ($slackman_opts->{'details'}) { @@ -1091,7 +1244,7 @@ sub call_package_new_config { $package = "(" . $manifest->[0]->{'package'} . ")"; } - print sprintf(" * %-50s %s\n", $new_config_file, $package); + print sprintf(" %-50s %s\n", $new_config_file, $package); } @@ -1257,10 +1410,12 @@ sub _packages_download { $count_downloads++; - print sprintf("[%03d/%03d] %-62s %s\n", $count_downloads, $num_downloads, $pkg->{'package'}, filesize_h(($pkg->{'size_compressed'} * 1024), 1)); + print sprintf("%-72s%8s\r", "[$count_downloads/$num_downloads] " . $pkg->{'package'}, filesize_h(($pkg->{'size_compressed'} * 1024), 1)); my ($package_path, $package_errors) = package_download($pkg); + print "\n"; + if (scalar @$package_errors) { $packages_errors->{$pkg->{'package'}} = $package_errors; } @@ -1280,14 +1435,14 @@ sub _packages_upgraded { return 1 unless(@$packages); print "\n\n"; - print sprintf("%s Package(s) upgraded\n", colored('SUCCESS', 'green bold')); + print sprintf("%s Package(s) upgraded\n", colored('DONE', 'green bold')); print sprintf("%s\n\n", "-"x80); foreach (@$packages) { my $pkg = get_package_info(basename($_)); - print sprintf(" * %s upgraded to %s version\n", + print sprintf(" %s upgraded to %s version\n", colored($pkg->{'name'}, 'bold'), colored($pkg->{'version'}, 'bold') ); @@ -1305,12 +1460,15 @@ sub _packages_installed { return 1 unless(@$packages); print "\n\n"; - print sprintf("%s Package(s) installed\n", colored('SUCCESS', 'green bold')); + print sprintf("%s Package(s) installed\n", colored('DONE', 'green bold')); print sprintf("%s\n\n", "-"x80); foreach (@$packages) { my $pkg = get_package_info(basename($_)); - print sprintf(" * installed %s %s version\n", $pkg->{'name'}, $pkg->{'version'}); + print sprintf(" installed %s %s version\n", + colored($pkg->{'name'}, 'bold'), + colored($pkg->{'version'}, 'bold') + ); } print "\n\n"; @@ -1328,7 +1486,7 @@ sub _packages_errors { print sprintf("%s\n\n", "-"x80); foreach my $pkg (keys %$packages_errors) { - print sprintf(" * %-50s %s\n", $pkg, join(', ', @{$packages_errors->{$pkg}})); + print sprintf(" %-50s %s\n", $pkg, join(', ', @{$packages_errors->{$pkg}})); } print "\n\n"; @@ -1359,8 +1517,8 @@ sub _kernel_update_message { $message .= "with @{[ BOLD ]}$lilo_command@{[ RESET ]} command.\n\n"; $message .= "For more information read:\n\n" - . " * /boot/README.initrd\n" - . " * mkinitrd(8)\n\n"; + . " - /boot/README.initrd\n" + . " - mkinitrd(8)\n\n"; print "\n"; print wrap("", "\t", $message); @@ -1456,12 +1614,10 @@ sub _check_package_duplicates { foreach (keys %$pkg_rows_ref) { - $pkg_id++; - my $row = $pkg_rows_ref->{$_}; push(@packages, $row->{'package'}); - print sprintf(" %s) %-40s (%s)\n", $pkg_id, $row->{'package'}, $row->{'timestamp'}); + print sprintf(" %s) %-40s (%s)\n", $pkg_id++, $row->{'package'}, $row->{'timestamp'}); } @@ -1526,6 +1682,7 @@ slackman-package - Install, upgrade and display information of Slackware package -c, --config=FILE Configuration file --root Set Slackware root directory --color=[always|auto|never] Colorize the output + --terse Display only a single description line when install or upgrade a package =head2 CHANGELOG OPTIONS @@ -1534,6 +1691,7 @@ slackman-package - Install, upgrade and display information of Slackware package --details Display ChangeLog details --security-fix Display only ChangeLog Security Fix --cve=CVE-YYYY-NNNNNN Search a CVE identifier into ChangeLogs + --announces Display announce in ChangeLog =head2 INFO OPTIONS @@ -1609,7 +1767,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/lib/Slackware/SlackMan/Command/Repo.pm b/lib/Slackware/SlackMan/Command/Repo.pm index 0f9cba7..8d06a1b 100644 --- a/lib/Slackware/SlackMan/Command/Repo.pm +++ b/lib/Slackware/SlackMan/Command/Repo.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw(); %EXPORT_TAGS = ( @@ -22,6 +22,7 @@ BEGIN { use Slackware::SlackMan; use Slackware::SlackMan::DB qw(:all); +use Slackware::SlackMan::Config qw(:all); use Slackware::SlackMan::Repo qw(:all); use Slackware::SlackMan::Utils qw(:all); use Slackware::SlackMan::Parser qw(:all); @@ -110,8 +111,8 @@ sub call_repo_add { my $download_exit_code = download_file($repo_url, $repo_tmpfile); - if ( $download_exit_code > 0 ) { - print colored('ERROR', 'red bold') . ": Repository file download error (cURL: $download_exit_code)\n"; + unless ( $download_exit_code == 200 ) { + print colored('ERROR', 'red bold') . ": Repository file download error ($download_exit_code)\n"; exit(255); } @@ -144,9 +145,9 @@ sub call_repo_add { $repo_desc = trim($repo_desc); - my %repo_config = parse_config($repo_content); + my $repo_config = get_config($repo_tmpfile); - unless ( %repo_config ) { + unless ( $repo_config ) { print colored('ERROR', 'red bold') . ": Invalid repository file ($repo_url)\n"; exit(255); } @@ -158,11 +159,11 @@ sub call_repo_add { print sprintf("%-30s %-50s\n", "Repository ID", "Description"); print sprintf("%s\n", "-"x80); - foreach ( keys %repo_config ) { + foreach ( keys %{$repo_config} ) { my $repo_id = "$repo_name:$_"; - my $repo_name = parse_variables($repo_config{$_}->{'name'}); - my $repo_mirror = $repo_config{$_}->{'mirror'}; + my $repo_name = parse_variables($repo_config->{$_}->{'name'}); + my $repo_mirror = $repo_config->{$_}->{'mirror'}; unless ($repo_mirror) { print colored('ERROR', 'red bold') . ": Invalid repository file ($repo_url)\n"; @@ -194,26 +195,33 @@ sub call_repo_list { my @repositories = get_repositories(); - print "\nAvailable repository\n\n"; - print sprintf("%s\n", "-"x132); - print sprintf("%-30s %-70s %-10s %-10s %-4s\n", "Repository ID", "Description", "Status", "Priority", "Packages"); - print sprintf("%s\n", "-"x132); + print "\nAvailable repository\n\n" if ($slackman_opts->{'format'} eq 'default'); + + my @rows = (); foreach my $repo_id (@repositories) { my $repo_info = get_repository($repo_id); my $num_pkgs = $dbh->selectrow_array('SELECT COUNT(*) AS packages FROM packages WHERE repository = ?', undef, $repo_id); - print sprintf("%-30s %-70s %-10s %-10s %-4s\n", + push(@rows, [ $repo_id, $repo_info->{'name'}, ($repo_info->{'enabled'} ? colored(sprintf("%-10s", 'Enabled'), 'GREEN') : 'Disabled'), $repo_info->{'priority'}, $num_pkgs - ); + ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' ', 'header' => '-' }, + 'headers' => [ 'Repository ID', 'Description', 'Status', 'Priority', 'Packages' ], + 'widths' => [ 0, 0, 10, 0, 0 ], + 'format' => $slackman_opts->{'format'} + }); + exit(0); } @@ -287,6 +295,13 @@ sub call_repo_info { exit(255); } + my @repos = get_repositories(); + + unless ( grep(/^$repo_id$/, @repos) ) { + print sprintf("%s Unknown repository!\n\n", colored('WARNING', 'yellow bold')); + exit(1); + } + update_repo_data($repo_id); my $repo_data = get_repository($repo_id); @@ -297,41 +312,64 @@ sub call_repo_info { } my $repo_content = file_read($repo_data->{config_file}); - my $repo_desc = ''; + my @repo_desc = (); LINE: foreach my $line ( split(/\n/, $repo_content ) ) { last LINE if ( $line =~ /^\[/); $line =~ s/^#//; - $repo_desc .= sprintf("%-15s : %s\n", ' ', trim($line)); + push(@repo_desc, trim($line)) if (length($line)); } - $repo_desc = trim($repo_desc); my $package_nums = $dbh->selectrow_array('SELECT COUNT(*) AS packages FROM packages WHERE repository = ?', undef, $repo_id); my $last_update = time_to_timestamp(db_meta_get("last-update.$repo_id.packages")); my @urls = qw/changelog packages manifest checksums gpgkey/; + my @rows = (); - print "\n"; - print sprintf("%-15s : %s\n", "ID", $repo_data->{'id'}); - print sprintf("%-15s : %s\n", "Name", $repo_data->{'name'}); - print sprintf("%-15s : %s\n", "Configuration", $repo_data->{'config_file'}); - print sprintf("\n%-15s %s\n\n", "Description", $repo_desc) if ($repo_desc && scalar(split(/\n/, $repo_desc)) > 1); - print sprintf("%-15s : %s\n", "Mirror", $repo_data->{'mirror'}); - print sprintf("%-15s : %s\n", "Status", (($repo_data->{'enabled'}) ? colored('enabled', 'GREEN') : colored('disabled', 'RED'))); - print sprintf("%-15s : %s\n", "Last Update", ($last_update || '')); - print sprintf("%-15s : %s\n", "Priority", $repo_data->{'priority'}); - print sprintf("%-15s : %s\n", "Excluded", join(', ', @{$repo_data->{'exclude'}})) if ($repo_data->{'exclude'}); - print sprintf("%-15s : %s\n", "Packages", $package_nums); - print sprintf("%-15s : %s\n", "Directory", $repo_data->{'cache_directory'}); - - print "\n\nRepository URLs\n\n"; + push(@rows, [ 'ID', $repo_data->{'id'} ]); + push(@rows, [ 'Name', $repo_data->{'name'} ]); + push(@rows, [ 'Configuration', $repo_data->{'config_file'} ]); + + if (@repo_desc) { + + push(@rows, [ '', '' ]); + + for (my $i=0; $i < @repo_desc; $i++) { + push(@rows, [ 'Description', $repo_desc[$i] ]) if ($i < 1); + push(@rows, [ ' ', $repo_desc[$i] ]) if ($i >= 1); + } + + } + + push(@rows, [ 'Arch Support', sprintf("x86: %s\tx86_64: %s\tarm: %s", + ($repo_data->{'arch'}->{'x86'} ? colored('yes', 'GREEN') : 'no'), + ($repo_data->{'arch'}->{'x86_64'} ? colored('yes', 'GREEN') : 'no'), + ($repo_data->{'arch'}->{'arm'} ? colored('yes', 'GREEN') : 'no') + )]); + + push(@rows, [ 'Mirror', $repo_data->{'mirror'} ]); + push(@rows, [ 'Status', (($repo_data->{'enabled'}) ? colored('enabled', 'GREEN') : colored('disabled', 'RED')) ]); + push(@rows, [ 'Last Update', ($last_update || '') ]); + push(@rows, [ 'Priority', $repo_data->{'priority'} ]); + push(@rows, [ 'Excluded', join(', ', @{$repo_data->{'exclude'}}) ] ) if ($repo_data->{'exclude'}); + push(@rows, [ 'Packages', $package_nums ]); + push(@rows, [ 'Directory', $repo_data->{'cache_directory'} ]); + + push(@rows, [ '', '' ]); + push(@rows, [ 'Repository URLs', '' ]); foreach (@urls) { next unless($repo_data->{$_}); - print sprintf(" - %-10s : %s\n", $_, $repo_data->{$_}); + push(@rows, [ " - $_" , $repo_data->{$_} ]); } + print table({ + 'rows' => \@rows, + 'separator' => { 'column' => ' : ' }, + }); + + print "\n"; exit(0); @@ -488,7 +526,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/lib/Slackware/SlackMan/Command/Update.pm b/lib/Slackware/SlackMan/Command/Update.pm index 066f846..0892511 100644 --- a/lib/Slackware/SlackMan/Command/Update.pm +++ b/lib/Slackware/SlackMan/Command/Update.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw(); %EXPORT_TAGS = ( @@ -89,7 +89,7 @@ sub call_update_repo_packages { logger->info(qq/Update "$repo" repository packages/); my $repo_data = get_repository($repo); - STDOUT->printflush(sprintf(" * %-30s", $repo)); + STDOUT->printflush(sprintf(" - %-30s", $repo)); parse_packages($repo_data, \&callback_status); STDOUT->printflush(colored("done\n", 'green')); @@ -121,7 +121,7 @@ sub call_update_repo_gpg_key { logger->info(qq/Update "$repo" repository GPG-KEY/); my $repo_data = get_repository($repo); - STDOUT->printflush(sprintf(" * %-30s", $repo)); + STDOUT->printflush(sprintf(" - %-30s", $repo)); my $gpg_key_path = sprintf('%s/%s/GPG-KEY', $slackman_conf->{'directory'}->{'cache'}, $repo); @@ -153,7 +153,7 @@ sub call_update_repo_changelog { logger->info(qq/Update "$repo" repository ChangeLog/); my $repo_data = get_repository($repo); - STDOUT->printflush(sprintf(" * %-30s", $repo)); + STDOUT->printflush(sprintf(" - %-30s", $repo)); parse_changelog($repo_data, \&callback_status); STDOUT->printflush(colored("done\n", 'green')); @@ -181,7 +181,7 @@ sub call_update_repo_manifest { my $repo_data = get_repository($repo); - STDOUT->printflush(sprintf(" * %-30s", $repo)); + STDOUT->printflush(sprintf(" - %-30s", $repo)); parse_manifest($repo_data, \&callback_status); STDOUT->printflush(colored("done\n", 'green')); @@ -311,7 +311,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/lib/Slackware/SlackMan/Config.pm b/lib/Slackware/SlackMan/Config.pm index 6761778..64a1604 100644 --- a/lib/Slackware/SlackMan/Config.pm +++ b/lib/Slackware/SlackMan/Config.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw( get_config ); %EXPORT_TAGS = ( @@ -203,12 +203,10 @@ sub parse { my ($self, $config_string) = @_; - my @lines = split(/\n/, $config_string); + my $section = '_'; # Root section + my $config_data = {}; - my $section; - my %config_data = (); - - foreach my $line (@lines) { + foreach my $line ( split(/\n/, $config_string) ) { chomp($line); @@ -229,19 +227,19 @@ sub parse { my $value = (( @$parsed_value == 1 ) ? $parsed_value->[0] : $parsed_value); if (not defined $section) { - $config_data{$field} = $value; + $config_data->{$field} = $value; next; } - $config_data{$section}{$field} = $value; + $config_data->{$section}->{$field} = $value; } } - $self->{'data'} = \%config_data; + $self->{'data'} = $config_data; - return \%config_data; + return $config_data; } @@ -321,7 +319,7 @@ sub replace { } -sub replaceAndSave { +sub replace_and_save { my ($self, $param, $new_value, $file) = @_; @@ -460,7 +458,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/DB.pm b/lib/Slackware/SlackMan/DB.pm index 649fb5d..62aa47e 100644 --- a/lib/Slackware/SlackMan/DB.pm +++ b/lib/Slackware/SlackMan/DB.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw{ @@ -42,7 +42,7 @@ use DBI; use Slackware::SlackMan; use Slackware::SlackMan::Utils qw(:all); -use constant SLACKMAN_SCHEMA_VERSION => 3; +use constant SLACKMAN_SCHEMA_VERSION => 4; use constant SLACKMAN_PACKAGES_TABLE => qq/CREATE TABLE IF NOT EXISTS "packages" ( "id" INTEGER PRIMARY KEY, @@ -124,6 +124,7 @@ use constant SLACKMAN_CHANGELOGS_TABLE => qq/CREATE TABLE IF NOT EXISTS "changel "category" VARCHAR, "status" VARCHAR, "description" VARCHAR, + "announce" TEXT, "security_fix" BOOL, "issues" VARCHAR)/; @@ -146,7 +147,7 @@ use constant SLACKMAN_SCHEMA => { use constant SLACKMAN_TABLES => qw( packages metadata changelogs history manifest ); use constant SLACKMAN_INDEXES => qw( history_idx packages_idx manifest_idx ); -# Override built-in DBI module subroutines for loggin +# Override built-in DBI module subroutines for log all SQL statements BEGIN { if ( $slackman_conf->{'logger'}->{'category'} =~ /sql/ ) { @@ -526,7 +527,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/DBus.pm b/lib/Slackware/SlackMan/DBus.pm index adfe5a9..13ce685 100644 --- a/lib/Slackware/SlackMan/DBus.pm +++ b/lib/Slackware/SlackMan/DBus.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw{}; @@ -63,6 +63,7 @@ dbus_signal('UpdatedManifest', [ 'string' ]); # Slackware and SlackMan version properties dbus_property('version', 'string', 'read'); dbus_property('slackware', 'string', 'read'); +dbus_property('isCurrent', 'bool', 'read'); # Methods @@ -70,6 +71,7 @@ dbus_property('slackware', 'string', 'read'); # ChangeLog methods dbus_method('ChangeLog', [ 'string' ], [[ 'dict', 'string', [ 'array', [ 'dict', 'string', 'string' ] ]]], { 'param_names' => [ 'repo_id' ] }); dbus_method('SecurityFix', [], [[ 'dict', 'string', [ 'array', [ 'dict', 'string', 'string' ] ]]]); +dbus_method('Announce', [ 'string' ], [[ 'dict', 'string', [ 'array', [ 'dict', 'string', 'string' ] ]]], { 'param_names' => [ 'repo_id' ] }); # Package methods dbus_method('PackageInfo', [ 'string' ], [[ 'dict', 'string', 'string' ]], { 'param_names' => [ 'package_name' ] }); @@ -95,12 +97,12 @@ sub version { sub slackware { + return get_slackware_release(); +} - my $release = get_slackware_release(); - $release = $slackman_conf->{'slackware'}->{'version'} if (defined $slackman_conf->{'slackware'}); - - return $release; +sub isCurrent { + return is_slackware_current(); } @@ -192,6 +194,32 @@ sub ChangeLog { } +sub Announce { + + my ($self, $repo_id) = @_; + + logger->debug("Call org.lotarproject.SlackMan.Announce method (args: repo_id=$repo_id)"); + + $slackman_opts = {}; + + $slackman_opts->{'after'} = '-7d'; + $slackman_opts->{'limits'} = 256; + $slackman_opts->{'repo'} = $repo_id if ($repo_id); + + _reload_data(); + + my $changelogs = package_changelog_announces(); + my $result = {}; + + foreach (@{$changelogs}) { + push( @{ $result->{ $_->{'repository'} } } , $_ ); + } + + return $result; + +} + + sub SecurityFix { my ($self) = @_; @@ -424,7 +452,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/Logger.pm b/lib/Slackware/SlackMan/Logger.pm index 16e0e3e..86fb9c1 100644 --- a/lib/Slackware/SlackMan/Logger.pm +++ b/lib/Slackware/SlackMan/Logger.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw{} @@ -246,7 +246,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/Package.pm b/lib/Slackware/SlackMan/Package.pm index 1e80c02..30cff0f 100644 --- a/lib/Slackware/SlackMan/Package.pm +++ b/lib/Slackware/SlackMan/Package.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw{ @@ -32,6 +32,7 @@ BEGIN { package_check_updates package_check_install package_search_files + package_changelog_announces }; %EXPORT_TAGS = ( @@ -52,13 +53,38 @@ use Slackware::SlackMan::DB qw(:all); use Slackware::SlackMan::Parser qw(:all); use Slackware::SlackMan::Pkgtools; + + +sub package_changelog_announces { + + my @query_filters = (); + + # Filter by date range + if (my $timestamp_options = timestamp_options_to_sql()) { + push(@query_filters, $timestamp_options); + } + + # Filter enabled repositories + push(@query_filters, repo_option_to_sql()); + push(@query_filters, 'announce IS NOT NULL'); + + my $query = 'SELECT repository, timestamp, announce FROM changelogs WHERE %s ORDER BY timestamp DESC LIMIT %s'; + $query = sprintf($query, join(' AND ', @query_filters), ($slackman_opts->{'limit'} || 25)); + + my $sth = $dbh->prepare($query); + $sth->execute(); + + return $sth->fetchall_arrayref({}); + +} + + sub package_changelogs { my ($package) = @_; my $option_repo = $slackman_opts->{'repo'}; my $option_cve = $slackman_opts->{'cve'}; - my @repositories = get_enabled_repositories(); my @query_filters = (); # Get only machine arch and "noarch" changelogs @@ -91,6 +117,8 @@ sub package_changelogs { push(@query_filters, sprintf('( "," || issues || "," LIKE %s )', $dbh->quote("%,$option_cve,%"))); } + push(@query_filters, 'announce IS NULL'); + my $query = 'SELECT * FROM changelogs WHERE %s ORDER BY timestamp DESC LIMIT %s'; $query = sprintf($query, join(' AND ', @query_filters), ($slackman_opts->{'limit'} || 25)); @@ -133,6 +161,10 @@ sub package_metadata { $size_uncompressed = $1 if ($_ =~ /^UNCOMPRESSED PACKAGE SIZE:\s+((.*)(K|M))/); } + # Convert "," to "." + $size_compressed =~ s/,/./; + $size_uncompressed =~ s/,/./; + if ($size_compressed =~ /M/) { $size_compressed =~ s/M//; $size_compressed = trim($size_compressed) * 1024; @@ -233,7 +265,7 @@ sub package_version_compare { sub package_install { - my $package = shift; + my ($package) = @_; installpkg($package); _update_history($package, 'install'); @@ -243,7 +275,7 @@ sub package_install { sub package_upgrade { - my $package = shift; + my ($package) = @_; my $pkg_info = get_package_info(basename($package)); @@ -393,9 +425,24 @@ sub package_check_install { # Filter repository push(@query_filters, repo_option_to_sql('packages')); + # Filter excluded packages if ($option_exclude) { - $option_exclude =~ s/\*/%/g; - push(@query_filters, sprintf('packages.name NOT LIKE %s', $dbh->quote($option_exclude))); + foreach my $exclude (@{$option_exclude}) { + $exclude =~ s/\*/%/g; + push(@query_filters, sprintf('packages.name NOT LIKE %s', $dbh->quote($exclude))); + } + } + + # Global main excluded packages + if (defined($slackman_conf->{'main'}->{'exclude'})) { + + my @excluded = split(/,/, $slackman_conf->{'main'}->{'exclude'}); + + foreach my $exclude (@excluded) { + $exclude =~ s/\*/%/g; + push(@query_filters, sprintf('packages.name NOT LIKE %s', $dbh->quote($exclude))); + } + } push(@query_filters, sprintf('packages.category = "%s"', $slackman_opts->{'category'})) if ($slackman_opts->{'category'}); @@ -545,10 +592,24 @@ sub package_check_updates { my $option_exclude = $slackman_opts->{'exclude'}; my $option_tag = $slackman_opts->{'tag'}; - # Exclude package + # Filter excluded packages if ($option_exclude) { - $option_exclude =~ s/\*/%/g; - push(@query_filters, qq/packages.name NOT LIKE "$option_exclude"/); + foreach my $exclude (@{$option_exclude}) { + $exclude =~ s/\*/%/g; + push(@query_filters, sprintf('packages.name NOT LIKE %s', $dbh->quote($exclude))); + } + } + + # Global excluded packages + if (defined($slackman_conf->{'main'}->{'exclude'})) { + + my @excluded = split(/,/, $slackman_conf->{'main'}->{'exclude'}); + + foreach my $exclude (@excluded) { + $exclude =~ s/\*/%/g; + push(@query_filters, sprintf('packages.name NOT LIKE %s', $dbh->quote($exclude))); + } + } # Filter installed package with tag @@ -556,10 +617,10 @@ sub package_check_updates { push(@query_filters, qq/history.tag = "$option_tag"/); } - foreach ( keys %{$slackman_conf->{'renames'}} ) { + foreach ( keys %{$slackman_conf->{'renames'}->{'_'}} ) { my $old_package_name = $_; - my $new_package_name = $slackman_conf->{'renames'}->{$_}; + my $new_package_name = $slackman_conf->{'renames'}->{'_'}->{$_}; push(@renamed_filters, qq/(history.name = "$old_package_name" AND packages.name = "$new_package_name")/); @@ -683,7 +744,7 @@ sub package_download { my $local_file = $package_url; $local_file =~ s/file:\/\///; - logger->info(sprintf("Create link of %s package and .asc file", $pkg->{'package'})); + logger->info(sprintf("Create link of %s package and %s.asc file", $pkg->{'package'}, $pkg->{'package'})); symlink($local_file, $package_path); symlink("$local_file.asc", "$package_path.asc"); @@ -694,7 +755,7 @@ sub package_download { my $download_package_status = download_file($package_url, "$package_path.part", 'progress-bar'); - if ( $download_package_status eq 0 ) { + if ( $download_package_status eq 200 ) { logger->info(sprintf("Downloaded %s package", $pkg->{'package'})); rename("$package_path.part", $package_path); @@ -702,7 +763,7 @@ sub package_download { } else { logger->error(sprintf("Error during download of %s package", $pkg->{'package'})); - push(@package_errors, "Download error (cURL: $download_package_status)"); + push(@package_errors, "Download error ($download_package_status)"); } @@ -712,7 +773,9 @@ sub package_download { unless (-e "$package_path.asc") { - if ( download_file("$package_url.asc", "$package_path.asc") == 200 ) { + my $download_asc_status = download_file("$package_url.asc", "$package_path.asc"); + + if ( $download_asc_status eq 200 ) { logger->info(sprintf("Downloaded signature of %s package", $pkg->{'package'})); } @@ -769,6 +832,7 @@ sub package_download { unless ($skip_check) { unless ($md5_check && $gpg_verify) { + unlink("$package_path.asc"); unlink($package_path) or warn "Failed to remove file: $!"; } @@ -873,7 +937,8 @@ sub package_search_files { my ($file) = @_; - $file = "/$file" unless ($file =~ /^\//); + #$file = "/$file" unless ($file =~ /^\//); + #$file = quotemeta($file); my $sth = $dbh->prepare('SELECT * FROM manifest WHERE files REGEXP(?)'); $sth->execute(qr/$file/); @@ -980,7 +1045,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/Parser.pm b/lib/Slackware/SlackMan/Parser.pm index 9e12130..9cf65df 100644 --- a/lib/Slackware/SlackMan/Parser.pm +++ b/lib/Slackware/SlackMan/Parser.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw{ @@ -22,6 +22,7 @@ BEGIN { parse_changelog parse_module_name parse_package_history + parse_announces }; %EXPORT_TAGS = ( @@ -40,6 +41,101 @@ use Slackware::SlackMan::Package qw(:all); use Slackware::SlackMan::Repo qw(:all); +sub parse_announces { + + my ($repo) = @_; + + my $repository = $repo->{'id'}; + my $changelog_separator = quotemeta('+--------------------------+'); + my $changelog_file = sprintf("%s/ChangeLog.txt", $repo->{'cache_directory'}); + my $changelog_contents = file_read($changelog_file); + + $dbh->do('DELETE FROM changelogs WHERE repository = ? AND announce IS NOT NULL', undef, $repository); + + chomp($changelog_contents); + + my @changelogs = split(/$changelog_separator/, $changelog_contents); + my @columns = qw(repository timestamp announce); + my @values = (); + my $data = {}; + + my @rules = ( + + # Standard Slackware ChangeLog + qr/^([[:graph:]]+\/[[:graph:]]+):\s+(added|rebuilt|removed|upgraded|updated|patched|renamed|moved|name change|switched)/i, + + #qr/^([[:graph:]]+\/[[:graph:]]+)\s(added|rebuilt|removed|upgraded|updated|patched|renamed|moved|name change|switched)/i, + + # AlienBob + qr/^([[:graph:]]+):\s+(updated to|upgraded to|added|added a|rebuilt|patched)\s+([[:graph:]]+)/i, + qr/^([[:graph:]]+):\s+(updated to|upgraded to|added|added a|rebuilt|patched)\s+((v\s|v)([[:graph:]]+))/i, + qr/^([[:graph:]]+) added version (\d.([[:graph:]]+))/i, + qr/^([[:graph:]]+) updated for version (\d.([[:graph:]]+))/i, + qr/^([[:graph:]]+)\s:\s(built|upgraded|update|updated)/i, + + # SlackOnly + qr/^(([[:graph:]]+)\/([[:graph:]]+))\s(added|removed|rebuilt|updated|upgraded)/i, + + # CSB + qr/^([[:graph:]]+):\s+(added|removed|rebuilt|updated|upgraded)*/i, + + # Others + qr/(\d+\.\d+)\/x86\:$/, + qr/compat32\:\s+|t?z\:\s+/i, + qr/\+\-\-\-/, + qr/latest\s-$/, + + ); + + foreach my $changelog (@changelogs) { + + chomp($changelog); + + my @lines = split(/\n/, trim($changelog)); + my $changelog_time = changelog_date_to_time($lines[0]); + my $changelog_timestamp = time_to_timestamp($changelog_time); + + @lines = @lines[ 1 .. $#lines ]; + + $data->{$changelog_timestamp} = (); + + CHANGELOG: foreach (@lines) { + + foreach my $regex (@rules) { + last CHANGELOG if ($_ =~ /$regex/); + } + + push(@{$data->{$changelog_timestamp}}, $_); + + } + + } + + foreach my $timestamp (keys %{$data}) { + + next unless ($data->{$timestamp}); + + my $announce = trim(join("\n", @{$data->{$timestamp}})); + + my @row = ( + $repository, + $timestamp, + $announce + ); + + push(@values, \@row) if ($announce); + + } + + db_bulk_insert( + 'table' => 'changelogs', + 'columns' => \@columns, + 'values' => \@values, + ); + +} + + sub parse_changelog { my ($repo, $callback_status) = @_; @@ -55,7 +151,7 @@ sub parse_changelog { my $changelog_contents = file_read($changelog_file); return(0) unless($changelog_contents); - $dbh->do('DELETE FROM changelogs WHERE repository = ?', undef, $repository); + $dbh->do('DELETE FROM changelogs WHERE repository = ? AND announce IS NULL', undef, $repository); chomp($changelog_contents); @@ -63,7 +159,7 @@ sub parse_changelog { my @columns = qw(timestamp package status name version arch build tag repository security_fix category description issues); my @values = (); - &$callback_status('parse') if ($callback_status); + &$callback_status('parsing') if ($callback_status); my $i = 0; @@ -228,6 +324,8 @@ sub parse_changelog { &$callback_status('save') if ($callback_status); + parse_announces($repo); + db_bulk_insert( 'table' => 'changelogs', 'columns' => \@columns, @@ -283,7 +381,7 @@ sub parse_packages { my @packages = split(/\n{2,}/, $packages_contents); my @checksums = parse_checksums($repo, $callback_status); - &$callback_status('parse') if ($callback_status); + &$callback_status('parsing') if ($callback_status); my $last_update = shift(@packages); $last_update =~ s/PACKAGES.TXT;\s+// if ($last_update); @@ -371,7 +469,7 @@ sub parse_manifest { db_meta_delete("manifest-last-update.$repository"); - &$callback_status('parse') if ($callback_status); + &$callback_status('parsing') if ($callback_status); bunzip2 \$manifest_input => \$manifest_contents or die "bunzip2 failed: $Bunzip2Error\n"; @@ -446,7 +544,9 @@ sub parse_package_history { my $slackware_root = $ENV{ROOT} || ''; - my @files = grep { -f } glob("$slackware_root/var/log/*packages/$package*"); + my @installed_files = grep { -f } glob($slackman_conf->{'pkgtools'}->{'packages'} . "/$package*"); + my @removed_files = grep { -f } glob($slackman_conf->{'pkgtools'}->{'removed-packages'} . "/$package*"); + my @files = ( @installed_files, @removed_files); logger->info("Update history of $package package"); @@ -521,12 +621,9 @@ sub parse_history { my ($callback_status) = @_; - my $slackware_root = $ENV{ROOT} || ''; - my $slackware_log_path = "$slackware_root/var/log"; - - my @files = grep { -f } glob("$slackware_log_path/*packages/*"); - my @installed_files = grep { -f } glob("$slackware_log_path/packages/*"); - my @removed_files = grep { -f } glob("$slackware_log_path/removed_packages/*"); + my @installed_files = grep { -f } glob($slackman_conf->{'pkgtools'}->{'packages'} . '/*'); + my @removed_files = grep { -f } glob($slackman_conf->{'pkgtools'}->{'removed-packages'} . '/*'); + my @files = ( @installed_files, @removed_files); my $local_history = scalar @files; my $local_installed = scalar @installed_files; @@ -556,7 +653,7 @@ sub parse_history { my @columns = qw(name package version build tag arch status timestamp upgraded summary description size_compressed size_uncompressed); - &$callback_status('parse') if ($callback_status); + &$callback_status('parsing') if ($callback_status); logger->debug('Parsing all local history files from /var/log/packages & /var/log/removed_packages directories'); my $i = 0; @@ -645,6 +742,7 @@ sub parse_variables { my $release_suffix = ''; $release_conf = $slackman_conf->{'slackware'}->{'version'} if (defined $slackman_conf->{'slackware'}); + $release_conf = 'current' if (is_slackware_current()); if ($arch eq 'x86_64') { $arch_bit = 64; } elsif ($arch =~ /x86|i[3456]86/) { $arch_bit = 32; $arch_family = 'x86'; } @@ -839,7 +937,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/Pkgtools.pm b/lib/Slackware/SlackMan/Pkgtools.pm index 17b4f34..8c48f19 100644 --- a/lib/Slackware/SlackMan/Pkgtools.pm +++ b/lib/Slackware/SlackMan/Pkgtools.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT = qw{ @@ -61,7 +61,11 @@ sub reinstallpkg { } sub _to_params { - return map { ((length($_) > 1) ? "--$_" : "-$_") } @_; + + return map { + ((length($_) > 1) ? "--$_" : "-$_") + } grep { $_ ne '' } @_; + } sub _pkg_exists { @@ -92,6 +96,7 @@ sub _pkgtool_action { my $action = shift; my $package = shift; + my @params = _to_params(@_); _check_root($action); @@ -185,7 +190,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/Repo.pm b/lib/Slackware/SlackMan/Repo.pm index bdabe74..bb18aae 100644 --- a/lib/Slackware/SlackMan/Repo.pm +++ b/lib/Slackware/SlackMan/Repo.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw{ @@ -55,6 +55,7 @@ load_repositories(); sub load_repositories { my @files = grep { -f } glob(sprintf('%s/*.repo', $slackman_conf->{'directory'}->{'repos'})); + my $arch = get_arch(); foreach my $file (@files) { @@ -66,8 +67,12 @@ sub load_repositories { foreach my $repo (@repos) { + # Skip main section "_" + next if ($repo eq '_'); + my $repo_config = $config_data->{$repo}; my $repo_id = "$config_name:$repo"; + my $repo_arch = {}; my $mirror = $repo_config->{'mirror'}; $mirror =~ s/\/$//; @@ -79,6 +84,49 @@ sub load_repositories { $repo_config->{'enabled'} ||= 0; $repo_config->{'exclude'} ||= undef; + # Set repo arch support + if (defined($repo_config->{'arch'})) { + + if (ref($repo_config->{'arch'}) ne 'ARRAY') { + $repo_config->{'arch'} = 'x86_64' if ($repo_config->{'arch'} eq 'x86-64'); + $repo_config->{'arch'} = [ $repo_config->{'arch'} ]; + } + + foreach (@{$repo_config->{'arch'}}) { + + my ($config_arch, $directory_prefix) = split(/:/, $_); + my $enabled = 1; + + if ($config_arch =~ /^!/) { + $enabled = 0; + $config_arch =~ s/^!//; + } + + $config_arch = 'x86_64' if ($config_arch eq 'x86-64'); + + $repo_arch->{$config_arch} = $enabled; + $repo_arch->{$config_arch} = $directory_prefix if ($directory_prefix); + + } + + $repo_config->{'arch'} = $repo_arch; + + } else { + + $repo_config->{'arch'} = { + 'x86' => 1, + 'x86_64' => 1, + 'arm' => 1, + }; + + } + + # Disable the repo if arch is not supported (eg. slackware:multilib on non x86_64 machine) + if ($arch eq 'x86_64') { $repo_config->{'enabled'} = 0 if (! $repo_config->{'arch'}->{'x86_64'}); } + elsif ($arch =~ /x86|i[3456]86/) { $repo_config->{'enabled'} = 0 if (! $repo_config->{'arch'}->{'x86'}); } + elsif ($arch =~ /arm(.*)/) { $repo_config->{'enabled'} = 0 if (! $repo_config->{'arch'}->{'arm'}); } + + $repo_config->{'changelog'} = "$mirror/ChangeLog.txt" unless(defined($repo_config->{'changelog'})); $repo_config->{'packages'} = "$mirror/PACKAGES.TXT" unless(defined($repo_config->{'packages'})); $repo_config->{'manifest'} = "$mirror/MANIFEST.bz2" unless(defined($repo_config->{'manifest'})); @@ -90,12 +138,31 @@ sub load_repositories { gpgkey filelist ); foreach (@keys_to_parse) { + $repo_config->{$_} =~ s/(\{|\})//g; $repo_config->{$_} =~ s/\$mirror/$mirror/; - } - foreach (@keys_to_parse) { + # Replace repo arch in $arch variable + if ($arch ne 'x86_64' && $arch =~ /x86|i[3456]86/) { + + if (defined($repo_config->{'arch'}->{'x86'}) && $repo_config->{'arch'}->{'x86'} =~ /x86|i[3456]86/) { + my $repo_arch = $repo_config->{'arch'}->{'x86'}; + $repo_config->{$_} =~ s/\$arch/$repo_arch/; + } + + } + + if ($arch =~ /arm(.*)/) { + + if (defined($repo_config->{'arch'}->{'arm'}) && $repo_config->{'arch'}->{'arm'} =~ /arm(.*)/) { + my $repo_arch = $repo_config->{'arch'}->{'arm'}; + $repo_config->{$_} =~ s/\$arch/$repo_arch/; + } + + } + $repo_config->{$_} = parse_variables($repo_config->{$_}); + } my $repo_cache_directory = $repo_id; @@ -133,7 +200,7 @@ sub set_repository_value { logger->debug(qq{$repo_id - Set "$key" = "$value"}); my $cfg = Slackware::SlackMan::Config->new($repo_file); - $cfg->replaceAndSave("$repo_section.$key", $value); + $cfg->replace_and_save("$repo_section.$key", $value); } @@ -405,7 +472,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/lib/Slackware/SlackMan/Utils.pm b/lib/Slackware/SlackMan/Utils.pm index 9fdc2e2..cc00a33 100644 --- a/lib/Slackware/SlackMan/Utils.pm +++ b/lib/Slackware/SlackMan/Utils.pm @@ -11,7 +11,7 @@ BEGIN { require Exporter; - $VERSION = 'v1.3.0'; + $VERSION = 'v1.4.0'; @ISA = qw(Exporter); @EXPORT_OK = qw( @@ -23,7 +23,6 @@ BEGIN { confirm confirm_choice create_lock - curl_cmd datetime_calc datetime_h dbus_notifications @@ -31,12 +30,15 @@ BEGIN { delete_lock directory_files download_file + failed_sign file_append file_handler file_read file_read_url file_write filesize_h + str_pad + table get_arch get_last_modified get_lock_pid @@ -44,17 +46,20 @@ BEGIN { get_slackware_release gpg_import_key gpg_verify + http_client + http_date_to_time + is_slackware_current ldd md5_check repo_option_to_sql + success_sign + terminal_width + time_h time_to_timestamp timestamp_options_to_sql timestamp_to_time trim uniq - w3c_date_to_time - success_sign - failed_sign versioncmp ); @@ -75,8 +80,8 @@ use Time::Piece; use Time::Seconds; use Carp (); use File::Basename; -use Net::DBus; use Term::ANSIColor qw(color colored :constants); +use HTTP::Tiny; use Slackware::SlackMan; @@ -85,23 +90,128 @@ use Slackware::SlackMan; $ENV{'PATH'} = '/bin:/usr/bin:/sbin:/usr/sbin'; +my $slackware_release = ''; +my $is_slackware_current = 0; + +my $slackware_version_file = $slackman_conf->{'directory'}->{'root'} . '/etc/slackware-version'; + +my ($slackware_version) = file_read($slackware_version_file) =~ (/Slackware (.*)/); + +if ($slackware_version =~ /\+/) { + $slackware_version =~ s/\+//; + $is_slackware_current = 1; +} + + +# HTTP Client +# +sub http_client { + + my %http_options = ( 'agent' => "SlackMan/$VERSION" ); + my $proxy_conf = $slackman_conf->{'proxy'}; + + if ($proxy_conf->{'enable'}) { + + my $proxy_url = undef; + + if ($proxy_conf->{'username'}) { + + $proxy_url = sprintf("%s://%s:%s@%s:%s", + $proxy_conf->{'protocol'}, + $proxy_conf->{'username'}, + $proxy_conf->{'password'}, + $proxy_conf->{'hostname'}, + $proxy_conf->{'port'}, + ); + + } else { + + $proxy_url = sprintf("%s://%s:%s", + $proxy_conf->{'protocol'}, + $proxy_conf->{'hostname'}, + $proxy_conf->{'port'}, + ); + + } + + $http_options{'http_proxy'} = $proxy_url; + $http_options{'https_proxy'} = $proxy_url; + + } + + my $http = HTTP::Tiny->new( %http_options ); + + return $http; + +} + + +# Progress bar +# +sub callback_progress_bar { + + my ( $options ) = @_; + + $| = 1; + + my $progress_width = 25; + my $progress_char = '='; + + my $text = $options->{'text'}; + my $downloaded_size = $options->{'downloaded-size'}; + my $download_size = $options->{'download-size'}; + my $download_start = $options->{'download-start'}; + + my $download_time = time - $download_start; + my $downloaded_size_h = filesize_h($downloaded_size, 1); + my $download_size_h = filesize_h($download_size, 1); + my $num_width = length $download_size_h; + my $percent = ($downloaded_size / +$download_size); + my $download_sec_left = ($download_time / $percent - $download_time); + my $download_speed = ($download_time && $downloaded_size) ? ($downloaded_size / $download_time) : 0; + my $percent_h = (100 * $percent); + my $download_speed_h = filesize_h($download_speed) . 'B/s'; + my $download_sec_left_h = 'ETA ' . time_h(int($download_sec_left)); + my $progress_size = (($progress_width - 1) * $downloaded_size / $download_size); + + if ($percent_h == 100) { + $download_sec_left_h = 'in ' . time_h($download_time) . ' '; + $download_speed_h = ($download_time && $downloaded_size) ? filesize_h(($download_size / $download_time)) . 'B/s' : '-'; + } + + return sprintf("\t%8s %3d%% [%-${progress_width}s] %8s %s \r", + $downloaded_size_h, $percent_h, $progress_char x $progress_size . '>', + $download_speed_h, $download_sec_left_h); + +} + + # SlackMan DBus interface # sub dbus_slackman { + + require Net::DBus; + return Net::DBus->system ->get_service('org.lotarproject.SlackMan') ->get_object('/org/lotarproject/SlackMan'); + } # Notification DBus interface # sub dbus_notifications { + + require Net::DBus; + return Net::DBus->session ->get_service('org.freedesktop.Notifications') ->get_object('/org/freedesktop/Notifications'); + } + # Code from Sort::Versions module # sub versioncmp( $$ ) { @@ -154,12 +264,16 @@ sub versioncmp( $$ ) { } +# Return unique values in array +# sub uniq { my %seen; return grep { !$seen{$_}++ } @_; } +# Return a list of libraries for specified binary file +# sub ldd { my ($file) = @_; @@ -172,11 +286,36 @@ sub ldd { } +# Display seconds in human-readable format +# +sub time_h { + + my ($seconds) = @_; + + if ($seconds > 24 * 60 * 60 * 2) { + return sprintf('%dd', ($seconds / (24 * 60 * 60))); + } + + if ($seconds > 60 * 60 * 2) { + return sprintf('%dh', ($seconds / (60 * 60))); + } + + if ($seconds > 60 * 2) { + return sprintf('%dm', ($seconds / (60))); + } + + return sprintf('%ds', $seconds); + +} + + +# Display datetime in human-readable format +# sub datetime_h { my ($timestamp) = @_; - my $ago = time() - $timestamp; + my $ago = time - $timestamp; if ($ago > 24 * 60 * 60 * 30 * 12 * 2) { return sprintf('%d years ago', ($ago / (24 * 60 * 60 * 30 * 12))); @@ -207,6 +346,8 @@ sub datetime_h { } +# Display the a size in human-readable format +# sub filesize_h { my ($size, $decimal, $padding) = @_; @@ -233,6 +374,8 @@ sub filesize_h { } +# Convert string to time +# sub datetime_calc { my ($string) = @_; @@ -260,6 +403,8 @@ sub datetime_calc { } +# File read (aka slurp) +# sub file_read { my ($filename) = @_; @@ -275,6 +420,8 @@ sub file_read { } +# File write (overwrite mode) +# sub file_write { my ($filename, $content) = @_; @@ -287,7 +434,7 @@ sub file_write { } - +# File write (append mode) sub file_append { my ($filename, $content, $autoflush) = @_; @@ -303,6 +450,8 @@ sub file_append { } +# Get file handler for file read/write/append +# sub file_handler { my ($filename, $mode) = @_; @@ -314,57 +463,50 @@ sub file_handler { } -sub curl_cmd { - - my ($curl_extra_flags) = @_; - - my $curl_flags = qq/-H "User-Agent: SlackMan\/$VERSION" -C - -L -k --fail --retry 5 --retry-max-time 0/; +sub download_file { - # Set proxy flags for cURL - if ($slackman_conf->{'proxy'}->{'enable'}) { + my ($url, $file, $progress) = @_; - if ($slackman_conf->{'proxy'}->{'username'}) { + my $total_data; + my $download_start = time; + my $options = {}; + my $http = http_client(); - $curl_flags .= sprintf(" -x %s://%s:%s@%s:%s", - $slackman_conf->{'proxy'}->{'protocol'}, - $slackman_conf->{'proxy'}->{'username'}, - $slackman_conf->{'proxy'}->{'password'}, - $slackman_conf->{'proxy'}->{'hostname'}, - $slackman_conf->{'proxy'}->{'port'}, - ); - - } else { - $curl_flags .= sprintf(" -x %s://%s:%s", - $slackman_conf->{'proxy'}->{'protocol'}, - $slackman_conf->{'proxy'}->{'hostname'}, - $slackman_conf->{'proxy'}->{'port'}, - ); - } + logger->info("[DOWNLOAD] Downloading $url and save into $file"); - } + open(DOWNLOAD, '>', $file) or Carp::croak("Can't open file $file for downloading: $?"); - my $curl_cmd = "curl $curl_flags $curl_extra_flags"; + print "\n\r" if ($progress); - logger->debug("CURL: $curl_cmd"); + $options->{data_callback} = sub { - return $curl_cmd; + my ($data, $response) = @_; + my $content_length = $response->{'headers'}->{'content-length'}; -} + print DOWNLOAD $data; # Save chunk into file + $total_data .= $data; -sub download_file { + STDOUT->printflush( callback_progress_bar( { + 'text' => basename($url), + 'downloaded-size' => length($total_data), + 'download-size' => $content_length, + 'download-start' => $download_start } ) ) if ($progress); - my ($url, $file, $progress) = @_; + }; - my $extra_curl_flags = '-s'; - $extra_curl_flags = '-#' if ($progress); + my $response = $http->request( 'GET', $url, $options ); - my $curl_cmd = curl_cmd("$extra_curl_flags -o $file $url"); + close (DOWNLOAD); - logger->info("[DOWNLOAD] Downloading $url and save into $file"); + if ( $response->{'success'} ) { + print "\n" if ($progress); + logger->info("[DOWNLOAD] done"); + return $response->{status}; + } - system( $curl_cmd ); - return $?; + logger->error(sprintf("[DOWNLOAD] Download error: %s - %s", $response->{status}, $response->{reason})); + return $response->{status}; } @@ -385,19 +527,18 @@ sub get_last_modified { } - my $curl_cmd = curl_cmd("-s -I $url"); + my $http = http_client(); logger->debug("Get 'Last-Modified' date of $url"); - my $headers = qx{ $curl_cmd }; - my $result = 0; + my $response = $http->request('HEAD', $url); - if ($headers =~ m/Last\-Modified\:\s+(.*)/) { - my $match = $1; - return w3c_date_to_time(trim($match)); + if ( $response->{'success'} ) { + my $last_modified = $response->{'headers'}{'last-modified'}; + return http_date_to_time($last_modified) if ($last_modified); } - return $result; + return 0; } @@ -482,7 +623,7 @@ sub timestamp_to_time { } -sub w3c_date_to_time { +sub http_date_to_time { my $timestamp = shift; return $timestamp unless($timestamp); @@ -606,7 +747,7 @@ sub callback_spinner { sub gpg_verify { - my $file = shift; + my ($file) = @_; logger->debug(qq/[GPG] verify file "$file" with "$file.asc"/); @@ -618,7 +759,7 @@ sub gpg_verify { sub gpg_import_key { - my $key_file = shift; + my ($key_file) = @_; my $key_contents = file_read($key_file); $key_contents =~ /uid\s+(.*)/; my $key_uid = $1; @@ -636,23 +777,13 @@ sub get_arch { } -my $slackware_release; - -sub _get_slackware_release { - - my $slackware_version_file = $slackman_conf->{'directory'}->{'root'} . '/etc/slackware-version'; - my $slackware_version = file_read($slackware_version_file); - - chomp($slackware_version); - - $slackware_version =~ /Slackware (.*)/; - return $1; - +sub is_slackware_current { + return $is_slackware_current; } sub get_slackware_release { - return $slackware_release ||= _get_slackware_release(); # Reduce "open" system call + return $slackware_version; } @@ -769,6 +900,112 @@ sub failed_sign { } +sub str_pad { + + my ($input, $pad_length) = @_; + + Carp::croak("Usage: str_pad(input, pad_length)") unless ($pad_length); + + my $result = $input; + my $length = length($input); + + for my $i (1..($pad_length-$length)) { + $result .= ' '; + } + + return $result; + +} + +sub terminal_width { + + my $res = qx{tput cols}; + chomp($res); + return $res; + +} + + +sub table { + + my ($args) = @_; + + my $col_separator = $args->{'separator'}->{'column'} || ' '; + my $header_separator = $args->{'separator'}->{'header'} || undef; + my $rows = $args->{'rows'} || (); + my $headers = $args->{'headers'} || (); + my $output_format = $args->{'format'} || 'default'; + my $widths = (); + + my @checks = @$rows; + + push(@checks, $headers) if ($headers); + + if ($output_format eq 'default') { + + for my $row (@checks) { + for (my $idx=0; $idx < @$row; $idx++) { + + if (defined($args->{'widths'}->[$idx]) && $args->{'widths'}->[$idx] > 0) { + $widths->[$idx] = $args->{'widths'}->[$idx]; + next; + } + + my $col = $row->[$idx]; + $widths->[$idx] = length($col) if (length($col) > ($widths->[$idx] || 0)); + + } + } + + } else { + + for (my $i=0; $i< @{$rows->[0]}; $i++) { + $widths->[$i] = 1; + } + + $header_separator = undef; + + $col_separator = ',' if ($output_format eq 'csv'); + $col_separator = "\t" if ($output_format eq 'tsv'); + + } + + my $format = join($col_separator, map { "%-${_}s" } @$widths) . "\n"; + my $table = ''; + + if ($headers) { + + my $header_row = sprintf($format, @$headers); + my $header_width = length($header_row); + + if ($header_separator) { + $table .= sprintf("%s\n", $header_separator x $header_width); + } + + $table .= $header_row; + + if ($header_separator) { + $table .= sprintf("%s\n", $header_separator x $header_width); + } + + } + + for my $row (@$rows) { + + if ($output_format eq 'default') { + $table .= sprintf($format, @$row); + + } else { + $table .= sprintf($format, map { trim($_) } @$row); + } + + } + + return $table; + +} + + 1; __END__ @@ -824,7 +1061,7 @@ L =head1 LICENSE AND COPYRIGHT -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This module is free software, you may distribute it under the same terms as Perl. diff --git a/pod/slackman-cron.conf.5.pod b/pod/slackman-cron.conf.5.pod index e5b1806..34ba853 100644 --- a/pod/slackman-cron.conf.5.pod +++ b/pod/slackman-cron.conf.5.pod @@ -65,7 +65,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/pod/slackman.conf.5.pod b/pod/slackman.conf.5.pod index c2f1734..7e7dd37 100644 --- a/pod/slackman.conf.5.pod +++ b/pod/slackman.conf.5.pod @@ -150,12 +150,12 @@ Proxy password =head1 [slackware] SECTION -B (default: actual Slackware release) +B (default: actual Slackware release) DEPRECATED =over Force Slackware version. The default value is actual Slackware version in -F file. +F file. B @@ -230,7 +230,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/pod/slackman.renames.5.pod b/pod/slackman.renames.5.pod index 6c65735..e1f27e1 100644 --- a/pod/slackman.renames.5.pod +++ b/pod/slackman.renames.5.pod @@ -51,7 +51,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/pod/slackman.repo.5.pod b/pod/slackman.repo.5.pod index 5842869..f456e09 100644 --- a/pod/slackman.repo.5.pod +++ b/pod/slackman.repo.5.pod @@ -33,7 +33,7 @@ Short description of repository B - name=My local repository + name = My local repository =back @@ -45,7 +45,31 @@ Enable or disable repository B - enabled=true + enabled = true + +=back + +B + +=over + +Specify the repository arch support (default is: x86,x86_64,arm). + +NOTE: Prepend C to disable the arch. + +B + +Enable "only" C: + + arch = x86_64 + +Enable C and C and disable C: + + arch = x86,x86_64,!arm + +Override C<$arch> variable: + + arch =x86:i486,x86_64 =back @@ -62,7 +86,7 @@ Support local (via "file" protocol) and remote url (http, https, ftp, etc.) B - mirror=http://example.org/slackware/ + mirror = http://example.org/slackware/ =back @@ -76,7 +100,7 @@ Specify repository priority (default is C<0> - "zero") B - priority=1 + priority = 1 =back @@ -90,7 +114,7 @@ Specify excluded packages for update or install (default C<>) B - exclude=kernel-*,kde-l10n-*,calligra-l10n-* + exclude = kernel-*,kde-l10n-*,calligra-l10n-* =back @@ -109,7 +133,7 @@ GPG-KEY file URL B - gpgkey=http://example.org/slackware/GPG-KEY + gpgkey = http://example.org/slackware/GPG-KEY =back @@ -121,7 +145,7 @@ Packages file URL B - packages=http://example.org/slackware/PACKAGES.TXT + packages = http://example.org/slackware/PACKAGES.TXT =back @@ -133,7 +157,7 @@ Filelist file URL B - filelist=http://example.org/slackware/FILELIST.TXT + filelist = http://example.org/slackware/FILELIST.TXT =back @@ -145,7 +169,7 @@ Changelog file URL B - changelog=http://example.org/slackware/ChangeLog.txt + changelog = http://example.org/slackware/ChangeLog.txt =back @@ -157,7 +181,7 @@ Manifest file URL B - manifest=http://example.org/slackware/MANIFEST.bz2 + manifest = http://example.org/slackware/MANIFEST.bz2 =back @@ -169,7 +193,7 @@ Checksums file URL B - chechsums=http://example.org/slackware/CHECHSUMS.md5 + chechsums = http://example.org/slackware/CHECHSUMS.md5 =back @@ -251,25 +275,25 @@ Slackware release suffix (eg. C<64> - for Slackware64, C - for Slackwarear B - name=Slackware{$release.suffix}-{$release.real} repository - mirror=http://example.org/slackware{$release.suffix}-{$release.real}/ + name = Slackware{$release.suffix}-{$release.real} repository + mirror = http://example.org/slackware{$release.suffix}-{$release.real}/ release.suffix => release.real => 14.2 - name=Slackware64-14.2 - mirror=http://example.org/slackware-14.2 + name = Slackware64-14.2 + mirror = http://example.org/slackware-14.2 B - name=Slackware{$release.suffix}-{$release} repository - mirror=http://example.org/slackware{$release.suffix}-{$release}/ + name = Slackware{$release.suffix}-{$release} repository + mirror = http://example.org/slackware{$release.suffix}-{$release}/ release.suffix => 64 release => current - name=Slackware64-current - mirror=http://example.org/slackware64-current + name = Slackware64-current + mirror = http://example.org/slackware64-current =head1 DISPLAY REPOSITORY CONFIGURATION @@ -331,7 +355,7 @@ Giuseppe Di Terlizzi =head1 COPYRIGHT AND LICENSE -Copyright 2016-2017 Giuseppe Di Terlizzi. +Copyright 2016-2018 Giuseppe Di Terlizzi. This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a diff --git a/slackbuilds/slackman-libsupport/slack-desc b/slackbuilds/slackman-libsupport/slack-desc index 4413f19..422cc69 100644 --- a/slackbuilds/slackman-libsupport/slack-desc +++ b/slackbuilds/slackman-libsupport/slack-desc @@ -7,10 +7,10 @@ |-----handy-ruler------------------------------------------------------| slackman-libsupport: slackman-libsupport (Perl library for SlackMan Package Manager) -slackman-libsupport: -slackman-libsupport: - DBD::SQLite -slackman-libsupport: - Net::DBus -slackman-libsupport: - XML::Twig +slackman-libsupport: +slackman-libsupport: +slackman-libsupport: +slackman-libsupport: slackman-libsupport: slackman-libsupport: slackman-libsupport: diff --git a/slackbuilds/slackman-libsupport/slackman-libsupport.SlackBuild b/slackbuilds/slackman-libsupport/slackman-libsupport.SlackBuild index 933a539..9fef696 100644 --- a/slackbuilds/slackman-libsupport/slackman-libsupport.SlackBuild +++ b/slackbuilds/slackman-libsupport/slackman-libsupport.SlackBuild @@ -2,7 +2,7 @@ # Slackware build script for slackman-libsupport -# Copyright 2017 Giuseppe Di Terlizzi +# Copyright 2017-2018 Giuseppe Di Terlizzi # All rights reserved. # # Redistribution and use of this script, with or without modification, is @@ -24,22 +24,10 @@ PRGNAM=slackman-libsupport -VERSION=${VERSION:-1.2.1} +VERSION=${VERSION:-1.4.0} BUILD=${BUILD:-1} TAG=${TAG:-_lotar} -# SlackMan dependencies: -# -# - DBD::SQlite -# - Net::DBus -# - XML::Twig -# -DBDSQLITE=1.55_03 -XMLTWIG=3.52 -NETDBUS=1.1.0 - -MAKETEST=no - if [ -z "$ARCH" ]; then case "$( uname -m )" in i?86) ARCH=i586 ;; @@ -68,81 +56,29 @@ else fi set -e - rm -rf $PKG mkdir -p $TMP $PKG $OUTPUT cd $TMP rm -rf $PRGNAM-$VERSION -SLACKMAN_PERL5LIBS=$PKG/usr/share/slackman/lib -SLACKMAN_PERL5PREFIX=$PKG/usr/share/slackman/foo # Will be removed - -MAKEFILE_ARGS="PREFIX=$SLACKMAN_PERL5PREFIX LIB=$SLACKMAN_PERL5LIBS" - -( PKGNAME=XML-Twig-$XMLTWIG - PKGURL=http://search.cpan.org/CPAN/authors/id/M/MI/MIROD/$PKGNAME.tar.gz - - [ -f $CWD/$PKGNAME.tar.gz ] || wget $PKGURL -O $CWD/$PKGNAME.tar.gz - - tar xzvf $CWD/$PKGNAME.tar.gz - cd $PKGNAME - chown -R root:root . - perl Makefile.PL -y $MAKEFILE_ARGS - make || exit 1 - if [ "$MAKETEST" = "yes" ]; then - make test - fi - make install - mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME - cp -a README* LICENSE $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME - chmod 644 $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME/* +CPANM=${CPANM:-"$CWD/cpanm"} +SLACKWARE_VERSION=$(cat /etc/slackware-version | awk '{ print $2 }') +MODULES="DBD::SQLite XML::Twig Net::DBus XML::Parser IO::Socket::SSL Net::SSLeay" -) || exit 1 +# TODO Add check of installed Perl modules (eg. Slackware 14.2+/15.0 include +# IO::Socket::SSL, Net::SSLeay and XML::Parser modules) -( PKGNAME=Net-DBus-$NETDBUS - PKGURL=http://search.cpan.org/CPAN/authors/id/D/DA/DANBERR/$PKGNAME.tar.gz - - [ -f $CWD/$PKGNAME.tar.gz ] || wget $PKGURL -O $CWD/$PKGNAME.tar.gz - - tar xzvf $CWD/$PKGNAME.tar.gz - - cd $PKGNAME - chown -R root:root . - perl Makefile.PL OPTIMIZE="$SLKCFLAGS" $MAKEFILE_ARGS - make || exit 1 - if [ "$MAKETEST" = "yes" ]; then - make test - fi - make install - mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME - cp -a README* LICENSE $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME - chmod 644 $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME/* - -) || exit 1 - -( PKGNAME=DBD-SQLite-$DBDSQLITE - PKGURL=http://search.cpan.org/CPAN/authors/id/I/IS/ISHIGAKI/$PKGNAME.tar.gz - - [ -f $CWD/$PKGNAME.tar.gz ] || wget $PKGURL -O $CWD/$PKGNAME.tar.gz - - tar xzvf $CWD/$PKGNAME.tar.gz - - cd $PKGNAME - chown -R root:root . - perl Makefile.PL OPTIMIZE="$SLKCFLAGS" $MAKEFILE_ARGS - make || exit 1 - if [ "$MAKETEST" = "yes" ]; then - make test - fi - make install - mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME - cp -a README* LICENSE $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME - chmod 644 $PKG/usr/doc/$PRGNAM-$VERSION/$PKGNAME/* +if [ ! -e $CPANM ]; then + curl -L https://cpanmin.us -o $CWD/cpanm +fi -) || exit 1 +for MODULE in $MODULES; do + perl $CPANM -L $PKG/usr/share/slackman --self-contained \ + --configure-args="--cflags=$SLKCFLAGS" --verbose --notest $MODULE +done -rm -rf $PKG/usr/share/slackman/foo +rm -rf $PKG/usr/share/slackman/bin find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \ | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true diff --git a/slackbuilds/slackman/slackman.SlackBuild b/slackbuilds/slackman/slackman.SlackBuild index 6737e81..a6b3355 100644 --- a/slackbuilds/slackman/slackman.SlackBuild +++ b/slackbuilds/slackman/slackman.SlackBuild @@ -24,7 +24,7 @@ PRGNAM=slackman -VERSION=${VERSION:-1.2.1} +VERSION=${VERSION:-1.4.0} BUILD=${BUILD:-1} TAG=${TAG:-_lotar} ARCH=noarch diff --git a/t/00-load.t b/t/00-load.t index d39f52f..d0f1c47 100644 --- a/t/00-load.t +++ b/t/00-load.t @@ -6,8 +6,6 @@ use warnings FATAL => 'all'; use Test::More; use File::Basename; -use lib '/usr/share/slackman/lib'; - my $current_directory = dirname(__FILE__); $ENV{ROOT} = "$current_directory/root"; diff --git a/t/01-package-info.t b/t/01-package-info.t index 4334589..2c70cdf 100644 --- a/t/01-package-info.t +++ b/t/01-package-info.t @@ -6,8 +6,6 @@ use warnings FATAL => 'all'; use Test::More; use File::Basename; -use lib '/usr/share/slackman/lib'; - my $current_directory = dirname(__FILE__); $ENV{ROOT} = "$current_directory/root"; diff --git a/t/02-variables.t b/t/02-variables.t index 0262195..f9ecb57 100644 --- a/t/02-variables.t +++ b/t/02-variables.t @@ -6,8 +6,6 @@ use warnings FATAL => 'all'; use Test::More; use File::Basename; -use lib '/usr/share/slackman/lib'; - my $current_directory = dirname(__FILE__); $ENV{ROOT} = "$current_directory/root"; diff --git a/t/03-config.t b/t/03-config.t index 398070b..5374042 100644 --- a/t/03-config.t +++ b/t/03-config.t @@ -6,8 +6,6 @@ use warnings FATAL => 'all'; use Test::More; use File::Basename; -use lib '/usr/share/slackman/lib'; - my $current_directory = dirname(__FILE__); $ENV{ROOT} = "$current_directory/root"; diff --git a/t/10-slackman.t b/t/10-slackman.t new file mode 100644 index 0000000..6490ae2 --- /dev/null +++ b/t/10-slackman.t @@ -0,0 +1,25 @@ +#!/usr/bin/perl + +use 5.10.0; +use strict; +use warnings FATAL => 'all'; +use Test::More; +use File::Basename; + +use IPC::Open3; + +my $current_directory = dirname(__FILE__); +$ENV{ROOT} = "$current_directory/root"; + +my $slackman_cmd = $current_directory . '/../blib/script/slackman'; +my $pid = -1; + +$pid = open3 'WRITE', 'READ', 'ERROR', $slackman_cmd; +cmp_ok($pid, '!=', 0, "Check 'slackman' PID"); + +# $pid = open3 'WRITE', 'READ', 'ERROR', 'sudo', $slackman_cmd, '--version'; +# cmp_ok($pid, '!=', 0, "Check 'slackman --version' PID"); +# +# like(scalar , qr/^SlackMan - Slackware Package Manager v(\d)\.(\d)\.(\d)$/, "Check 'slackman --version' output"); + +done_testing();