From faf78e24948280b25ccad71e5fe027809f8c6279 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Tue, 23 Apr 2024 06:10:50 +0200 Subject: Adding upstream version 2.9.2. Signed-off-by: Daniel Baumann --- CMakeLists.txt | 2 +- apt-pkg/acquire-item.cc | 4 +- apt-pkg/aptconfiguration.cc | 35 ++++++ apt-pkg/aptconfiguration.h | 2 + apt-pkg/contrib/error.cc | 28 ++++- apt-pkg/contrib/error.h | 23 ++++ apt-pkg/contrib/progress.cc | 10 +- apt-pkg/deb/deblistparser.cc | 2 +- apt-pkg/deb/dpkgpm.cc | 2 +- apt-pkg/edsp.cc | 4 +- apt-pkg/tagfile.cc | 32 +++-- apt-pkg/tagfile.h | 8 ++ apt-private/acqprogress.cc | 5 +- apt-private/private-cmndline.cc | 18 +-- apt-private/private-install.cc | 29 +++-- apt-private/private-main.cc | 2 + apt-private/private-moo.cc | 2 +- apt-private/private-output.cc | 35 ++++-- apt-private/private-output.h | 11 +- apt-private/private-show.cc | 10 +- apt-private/private-update.cc | 6 +- doc/apt-verbatim.ent | 2 +- doc/apt.conf.5.xml | 41 ++++++- doc/apt.ent | 17 +++ doc/examples/configure-index | 4 + doc/po/apt-doc.pot | 84 ++++++++++++- doc/po/de.po | 129 +++++++++++++++++++- doc/po/es.po | 128 +++++++++++++++++++- doc/po/fr.po | 128 +++++++++++++++++++- doc/po/it.po | 151 ++++++++++++++++++----- doc/po/ja.po | 128 +++++++++++++++++++- doc/po/nl.po | 128 +++++++++++++++++++- doc/po/pl.po | 128 +++++++++++++++++++- doc/po/pt.po | 128 +++++++++++++++++++- doc/po/pt_BR.po | 76 +++++++++++- po/apt-all.pot | 49 ++++++-- po/ar.po | 47 ++++++-- po/ast.po | 47 ++++++-- po/bg.po | 47 ++++++-- po/bs.po | 47 ++++++-- po/ca.po | 47 ++++++-- po/cs.po | 155 ++++++++++++------------ po/cy.po | 47 ++++++-- po/da.po | 47 ++++++-- po/de.po | 47 ++++++-- po/dz.po | 47 ++++++-- po/el.po | 47 ++++++-- po/es.po | 47 ++++++-- po/eu.po | 47 ++++++-- po/fi.po | 47 ++++++-- po/fr.po | 47 ++++++-- po/gl.po | 47 ++++++-- po/hu.po | 47 ++++++-- po/it.po | 47 ++++++-- po/ja.po | 45 +++++-- po/km.po | 47 ++++++-- po/ko.po | 45 +++++-- po/ku.po | 47 ++++++-- po/lt.po | 47 ++++++-- po/mr.po | 47 ++++++-- po/nb.po | 47 ++++++-- po/ne.po | 47 ++++++-- po/nl.po | 47 ++++++-- po/nn.po | 47 ++++++-- po/pl.po | 49 ++++++-- po/pt.po | 47 ++++++-- po/pt_BR.po | 47 ++++++-- po/ro.po | 49 ++++++-- po/ru.po | 49 ++++++-- po/sk.po | 49 ++++++-- po/sl.po | 51 ++++++-- po/sv.po | 47 ++++++-- po/th.po | 45 +++++-- po/tl.po | 47 ++++++-- po/tr.po | 47 ++++++-- po/uk.po | 49 ++++++-- po/vi.po | 45 +++++-- po/zh_CN.po | 172 ++++++++++++++------------- po/zh_TW.po | 47 ++++++-- test/libapt/acqprogress_test.cc | 2 +- test/libapt/authconf_test.cc | 2 +- test/libapt/cachefilter_test.cc | 2 +- test/libapt/cdrom_test.cc | 2 +- test/libapt/cdromfindpackages_test.cc | 2 +- test/libapt/commandline_test.cc | 2 +- test/libapt/common.h | 11 ++ test/libapt/compareversion_test.cc | 2 +- test/libapt/configuration_test.cc | 34 +++++- test/libapt/extracttar_test.cc | 2 +- test/libapt/file-helpers.cc | 2 +- test/libapt/fileutl_test.cc | 2 +- test/libapt/getarchitectures_test.cc | 2 +- test/libapt/getlanguages_test.cc | 2 +- test/libapt/getlistoffilesindir_test.cc | 2 +- test/libapt/globalerror_test.cc | 2 +- test/libapt/gtest_runner.cc | 2 +- test/libapt/hashsums_test.cc | 2 +- test/libapt/indexcopytosourcelist_test.cc | 2 +- test/libapt/install_progress_test.cc | 2 +- test/libapt/json_test.cc | 2 +- test/libapt/openmaybeclearsignedfile_test.cc | 2 +- test/libapt/parsedepends_test.cc | 35 +++++- test/libapt/pattern_test.cc | 2 +- test/libapt/priority_test.cc | 2 +- test/libapt/sourcelist_test.cc | 2 +- test/libapt/srvrecs_test.cc | 2 +- test/libapt/stringview_test.cc | 2 +- test/libapt/strutil_test.cc | 2 +- test/libapt/tagfile_test.cc | 2 +- test/libapt/tagsection_test.cc | 2 +- test/libapt/teestream_test.cc | 2 +- test/libapt/uri_test.cc | 2 +- 112 files changed, 3348 insertions(+), 643 deletions(-) create mode 100644 test/libapt/common.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 13f4eaa..00ba2e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,7 +206,7 @@ endif() # Configure some variables like package, version and architecture. set(PACKAGE ${PROJECT_NAME}) set(PACKAGE_MAIL "APT Development Team ") -set(PACKAGE_VERSION "2.9.1") +set(PACKAGE_VERSION "2.9.2") string(REGEX MATCH "^[0-9.]+" PROJECT_VERSION ${PACKAGE_VERSION}) if (NOT DEFINED DPKG_DATADIR) diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 3c491ad..b534d56 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -2013,6 +2013,8 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c return; } + _error->Audit(_("Repositories should provide a clear-signed InRelease file, but none found at %s."), Target.URI.c_str()); + // Queue the 'old' InRelease file for removal if we try Release.gpg // as otherwise the file will stay around and gives a false-auth // impression (CVE-2012-0214) @@ -3985,7 +3987,7 @@ void pkgAcqFile::Done(string const &Message,HashStringList const &CalcHashes, _error->PushToStack(); _error->Errno("pkgAcqFile::Done", "Symlinking file %s failed", DestFile.c_str()); std::stringstream msg; - _error->DumpErrors(msg, GlobalError::DEBUG, false); + _error->DumpErrors(msg, GlobalError::NOTICE, false); _error->RevertToStack(); ErrorText = msg.str(); Status = StatError; diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 982e68b..f462b6e 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -563,4 +563,39 @@ bool Configuration::checkUsrMerged() return true; } /*}}}*/ +// isUsrMerged - whether usr is merged t /*{{{*/ +// --------------------------------------------------------------------- +/* */ +std::string Configuration::color(std::string const &colorName, std::string const &content) +{ + if (not _config->FindB("APT::Color")) + return content; + + auto colors = ::Configuration(_config->Tree("APT::Color")); + auto color = colors.Find(colorName); + + // Resolve the color recursively. A color string has the following format + // := \x1B ; fully resolved color + // | \\x1B ; color escaped. + // | ; a simple color name + // | ; a sequence of colors + if (color.find(" ") != color.npos) + { + std::string res; + for (auto &&colorPart : VectorizeString(color, ' ')) + res += Configuration::color(colorPart); + color = res; + } + else if (not color.empty() && color[0] != '\x1B') + { + if (APT::String::Startswith(color, "\\x1B")) + color = "\x1B" + color.substr(4); + else + color = Configuration::color(color); + } + if (content.empty()) + return color; + return color + content + Configuration::color("Neutral"); +} + /*}}}*/ } diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index 3e2636e..58c925b 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -130,7 +130,9 @@ namespace Configuration { /*{{{*/ APT_PUBLIC bool isChroot(); /** \return Check usr is merged or produce error. */ APT_PUBLIC bool checkUsrMerged(); + APT_PUBLIC std::string color(std::string const &colorName, std::string const &content = ""); #endif + /*}}}*/ } /*}}}*/ diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc index c9bb622..83e90a0 100644 --- a/apt-pkg/contrib/error.cc +++ b/apt-pkg/contrib/error.cc @@ -34,6 +34,7 @@ #include #include +#include /*}}}*/ // Global Error Object /*{{{*/ @@ -64,6 +65,7 @@ GEMessage(FatalE, FATAL) GEMessage(Errno, ERROR) GEMessage(WarningE, WARNING) GEMessage(NoticeE, NOTICE) +GEMessage(AuditE, AUDIT) GEMessage(DebugE, DEBUG) #undef GEMessage /*}}}*/ @@ -121,6 +123,7 @@ GEMessage(Fatal, FATAL) GEMessage(Error, ERROR) GEMessage(Warning, WARNING) GEMessage(Notice, NOTICE) +GEMessage(Audit, AUDIT) GEMessage(Debug, DEBUG) #undef GEMessage /*}}}*/ @@ -252,11 +255,13 @@ void GlobalError::MergeWithStack() { APT_HIDDEN std::ostream &operator<<(std::ostream &out, GlobalError::Item i) { static constexpr auto COLOR_RESET = "\033[0m"; - static constexpr auto COLOR_NOTICE = "\033[33m"; // normal yellow + static constexpr auto COLOR_BOLD = "\033[1m"; // bold neutral + static constexpr auto COLOR_NOTICE = "\033[1m"; // bold neutral static constexpr auto COLOR_WARN = "\033[1;33m"; // bold yellow static constexpr auto COLOR_ERROR = "\033[1;31m"; // bold red bool use_color = _config->FindB("APT::Color", false); + auto out_ver = _config->FindI("APT::Output-Version"); if (use_color) { @@ -270,6 +275,7 @@ APT_HIDDEN std::ostream &operator<<(std::ostream &out, GlobalError::Item i) out << COLOR_WARN; break; case GlobalError::NOTICE: + case GlobalError::AUDIT: out << COLOR_NOTICE; break; default: @@ -281,19 +287,26 @@ APT_HIDDEN std::ostream &operator<<(std::ostream &out, GlobalError::Item i) { case GlobalError::FATAL: case GlobalError::ERROR: - out << 'E'; + // TRANSLATOR: This is a warning level displayed before the message + out << (out_ver < 30 ? "E:" : _("Error:")); break; case GlobalError::WARNING: - out << 'W'; + // TRANSLATOR: This is a warning level displayed before the message + out << (out_ver < 30 ? "W:" : _("Warning:")); break; case GlobalError::NOTICE: - out << 'N'; + // TRANSLATOR: This is a warning level displayed before the message + out << (out_ver < 30 ? "N:" : _("Notice:")); + break; + case GlobalError::AUDIT: + out << (out_ver < 30 ? "A:" : _("Audit:")); break; case GlobalError::DEBUG: - out << 'D'; + // TRANSLATOR: This is a warning level displayed before the message + out << _("Debug:"); break; } - out << ": "; + out << " "; if (use_color) { @@ -303,7 +316,10 @@ APT_HIDDEN std::ostream &operator<<(std::ostream &out, GlobalError::Item i) case GlobalError::ERROR: case GlobalError::WARNING: case GlobalError::NOTICE: + case GlobalError::AUDIT: out << COLOR_RESET; + if (out_ver >= 30) + out << COLOR_BOLD; break; default: break; diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index 35e39ee..7922320 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -66,6 +66,8 @@ public: /*{{{*/ WARNING = 20, /** \brief deprecation warnings, old fallback behavior, … */ NOTICE = 10, + /** \brief future deprecation warnings, divergence from best practices */ + AUDIT = 5, /** \brief for developers only in areas it is hard to print something directly */ DEBUG = 0 }; @@ -109,6 +111,15 @@ public: /*{{{*/ */ bool NoticeE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD; + /** \brief add an audit message with errno to the list + * + * \param Function name of the function generating the error + * \param Description format string for the error message + * + * \return \b false + */ + bool AuditE(const char *Function,const char *Description,...) APT_PRINTF(3) APT_COLD; + /** \brief add a debug message with errno to the list * * \param Function name of the function generating the error @@ -193,6 +204,18 @@ public: /*{{{*/ */ bool Notice(const char *Description,...) APT_PRINTF(2) APT_COLD; + /** \brief add an audit message to the list + * + * An audit message highlights divergences from best practices and + * future deprecations. It my for example include additional messages + * targeted at repository owners. + * + * \param Description Format string for the message + * + * \return \b false + */ + bool Audit(const char *Description,...) APT_PRINTF(2) APT_COLD; + /** \brief add a debug message to the list * * \param Description Format string for the message diff --git a/apt-pkg/contrib/progress.cc b/apt-pkg/contrib/progress.cc index df068e4..5f440a7 100644 --- a/apt-pkg/contrib/progress.cc +++ b/apt-pkg/contrib/progress.cc @@ -156,12 +156,12 @@ void OpTextProgress::Done() char S[300] = {}; if (_error->PendingError() == true) snprintf(S,sizeof(S),_("%c%s... Error!"),'\r',OldOp.c_str()); - else if (not _config->FindB("APT::Internal::OpProgress::EraseLines", true)) + else if (not _config->FindB("APT::Internal::OpProgress::EraseLines", _config->FindI("APT::Output-Version") >= 30)) snprintf(S,sizeof(S),_("%c%s... Done"),'\r',OldOp.c_str()); Write(S); // FIXME: apt-cdrom relies on this end of line being printed - if (_error->PendingError() || not _config->FindB("APT::Internal::OpProgress::EraseLines", true)) - cout << endl; + if (_error->PendingError() || not _config->FindB("APT::Internal::OpProgress::EraseLines", _config->FindI("APT::Output-Version") >= 30)) + cout << endl; OldOp = string(); } @@ -202,8 +202,8 @@ void OpTextProgress::Update() { snprintf(S,sizeof(S),"\r%s",OldOp.c_str()); Write(S); - if (_config->FindB("APT::Internal::OpProgress::EraseLines", true)) - cout << endl; + if (_config->FindB("APT::Internal::OpProgress::EraseLines", _config->FindI("APT::Output-Version") >= 30)) + cout << endl; } // Print the spinner. Absolute progress shows us a time progress. diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 46c3629..071189b 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -608,7 +608,7 @@ const char *debListParser::ParseDepends(const char *Start, const char *Stop, { // Skip the '(' for (I++; I != Stop && isspace_ascii(*I) != 0 ; I++); - if (I + 3 >= Stop) + if (I + 3 > Stop) return 0; I = ConvertRelation(I,Op); diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 4f87cc2..82035ee 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1301,7 +1301,7 @@ void pkgDPkgPM::StartPtyMagic() /*{{{*/ free(d->slave); d->slave = NULL; } - _error->DumpErrors(std::cerr, GlobalError::DEBUG, false); + _error->DumpErrors(std::cerr, GlobalError::NOTICE, false); } _error->RevertToStack(); } diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc index b0ac4ae..a02e400 100644 --- a/apt-pkg/edsp.cc +++ b/apt-pkg/edsp.cc @@ -435,7 +435,7 @@ bool EDSP::ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progres if (Progress != nullptr) Progress->Done(); Progress = nullptr; - _error->DumpErrors(std::cerr, GlobalError::DEBUG, false); + _error->DumpErrors(std::cerr, GlobalError::NOTICE, false); } std::string msg = SubstVar(SubstVar(section.FindS("Message"), "\n .\n", "\n\n"), "\n ", "\n"); if (msg.empty() == true) { @@ -1044,7 +1044,7 @@ bool EIPP::ReadResponse(int const input, pkgPackageManager * const PM, OpProgres if (Progress != nullptr) Progress->Done(); Progress = nullptr; - _error->DumpErrors(std::cerr, GlobalError::DEBUG, false); + _error->DumpErrors(std::cerr, GlobalError::NOTICE, false); } std::string msg = SubstVar(SubstVar(section.FindS("Message"), "\n .\n", "\n\n"), "\n ", "\n"); if (msg.empty() == true) { diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 95ae4a4..934a89d 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -12,6 +12,7 @@ // Include Files /*{{{*/ #include +#include #include #include #include @@ -30,8 +31,9 @@ #include /*}}}*/ -using std::string; using APT::StringView; +using APT::Configuration::color; +using std::string; class APT_HIDDEN pkgTagFilePrivate /*{{{*/ { @@ -972,19 +974,23 @@ pkgTagSection::Tag pkgTagSection::Tag::Rewrite(std::string const &Name, std::str else return Tag(REWRITE, Name, Data); } -static bool WriteTag(FileFd &File, std::string Tag, StringView Value) +static bool WriteTag(FileFd &File, std::string Tag, StringView Value, pkgTagSection::WriteFlags flags) { if (Value.empty() || isspace_ascii(Value[0]) != 0) Tag.append(":"); else Tag.append(": "); + + if (flags & pkgTagSection::WRITE_HUMAN) + Tag = color("Show::Field", Tag); + Tag.append(Value.data(), Value.length()); Tag.append("\n"); return File.Write(Tag.c_str(), Tag.length()); } -static bool RewriteTags(FileFd &File, pkgTagSection const * const This, char const * const Tag, - std::vector::const_iterator &R, - std::vector::const_iterator const &REnd) +static bool RewriteTags(FileFd &File, pkgTagSection const *const This, char const *const Tag, + std::vector::const_iterator &R, + std::vector::const_iterator const &REnd, pkgTagSection::WriteFlags flags) { size_t const TagLen = strlen(Tag); for (; R != REnd; ++R) @@ -1002,11 +1008,15 @@ static bool RewriteTags(FileFd &File, pkgTagSection const * const This, char con else continue; - return WriteTag(File, Tag, data); + return WriteTag(File, Tag, data, flags); } return true; } bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::vector const &Rewrite) const +{ + return Write(File, WRITE_DEFAULT, Order, Rewrite); +} +bool pkgTagSection::Write(FileFd &File, pkgTagSection::WriteFlags flags, char const *const *const Order, std::vector const &Rewrite) const { // first pass: Write everything we have an order for if (Order != NULL) @@ -1014,7 +1024,7 @@ bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::v for (unsigned int I = 0; Order[I] != 0; ++I) { std::vector::const_iterator R = Rewrite.begin(); - if (RewriteTags(File, this, Order[I], R, Rewrite.end()) == false) + if (RewriteTags(File, this, Order[I], R, Rewrite.end(), flags) == false) return false; if (R != Rewrite.end()) continue; @@ -1022,7 +1032,7 @@ bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::v if (Exists(Order[I]) == false) continue; - if (WriteTag(File, Order[I], FindRaw(Order[I])) == false) + if (WriteTag(File, Order[I], FindRaw(Order[I]), flags) == false) return false; } } @@ -1047,12 +1057,12 @@ bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::v std::string const name(fieldname, fieldnamelen); std::vector::const_iterator R = Rewrite.begin(); - if (RewriteTags(File, this, name.c_str(), R, Rewrite.end()) == false) + if (RewriteTags(File, this, name.c_str(), R, Rewrite.end(), flags) == false) return false; if (R != Rewrite.end()) continue; - if (WriteTag(File, name, FindRaw(name)) == false) + if (WriteTag(File, name, FindRaw(name), flags) == false) return false; } } @@ -1076,7 +1086,7 @@ bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::v continue; } - if (WriteTag(File, name, ((R->Action == Tag::RENAME) ? FindRaw(R->Name) : R->Data)) == false) + if (WriteTag(File, name, ((R->Action == Tag::RENAME) ? FindRaw(R->Name) : R->Data), flags) == false) return false; } return true; diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index 0020d28..45529c9 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -166,6 +166,14 @@ class APT_PUBLIC pkgTagSection * @return \b true if successful, otherwise \b false */ bool Write(FileFd &File, char const * const * const Order = NULL, std::vector const &Rewrite = std::vector()) const; +#ifdef APT_COMPILING_APT + enum WriteFlags + { + WRITE_DEFAULT = 0, + WRITE_HUMAN = (1 << 0), /* write human readable output, may include highlighting */ + }; + bool Write(FileFd &File, WriteFlags flags, char const *const *const Order = NULL, std::vector const &Rewrite = std::vector()) const; +#endif }; diff --git a/apt-private/acqprogress.cc b/apt-private/acqprogress.cc index 1f5acdd..b4b16e6 100644 --- a/apt-private/acqprogress.cc +++ b/apt-private/acqprogress.cc @@ -9,6 +9,7 @@ // Include files /*{{{*/ #include +#include #include #include #include @@ -281,14 +282,14 @@ bool AcqTextStatus::Pulse(pkgAcquire *Owner) // Draw the current status if (_config->FindB("Apt::Color", false) == true) - out << _config->Find("APT::Color::Yellow"); + out << APT::Configuration::color("Yellow"); if (LastLineLength > Line.length()) clearLastLine(); else out << '\r'; out << Line << std::flush; if (_config->FindB("Apt::Color", false) == true) - out << _config->Find("APT::Color::Neutral") << std::flush; + out << APT::Configuration::color("Neutral") << std::flush; LastLineLength = Line.length(); Update = false; diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc index 3d6816d..b05ec89 100644 --- a/apt-private/private-cmndline.cc +++ b/apt-private/private-cmndline.cc @@ -246,10 +246,8 @@ static bool addArgumentsAPTGet(std::vector &Args, char const } else if (CmdMatches("clean", "autoclean", "auto-clean", "distclean", "dist-clean", "check", "download", "changelog") || CmdMatches("markauto", "unmarkauto")) // deprecated commands - ; - else if (CmdMatches("moo")) - addArg(0, "color", "APT::Moo::Color", 0); - + { + } if (CmdMatches("install", "reinstall", "remove", "purge", "upgrade", "dist-upgrade", "dselect-upgrade", "autoremove", "auto-remove", "autopurge", "check", "clean", "autoclean", "auto-clean", "distclean", "dist-clean", @@ -409,7 +407,9 @@ std::vector getCommandArgs(APT_CMD const Program, char const addArg('h', "help", "help", 0); addArg('v', "version", "version", 0); // general options + addArg(0, "color", "APT::Color", 0); addArg('q', "quiet", "quiet", CommandLine::IntLevel); + addArg(0, "audit", "APT::Audit", 0); addArg('q', "silent", "quiet", CommandLine::IntLevel); addArg('c', "config-file", 0, CommandLine::ConfigFile); addArg('o', "option", 0, CommandLine::ArbItem); @@ -487,8 +487,8 @@ static void BinarySpecificConfiguration(char const * const Binary) /*{{{*/ } if (binary == "apt" || binary == "apt-config") { - if (getenv("NO_COLOR") == nullptr) - _config->CndSet("Binary::apt::APT::Color", true); + if (getenv("NO_COLOR") == nullptr && getenv("APT_NO_COLOR") == nullptr) + _config->CndSet("Binary::apt::APT::Color", true); _config->CndSet("Binary::apt::APT::Output-Version", 30); _config->CndSet("Binary::apt::APT::Cache::Show::Version", 2); _config->CndSet("Binary::apt::APT::Cache::AllVersions", false); @@ -602,10 +602,12 @@ unsigned short DispatchCommandLine(CommandLine &CmdL, std::vectorPendingError(); - if (_config->FindI("quiet",0) > 0) + if (_config->FindB("APT::Audit")) + _error->DumpErrors(GlobalError::AUDIT); + else if (_config->FindI("quiet",0) > 0) _error->DumpErrors(); else - _error->DumpErrors(GlobalError::DEBUG); + _error->DumpErrors(GlobalError::NOTICE); if (returned == false) return 100; return Errors == true ? 100 : 0; diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc index ecbd703..9a2ed0b 100644 --- a/apt-private/private-install.cc +++ b/apt-private/private-install.cc @@ -227,11 +227,11 @@ bool InstallPackages(CacheFile &Cache, APT::PackageVector &HeldBackPackages, boo // Show all the various warning indicators if (_config->FindI("APT::Output-Version") < 30) ShowDel(c1out,Cache); + if (_config->FindI("APT::Output-Version") >= 30 && _config->FindB("APT::Get::Show-Upgraded",true) == true) + ShowUpgraded(c1out,Cache); ShowNew(c1out,Cache); if (_config->FindI("APT::Output-Version") >= 30) ShowWeakDependencies(Cache); - if (_config->FindI("APT::Output-Version") >= 30 && _config->FindB("APT::Get::Show-Upgraded",true) == true) - ShowUpgraded(c1out,Cache); if (ShwKept == true) { ShowPhasing(c1out, Cache, PhasingPackages); @@ -684,6 +684,16 @@ bool DoAutomaticRemove(CacheFile &Cache) // if we don't remove them, we should show them! if (doAutoRemove == false && autoRemoveCount != 0) { + std::string note; + std::string autocmd = "apt autoremove"; + if (getenv("SUDO_USER") != nullptr) + { + auto const envsudocmd = getenv("SUDO_COMMAND"); + auto const envshell = getenv("SHELL"); + if (envsudocmd == nullptr || envshell == nullptr || strcmp(envsudocmd, envshell) != 0) + autocmd = "sudo " + autocmd; + } + strprintf(note, P_("Use '%s' to remove it.", "Use '%s' to remove them.", autoRemoveCount), autocmd.c_str()); if (smallList == false) { // trigger marking now so that the package list is correct @@ -693,21 +703,14 @@ bool DoAutomaticRemove(CacheFile &Cache) "The following packages were automatically installed and are no longer required:", autoRemoveCount), Universe, [&Cache](pkgCache::PkgIterator const &Pkg) { return (*Cache)[Pkg].Garbage == true && (*Cache)[Pkg].Delete() == false; }, - &PrettyFullName, CandidateVersion(&Cache)); + &PrettyFullName, CandidateVersion(&Cache), "", note); } else + { ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n", "%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount); - std::string autocmd = "apt autoremove"; - if (getenv("SUDO_USER") != nullptr) - { - auto const envsudocmd = getenv("SUDO_COMMAND"); - auto const envshell = getenv("SHELL"); - if (envsudocmd == nullptr || envshell == nullptr || strcmp(envsudocmd, envshell) != 0) - autocmd = "sudo " + autocmd; + c1out << note << std::endl; } - ioprintf(c1out, P_("Use '%s' to remove it.", "Use '%s' to remove them.", autoRemoveCount), autocmd.c_str()); - c1out << std::endl; } return true; } @@ -1104,7 +1107,7 @@ bool DoInstall(CommandLine &CmdL) if (_config->FindI("APT::Output-Version") < 30 && Cache->InstCount() != verset[MOD_INSTALL].size()) ShowList(c1out, _("The following additional packages will be installed:"), Universe, PkgIsExtraInstalled(&Cache, &verset[MOD_INSTALL]), - &PrettyFullName, CandidateVersion(&Cache), "APT::Color::Green"); + &PrettyFullName, CandidateVersion(&Cache), "action::install-dependencies"); /* Print out a list of suggested and recommended packages */ if (_config->FindI("APT::Output-Version") < 30) diff --git a/apt-private/private-main.cc b/apt-private/private-main.cc index a80f03c..f28f5cb 100644 --- a/apt-private/private-main.cc +++ b/apt-private/private-main.cc @@ -68,6 +68,8 @@ void CheckIfSimulateMode(CommandLine &CmdL) /*{{{*/ " Keep also in mind that locking is deactivated,\n" " so don't depend on the relevance to the real current situation!\n"), _config->Find("Binary").c_str()); + if (_config->FindI("APT::Output-Version") >= 30) + std::cout << std::endl; _config->Set("Debug::NoLocking",true); } } diff --git a/apt-private/private-moo.cc b/apt-private/private-moo.cc index 2a9ed93..5eb6db5 100644 --- a/apt-private/private-moo.cc +++ b/apt-private/private-moo.cc @@ -96,7 +96,7 @@ static bool DoMoo2(time_t const timenow) /*{{{*/ return printMooLine(timenow); std::string const moo = getMooLine(timenow); size_t const depth = moo.length()/4; - if (_config->FindB("APT::Moo::Color", false) == false) + if (_config->FindB("APT::Color", false) == false) c1out << OutputInDepth(depth, " ") << " (__) \n" << OutputInDepth(depth, " ") << " _______~(..)~ \n" << diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc index 95dc740..09d03d3 100644 --- a/apt-private/private-output.cc +++ b/apt-private/private-output.cc @@ -1,6 +1,7 @@ // Include files /*{{{*/ #include +#include #include #include #include @@ -30,6 +31,7 @@ /*}}}*/ using namespace std; +using APT::Configuration::color; std::ostream c0out(0); std::ostream c1out(0); @@ -86,7 +88,7 @@ bool InitOutput(std::basic_streambuf * const out) /*{{{*/ SigWinch(0); } - if (isatty(STDOUT_FILENO) == 0 || not _config->FindB("APT::Color", true) || getenv("NO_COLOR") != nullptr) + if (isatty(STDOUT_FILENO) == 0 || not _config->FindB("APT::Color", true) || getenv("NO_COLOR") != nullptr || getenv("APT_NO_COLOR") != nullptr) { _config->Set("APT::Color", false); _config->Set("APT::Color::Highlight", ""); @@ -94,6 +96,7 @@ bool InitOutput(std::basic_streambuf * const out) /*{{{*/ } else { // Colors _config->CndSet("APT::Color::Highlight", "\x1B[32m"); + _config->CndSet("APT::Color::Bold", "\x1B[1m"); _config->CndSet("APT::Color::Neutral", "\x1B[0m"); _config->CndSet("APT::Color::Red", "\x1B[31m"); @@ -103,6 +106,14 @@ bool InitOutput(std::basic_streambuf * const out) /*{{{*/ _config->CndSet("APT::Color::Magenta", "\x1B[35m"); _config->CndSet("APT::Color::Cyan", "\x1B[36m"); _config->CndSet("APT::Color::White", "\x1B[37m"); + + _config->CndSet("APT::Color::Action::Upgrade", "green"); + _config->CndSet("APT::Color::Action::Install", "green"); + _config->CndSet("APT::Color::Action::Install-Dependencies", "green"); + _config->CndSet("APT::Color::Action::Downgrade", "yellow"); + _config->CndSet("APT::Color::Action::Remove", "red"); + _config->CndSet("APT::Color::Show::Field", "\x1B[1m"); + _config->CndSet("APT::Color::Show::Package", "\x1B[32m"); } return true; @@ -302,8 +313,8 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records, /*{{{*/ else if (V.ParentPkg()->CurrentState == pkgCache::State::ConfigFiles) StatusStr = _("[residual-config]"); output = SubstVar(output, "${apt:Status}", StatusStr); - output = SubstVar(output, "${color:highlight}", _config->Find("APT::Color::Highlight", "")); - output = SubstVar(output, "${color:neutral}", _config->Find("APT::Color::Neutral", "")); + output = SubstVar(output, "${color:highlight}", color("Highlight")); + output = SubstVar(output, "${color:neutral}", color("Neutral")); output = SubstVar(output, "${Description}", GetShortDescription(CacheFile, records, P)); if (output.find("${LongDescription}") != string::npos) output = SubstVar(output, "${LongDescription}", GetLongDescription(CacheFile, records, P)); @@ -555,7 +566,7 @@ void ShowNew(ostream &out,CacheFile &Cache) [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].NewInstall(); }, &PrettyFullName, CandidateVersion(&Cache), - "APT::Color::Green"); + "action::install"); return; } @@ -563,12 +574,12 @@ void ShowNew(ostream &out,CacheFile &Cache) [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].NewInstall() && (Cache[Pkg].Flags & pkgCache::Flag::Auto) == 0; }, &PrettyFullName, CandidateVersion(&Cache), - "APT::Color::Green"); + "action::install"); ShowList(out,_("Installing dependencies:"), Universe, [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].NewInstall() && Cache[Pkg].Flags & pkgCache::Flag::Auto;}, &PrettyFullName, CandidateVersion(&Cache), - "APT::Color::Green"); + "action::install-dependencies"); } /*}}}*/ // ShowDel - Show packages to delete /*{{{*/ @@ -586,7 +597,7 @@ void ShowDel(ostream &out,CacheFile &Cache) return str; }, CandidateVersion(&Cache), - "APT::Color::Red"); + "action::remove"); } /*}}}*/ // ShowPhasing - Show packages kept due to phasing /*{{{*/ @@ -625,7 +636,7 @@ void ShowUpgraded(ostream &out,CacheFile &Cache) }, &PrettyFullName, CurrentToCandidateVersion(&Cache), - "APT::Color::Green"); + "action::upgrade"); } /*}}}*/ // ShowDowngraded - Show downgraded packages /*{{{*/ @@ -642,7 +653,7 @@ bool ShowDowngraded(ostream &out,CacheFile &Cache) }, &PrettyFullName, CurrentToCandidateVersion(&Cache), - "APT::Color::Yellow"); + "action::downgrade"); } /*}}}*/ // ShowHold - Show held but changed packages /*{{{*/ @@ -791,10 +802,12 @@ bool YnPrompt(char const * const Question, bool const Default, bool const ShowGl // if we ask interactively, show warnings/notices before the question if (ShowGlobalErrors == true && AssumeYes == false && AssumeNo == false) { - if (_config->FindI("quiet",0) > 0) + if (_config->FindB("APT::Audit")) + _error->DumpErrors(c2o, GlobalError::AUDIT); + else if (_config->FindI("quiet",0) > 0) _error->DumpErrors(c2o); else - _error->DumpErrors(c2o, GlobalError::DEBUG); + _error->DumpErrors(c2o, GlobalError::NOTICE); } c2o << Question << std::flush; diff --git a/apt-private/private-output.h b/apt-private/private-output.h index 4cc7c01..0eba6f4 100644 --- a/apt-private/private-output.h +++ b/apt-private/private-output.h @@ -1,6 +1,7 @@ #ifndef APT_PRIVATE_OUTPUT_H #define APT_PRIVATE_OUTPUT_H +#include #include #include #include @@ -18,7 +19,6 @@ class CacheFile; class pkgDepCache; class pkgRecords; - APT_PUBLIC extern std::ostream c0out; APT_PUBLIC extern std::ostream c1out; APT_PUBLIC extern std::ostream c2out; @@ -43,7 +43,8 @@ template bool PredicateC Predicate, DisplayP PkgDisplay, DisplayV VerboseDisplay, - std::string colorName = "APT::Color::Neutral") + std::string colorName = "", + std::string Note = "") { size_t const ScreenWidth = (::ScreenWidth > 3) ? ::ScreenWidth - 3 : 0; int ScreenUsed = 0; @@ -52,8 +53,8 @@ template bool bool printedTitle = false; std::vector PackageList; - auto setColor = _config->FindI("APT::Output-Version") >= 30 ? _config->Find(colorName) : ""; - auto resetColor = _config->FindI("APT::Output-Version") >= 30 ? _config->Find("APT::Color::Neutral") : ""; + auto setColor = APT::Configuration::color(colorName); + auto resetColor = not setColor.empty() ? APT::Configuration::color("neutral") : ""; for (auto const &Pkg: cont) { @@ -105,6 +106,8 @@ template bool ShowWithColumns(out, PackageList, 2, ScreenWidth); out << resetColor; } + if (not Note.empty()) + out << Note << std::endl; if (_config->FindI("APT::Output-Version") >= 30) out << std::endl; return false; diff --git a/apt-private/private-show.cc b/apt-private/private-show.cc index cefbd9b..4ae0430 100644 --- a/apt-private/private-show.cc +++ b/apt-private/private-show.cc @@ -1,6 +1,7 @@ // Includes /*{{{*/ #include +#include #include #include #include @@ -33,6 +34,8 @@ #include /*}}}*/ +using APT::Configuration::color; + pkgRecords::Parser &LookupParser(pkgRecords &Recs, pkgCache::VerIterator const &V, pkgCache::VerFileIterator &Vf) /*{{{*/ { Vf = V.FileList(); @@ -271,7 +274,8 @@ static bool DisplayRecordV2(pkgCacheFile &CacheFile, pkgRecords &Recs, /*{{{*/ RW.push_back(pkgTagSection::Tag::Remove("Description")); RW.push_back(pkgTagSection::Tag::Remove("Description-md5")); // improve - RW.push_back(pkgTagSection::Tag::Rewrite("Package", V.ParentPkg().FullName(true))); + RW.push_back(pkgTagSection::Tag::Rewrite("Package", color("Show::Package", V.ParentPkg().FullName(true)))); + RW.push_back(pkgTagSection::Tag::Rewrite("Installed-Size", installed_size)); RW.push_back(pkgTagSection::Tag::Remove("Size")); RW.push_back(pkgTagSection::Tag::Rewrite("Download-Size", package_size)); @@ -282,7 +286,7 @@ static bool DisplayRecordV2(pkgCacheFile &CacheFile, pkgRecords &Recs, /*{{{*/ FileFd stdoutfd; if (stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false) == false || - Tags.Write(stdoutfd, TFRewritePackageOrder, RW) == false || stdoutfd.Close() == false) + Tags.Write(stdoutfd, pkgTagSection::WRITE_HUMAN, TFRewritePackageOrder, RW) == false || stdoutfd.Close() == false) return _error->Error("Internal Error, Unable to parse a package record"); // write the description @@ -291,7 +295,7 @@ static bool DisplayRecordV2(pkgCacheFile &CacheFile, pkgRecords &Recs, /*{{{*/ if (Desc.end() == false) { pkgRecords::Parser &P = Recs.Lookup(Desc.FileList()); - out << "Description: " << P.LongDesc(); + out << color("Show::Field", "Description: ") << P.LongDesc(); } // write a final newline (after the description) diff --git a/apt-private/private-update.cc b/apt-private/private-update.cc index cc0753c..6edde05 100644 --- a/apt-private/private-update.cc +++ b/apt-private/private-update.cc @@ -266,7 +266,11 @@ bool DoUpdate() if (upgradable == 0) c1out << _("All packages are up to date.") << std::endl; else - ioprintf(c1out, msg, upgradable); + { + c1out << _config->Find("APT::Color::Bold"); + ioprintf(c1out, msg, upgradable); + c1out << _config->Find("APT::Color::Neutral"); + } RunScripts("APT::Update::Post-Invoke-Stats"); } diff --git a/doc/apt-verbatim.ent b/doc/apt-verbatim.ent index 6f94904..d19a376 100644 --- a/doc/apt-verbatim.ent +++ b/doc/apt-verbatim.ent @@ -274,7 +274,7 @@ "> - + diff --git a/doc/apt.conf.5.xml b/doc/apt.conf.5.xml index 2ae569e..e873cf5 100644 --- a/doc/apt.conf.5.xml +++ b/doc/apt.conf.5.xml @@ -19,7 +19,7 @@ &apt-email; &apt-product; - 2024-02-21T00:00:00Z + 2024-04-19T00:00:00Z @@ -174,6 +174,45 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";}; + + + This scope defines colors and styles. The basic colors supported are + , + , + , + , + , + , and + . + + + The subscope defines the colors for package lists + in and similar commands. The following options may be set: + , + , + , + , + ; corresponding to their + lists in the &apt; output. + + + Each color may reference one or more other color options by name, relative + to . Their escape sequences will be combined. + + +APT::Color::Bold "\x1B[1m"; +APT::Color::Action::Install "cyan"; +APT::Color::Action::Upgrade "bold action::install"; + + + Colors may be turned on or off completely by setting + to or , by utilizing NO_COLOR + or APT_NO_COLOR environment variables, or using the + , command-line options. + + + + This scope defines which compression formats are supported, how compression diff --git a/doc/apt.ent b/doc/apt.ent index a6abb0e..b502073 100644 --- a/doc/apt.ent +++ b/doc/apt.ent @@ -48,6 +48,13 @@ + + + Show audit (and notice) messages. This overrides the quiet option, but only for notice messages, not progress ones. + + + + @@ -70,6 +77,16 @@ + + + + +Turn colors on or off. Colors are on by default on supported terminals for &apt; and +can also be disabled using the NO_COLOR or APT_NO_COLOR environment variables, +or further configured by the configuration option and scope, see &apt-conf; for information on that. + + + ">