Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package maildir-utils for openSUSE:Factory 
checked in at 2023-04-09 20:32:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/maildir-utils (Old)
 and      /work/SRC/openSUSE:Factory/.maildir-utils.new.19717 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "maildir-utils"

Sun Apr  9 20:32:58 2023 rev:42 rq:1078170 version:1.10.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/maildir-utils/maildir-utils.changes      
2023-04-03 00:52:00.506372031 +0200
+++ /work/SRC/openSUSE:Factory/.maildir-utils.new.19717/maildir-utils.changes   
2023-04-09 20:32:58.660547577 +0200
@@ -1,0 +2,15 @@
+Sun Apr  9 14:53:13 UTC 2023 - Michael Vetter <mvet...@suse.com>
+
+- Update to 1.10.2:
+  * improve unit tests
+  * fix threading issue with file-based logging
+  * re-enable --after option for mu cfind
+  * allow extracting message-parts from message (mu extract)
+  * allow using relative message paths (view/extract/verify)
+  Mu4e:
+  * by default, don't reuse frame with composing in new frame
+  * allow for disabling global modeline items
+  * create random name for newly detached views
+  * documentation update
+
+-------------------------------------------------------------------

Old:
----
  mu-1.10.1.tar.xz

New:
----
  mu-1.10.2.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ maildir-utils.spec ++++++
--- /var/tmp/diff_new_pack.Gy91bo/_old  2023-04-09 20:32:59.404551879 +0200
+++ /var/tmp/diff_new_pack.Gy91bo/_new  2023-04-09 20:32:59.412551925 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           maildir-utils
-Version:        1.10.1
+Version:        1.10.2
 Release:        0
 Summary:        Maildir indexer and searcher
 License:        GPL-3.0-or-later

++++++ mu-1.10.1.tar.xz -> mu-1.10.2.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/Makefile new/mu-1.10.2/Makefile
--- old/mu-1.10.1/Makefile      2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/Makefile      2023-04-09 14:05:50.000000000 +0200
@@ -50,7 +50,7 @@
        @ln -sf $(BUILDDIR)/compile_commands.json $(CURDIR) || /bin/true
 
 $(BUILDDIR):
-       @$(MESON) $(MESON_FLAGS) $(BUILDDIR)
+       @$(MESON) setup $(MESON_FLAGS) $(BUILDDIR)
 
 check: test
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/README.org new/mu-1.10.2/README.org
--- old/mu-1.10.1/README.org    2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/README.org    2023-04-09 14:05:50.000000000 +0200
@@ -17,8 +17,8 @@
 *Note*: you are looking at the *development* branch, which is where new code is
 being developed and tested, and which may occasionally break.
 
