Patchwork [2,of,2,RFC] cmdserver: allow to start server without repository

login
register
mail settings
Submitter Yuya Nishihara
Date March 6, 2014, 1:02 p.m.
Message ID <e80644fac8a3fb63a420.1394110923@gimlet>
Download mbox | patch
Permalink /patch/3878/
State Accepted
Commit e811b93f2cb15d56e01dab5e6602b9a84a4e11d9
Headers show

Comments

Yuya Nishihara - March 6, 2014, 1:02 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1393856484 -32400
#      Mon Mar 03 23:21:24 2014 +0900
# Node ID e80644fac8a3fb63a420aefd68253e251a954253
# Parent  f5a932e110053629281ab0597349dc78a045418e
cmdserver: allow to start server without repository

Typical use case is to clone repository through command server.  Clone may
require user interaction, so command-server protocol is beneficial over
raw stdio channels.
Idan Kamara - March 6, 2014, 2:40 p.m.
On Thu, Mar 6, 2014 at 3:02 PM, Yuya Nishihara <yuya@tcha.org> wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1393856484 -32400
> #      Mon Mar 03 23:21:24 2014 +0900
> # Node ID e80644fac8a3fb63a420aefd68253e251a954253
> # Parent  f5a932e110053629281ab0597349dc78a045418e
> cmdserver: allow to start server without repository
>
> Typical use case is to clone repository through command server.  Clone may
> require user interaction, so command-server protocol is beneficial over
> raw stdio channels.

This is useful and something that has been missing since the beginning. +1!
Giovanni Gherdovich - March 6, 2014, 3:36 p.m.
On Thu, Mar 6, 2014 at 3:40 PM, Idan Kamara <idankk86@gmail.com> wrote:
>
> On Thu, Mar 6, 2014 at 3:02 PM, Yuya Nishihara <yuya@tcha.org> wrote:
> > # HG changeset patch
> > # User Yuya Nishihara <yuya@tcha.org>
> > # Date 1393856484 -32400
> > #      Mon Mar 03 23:21:24 2014 +0900
> > # Node ID e80644fac8a3fb63a420aefd68253e251a954253
> > # Parent  f5a932e110053629281ab0597349dc78a045418e
> > cmdserver: allow to start server without repository
> >
> > Typical use case is to clone repository through command server.  Clone
may
> > require user interaction, so command-server protocol is beneficial over
> > raw stdio channels.
>
> This is useful and something that has been missing since the beginning.
+1!

Absolutely !
Thank you Yuya for driving the vagon and having written this.

GGhh
Augie Fackler - March 6, 2014, 3:37 p.m.
On Thu, Mar 06, 2014 at 10:02:03PM +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya@tcha.org>
> # Date 1393856484 -32400
> #      Mon Mar 03 23:21:24 2014 +0900
> # Node ID e80644fac8a3fb63a420aefd68253e251a954253
> # Parent  f5a932e110053629281ab0597349dc78a045418e
> cmdserver: allow to start server without repository

Queueing these, thanks.

