The output in default.import is based on a modified version of Felipe's git-remote-nm with Blake2 hashing replaced by SHA1 (for portability). This enable git-pull, so test that as well. --- git-remote-notmuch.c | 129 ++++++++++++++++++++++++++++++++++++++++ test/T860-git-remote.sh | 38 +++++++++++- 2 files changed, 166 insertions(+), 1 deletion(-) diff --git a/git-remote-notmuch.c b/git-remote-notmuch.c index cfc43a68..a4ed98e2 100644 --- a/git-remote-notmuch.c +++ b/git-remote-notmuch.c @@ -76,6 +76,54 @@ static unsigned long read_lastmod (const void *ctx, const char *dir) { return num; } +static void +store_lastmod (notmuch_database_t *notmuch, const char *dir) { + char *filename = NULL; + FILE *out; + + ASSERT(filename = talloc_asprintf (notmuch, "%s/lastmod", dir)); + + ASSERT(out = fopen (filename, "w")); + + ASSERT(fprintf (out, "%zu\n", notmuch_database_get_revision (notmuch, NULL)) > 0); +} + +static void +read_one_line (FILE *stream, char **line_p, size_t *len_p) { + ssize_t nread; + + nread = getline(line_p, len_p, stream); + if (nread < 0) { + perror ("getline"); + exit (EXIT_FAILURE); + } + ASSERT(line_p); + + chomp_newline(*line_p); +} + +static const char* +shell2string (const char* command) { + FILE *out; + char *line = NULL; + size_t len; + + out = popen (command,"r"); + if (out == NULL) { + perror("popen"); + exit(EXIT_FAILURE); + } + + read_one_line (out, &line, &len); + return line; +} + +static void +wr_data(const char *data) { + printf ("data %zu\n", strlen(data)); + fputs (data, stdout); +} + static void cmd_capabilities () { fputs("import\nexport\nrefspec refs/heads/*:refs/notmuch/*\n\n", stdout); @@ -97,6 +145,85 @@ usage() { exit(EXIT_FAILURE); } +static void +cmd_import (notmuch_database_t *notmuch) { + const char* ident = NULL; + const char* lastmod_str = NULL; + notmuch_messages_t *messages; + notmuch_status_t status; + notmuch_query_t *query; + char *mid_buf = NULL; + size_t mid_buf_len = 0; + + ident = shell2string("git var GIT_COMMITTER_IDENT"); + + printf ("feature done\ncommit refs/notmuch/master\nmark :1\ncommitter %s\n", ident); + + ASSERT(lastmod_str = talloc_asprintf (notmuch, "lastmod: %zu\n", lastmod)); + wr_data (lastmod_str); + if (lastmod > 0) + puts("from refs/notmuch/master^0"); + puts("deleteall"); + + status = notmuch_query_create_with_syntax (notmuch, + "", + NOTMUCH_QUERY_SYNTAX_XAPIAN, + &query); + + if (print_status_database ("git-remote-nm", notmuch, status)) + exit(EXIT_FAILURE); + + if (debug_flags && strchr (debug_flags, 's')) + notmuch_query_set_sort (query, NOTMUCH_SORT_NEWEST_FIRST); + else + notmuch_query_set_sort (query, NOTMUCH_SORT_UNSORTED); + + status = notmuch_query_search_messages (query, &messages); + if (print_status_query ("git-remote-nm", query, status)) + exit(EXIT_FAILURE); + + for (; + notmuch_messages_valid (messages); + notmuch_messages_move_to_next (messages)) { + + const char* tag_buf = ""; + const char* mid; + + const char* hash; + + notmuch_message_t *message = notmuch_messages_get (messages); + mid = notmuch_message_get_message_id (message); + + if (hex_encode (notmuch, mid, &mid_buf, &mid_buf_len) != HEX_SUCCESS) { + fprintf (stderr, "Error: failed to hex-encode message-id %s\n", mid); + exit(EXIT_FAILURE); + } + + /* we can't use _notmuch_sha1_from_string because we don't want + * to include the null terminator */ + GChecksum *sha1; + sha1 = g_checksum_new (G_CHECKSUM_SHA1); + g_checksum_update (sha1, (const guchar *) mid, strlen (mid)); + hash = g_checksum_get_string (sha1); + printf ("M 644 inline %2.2s/%2.2s/%s/tags\n", hash, hash+2, mid_buf); + + g_checksum_free (sha1); + + for (notmuch_tags_t *tags = notmuch_message_get_tags (message); + notmuch_tags_valid (tags); + notmuch_tags_move_to_next (tags)) { + const char *tag_str = notmuch_tags_get (tags); + ASSERT(tag_buf=talloc_asprintf (message, "%s%s\n", tag_buf, tag_str)); + } + wr_data (tag_buf); + notmuch_message_destroy (message); + } + puts(""); + puts("done"); + fflush (stdout); + store_lastmod(notmuch, nm_dir); +} + int main (int argc, char *argv[]) { @@ -169,6 +296,8 @@ main (int argc, char *argv[]) if (STRNCMP_LITERAL (s, "capabilities")== 0) cmd_capabilities (); + else if (STRNCMP_LITERAL (s, "import") == 0) + cmd_import (db); else if (STRNCMP_LITERAL (s, "list") == 0) cmd_list (); diff --git a/test/T860-git-remote.sh b/test/T860-git-remote.sh index 7b2b6b49..d5809e6b 100755 --- a/test/T860-git-remote.sh +++ b/test/T860-git-remote.sh @@ -20,7 +20,7 @@ export GIT_COMMITTER_NAME="Notmuch Test Suite" export GIT_COMMITTER_EMAIL="notmuch@example.com" export GIT_REMOTE_NM_DEBUG="s" export GIT_REMOTE_NM_LOG=grn-log.txt -EXPECTED=$NOTMUCH_SRCDIR/test/git-remote-nm.expected-output +EXPECTED=$NOTMUCH_SRCDIR/test/git-remote.expected-output TAG_FILE="87/b1/4EFC743A.3060609@april.org/tags" @@ -42,4 +42,40 @@ cat <<EOF > EXPECTED EOF test_expect_equal_file EXPECTED OUTPUT +test_begin_subtest 'import writes lastmod file' +echo import | run_helper dummy-alias dummy-url > /dev/null +lastmod=$(notmuch count --lastmod '*' | cut -f3) +test_expect_equal "${lastmod}" "$(cat ${git_tmp}/notmuch/lastmod)" + +# note that this test must not be the first time import is run, +# because it depends on the lastmod file +test_begin_subtest 'import produces expected output' +echo import | run_helper | notmuch_sanitize_git > OUTPUT +test_expect_equal_file $EXPECTED/default.import OUTPUT + +test_begin_subtest "clone has every message" +git clone notmuch::currently-ignored repo +find repo -name tags -type f | sed -e s,repo/../../,id:, -e s,/tags$,, | sort > OUTPUT +notmuch search --output=messages '*' | sort > EXPECTED +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "pull get new tag" +notmuch tag +zznew -- id:4EFC743A.3060609@april.org +git -C repo pull +cat<<EOF >EXPECTED +inbox +unread +zznew +EOF +test_expect_equal_file EXPECTED repo/$TAG_FILE + +test_begin_subtest "pull sees deletion" +notmuch tag -unread -- id:4EFC743A.3060609@april.org +git -C repo pull +cat<<EOF >EXPECTED +inbox +zznew +EOF +test_expect_equal_file EXPECTED repo/$TAG_FILE + test_done -- 2.43.0 _______________________________________________ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-leave@notmuchmail.org