-Distribution and non-adventurous users are instead recommended to use the 
[[https://github.com/djcb/mu/tree/release/1.8][1.8
-Release Branch]] or to pick up one of the 
[[https://github.com/djcb/mu/releases][1.8 Releases]].
+Distributions and non-adventurous users are instead recommended to use the 
[[https://github.com/djcb/mu/tree/release/1.10][1.10
+Release Branch]] or to pick up one of the 
[[https://github.com/djcb/mu/releases][1.10 Releases]].
 
 Given the enormous amounts of e-mail many people gather and the importance of
 e-mail message in our work-flows, it's essential to quickly deal with all that
@@ -41,7 +41,7 @@
 - ~mu-guile~: bindings for the Guile/Scheme programming language (version 3.0 
and
   later)
 
-~mu~ is written in C and C++; ~mu4e~ is written in ~elisp~ and ~mu-guile~ in a 
mix of C++ and
+~mu~ is written in C++; ~mu4e~ is written in ~elisp~ and ~mu-guile~ in a mix 
of C++ and
 Scheme.
 
 Note, ~mu~ is available in Linux distributions (e.g. Debian/Ubuntu and Fedora)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/message/mu-message-part.cc 
new/mu-1.10.2/lib/message/mu-message-part.cc
--- old/mu-1.10.1/lib/message/mu-message-part.cc        2023-04-02 
08:28:53.000000000 +0200
+++ new/mu-1.10.2/lib/message/mu-message-part.cc        2023-04-09 
14:05:50.000000000 +0200
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 2022 Dirk-Jan C. Binnema <d...@djcbsoftware.nl>
+** Copyright (C) 2023 Dirk-Jan C. Binnema <d...@djcbsoftware.nl>
 **
 ** This program is free software; you can redistribute it and/or modify it
 ** under the terms of the GNU General Public License as published by the
@@ -156,16 +156,18 @@
                return mime_object().to_string_opt();
 }
 
-
-
 Result<size_t>
 MessagePart::to_file(const std::string& path, bool overwrite) const noexcept
 {
-       if (!mime_object().is_part())
-               return Err(Error::Code::InvalidArgument,
-                          "not a part");
-       else
+       if (mime_object().is_part())
                return MimePart{mime_object()}.to_file(path, overwrite);
+       else if (mime_object().is_message_part()) {
+               if (auto&& msg{MimeMessagePart{mime_object()}.get_message()}; 
!msg)
+                       return Err(Error::Code::Message, "failed to get 
message-part");
+               else
+                       return msg->to_file(path, overwrite);
+       } else
+               return mime_object().to_file(path, overwrite);
 }
 
 bool
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/message/mu-message-part.hh 
new/mu-1.10.2/lib/message/mu-message-part.hh
--- old/mu-1.10.1/lib/message/mu-message-part.hh        2023-04-02 
08:28:53.000000000 +0200
+++ new/mu-1.10.2/lib/message/mu-message-part.hh        2023-04-09 
14:05:50.000000000 +0200
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 2022 Dirk-Jan C. Binnema <d...@djcbsoftware.nl>
+** Copyright (C) 2023 Dirk-Jan C. Binnema <d...@djcbsoftware.nl>
 **
 ** This program is free software; you can redistribute it and/or modify it
 ** under the terms of the GNU General Public License as published by the
@@ -53,7 +53,6 @@
         */
        ~MessagePart();
 
-
        /**
         * Get the underlying MimeObject; you need to include mu-mime-object.hh
         * to do anything useful with it.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/message/mu-message.cc 
new/mu-1.10.2/lib/message/mu-message.cc
--- old/mu-1.10.1/lib/message/mu-message.cc     2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/lib/message/mu-message.cc     2023-04-09 14:05:50.000000000 
+0200
@@ -73,11 +73,13 @@
 static void fill_document(Message::Private& priv);
 
 static Result<struct stat>
-get_statbuf(const std::string& path)
+get_statbuf(const std::string& path, Message::Options opts = 
Message::Options::None)
 {
-       if (!g_path_is_absolute(path.c_str()))
+       if (none_of(opts & Message::Options::AllowRelativePath) &&
+           !g_path_is_absolute(path.c_str()))
                return Err(Error::Code::File, "path '%s' is not absolute",
                           path.c_str());
+
        if (::access(path.c_str(), R_OK) != 0)
                return Err(Error::Code::File, "file @ '%s' is not readable",
                           path.c_str());
@@ -97,7 +99,7 @@
 Message::Message(const std::string& path,  Message::Options opts):
        priv_{std::make_unique<Private>(opts)}
 {
-       const auto statbuf{get_statbuf(path)};
+       const auto statbuf{get_statbuf(path, opts)};
        if (!statbuf)
                throw statbuf.error();
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/message/mu-message.hh 
new/mu-1.10.2/lib/message/mu-message.hh
--- old/mu-1.10.1/lib/message/mu-message.hh     2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/lib/message/mu-message.hh     2023-04-09 14:05:50.000000000 
+0200
@@ -45,10 +45,12 @@
 class Message {
 public:
        enum struct Options {
-               None         = 0,       /**< Defaults */
-               Decrypt      = 1 << 0,  /**< Attempt to decrypt */
-               RetrieveKeys = 1 << 1,  /**< Auto-retrieve crypto keys (implies 
network
-                                          * access) */
+               None              = 0,          /**< Defaults */
+               Decrypt           = 1 << 0,     /**< Attempt to decrypt */
+               RetrieveKeys      = 1 << 1,     /**< Auto-retrieve crypto keys 
(implies network
+                                                  * access) */
+               AllowRelativePath = 1 << 2,     /**< Allow relateive paths for 
filename
+                                                  * in make_from_path */
        };
 
        /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/message/mu-mime-object.cc 
new/mu-1.10.2/lib/message/mu-mime-object.cc
--- old/mu-1.10.1/lib/message/mu-mime-object.cc 2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/lib/message/mu-mime-object.cc 2023-04-09 14:05:50.000000000 
+0200
@@ -125,8 +125,6 @@
        return hdrs;
 }
 
-
-
 Result<size_t>
 MimeObject::write_to_stream(const MimeFormatOptions& f_opts,
                            MimeStream& stream) const
@@ -139,6 +137,22 @@
                return Ok(static_cast<size_t>(written));
 }
 
+Result<size_t>
+MimeObject::to_file(const std::string& path, bool overwrite) const noexcept
+{
+       GError *err{};
+       auto strm{g_mime_stream_fs_open(path.c_str(),
+                                       O_WRONLY | O_CREAT | O_TRUNC 
|(overwrite ? 0 : O_EXCL),
+                                       S_IRUSR|S_IWUSR,
+                                       &err)};
+       if (!strm)
+               return Err(Error::Code::File, &err, "failed to open '%s'", 
path.c_str());
+
+       MimeStream stream{MimeStream::make_from_stream(strm)};
+       return write_to_stream({}, stream);
+}
+
+
 Option<std::string>
 MimeObject::to_string_opt() const noexcept
 {
@@ -525,11 +539,8 @@
        buffer.resize(buflen);
 
        return buffer;
-
 }
 
-
-
 Result<size_t>
 MimePart::to_file(const std::string& path, bool overwrite) const noexcept
 {
@@ -558,9 +569,6 @@
        return Ok(static_cast<size_t>(written));
 }
 
-
-
-
 void
 MimeMultipart::for_each(const ForEachFunc& func) const noexcept
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/message/mu-mime-object.hh 
new/mu-1.10.2/lib/message/mu-mime-object.hh
--- old/mu-1.10.1/lib/message/mu-mime-object.hh 2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/lib/message/mu-mime-object.hh 2023-04-09 14:05:50.000000000 
+0200
@@ -829,6 +829,16 @@
         */
        Option<std::string> to_string_opt() const noexcept;
 
+       /**
+        * Write object to a file
+        *
+        * @param path path to file
+        * @param overwrite if true, overwrite existing file, if it bqexists
+        *
+        * @return size of the wrtten file, or an error.
+        */
+       Result<size_t> to_file(const std::string& path, bool overwrite) const 
noexcept;
+
        /*
         * subtypes.
         */
@@ -1101,7 +1111,6 @@
         */
        Option<std::string> to_string() const noexcept;
 
-
        /**
         * Write part to a file
         *
@@ -1113,7 +1122,6 @@
        Result<size_t> to_file(const std::string& path, bool overwrite)
                const noexcept;
 
-
        /**
         * Types of Content Encoding.
         *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/message/test-mu-message.cc 
new/mu-1.10.2/lib/message/test-mu-message.cc
--- old/mu-1.10.1/lib/message/test-mu-message.cc        2023-04-02 
08:28:53.000000000 +0200
+++ new/mu-1.10.2/lib/message/test-mu-message.cc        2023-04-09 
14:05:50.000000000 +0200
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 2022 Dirk-Jan C. Binnema <d...@djcbsoftware.nl>
+** Copyright (C) 2023 Dirk-Jan C. Binnema <d...@djcbsoftware.nl>
 **
 ** This program is free software; you can redistribute it and/or modify it
 ** under the terms of the GNU General Public License as published by the
@@ -249,6 +249,10 @@
        {
                auto&& part{message->parts().at(3)};
                g_assert_true(part.mime_type() == "message/rfc822");
+
+               const auto fname{*cache_path + "/msgpart"};
+               g_assert_cmpuint(part.to_file(fname, true).value_or(123), ==, 
139);
+               g_assert_true(::access(fname.c_str(), F_OK) == 0);
        }
 
        {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/mu-maildir.cc 
new/mu-1.10.2/lib/mu-maildir.cc
--- old/mu-1.10.1/lib/mu-maildir.cc     2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/lib/mu-maildir.cc     2023-04-09 14:05:50.000000000 +0200
@@ -155,7 +155,7 @@
        if (auto&& res = check_subdir(src, in_cur); !res)
                return Err(std::move(res.error()));
 
-       char *srcfile{g_path_get_basename(src.c_str())};
+       const auto srcfile{to_string_gchar(g_path_get_basename(src.c_str()))};
 
        /* create targetpath; note: make the filename *cough* unique by
         * including a hash of the srcname in the targetname. This helps if
@@ -165,15 +165,13 @@
        if (unique_names)
                fulltargetpath = join_paths(targetpath,
                                            in_cur ? "cur" : "new",
-                                           format("%u_%s",
+                                           format("%08x-%s",
                                                   g_str_hash(src.c_str()),
-                                                  srcfile));
+                                                  srcfile.c_str()));
        else
                fulltargetpath = join_paths(targetpath,
                                            in_cur ? "cur" : "new",
-                                           srcfile);
-       g_free(srcfile);
-
+                                           srcfile.c_str());
        return fulltargetpath;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/utils/meson.build 
new/mu-1.10.2/lib/utils/meson.build
--- old/mu-1.10.1/lib/utils/meson.build 2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/lib/utils/meson.build 2023-04-09 14:05:50.000000000 +0200
@@ -65,4 +65,10 @@
                 cpp_args: ['-DBUILD_TESTS'],
                 dependencies: [glib_dep, config_h_dep, lib_mu_utils_dep]))
 
+test('test-logger',
+     executable('test-logger', 'mu-logger.cc',
+                install: false,
+                cpp_args: ['-DBUILD_TESTS'],
+                dependencies: [glib_dep, lib_mu_utils_dep]))
+
 subdir('tests')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/utils/mu-logger.cc 
new/mu-1.10.2/lib/utils/mu-logger.cc
--- old/mu-1.10.1/lib/utils/mu-logger.cc        2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/lib/utils/mu-logger.cc        2023-04-09 14:05:50.000000000 
+0200
@@ -28,6 +28,9 @@
 #include <fstream>
 #include <cstring>
 
+#include <thread>
+#include <mutex>
+
 #include "mu-logger.hh"
 
 using namespace Mu;
@@ -36,6 +39,7 @@
 static Mu::Logger::Options     MuLogOptions;
 static std::ofstream           MuStream;
 static auto                    MaxLogFileSize   = 1000 * 1024;
+static std::mutex              logger_mtx;
 
 static std::string MuLogPath;
 
@@ -45,6 +49,13 @@
        if (MuStream.is_open())
                return true;
 
+       const auto 
logdir{to_string_gchar(g_path_get_dirname(MuLogPath.c_str()))};
+       if (g_mkdir_with_parents(logdir.c_str(), 0700) != 0) {
+               std::cerr << "creating " << logdir << " failed:" << 
g_strerror(errno)
+                         << std::endl;
+               return false;
+       }
+
        MuStream.open(MuLogPath, std::ios::out | std::ios::app);
        if (!MuStream.is_open()) {
                std::cerr << "opening " << MuLogPath << " failed:" << 
g_strerror(errno)
@@ -84,6 +95,8 @@
 static GLogWriterOutput
 log_file(GLogLevelFlags level, const GLogField* fields, gsize n_fields, 
gpointer user_data)
 {
+       std::lock_guard lock{logger_mtx};
+
        if (!maybe_open_logfile())
                return G_LOG_WRITER_UNHANDLED;
 
@@ -124,7 +137,6 @@
        return Ok(Logger(path, opts));
 }
 
-
 Mu::Logger::Logger(const std::string& path, Mu::Logger::Options opts)
 {
        if (g_getenv("MU_LOG_STDOUTERR"))
@@ -147,7 +159,8 @@
                    }
 
                    // log to the journal, or, if not available to a file.
-                   if (log_journal(level, fields, n_fields, user_data) != 
G_LOG_WRITER_HANDLED)
+                   if (any_of(MuLogOptions & Options::File) ||
+                       log_journal(level, fields, n_fields, user_data) != 
G_LOG_WRITER_HANDLED)
                            return log_file(level, fields, n_fields, user_data);
                    else
                            return G_LOG_WRITER_HANDLED;
@@ -172,3 +185,56 @@
 
        MuLogInitialized = false;
 }
+
+
+#ifdef BUILD_TESTS
+#include <vector>
+#include <atomic>
+
+#include "mu-test-utils.hh"
+
+static void
+test_logger_threads(void)
+{
+       const auto testpath{test_random_tmpdir() + "/test.log"};
+       g_message("log-file: %s", testpath.c_str());
+
+       auto logger = Logger::make(testpath.c_str(), Logger::Options::File | 
Logger::Options::Debug);
+       assert_valid_result(logger);
+
+       const auto              thread_num = 16;
+       std::atomic<bool>       running    = true;
+
+       std::vector<std::thread> threads;
+
+       /* log to the logger file from many threass */
+       for (auto n = 0; n != thread_num; ++n)
+               threads.emplace_back(
+                       std::thread([n,&running]{
+                               while (running) {
+                                       g_debug("log message from thread <%d>", 
n);
+                                       std::this_thread::yield();
+                               }
+                       }));
+
+       using namespace std::chrono_literals;
+       std::this_thread::sleep_for(1s);
+       running = false;
+
+       for (auto n = 0; n != 16; ++n)
+               if (threads[n].joinable())
+                       threads[n].join();
+}
+
+
+int
+main(int argc, char* argv[])
+{
+       mu_test_init(&argc, &argv);
+
+       g_test_add_func("/utils/logger", test_logger_threads);
+
+       return g_test_run();
+}
+
+#endif /*BUILD_TESTS*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/utils/mu-logger.hh 
new/mu-1.10.2/lib/utils/mu-logger.hh
--- old/mu-1.10.1/lib/utils/mu-logger.hh        2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/lib/utils/mu-logger.hh        2023-04-09 14:05:50.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 2020-2022 Dirk-Jan C. Binnema <d...@djcbsoftware.nl>
+** Copyright (C) 2020-2023 Dirk-Jan C. Binnema <d...@djcbsoftware.nl>
 **
 ** This program is free software; you can redistribute it and/or modify it
 ** under the terms of the GNU General Public License as published by the
