From: David Bremner <david@tethera.net>
To: notmuch@notmuchmail.org
Subject: [PATCH 2/5] cli: start remote helper for git.
Date: Wed, 28 Aug 2024 08:45:55 -0700 [thread overview]
Message-ID: <20240828160710.866567-3-david@tethera.net> (raw)
In-Reply-To: <20240828160710.866567-1-david@tethera.net>
This is closely based on git-remote-nm (in ruby) by Felipe Contreras.
Initially just implement the commands 'capabilites' and 'list'. This
isn't enough to do anything useful so start some unit tests.
---
Makefile.local | 7 +-
git-remote-notmuch.c | 181 ++++++++++++++++++++++++++++++++++++++++
test/T860-git-remote.sh | 45 ++++++++++
3 files changed, 232 insertions(+), 1 deletion(-)
create mode 100644 git-remote-notmuch.c
create mode 100755 test/T860-git-remote.sh
diff --git a/Makefile.local b/Makefile.local
index 7699c208..2ac494b8 100644
--- a/Makefile.local
+++ b/Makefile.local
@@ -1,7 +1,8 @@
# -*- makefile-gmake -*-
.PHONY: all
-all: notmuch notmuch-shared build-man build-info ruby-bindings python-cffi-bindings notmuch-git nmbug
+all: notmuch notmuch-shared git-remote-notmuch \
+ build-man build-info ruby-bindings python-cffi-bindings notmuch-git nmbug
ifeq ($(MAKECMDGOALS),)
ifeq ($(shell cat .first-build-message 2>/dev/null),)
@NOTMUCH_FIRST_BUILD=1 $(MAKE) --no-print-directory all
@@ -274,6 +275,9 @@ notmuch: $(notmuch_client_modules) lib/libnotmuch.a util/libnotmuch_util.a parse
notmuch-shared: $(notmuch_client_modules) lib/$(LINKER_NAME)
$(call quiet,$(FINAL_NOTMUCH_LINKER) $(CFLAGS)) $(notmuch_client_modules) $(FINAL_NOTMUCH_LDFLAGS) -o $@
+git-remote-notmuch: git-remote-notmuch.o status.o
+ $(call quiet,$(FINAL_NOTMUCH_LINKER) $(CFLAGS)) $^ $(FINAL_NOTMUCH_LDFLAGS) -o $@
+
.PHONY: install
install: all install-man install-info
mkdir -p "$(DESTDIR)$(prefix)/bin/"
@@ -302,6 +306,7 @@ endif
SRCS := $(SRCS) $(notmuch_client_srcs)
CLEAN := $(CLEAN) notmuch notmuch-shared $(notmuch_client_modules)
+CLEAN := $(CLEAN) git-remote-notmuch git-remote-notmuch.o
CLEAN := $(CLEAN) version.stamp notmuch-*.tar.gz.tmp
CLEAN := $(CLEAN) .deps
diff --git a/git-remote-notmuch.c b/git-remote-notmuch.c
new file mode 100644
index 00000000..cfc43a68
--- /dev/null
+++ b/git-remote-notmuch.c
@@ -0,0 +1,181 @@
+/* notmuch - Not much of an email program, (just index and search)
+ *
+ * Copyright © 2023 Felipe Contreras
+ * Copyright © 2024 David Bremner
+ *
+ * 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 Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ *
+ * Authors: Felipe Contreras
+ * David Bremner <david@tethera.net>
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <notmuch.h>
+#include "notmuch-client.h"
+#include "path-util.h"
+#include "hex-escape.h"
+#include "string-util.h"
+
+#define ASSERT(x) assert((x))
+
+/* File scope globals */
+const char *alias = NULL;
+const char *nm_dir = NULL;
+const char *url = NULL;
+const char* debug_flags = NULL;
+unsigned long lastmod;
+notmuch_database_t *db;
+FILE *log_file = NULL;
+
+static void
+flog (const char *format, ...) {
+ va_list va_args;
+
+ if (log_file) {
+ va_start (va_args, format);
+ vfprintf (log_file, format, va_args);
+ fflush (log_file);
+ va_end (va_args);
+ }
+}
+
+static unsigned long read_lastmod (const void *ctx, const char *dir) {
+ char *filename = NULL;
+ unsigned long num = 0;
+
+ FILE *in;
+
+ ASSERT(filename = talloc_asprintf (ctx, "%s/lastmod", dir));
+
+ in = fopen (filename, "r");
+ if (in) {
+ ASSERT(fscanf (in, "%zu", &num) == 1);
+ } else {
+ if (errno != ENOENT) {
+ fprintf (stderr, "error opening lastmod file");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ flog ("loaded lastmod = %zu\n", num);
+
+ return num;
+}
+
+static void
+cmd_capabilities () {
+ fputs("import\nexport\nrefspec refs/heads/*:refs/notmuch/*\n\n", stdout);
+ fflush (stdout);
+}
+
+static void
+cmd_list () {
+ unsigned long current_lastmod;
+ current_lastmod = notmuch_database_get_revision (db, NULL);
+ printf("? refs/heads/master%s\n\n",
+ lastmod == current_lastmod ? " unchanged" : "");
+ fflush (stdout);
+}
+
+static void
+usage() {
+ fprintf (stderr, "usage: git-remote-nm ALIAS URL\n");
+ exit(EXIT_FAILURE);
+}
+
+int
+main (int argc, char *argv[])
+{
+ notmuch_status_t status;
+ char *status_string = NULL;
+ const char* git_dir;
+ ssize_t nread;
+ size_t len = 0;
+ const char *log_file_name;
+
+ char *line = NULL;
+
+ debug_flags = getenv ("GIT_REMOTE_NM_DEBUG");
+ log_file_name = getenv ("GIT_REMOTE_NM_LOG");
+
+ if (log_file_name)
+ log_file = fopen (log_file_name, "w");
+
+ if (argc != 3)
+ usage();
+ /* setup globals */
+ alias = argv[1];
+ url = argv[2];
+
+ status = notmuch_database_open_with_config (NULL,
+ NOTMUCH_DATABASE_MODE_READ_WRITE,
+ NULL,
+ NULL,
+ &db,
+ &status_string);
+ if (status) {
+ if (status_string) {
+ fputs (status_string, stderr);
+ free (status_string);
+ status_string = NULL;
+ }
+ return EXIT_FAILURE;
+ }
+
+ git_dir = getenv ("GIT_DIR");
+ if (! git_dir) {
+ fprintf (stderr, "GIT_DIR not set\n");
+ exit(EXIT_FAILURE);
+ }
+ flog ("GIT_DIR=%s\n", git_dir);
+
+ ASSERT(nm_dir = talloc_asprintf(db, "%s/%s", git_dir, "notmuch"));
+
+ status = mkdir_recursive (db, nm_dir, 0700, &status_string);
+ if (status) {
+ if (status_string)
+ fputs(status_string, stderr);
+
+ exit (EXIT_FAILURE);
+ }
+
+ lastmod = read_lastmod (db, nm_dir);
+
+ while ((nread = getline(&line, &len, stdin)) != -1) {
+ size_t count=0;
+ char *s = line;
+ flog ("command = %s\n", line);
+
+ /* skip leading space */
+ while (*s && isspace(*s)) s++;
+ while (s[count] && ! isspace(s[count])) count++;
+
+ if (count == 0)
+ break;
+
+ if (STRNCMP_LITERAL (s, "capabilities")== 0)
+ cmd_capabilities ();
+ else if (STRNCMP_LITERAL (s, "list") == 0)
+ cmd_list ();
+
+ fflush(stdout);
+ flog ("finished command = %s\n", s);
+ }
+ flog ("finished loop\n");
+
+ notmuch_database_destroy (db);
+}
diff --git a/test/T860-git-remote.sh b/test/T860-git-remote.sh
new file mode 100755
index 00000000..7b2b6b49
--- /dev/null
+++ b/test/T860-git-remote.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+test_description='git-remote-notmuch'
+. $(dirname "$0")/test-lib.sh || exit 1
+
+notmuch_sanitize_git() {
+ sed 's/^committer \(.*\) \(<[^>]*>\) [1-9][0-9]* [-+][0-9]*/committer \1 \2 TIMESTAMP TIMEZONE/'
+}
+
+add_email_corpus
+
+mkdir repo
+
+git_tmp=$(mktemp -d gitXXXXXXXX)
+
+run_helper () {
+ GIT_DIR=${git_tmp} git-remote-notmuch dummy-alias dummy-url
+}
+
+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
+
+TAG_FILE="87/b1/4EFC743A.3060609@april.org/tags"
+
+test_begin_subtest 'capabilities'
+echo capabilities | run_helper > OUTPUT
+cat <<EOF > EXPECTED
+import
+export
+refspec refs/heads/*:refs/notmuch/*
+
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest 'list'
+echo list | run_helper > OUTPUT
+cat <<EOF > EXPECTED
+? refs/heads/master
+
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_done
--
2.43.0
\r
next prev parent reply other threads:[~2024-08-28 16:13 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-28 15:45 WIP: git-remote-notmuch David Bremner
2024-08-28 15:45 ` [PATCH 1/5] util: refactor sync_dir and mkdir_recursive David Bremner
2024-08-28 15:45 ` David Bremner [this message]
2024-08-28 15:45 ` [PATCH 3/5] cli/git-remote: add support for import command David Bremner
2024-08-28 15:45 ` [PATCH 4/5] cli/git-remote: add export command David Bremner
2024-08-28 15:45 ` [PATCH 5/5] cli/git-remote: add time performance test David Bremner
2024-08-28 21:11 ` WIP: git-remote-notmuch David Bremner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://notmuchmail.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240828160710.866567-3-david@tethera.net \
--to=david@tethera.net \
--cc=notmuch@notmuchmail.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhetil.org/notmuch.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).