>
> Typical use case is to clone repository through command server.  Clone may
> require user interaction, so command-server protocol is beneficial over
> raw stdio channels.
>
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -5168,7 +5168,6 @@ def serve(ui, repo, **opts):
>          s.serve_forever()
>
>      if opts["cmdserver"]:
> -        checkrepo()
>          s = commandserver.server(ui, repo, opts["cmdserver"])
>          return s.serve()
>
> diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
> --- a/mercurial/commandserver.py
> +++ b/mercurial/commandserver.py
> @@ -142,11 +142,15 @@ class server(object):
>              else:
>                  logfile = open(logpath, 'a')
>
> -        # the ui here is really the repo ui so take its baseui so we don't end
> -        # up with its local configuration
> -        self.ui = repo.baseui
> -        self.repo = repo
> -        self.repoui = repo.ui
> +        if repo:
> +            # the ui here is really the repo ui so take its baseui so we don't
> +            # end up with its local configuration
> +            self.ui = repo.baseui
> +            self.repo = repo
> +            self.repoui = repo.ui
> +        else:
> +            self.ui = ui
> +            self.repo = self.repoui = None
>
>          if mode == 'pipe':
>              self.cerr = channeledoutput(sys.stderr, sys.stdout, 'e')
> @@ -183,12 +187,13 @@ class server(object):
>          # copy the uis so changes (e.g. --config or --verbose) don't
>          # persist between requests
>          copiedui = self.ui.copy()
> -        self.repo.baseui = copiedui
> -        # clone ui without using ui.copy because this is protected
> -        repoui = self.repoui.__class__(self.repoui)
> -        repoui.copy = copiedui.copy # redo copy protection
> -        self.repo.ui = self.repo.dirstate._ui = repoui
> -        self.repo.invalidateall()
> +        if self.repo:
> +            self.repo.baseui = copiedui
> +            # clone ui without using ui.copy because this is protected
> +            repoui = self.repoui.__class__(self.repoui)
> +            repoui.copy = copiedui.copy # redo copy protection
> +            self.repo.ui = self.repo.dirstate._ui = repoui
> +            self.repo.invalidateall()
>
>          req = dispatch.request(args[:], copiedui, self.repo, self.cin,
>                                 self.cout, self.cerr)
> diff --git a/tests/test-commandserver.py b/tests/test-commandserver.py
> --- a/tests/test-commandserver.py
> +++ b/tests/test-commandserver.py
> @@ -294,6 +294,11 @@ def mqoutsidechanges(server):
>      # repo.mq should be recreated to point to new queue
>      runcommand(server, ['qqueue', '--active'])
>
> +def startwithoutrepo(server):
> +    readchannel(server)
> +    runcommand(server, ['init', 'repo2'])
> +    runcommand(server, ['id', '-R', 'repo2'])
> +
>  if __name__ == '__main__':
>      os.system('hg init repo')
>      os.chdir('repo')
> @@ -329,3 +334,7 @@ if __name__ == '__main__':
>      hgrc.write('[extensions]\nmq=\n')
>      hgrc.close()
>      check(mqoutsidechanges)
> +
> +    os.chdir('..')
> +    check(hellomessage)
> +    check(startwithoutrepo)
> diff --git a/tests/test-commandserver.py.out b/tests/test-commandserver.py.out
> --- a/tests/test-commandserver.py.out
> +++ b/tests/test-commandserver.py.out
> @@ -237,3 +237,16 @@ popping 0.diff
>  patch queue now empty
>   runcommand qqueue --active
>  foo
> +
> +testing hellomessage:
> +
> +o, 'capabilities: getencoding runcommand\nencoding: ***'
> + runcommand id
> +abort: there is no Mercurial repository here (.hg not found)
> + [255]
> +
> +testing startwithoutrepo:
> +
> + runcommand init repo2
> + runcommand id -R repo2
> +000000000000 tip
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
Yuya Nishihara - March 6, 2014, 4:47 p.m.
On Thu, 6 Mar 2014 16:36:07 +0100, Giovanni Gherdovich wrote:
> On Thu, Mar 6, 2014 at 3:40 PM, Idan Kamara <idankk86@gmail.com> wrote:
> >
> > On Thu, Mar 6, 2014 at 3:02 PM, Yuya Nishihara <yuya@tcha.org> wrote:
> > > # HG changeset patch
> > > # User Yuya Nishihara <yuya@tcha.org>
> > > # Date 1393856484 -32400
> > > #      Mon Mar 03 23:21:24 2014 +0900
> > > # Node ID e80644fac8a3fb63a420aefd68253e251a954253
> > > # Parent  f5a932e110053629281ab0597349dc78a045418e
> > > cmdserver: allow to start server without repository
> > >
> > > Typical use case is to clone repository through command server.  Clone
> may
> > > require user interaction, so command-server protocol is beneficial over
> > > raw stdio channels.
> >
> > This is useful and something that has been missing since the beginning.
> +1!
> 
> Absolutely !
> Thank you Yuya for driving the vagon and having written this.

Thanks.

BTW, were there some concern not to implement this at the initial design?

This patch solves my problem, but I guess python-hglib will need another
command to set self.repo after server started, for example,

  hglib.clone()
    start command server without repo
    runcommand "clone from to"
    set server.repo = to (in some way)
    return hgclient object

Regards,
Idan Kamara - March 7, 2014, 9:27 a.m.
On Thu, Mar 6, 2014 at 6:47 PM, Yuya Nishihara <yuya@tcha.org> wrote:
> On Thu, 6 Mar 2014 16:36:07 +0100, Giovanni Gherdovich wrote:
>> On Thu, Mar 6, 2014 at 3:40 PM, Idan Kamara <idankk86@gmail.com> wrote:
>> >
>> > On Thu, Mar 6, 2014 at 3:02 PM, Yuya Nishihara <yuya@tcha.org> wrote:
>> > > # HG changeset patch
>> > > # User Yuya Nishihara <yuya@tcha.org>
>> > > # Date 1393856484 -32400
>> > > #      Mon Mar 03 23:21:24 2014 +0900
>> > > # Node ID e80644fac8a3fb63a420aefd68253e251a954253
>> > > # Parent  f5a932e110053629281ab0597349dc78a045418e
>> > > cmdserver: allow to start server without repository
>> > >
>> > > Typical use case is to clone repository through command server.  Clone
>> may
>> > > require user interaction, so command-server protocol is beneficial over
>> > > raw stdio channels.
>> >
>> > This is useful and something that has been missing since the beginning.
>> +1!
>>
>> Absolutely !
>> Thank you Yuya for driving the vagon and having written this.
>
> Thanks.
>
> BTW, were there some concern not to implement this at the initial design?

Not that I recall, I guess just the thought that most of the benefits
come from interacting with a repo.