@@ -39,12 +39,12 @@
        enum struct Options {
                None      = 0,      /**< Nothing specific */
                StdOutErr = 1 << 1, /**< Log to stdout/stderr */
-               Debug     = 1 << 2, /**< Include debug-level logs */
+               File      = 1 << 2, /**< Force logging to file, even if journal 
available */
+               Debug     = 1 << 3, /**< Include debug-level logs */
        };
 
-
        /**
-        * Initialize the logging system.
+        * Initialize the logging sub-system.
         *
         * Note that the path is only used if structured logging fails --
         * practically, it goes to the file if there's no systemd/journald.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/utils/mu-test-utils.cc 
new/mu-1.10.2/lib/utils/mu-test-utils.cc
--- old/mu-1.10.1/lib/utils/mu-test-utils.cc    2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/lib/utils/mu-test-utils.cc    2023-04-09 14:05:50.000000000 
+0200
@@ -93,6 +93,11 @@
 void
 Mu::mu_test_init(int *argc, char ***argv)
 {
+       const auto tmpdir{test_random_tmpdir()};
+
+       g_setenv("MU_TEST", "yes", TRUE);
+       g_setenv("XDG_CACHE_HOME", tmpdir.c_str(), TRUE);
+
        g_test_init(argc, argv, NULL);
 
        if (!g_test_verbose())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/lib/utils/mu-test-utils.hh 
new/mu-1.10.2/lib/utils/mu-test-utils.hh
--- old/mu-1.10.1/lib/utils/mu-test-utils.hh    2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/lib/utils/mu-test-utils.hh    2023-04-09 14:05:50.000000000 
+0200
@@ -36,7 +36,7 @@
 }
 
 /**
- * mu wrapper for g_test_init
+ * mu wrapper for g_test_init. Sets environment variable MU_TEST to 1.
  *
  * @param argc
  * @param argv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/man/mu-cfind.1.org 
new/mu-1.10.2/man/mu-cfind.1.org
--- old/mu-1.10.1/man/mu-cfind.1.org    2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/man/mu-cfind.1.org    2023-04-09 14:05:50.000000000 +0200
@@ -70,15 +70,15 @@
 addresses was seen in one of the address fields; this is to exclude addresses
 only seen in mailing-list messages. See the ~--my-address~ parameter to *mu 
init*.
 
-# ** --after=<timestamp> only show addresses last seen after
-# =<timestamp>=. =<timestamp>= is a UNIX *time_t* value, the number of
-# seconds since 1970-01-01 (in UTC).
+** --after=<timestamp> only show addresses last seen after
+=<timestamp>=. =<timestamp>= is a UNIX *time_t* value, the number of
+seconds since 1970-01-01 (in UTC).
 
-# From the command line, you can use the *date* command to get this value. For
-# example, only consider addresses last seen after 2009-06-01, you could 
specify
-# #+begin_example
-#   --after=`date +%s --date='2009-06-01'`
-# #+end_example
+From the command line, you can use the *date* command to get this value. For
+example, only consider addresses last seen after 2020-06-01, you could specify
+#+begin_example
+  --after=`date +%s --date='2020-06-01'`
+#+end_example
 
 #+include: "muhome.inc" :minlevel 2
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/meson.build new/mu-1.10.2/meson.build
--- old/mu-1.10.1/meson.build   2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/meson.build   2023-04-09 14:05:50.000000000 +0200
@@ -17,7 +17,7 @@
 
################################################################################
 # project setup
 project('mu', ['c', 'cpp'],
-        version: '1.10.1',
+        version: '1.10.2',
         meson_version: '>= 0.56.0',
         license: 'GPL-3.0-or-later',
         default_options : [
@@ -216,3 +216,8 @@
 
################################################################################
 # write-out config.h
 configure_file(output : 'config.h', configuration : config_h_data)
+
+if gmime_dep.version() == '3.2.13'
+  warning('gmime version 3.2.13 detected, which as a decoding bug')
+  warning('See: https://github.com/jstedfast/gmime/issues/133')
+endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu/mu-cmd-find.cc 
new/mu-1.10.2/mu/mu-cmd-find.cc
--- old/mu-1.10.1/mu/mu-cmd-find.cc     2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu/mu-cmd-find.cc     2023-04-09 14:05:50.000000000 +0200
@@ -178,7 +178,11 @@
        else if (info.footer)
                return true;
 
-       if (auto&& res = maildir_link(msg->path(), opts.find.linksdir); !res) {
+       /* during test, do not create "unique names" (i.e., names with path
+        * hashes), so we get a predictable result */
+       const auto unique_names{!g_getenv("MU_TEST")&&!g_test_initialized()};
+
+       if (auto&& res = maildir_link(msg->path(), opts.find.linksdir, 
unique_names); !res) {
                res.error().fill_g_error(err);
                return false;
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu/mu-cmd.cc new/mu-1.10.2/mu/mu-cmd.cc
--- old/mu-1.10.1/mu/mu-cmd.cc  2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu/mu-cmd.cc  2023-04-09 14:05:50.000000000 +0200
@@ -156,12 +156,7 @@
 {
        using Format = Options::View::Format;
 
-       // make absolute.
-       const auto 
fpath{to_string_opt_gchar(g_canonicalize_filename(fname.c_str(), NULL))};
-       if (!fpath)
-               return Err(Error::Code::File, "invalid file '%s'", 
fname.c_str());
-
-       auto message{Message::make_from_path(*fpath, 
message_options(opts.view))};
+       auto message{Message::make_from_path(fname, 
message_options(opts.view))};
        if (!message)
                return Err(message.error());
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu/mu-cmd.hh new/mu-1.10.2/mu/mu-cmd.hh
--- old/mu-1.10.1/mu/mu-cmd.hh  2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu/mu-cmd.hh  2023-04-09 14:05:50.000000000 +0200
@@ -40,7 +40,7 @@
 constexpr Message::Options
 message_options(const CmdOpts& cmdopts)
 {
-       Message::Options mopts{};
+       Message::Options mopts{Message::Options::AllowRelativePath};
 
        if (cmdopts.decrypt)
                mopts |= Message::Options::Decrypt;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu/mu-options.cc 
new/mu-1.10.2/mu/mu-options.cc
--- old/mu-1.10.1/mu/mu-options.cc      2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu/mu-options.cc      2023-04-09 14:05:50.000000000 +0200
@@ -191,6 +191,10 @@
                       "Regular expression pattern to match");
        sub.add_flag("--personal,-p", opts.cfind.personal,
                       "Only show 'personal' contacts");
+       sub.add_option("--after", opts.cfind.after,
+                      "Only show results after some timestamps")
+               ->type_name("<time_t>")
+               ->check(CLI::PositiveNumber);
        sub.add_option("--maxnum,-n", opts.cfind.maxnum,
                       "Maximum number of results")
                ->type_name("<number>")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu/mu.cc new/mu-1.10.2/mu/mu.cc
--- old/mu-1.10.1/mu/mu.cc      2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu/mu.cc      2023-04-09 14:05:50.000000000 +0200
@@ -104,7 +104,6 @@
         * there's a subcommand
         */
 
-
        /*
         * set up logging
         */
@@ -113,6 +112,8 @@
                lopts |= Logger::Options::StdOutErr;
        if (opts->debug)
                lopts |= Logger::Options::Debug;
+       if (g_getenv("MU_TEST"))
+               lopts |= Logger::Options::File;
 
        const auto logger = 
Logger::make(opts->runtime_path(RuntimePath::LogFile),
                                         lopts);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu/tests/test-mu-cmd.cc 
new/mu-1.10.2/mu/tests/test-mu-cmd.cc
--- old/mu-1.10.1/mu/tests/test-mu-cmd.cc       2023-04-02 08:28:53.000000000 
+0200
+++ new/mu-1.10.2/mu/tests/test-mu-cmd.cc       2023-04-09 14:05:50.000000000 
+0200
@@ -248,8 +248,9 @@
        output = erroutput = NULL;
 
        /* furthermore, two symlinks should be there */
-       const auto f1{format("%s/cur/3419760385_rfc822.1", tmpdir.c_str())};
-       const auto f2{format("%s/cur/3419760386_rfc822.2", tmpdir.c_str())};
+       const auto f1{format("%s/cur/rfc822.1", tmpdir.c_str())};
+       const auto f2{format("%s/cur/rfc822.2", tmpdir.c_str())};
+
 
        g_assert_cmpuint(determine_dtype(f1.c_str(), true), ==, DT_LNK);
        g_assert_cmpuint(determine_dtype(f2.c_str(), true), ==, DT_LNK);
@@ -306,51 +307,51 @@
 /*     search ("subject:atoms", 1); */
 /* } */
 
-static void
-test_mu_extract_01(void)
-{
-       gchar *cmdline, *output, *erroutput, *tmpdir;
-
-       tmpdir = test_mu_common_get_random_tmpdir();
-       g_assert(g_mkdir_with_parents(tmpdir, 0700) == 0);
-
-       cmdline = g_strdup_printf("%s extract %s%cFoo%ccur%cmail5",
-                                 MU_PROGRAM,
-                                 MU_TESTMAILDIR2,
-                                 G_DIR_SEPARATOR,
-                                 G_DIR_SEPARATOR,
-                                 G_DIR_SEPARATOR);
-
-       if (g_test_verbose())
-               g_print("cmd: %s\n", cmdline);
-
-       output = erroutput = NULL;
-       g_assert(g_spawn_command_line_sync(cmdline, &output, &erroutput, NULL, 
NULL));
-
-       // ERROR:test-mu-cmd.cc:347:void test_mu_extract_01(): assertion failed 
(output ==
-       // "MIME-parts in this message:\n" " 1 <none> text/plain [<none>] (27 
bytes)\n" " 2
-       // sittingbull.jpg image/jpeg [inline] (23.9\302\240kB)\n" " 3 
custer.jpg image/jpeg
-       // [inline] (21.6\302\240kB)\n"):
-       // ("MIME-parts in this message:\n 1 <none> text/plain [<none>] (27 
bytes)\n 2
-       // sittingbull.jpg image/jpeg [inline] (23.9 kB)\n 3 custer.jpg 
image/jpeg [inline] (21.6
-       // kB)\n" == "MIME-parts in this message:\n 1 <none> text/plain 
[<none>] (27 bytes)\n 2
-       // sittingbull.jpg image/jpeg [inline] (23.9\302\240kB)\n 3 custer.jpg 
image/jpeg [inline]
-       // (21.6\302\240kB)\n")
-       /* g_assert_cmpstr (output, */
-       /*               ==, */
-       /*               "MIME-parts in this message:\n" */
-       /*               "  1 <none> text/plain [<none>] (27 bytes)\n" */
-       /*               "  2 sittingbull.jpg image/jpeg [inline] 
(23.9\302\240kB)\n" */
-       /*               "  3 custer.jpg image/jpeg [inline] 
(21.6\302\240kB)\n"); */
-
-       /* we expect zero lines of error output */
-       g_assert_cmpuint(newlines_in_output(erroutput), ==, 0);
-
-       g_free(output);
-       g_free(erroutput);
-       g_free(cmdline);
-       g_free(tmpdir);
-}
+// static void
+// test_mu_extract_01(void)
+// {
+//     gchar *cmdline, *output, *erroutput, *tmpdir;
+
+//     tmpdir = test_mu_common_get_random_tmpdir();
+//     g_assert(g_mkdir_with_parents(tmpdir, 0700) == 0);
+
+//     cmdline = g_strdup_printf("%s extract %s%cFoo%ccur%cmail5",
+//                               MU_PROGRAM,
+//                               MU_TESTMAILDIR2,
+//                               G_DIR_SEPARATOR,
+//                               G_DIR_SEPARATOR,
+//                               G_DIR_SEPARATOR);
+
+//     if (g_test_verbose())
+//             g_print("cmd: %s\n", cmdline);
+
+//     output = erroutput = NULL;
+//     g_assert(g_spawn_command_line_sync(cmdline, &output, &erroutput, NULL, 
NULL));
+
+//     // ERROR:test-mu-cmd.cc:347:void test_mu_extract_01(): assertion failed 
(output ==
+//     // "MIME-parts in this message:\n" " 1 <none> text/plain [<none>] (27 
bytes)\n" " 2
+//     // sittingbull.jpg image/jpeg [inline] (23.9\302\240kB)\n" " 3 
custer.jpg image/jpeg
+//     // [inline] (21.6\302\240kB)\n"):
+//     // ("MIME-parts in this message:\n 1 <none> text/plain [<none>] (27 
bytes)\n 2
+//     // sittingbull.jpg image/jpeg [inline] (23.9 kB)\n 3 custer.jpg 
image/jpeg [inline] (21.6
+//     // kB)\n" == "MIME-parts in this message:\n 1 <none> text/plain 
[<none>] (27 bytes)\n 2
+//     // sittingbull.jpg image/jpeg [inline] (23.9\302\240kB)\n 3 custer.jpg 
image/jpeg [inline]
+//     // (21.6\302\240kB)\n")
+//     /* g_assert_cmpstr (output, */
+//     /*               ==, */
+//     /*               "MIME-parts in this message:\n" */
+//     /*               "  1 <none> text/plain [<none>] (27 bytes)\n" */
+//     /*               "  2 sittingbull.jpg image/jpeg [inline] 
(23.9\302\240kB)\n" */
+//     /*               "  3 custer.jpg image/jpeg [inline] 
(21.6\302\240kB)\n"); */
+
+//     /* we expect zero lines of error output */
+//     g_assert_cmpuint(newlines_in_output(erroutput), ==, 0);
+
+//     g_free(output);
+//     g_free(erroutput);
+//     g_free(cmdline);
+//     g_free(tmpdir);
+// }
 
 static gint64
 get_file_size(const char* path)
@@ -820,11 +821,6 @@
 {
        int rv;
 
-       /* currently, something is broken on Ubuntu CI (but not elsewhere);
-        * selectively turn this test off */
-       if (!g_getenv("RUN_TEST_MU_CMD"))
-               return 0;
-
        mu_test_init(&argc, &argv);
 
        if (!set_en_us_utf8_locale())
@@ -839,14 +835,13 @@
        g_test_add_func("/mu-cmd/test-mu-find-file", test_mu_find_file);
        g_test_add_func("/mu-cmd/test-mu-find-mime", test_mu_find_mime);
 
-
        g_test_add_func ("/mu-cmd/test-mu-find-links", test_mu_find_links);
 
        g_test_add_func("/mu-cmd/test-mu-find-text-in-rfc822", 
test_mu_find_text_in_rfc822);
 
        g_test_add_func("/mu-cmd/test-mu-find-03", test_mu_find_03);
        g_test_add_func("/mu-cmd/test-mu-find-maildir-special", 
test_mu_find_maildir_special);
-       g_test_add_func("/mu-cmd/test-mu-extract-01", test_mu_extract_01);
+       // g_test_add_func("/mu-cmd/test-mu-extract-01", test_mu_extract_01);
        g_test_add_func("/mu-cmd/test-mu-extract-02", test_mu_extract_02);
        g_test_add_func("/mu-cmd/test-mu-extract-03", test_mu_extract_03);
        g_test_add_func("/mu-cmd/test-mu-extract-overwrite", 
test_mu_extract_overwrite);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu4e/TODO new/mu-1.10.2/mu4e/TODO
--- old/mu-1.10.1/mu4e/TODO     2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu4e/TODO     1970-01-01 01:00:00.000000000 +0100
@@ -1,19 +0,0 @@
-* TODO
-
-*** mu4e-get-sub-maildirs
-*** extract mailing list name
-*** mark thread
-*** bounce support
-*** sorting
-*** tool bars
-*** refiling-by-pattern
-*** inspect message (muile)
-*** message statistics
-*** include exchange handling / org integration
-*** integrate bbdb
-*** identity support
-
-
-# Local Variables:
-# mode: org; org-startup-folded: nil
-# End:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu4e/mu4e-modeline.el 
new/mu-1.10.2/mu4e/mu4e-modeline.el
--- old/mu-1.10.1/mu4e/mu4e-modeline.el 2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu4e/mu4e-modeline.el 2023-04-09 14:05:50.000000000 +0200
@@ -48,6 +48,14 @@
   :type 'boolean
   :group 'mu4e-modeline)
 
+(defcustom mu4e-modeline-show-global t
+  "Whether to populate global modeline segments.
+
+If non-nil, show both buffer-specific and global modeline items,
+otherwise only present buffer-specific information."
+  :type 'boolean
+  :group 'mu4e-modeline)
+
 (defvar-local mu4e--modeline-buffer-items nil
   "List of buffer-local items for the mu4e modeline.
 Each element is function that evaluates to a string.")
@@ -90,15 +98,17 @@
             (mapconcat
              (lambda (func) (or (funcall func) "")) lst " ")))
          (global-string ;; global string is _cached_ as it may be expensive.
-          (or mu4e--modeline-global-string-cached
-              (setq mu4e--modeline-global-string-cached
-                    (funcall collect mu4e--modeline-global-items)))))
+          (and
+           mu4e-modeline-show-global
+           (or mu4e--modeline-global-string-cached
+               (setq mu4e--modeline-global-string-cached
+                     (funcall collect mu4e--modeline-global-items))))))
     (concat
      ;; (local) buffer items are _not_ cached, so they'll get update
      ;; automatically when leaving the buffer.
      (mu4e--modeline-quote-and-truncate
       (funcall collect mu4e--modeline-buffer-items))
-     " "
+     (and global-string " ")
      global-string)))
 
 (define-minor-mode mu4e-modeline-mode
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu4e/mu4e-view.el 
new/mu-1.10.2/mu4e/mu4e-view.el
--- old/mu-1.10.1/mu4e/mu4e-view.el     2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu4e/mu4e-view.el     2023-04-09 14:05:50.000000000 +0200
@@ -327,11 +327,14 @@
   (unless mu4e-linked-headers-buffer
     (mu4e-error "This view buffer is already detached."))
   (mu4e-message "Detached view buffer from %s"
-                (prog1 mu4e-linked-headers-buffer
+                (progn mu4e-linked-headers-buffer
                   (with-current-buffer mu4e-linked-headers-buffer
                     (when (eq (selected-window) mu4e~headers-view-win)
                       (setq mu4e~headers-view-win nil)))
-                  (setq mu4e-linked-headers-buffer nil))))
+                  (setq mu4e-linked-headers-buffer nil)
+                  ;; automatically rename mu4e-view-article buffer when
+                  ;; detaching; will get renamed back when reattaching
+                  (rename-buffer (make-temp-name (buffer-name)) t))))
 
 (defun mu4e-view-attach (headers-buffer)
   "Attaches a view buffer to a headers buffer."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu4e/mu4e-window.el 
new/mu-1.10.2/mu4e/mu4e-window.el
--- old/mu-1.10.1/mu4e/mu4e-window.el   2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu4e/mu4e-window.el   2023-04-09 14:05:50.000000000 +0200
@@ -297,22 +297,28 @@
             ('(view . vertical) '((window-min-width . fit-window-to-buffer)))
             (`(,_ . t) nil)))
          (window-action (cond
-                         ((eq buffer-type 'main) '(display-buffer-full-frame))
+                         ((eq buffer-type 'main) '(display-buffer-reuse-window
+                                                   
display-buffer-reuse-mode-window
+                                                   display-buffer-full-frame))
                          ((and (eq buffer-type 'compose) 
mu4e-compose-in-new-frame)
                           '(display-buffer-pop-up-frame))
                          ((memq buffer-type '(headers compose))
-                          '(display-buffer-reuse-mode-window 
display-buffer-same-window))
+                          '(display-buffer-reuse-window
+                            display-buffer-reuse-mode-window
+                            display-buffer-same-window))
                          ((memq mu4e-split-view '(horizontal vertical))
                           '(display-buffer-in-direction))
                          ((memq mu4e-split-view '(single-window))
-                          '(display-buffer-same-window))
+                          '(display-buffer-reuse-window
+                            display-buffer-reuse-mode-window
+                            display-buffer-same-window))
                          ;; I cannot discern a difference between
                          ;; `single-window' and "anything else" in
                          ;; `mu4e-split-view'.
-                         (t '(display-buffer-same-window))))
-         (arg `((display-buffer-reuse-window
-                 display-buffer-reuse-mode-window
-                 ,@window-action)
+                         (t '(display-buffer-reuse-window
+                              display-buffer-reuse-mode-window
+                              display-buffer-same-window))))
+         (arg `((,@window-action)
                 ,@window-size
                 ,direction
                 )))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mu-1.10.1/mu4e/mu4e.texi new/mu-1.10.2/mu4e/mu4e.texi
--- old/mu-1.10.1/mu4e/mu4e.texi        2023-04-02 08:28:53.000000000 +0200
+++ new/mu-1.10.2/mu4e/mu4e.texi        2023-04-09 14:05:50.000000000 +0200
@@ -842,7 +842,9 @@
 in such cases, there won't be any further notifications.
 
 The @emph{Maildirs} item is very similar to Bookmarks -- consider maildirs here
-as being a special kind of bookmark query that matches a Maildir.
+as being a special kind of bookmark query that matches a Maildir. You can
+configure this using the variable @code{mu4e-maildir-shortcuts}; see its
+docstring and @xref{Maildir searches} for more details.
 
 @node Miscellaneous
 @section Miscellaneous
@@ -1205,10 +1207,20 @@
 easily by customizing @code{display-buffer-alist}, which governs how Emacs --
 and thus @t{mu4e} -- must display your buffers.
 
-That means you can instruct @t{mu4e} to place message views in separate tabs or
-frames, if you so desire.
+Let's look at some examples.
+
+@subsection Fine-tuning the main buffer display
+
+By default @t{mu4e}'s main buffer occupies the complete frame, but this can be
+changed to use the current window:
+
+@lisp
+(add-to-list 'display-buffer-alist
+             `(,(regexp-quote mu4e-main-buffer-name)
+               display-buffer-same-window))
+@end lisp
 
