New Upstream Release - golang-github-zenhack-go.notmuch
Ready changes
Summary
Merged new upstream version: 0.0~git20220918.0c91863 (was: 0.0~git20190821.5a19619).
Resulting package
Built on 2022-10-13T10:44 (took 3m13s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases golang-github-zenhack-go.notmuch-dev
Lintian Result
- golang-github-zenhack-go.notmuch-dev_0.0~git20220918.0c91863-1~jan+nur1_all.deb
- golang-github-zenhack-go.notmuch_0.0~git20220918.0c91863-1~jan+nur1.dsc
- golang-github-zenhack-go.notmuch_0.0~git20220918.0c91863-1~jan+nur1_amd64.buildinfo
- golang-github-zenhack-go.notmuch_0.0~git20220918.0c91863-1~jan+nur1_amd64.changes
Diff
diff --git a/db.go b/db.go
index a999567..3b85d04 100644
--- a/db.go
+++ b/db.go
@@ -60,14 +60,65 @@ func Create(path string) (*DB, error) {
// Open opens the database at the location path using mode. Caller is responsible
// for closing the database when done.
func Open(path string, mode DBMode) (*DB, error) {
- cpath := C.CString(path)
- defer C.free(unsafe.Pointer(cpath))
+ config := ""
+ return OpenWithConfig(&path, &config, nil, mode)
+}
+
+// OpenWithConfig opens the database at the location 'path' using 'mode' and
+// the configuration in 'config'.
+//
+// If 'path' is nil, use the location specified:
+// - in the environment variable $NOTMUCH_DATABASE, if non-empty
+// - in a configuration file, located as described in 'config'
+// - by $XDG_DATA_HOME/notmuch/<profile>, if profile argument is set
+//
+// If 'path' is non-nil, but does not appear to be a Xapian database, check
+// for a directory '.notmuch/xapian' below 'path'.
+//
+// If 'config' is nil, it will look:
+// - the environment variable $NOTMUCH_CONFIG, if non-empty
+// - $XDG_CONFIG_HOME/notmuch
+// - $HOME/.notmuch-config
+//
+// If 'config' is an empty string (""), then it will not open any configuration
+// file.
+//
+// If 'profile' is nil, it will use:
+// - the environment variable $NOTMUCH_PROFILE if defined
+// - otherwise 'default' for directories, and '' for paths
+//
+// If 'profile' is non-nil, append to the directory / file path determined
+// for 'config' and 'path'.
+//
+// Caller is responsible for closing the database when done.
+func OpenWithConfig(path, config, profile *string, mode DBMode) (*DB, error) {
+ var cpath *C.char
+ if path != nil {
+ cpath = C.CString(*path)
+ defer C.free(unsafe.Pointer(cpath))
+ }
+
+ var cconfig *C.char
+ if config != nil {
+ cconfig = C.CString(*config)
+ defer C.free(unsafe.Pointer(cconfig))
+ }
+
+ var cprofile *C.char
+ if profile != nil {
+ cprofile = C.CString(*profile)
+ defer C.free(unsafe.Pointer(cprofile))
+ }
+
+ var errMsg string
+ cErrMsg := C.CString(errMsg)
+ defer C.free(unsafe.Pointer(cErrMsg))
cmode := C.notmuch_database_mode_t(mode)
var cdb *C.notmuch_database_t
cdbptr := (**C.notmuch_database_t)(&cdb)
- err := statusErr(C.notmuch_database_open(cpath, cmode, cdbptr))
- if err != nil {
+ err := statusErr(C.notmuch_database_open_with_config(cpath, cmode, cconfig, cprofile, cdbptr, &cErrMsg))
+ if err != nil || errMsg != "" {
return nil, err
}
db := &DB{cptr: unsafe.Pointer(cdb)}
@@ -149,7 +200,9 @@ func (db *DB) AddMessage(filename string) (*Message, error) {
defer C.free(unsafe.Pointer(cfilename))
var cmsg *C.notmuch_message_t
- if err := statusErr(C.notmuch_database_index_file(db.toC(), cfilename, nil, &cmsg)); err != nil {
+ err := statusErr(C.notmuch_database_index_file(db.toC(), cfilename, nil, &cmsg))
+
+ if err != nil && err != ErrDuplicateMessageID {
return nil, err
}
msg := &Message{
@@ -157,7 +210,7 @@ func (db *DB) AddMessage(filename string) (*Message, error) {
parent: (*cStruct)(db),
}
setGcClose(msg)
- return msg, nil
+ return msg, err
}
// RemoveMessage remove a message filename from the current database. If the
diff --git a/db_test.go b/db_test.go
index 247edfd..63290e5 100644
--- a/db_test.go
+++ b/db_test.go
@@ -308,3 +308,126 @@ func TestConfigListNext(t *testing.T) {
t.Errorf("iteration did not stop after the end of the options")
}
}
+
+func TestOpenWithConfig(t *testing.T) {
+ // Temp dir for our configs and profiles
+ tmpDir, err := os.MkdirTemp("", "notmuch")
+ if err != nil {
+ t.Fatalf("MkdirTemp(): unexpected error: %s", err)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ // "Default" profile
+ defaultProfileDir := path.Join(tmpDir, "notmuch", "default")
+ if err := os.MkdirAll(defaultProfileDir, 0700); err != nil {
+ t.Fatalf("MkdirAll(%s): unexpected error: %s", defaultProfileDir, err)
+ }
+
+ // "Test" profile
+ testProfile := "testProfile"
+ testProfileDir := path.Join(tmpDir, "notmuch", testProfile)
+ if err := os.MkdirAll(testProfileDir, 0700); err != nil {
+ t.Fatalf("MkdirAll(%s): unexpected error: %s", testProfileDir, err)
+ }
+
+ for _, dir := range []string{testProfileDir, defaultProfileDir, tmpDir} {
+ config, err := os.Create(path.Join(dir, "config"))
+ if err != nil {
+ t.Fatalf("CreateTemp(%s): unexpected error: %s", dir, err)
+ }
+ defer config.Close()
+ if _, err := config.WriteString(fmt.Sprintf("[database]\npath=%s\n", dbPath)); err != nil {
+ t.Fatalf("WriteString(%q): unexpected error: %s", config.Name(), err)
+ }
+ }
+
+ configPath := path.Join(tmpDir, "config")
+ badPath := "/nowherexyz73"
+ badProfile := "nowherexyz13"
+
+ type args struct {
+ path *string
+ config *string
+ profile *string
+ xdg_home *string
+ mode DBMode
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {
+ name: "with default profile",
+ args: args{
+ mode: DBReadOnly,
+ xdg_home: &tmpDir,
+ },
+ },
+ {
+ name: "with custom profile",
+ args: args{
+ mode: DBReadOnly,
+ profile: &testProfile,
+ xdg_home: &tmpDir,
+ },
+ },
+ {
+ name: "with config file",
+ args: args{
+ path: nil,
+ config: &configPath,
+ mode: DBReadOnly,
+ },
+ },
+ {
+ name: "with db path only",
+ args: args{
+ path: &dbPath,
+ mode: DBReadOnly,
+ },
+ },
+ {
+ name: "with non-existent config file",
+ args: args{
+ config: &badPath,
+ },
+ wantErr: true,
+ },
+ {
+ name: "with non-existent path",
+ args: args{
+ path: &badPath,
+ },
+ wantErr: true,
+ },
+ {
+ name: "with non-existent profile",
+ args: args{
+ profile: &badProfile,
+ xdg_home: &tmpDir,
+ },
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if tt.args.xdg_home != nil {
+ os.Setenv("XDG_CONFIG_HOME", *tt.args.xdg_home)
+ defer os.Unsetenv("XDG_CONFIG_HOME")
+ }
+
+ db, err := OpenWithConfig(tt.args.path, tt.args.config, tt.args.profile, tt.args.mode)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("OpenWithConfig() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+
+ if !tt.wantErr {
+ if want, got := 1, db.Version(); got < want {
+ t.Errorf("db.Version(): want at least %d got %d", want, got)
+ }
+ }
+ })
+ }
+}
diff --git a/debian/changelog b/debian/changelog
index 7052137..a80b813 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,9 @@
-golang-github-zenhack-go.notmuch (0.0~git20190821.5a19619-3) UNRELEASED; urgency=low
+golang-github-zenhack-go.notmuch (0.0~git20220918.0c91863-1) UNRELEASED; urgency=low
* Set upstream metadata fields: Bug-Database, Bug-Submit.
+ * New upstream snapshot.
- -- Debian Janitor <janitor@jelmer.uk> Sun, 30 Aug 2020 16:41:32 -0000
+ -- Debian Janitor <janitor@jelmer.uk> Thu, 13 Oct 2022 10:42:09 -0000
golang-github-zenhack-go.notmuch (0.0~git20190821.5a19619-2) unstable; urgency=medium
diff --git a/message.go b/message.go
index ee56c1f..a4bd535 100644
--- a/message.go
+++ b/message.go
@@ -117,6 +117,50 @@ func (m *Message) RemoveAllTags() error {
return statusErr(C.notmuch_message_remove_all_tags(m.toC()))
}
+// Properties returns the properties for the current message, returning a
+// *MessageProperties which can be used to iterate over all properties using
+// `MessageProperties.Next(MessageProperty)`
+func (m *Message) Properties(key string, exact bool) *MessageProperties {
+ cexact := 0
+ if exact {
+ cexact = 1
+ }
+ ckey := C.CString(key)
+ defer C.free(unsafe.Pointer(ckey))
+ cprops := C.notmuch_message_get_properties(m.toC(), ckey, C.int(cexact))
+ props := &MessageProperties{
+ cptr: unsafe.Pointer(cprops),
+ parent: (*cStruct)(m),
+ }
+ setGcClose(props)
+ return props
+}
+
+// AddProperty adds a property to the message.
+func (m *Message) AddProperty(key string, value string) error {
+ ckey := C.CString(key)
+ defer C.free(unsafe.Pointer(ckey))
+ cvalue := C.CString(value)
+ defer C.free(unsafe.Pointer(cvalue))
+ return statusErr(C.notmuch_message_add_property(m.toC(), ckey, cvalue))
+}
+
+// RemoveProperty removes a key/value pair from the message properties.
+func (m *Message) RemoveProperty(key string, value string) error {
+ ckey := C.CString(key)
+ defer C.free(unsafe.Pointer(ckey))
+ cvalue := C.CString(value)
+ defer C.free(unsafe.Pointer(cvalue))
+ return statusErr(C.notmuch_message_remove_property(m.toC(), ckey, cvalue))
+}
+
+// RemoveAllProperties removes all properties with key from the message.
+func (m *Message) RemoveAllProperties(key string) error {
+ ckey := C.CString(key)
+ defer C.free(unsafe.Pointer(ckey))
+ return statusErr(C.notmuch_message_remove_all_properties(m.toC(), ckey))
+}
+
// Atomic allows a transactional change of tags to the message.
func (m *Message) Atomic(callback func(*Message)) error {
if err := statusErr(C.notmuch_message_freeze(m.toC())); err != nil {
diff --git a/message_properties.go b/message_properties.go
new file mode 100644
index 0000000..3361877
--- /dev/null
+++ b/message_properties.go
@@ -0,0 +1,62 @@
+package notmuch
+
+// Copyright © 2015 The go.notmuch Authors. Authors can be found in the AUTHORS file.
+// Licensed under the GPLv3 or later.
+// See COPYING at the root of the repository for details.
+
+// #cgo LDFLAGS: -lnotmuch
+// #include <stdlib.h>
+// #include <notmuch.h>
+import "C"
+
+// MessageProperties represent a notmuch properties type.
+type MessageProperties cStruct
+
+func (props *MessageProperties) toC() *C.notmuch_message_properties_t {
+ return (*C.notmuch_message_properties_t)(props.cptr)
+}
+
+func (props *MessageProperties) Close() error {
+ return (*cStruct)(props).doClose(func() error {
+ C.notmuch_message_properties_destroy(props.toC())
+ return nil
+ })
+}
+
+// Next retrieves the next prop from the result set. Next returns true if a prop
+// was successfully retrieved.
+func (props *MessageProperties) Next(p **MessageProperty) bool {
+ if !props.valid() {
+ return false
+ }
+ *p = props.get()
+ C.notmuch_message_properties_move_to_next(props.toC())
+ return true
+}
+
+// Return a slice of strings containing each element of props.
+func (props *MessageProperties) slice() []string {
+ var prop *MessageProperty
+ ret := []string{}
+ for props.Next(&prop) {
+ ret = append(ret, prop.Value)
+ }
+ return ret
+}
+
+func (props *MessageProperties) get() *MessageProperty {
+ ckey := C.notmuch_message_properties_key(props.toC())
+ cvalue := C.notmuch_message_properties_value(props.toC())
+
+ prop := &MessageProperty{
+ Key: C.GoString(ckey),
+ Value: C.GoString(cvalue),
+ properties: props,
+ }
+ return prop
+}
+
+func (props *MessageProperties) valid() bool {
+ cbool := C.notmuch_message_properties_valid(props.toC())
+ return int(cbool) != 0
+}
diff --git a/message_properties_test.go b/message_properties_test.go
new file mode 100644
index 0000000..29e861e
--- /dev/null
+++ b/message_properties_test.go
@@ -0,0 +1,39 @@
+package notmuch
+
+import (
+ "testing"
+)
+
+func TestMessagesProperties(t *testing.T) {
+ db, err := Open(dbPath, DBReadWrite)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+
+ qs := "subject:\"Introducing myself\""
+ messages, err := db.NewQuery(qs).Messages()
+ if err != nil {
+ t.Fatalf("error getting the messages: %s", err)
+ }
+
+ first := &Message{}
+ found := messages.Next(&first)
+ if !found {
+ t.Fatalf("couldn't get the first message: %s", err)
+ }
+
+ if err := first.AddProperty("go-notmuch-test", "success"); err != nil {
+ t.Fatalf("couldn't add property: %s", err)
+ }
+
+ properties := first.Properties("go-notmuch-test", true)
+ property := &MessageProperty{}
+ for properties.Next(&property) {
+ if property.Key == "go-notmuch-test" && property.Value == "success" {
+ return
+ }
+ }
+
+ t.Fatalf("couldn't find expected property")
+}
diff --git a/message_property.go b/message_property.go
new file mode 100644
index 0000000..bf313c5
--- /dev/null
+++ b/message_property.go
@@ -0,0 +1,21 @@
+package notmuch
+
+// Copyright © 2015 The go.notmuch Authors. Authors can be found in the AUTHORS file.
+// Licensed under the GPLv3 or later.
+// See COPYING at the root of the repository for details.
+
+// #cgo LDFLAGS: -lnotmuch
+// #include <stdlib.h>
+// #include <notmuch.h>
+import "C"
+
+// MessageProperty represents a property in the database.
+type MessageProperty struct {
+ Key string
+ Value string
+ properties *MessageProperties
+}
+
+func (p *MessageProperty) String() string {
+ return p.Key + "=" + p.Value
+}
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/share/gocode/src/github.com/zenhack/go.notmuch/message_properties.go -rw-r--r-- root/root /usr/share/gocode/src/github.com/zenhack/go.notmuch/message_properties_test.go -rw-r--r-- root/root /usr/share/gocode/src/github.com/zenhack/go.notmuch/message_property.go
No differences were encountered in the control files