Patchwork [2,of,3] chg: fallback to original hg for some unsupported commands or flags

login
register
mail settings
Submitter Jun Wu
Date Feb. 24, 2016, 2:31 p.m.
Message ID <b7c36ebb96f5492f3dd9.1456324284@x1c>
Download mbox | patch
Permalink /patch/13354/
State Superseded
Commit 0a17cfbe54294998efbcd85e7e4a4d21c592b0c0
Delegated to: Yuya Nishihara
Headers show

Comments

Jun Wu - Feb. 24, 2016, 2:31 p.m.
# HG changeset patch
# User Jun Wu <quark@fb.com>
# Date 1456322383 0
#      Wed Feb 24 13:59:43 2016 +0000
# Node ID b7c36ebb96f5492f3dd90bacbb8fee65c6eabb59
# Parent  fb9caea246de70223b26fe94ffcd1f6b32ba49a6
chg: fallback to original hg for some unsupported commands or flags

There are some known unsupported commands or flags for chg, such as hg serve
and hg foo --time. This patch detects these situations and transparently fall
back to the original hg. So the users won't bother remembering what chg can
and cannot do by themselves.

The current detection is not 100% accurate since we do not have an equivalent
command line parser in C. In the future we may want to implement a more
accurate "unsupported" check server-side.
Yuya Nishihara - Feb. 25, 2016, 1:42 p.m.
On Wed, 24 Feb 2016 14:31:24 +0000, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu <quark@fb.com>
> # Date 1456322383 0
> #      Wed Feb 24 13:59:43 2016 +0000
> # Node ID b7c36ebb96f5492f3dd90bacbb8fee65c6eabb59
> # Parent  fb9caea246de70223b26fe94ffcd1f6b32ba49a6
> chg: fallback to original hg for some unsupported commands or flags
> 
> There are some known unsupported commands or flags for chg, such as hg serve
> and hg foo --time. This patch detects these situations and transparently fall
> back to the original hg. So the users won't bother remembering what chg can
> and cannot do by themselves.
> 
> The current detection is not 100% accurate since we do not have an equivalent
> command line parser in C. In the future we may want to implement a more
> accurate "unsupported" check server-side.
> 
> diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
> --- a/contrib/chg/chg.c
> +++ b/contrib/chg/chg.c
> @@ -448,11 +448,40 @@
>  	abortmsg("failed to prepare pager (errno = %d)", errno);
>  }
>  
> +/*
> + * Test whether the command is unsupported or not. This is not designed to
> + * cover all cases like hg --flag ... serve. But it's fast and do not depend
> + * on the server.
> + */
> +static int isunsupported(int argc, const char *argv[])
> +{
> +	int i;
> +	for (i = 0; i < argc; ++i) {
> +		if (!strcmp(argv[i], "--"))
> +			break;
> +		if (i == 0 && strcmp("serve", argv[i]) == 0)
> +			return 1;
> +		if (strcmp("--time", argv[i]) == 0)
> +			return 1;
> +	}
> +	return 0;
> +}

Can it be more explicit? I'm sure "hg serve" (without -d) should work.

I understand that this trick would be somewhat useful, but it disables the
way to test the behavior of "chg serve" for example.
Jun Wu - Feb. 25, 2016, 2:11 p.m.
On 02/25/2016 01:42 PM, Yuya Nishihara wrote:
> Can it be more explicit? I'm sure "hg serve" (without -d) should
> work.

Yes. Will send V2 (probably after we get some conclusion about the 3
of 3).

Patch

diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
--- a/contrib/chg/chg.c
+++ b/contrib/chg/chg.c
@@ -448,11 +448,40 @@ 
 	abortmsg("failed to prepare pager (errno = %d)", errno);
 }
 
+/*
+ * Test whether the command is unsupported or not. This is not designed to
+ * cover all cases like hg --flag ... serve. But it's fast and do not depend
+ * on the server.
+ */
+static int isunsupported(int argc, const char *argv[])
+{
+	int i;
+	for (i = 0; i < argc; ++i) {
+		if (!strcmp(argv[i], "--"))
+			break;
+		if (i == 0 && strcmp("serve", argv[i]) == 0)
+			return 1;
+		if (strcmp("--time", argv[i]) == 0)
+			return 1;
+	}
+	return 0;
+}
+
+static void execoriginalhg(const char *argv[])
+{
+	debugmsg("execute original hg");
+	if (execvp(gethgcmd(), (char **)argv) < 0)
+		abortmsg("failed to exec original hg (errno = %d)", errno);
+}
+
 int main(int argc, const char *argv[], const char *envp[])
 {
 	if (getenv("CHGDEBUG"))
 		enabledebugmsg();
 
+	if (isunsupported(argc, argv))
+		execoriginalhg(argv);
+
 	struct cmdserveropts opts;
 	initcmdserveropts(&opts);
 	setcmdserveropts(&opts);