Patchwork [1,of,4,V2] debug: add a 'debugdownload' command

login
register
mail settings
Submitter Boris Feld
Date Jan. 8, 2018, 11 a.m.
Message ID <cfcfc7938b0411f91f86.1515409218@FB>
Download mbox | patch
Permalink /patch/26608/
State Superseded
Headers show

Comments

Boris Feld - Jan. 8, 2018, 11 a.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1513326616 -3600
#      Fri Dec 15 09:30:16 2017 +0100
# Node ID cfcfc7938b0411f91f8626500cafaad0d522e1ee
# Parent  f04d16bef2c71986f256a7bf2c97163d726d4909
# EXP-Topic largefile-url
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r cfcfc7938b04
debug: add a 'debugdownload' command

This command resolve and fetch and URL through the Mercurial logic. Mercurial
logic add various headers (including authentication) while resolving an URL so
the commands helps with building the same request Mercurial would be doing.

A new test file is created because we'll add more logic regarding Mercurial
download logic and it will grow to a reasonable size.
Yuya Nishihara - Jan. 8, 2018, 1:34 p.m.
On Mon, 08 Jan 2018 12:00:18 +0100, Boris Feld wrote:
> # HG changeset patch
> # User Boris Feld <boris.feld@octobus.net>
> # Date 1513326616 -3600
> #      Fri Dec 15 09:30:16 2017 +0100
> # Node ID cfcfc7938b0411f91f8626500cafaad0d522e1ee
> # Parent  f04d16bef2c71986f256a7bf2c97163d726d4909
> # EXP-Topic largefile-url
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r cfcfc7938b04
> debug: add a 'debugdownload' command
> 
> This command resolve and fetch and URL through the Mercurial logic. Mercurial
> logic add various headers (including authentication) while resolving an URL so
> the commands helps with building the same request Mercurial would be doing.
> 
> A new test file is created because we'll add more logic regarding Mercurial
> download logic and it will grow to a reasonable size.
> 
> diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
> --- a/mercurial/debugcommands.py
> +++ b/mercurial/debugcommands.py
> @@ -69,6 +69,7 @@ from . import (
>      templater,
>      treediscovery,
>      upgrade,
> +    url as urlmod,
>      util,
>      vfs as vfsmod,
>  )
> @@ -786,6 +787,28 @@ def debugdiscovery(ui, repo, remoteurl="
>      localrevs = opts['rev']
>      doit(localrevs, remoterevs)
>  
> +

Please run test-check-commit.t.

> +_chunksize = 4 << 10
> +
> +@command('debugdownload',
> +    [
> +        ('o', 'output', '', _('URL')),

Nit: s/URL/output file/ ?

> +def debugdownload(ui, url, output=None, **opts):
> +    """Download a resource using Mercurial logic and config
> +    """
> +    fh = urlmod.open(ui, url, output)
> +
> +    dest = ui
> +    if output:
> +        dest = open(output, "wb", _chunksize)
> +
> +    data = fh.read(_chunksize)
> +    while data:
> +        dest.write(data)
> +        data = fh.read(_chunksize)

Need to close dest if it isn't ui. Perhaps we can extract a subset of
cmdutil.makefileobj() which requires a repo object. (We could make a repo
argument optional, but that would conflict with my patches to port it to
templater. :)

Patch

diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -69,6 +69,7 @@  from . import (
     templater,
     treediscovery,
     upgrade,
+    url as urlmod,
     util,
     vfs as vfsmod,
 )
@@ -786,6 +787,28 @@  def debugdiscovery(ui, repo, remoteurl="
     localrevs = opts['rev']
     doit(localrevs, remoterevs)
 
+
+_chunksize = 4 << 10
+
+@command('debugdownload',
+    [
+        ('o', 'output', '', _('URL')),
+    ],
+    norepo=True)
+def debugdownload(ui, url, output=None, **opts):
+    """Download a resource using Mercurial logic and config
+    """
+    fh = urlmod.open(ui, url, output)
+
+    dest = ui
+    if output:
+        dest = open(output, "wb", _chunksize)
+
+    data = fh.read(_chunksize)
+    while data:
+        dest.write(data)
+        data = fh.read(_chunksize)
+
 @command('debugextensions', cmdutil.formatteropts, [], norepo=True)
 def debugextensions(ui, **opts):
     '''show information about active extensions'''
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -85,6 +85,7 @@  Show debug commands if there are no othe
   debugdeltachain
   debugdirstate
   debugdiscovery
+  debugdownload
   debugextensions
   debugfileset
   debugformat
@@ -263,6 +264,7 @@  Show all commands + options
   debugdeltachain: changelog, manifest, dir, template
   debugdirstate: nodates, datesort
   debugdiscovery: old, nonheads, rev, ssh, remotecmd, insecure
+  debugdownload: output
   debugextensions: template
   debugfileset: rev
   debugformat: template
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -919,6 +919,8 @@  Test list of internal help commands
                  show the contents of the current dirstate
    debugdiscovery
                  runs the changeset discovery protocol in isolation
+   debugdownload
+                 Download a resource using Mercurial logic and config
    debugextensions
                  show information about active extensions
    debugfileset  parse and apply a fileset specification
diff --git a/tests/test-url-download.t b/tests/test-url-download.t
new file mode 100644
--- /dev/null
+++ b/tests/test-url-download.t
@@ -0,0 +1,36 @@ 
+#require serve
+
+  $ hg init server
+  $ hg serve -R server -p $HGPORT -d --pid-file=hg1.pid -E ../error.log
+  $ cat hg1.pid >> $DAEMON_PIDS
+
+Check basic fetching
+
+  $ hg debugdownload "http://localhost:$HGPORT/?cmd=lookup&key=tip"
+  1 0000000000000000000000000000000000000000
+  $ hg debugdownload  -o null.txt "http://localhost:$HGPORT/?cmd=lookup&key=null"
+  $ cat null.txt
+  1 0000000000000000000000000000000000000000
+
+Check the request is made from the usual Mercurial logic
+(rev details, give different content if the request has a Mercurial user agent)
+
+  $ get-with-headers.py --headeronly "localhost:$HGPORT" "rev/tip" content-type
+  200 Script output follows
+  content-type: text/html; charset=ascii
+  $ hg debugdownload "http://localhost:$HGPORT/rev/tip"
+  
+  # HG changeset patch
+  # User 
+  # Date 0 0
+  # Node ID 0000000000000000000000000000000000000000
+  
+  
+  
+  
+
+Check other kind of compatible url
+
+  $ hg debugdownload ./null.txt
+  1 0000000000000000000000000000000000000000
+