>
> This patch solves my problem, but I guess python-hglib will need another
> command to set self.repo after server started, for example,
>
>   hglib.clone()
>     start command server without repo
>     runcommand "clone from to"
>     set server.repo = to (in some way)
>     return hgclient object

Yeah, we can either add a command to the protocol that lets you
'chrepo', but I'm not sure if opening a new instance after you've got
a repo is so bad.
Yuya Nishihara - March 7, 2014, 4:47 p.m.
On Fri, 7 Mar 2014 11:27:36 +0200, Idan Kamara wrote:
> On Thu, Mar 6, 2014 at 6:47 PM, Yuya Nishihara <yuya@tcha.org> wrote:
> > BTW, were there some concern not to implement this at the initial design?
> 
> Not that I recall, I guess just the thought that most of the benefits
> come from interacting with a repo.

I see.  I was a bit afraid that I've changed the command server to wrong
direction.

> > This patch solves my problem, but I guess python-hglib will need another
> > command to set self.repo after server started, for example,
> >
> >   hglib.clone()
> >     start command server without repo
> >     runcommand "clone from to"
> >     set server.repo = to (in some way)
> >     return hgclient object
> 
> Yeah, we can either add a command to the protocol that lets you
> 'chrepo', but I'm not sure if opening a new instance after you've got
> a repo is so bad.

True.  It can start new server, so "chrepo" command won't be important.

Regards,

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5168,7 +5168,6 @@  def serve(ui, repo, **opts):
         s.serve_forever()
 
     if opts["cmdserver"]:
-        checkrepo()
         s = commandserver.server(ui, repo, opts["cmdserver"])
         return s.serve()
 
diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py
--- a/mercurial/commandserver.py
+++ b/mercurial/commandserver.py
@@ -142,11 +142,15 @@  class server(object):
             else:
                 logfile = open(logpath, 'a')
 
-        # the ui here is really the repo ui so take its baseui so we don't end
-        # up with its local configuration
-        self.ui = repo.baseui
-        self.repo = repo
-        self.repoui = repo.ui
+        if repo:
+            # the ui here is really the repo ui so take its baseui so we don't
+            # end up with its local configuration
+            self.ui = repo.baseui
+            self.repo = repo
+            self.repoui = repo.ui
+        else:
+            self.ui = ui
+            self.repo = self.repoui = None
 
         if mode == 'pipe':
             self.cerr = channeledoutput(sys.stderr, sys.stdout, 'e')
@@ -183,12 +187,13 @@  class server(object):
         # copy the uis so changes (e.g. --config or --verbose) don't
         # persist between requests
         copiedui = self.ui.copy()
-        self.repo.baseui = copiedui
-        # clone ui without using ui.copy because this is protected
-        repoui = self.repoui.__class__(self.repoui)
-        repoui.copy = copiedui.copy # redo copy protection
-        self.repo.ui = self.repo.dirstate._ui = repoui
-        self.repo.invalidateall()
+        if self.repo:
+            self.repo.baseui = copiedui
+            # clone ui without using ui.copy because this is protected
+            repoui = self.repoui.__class__(self.repoui)
+            repoui.copy = copiedui.copy # redo copy protection
+            self.repo.ui = self.repo.dirstate._ui = repoui
+            self.repo.invalidateall()
 
         req = dispatch.request(args[:], copiedui, self.repo, self.cin,
                                self.cout, self.cerr)
diff --git a/tests/test-commandserver.py b/tests/test-commandserver.py
--- a/tests/test-commandserver.py
+++ b/tests/test-commandserver.py
@@ -294,6 +294,11 @@  def mqoutsidechanges(server):
     # repo.mq should be recreated to point to new queue
     runcommand(server, ['qqueue', '--active'])
 
+def startwithoutrepo(server):
+    readchannel(server)
+    runcommand(server, ['init', 'repo2'])
+    runcommand(server, ['id', '-R', 'repo2'])
+
 if __name__ == '__main__':
     os.system('hg init repo')
     os.chdir('repo')
@@ -329,3 +334,7 @@  if __name__ == '__main__':
     hgrc.write('[extensions]\nmq=\n')
     hgrc.close()
     check(mqoutsidechanges)
+
+    os.chdir('..')
+    check(hellomessage)
+    check(startwithoutrepo)
diff --git a/tests/test-commandserver.py.out b/tests/test-commandserver.py.out
--- a/tests/test-commandserver.py.out
+++ b/tests/test-commandserver.py.out
@@ -237,3 +237,16 @@  popping 0.diff
 patch queue now empty
  runcommand qqueue --active
 foo
+
+testing hellomessage:
+
+o, 'capabilities: getencoding runcommand\nencoding: ***'
+ runcommand id
+abort: there is no Mercurial repository here (.hg not found)
+ [255]
+
+testing startwithoutrepo:
+
+ runcommand init repo2
+ runcommand id -R repo2
+000000000000 tip