-@subsection Display Customization Example
+@subsection Fine-tuning headers buffer display
 
 You do not need to configure @code{mu4e-split-view} for this to work. In the
 absence of explicit rules to the contrary, @t{mu4e} will fall back on the value
@@ -1219,9 +1231,10 @@
 
 @lisp
 (add-to-list 'display-buffer-alist
-  '(("\\*mu4e-headers\\*" display-buffer-in-side-window
-    (side . right)
-    (window-width . 0.5)))
+             `(,(regexp-quote mu4e-headers-buffer-name)
+               display-buffer-in-side-window
+               (side . right)
+               (window-width . 0.5)))
 @end lisp
 
 You can type @key{C-x w s} to toggle the side windows to hide or show them at
@@ -1504,13 +1517,13 @@
 typing @key{Z}.
 
 You can freely rename a message view buffer -- such as with @key{C-x x
-r} -- if you want multiple, open messages.
+r} -- if you want a custom, non-randomized name.
 
 Detached messages are often useful for workflows involving lots of
 simultaneous messages.
 
 You can @emph{tear off} the window a message is in and place it in a
-new tab by typing @key{C-x w ^ f}. You can also detach a window and
+new frame by typing @key{C-x w ^ f}. You can also detach a window and
 put it in its own tab with @key{C-x w ^ t}.
 
 @node Editor view
@@ -3112,7 +3125,7 @@
 handled through a minor-mode @code{mu4e-modeline-mode}, which is enabled by
 default when @t{mu4e} is running.
 
-To completely turn off the modeline support, set @code{mu4e-support-modeline} 
to
+To completely turn off the modeline support, set @code{mu4e-modeline-support} 
to
 @t{nil} before starting @t{mu4e}.
 
 @t{mu4e} shares information on the modeline in two ways:
@@ -3125,8 +3138,11 @@
 @item global: information about the results for the ``favorite query''
 @end itemize
 
-All of the bookmark items provide more details in their @code{help-echo}, i.e.,
-their tooltip.
+The global indicators can be disabled by setting 
@code{mu4e-modeline-show-global}
+to @t{nil}.
+
+All of the bookmark items provide more details in their @code{help-echo},
+i.e., their tooltip.
 
 @subsection Query parameters bookmark item
 The query parameters in the modeline start with the various query flags (such 
as

Reply via email to