prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Scripts: "done" hook is not executed.
  ##### Steps to reproduce the problem:
  1. `touch foo`
  2. `mitmdump -r foo -s examples\stub.py`
  ##### What is the expected behavior?
  
  ```
  start
  configure
  done
  ```
  ##### What went wrong?
  
  ```
  start
  configure
  ```
  ##### Any other comments? What have you tried so far?
  
  Somewhat related: Rename it to `stop` ?
  
  ---
  
  Mitmproxy Version: master
  Operating System: Win10 x64
  
  
  </issue>
  <code>
  [start of mitmproxy/dump.py]
  1 from __future__ import absolute_import, print_function, division
  2 
  3 import sys
  4 
  5 from typing import Optional  # noqa
  6 import typing  # noqa
  7 
  8 import click
  9 
  10 from mitmproxy import controller
  11 from mitmproxy import exceptions
  12 from mitmproxy import flow
  13 from mitmproxy import builtins
  14 from mitmproxy import utils
  15 from mitmproxy import options
  16 from mitmproxy.builtins import dumper
  17 from netlib import tcp
  18 
  19 
  20 class DumpError(Exception):
  21     pass
  22 
  23 
  24 class Options(options.Options):
  25     def __init__(
  26             self,
  27             keepserving=False,  # type: bool
  28             filtstr=None,  # type: Optional[str]
  29             flow_detail=1,  # type: int
  30             tfile=None,  # type: Optional[typing.io.TextIO]
  31             **kwargs
  32     ):
  33         self.filtstr = filtstr
  34         self.flow_detail = flow_detail
  35         self.keepserving = keepserving
  36         self.tfile = tfile
  37         super(Options, self).__init__(**kwargs)
  38 
  39 
  40 class DumpMaster(flow.FlowMaster):
  41 
  42     def __init__(self, server, options):
  43         flow.FlowMaster.__init__(self, options, server, flow.State())
  44         self.has_errored = False
  45         self.addons.add(options, *builtins.default_addons())
  46         self.addons.add(options, dumper.Dumper())
  47         # This line is just for type hinting
  48         self.options = self.options  # type: Options
  49         self.replay_ignore_params = options.replay_ignore_params
  50         self.replay_ignore_content = options.replay_ignore_content
  51         self.replay_ignore_host = options.replay_ignore_host
  52         self.refresh_server_playback = options.refresh_server_playback
  53         self.replay_ignore_payload_params = options.replay_ignore_payload_params
  54 
  55         self.set_stream_large_bodies(options.stream_large_bodies)
  56 
  57         if self.server and self.options.http2 and not tcp.HAS_ALPN:  # pragma: no cover
  58             print("ALPN support missing (OpenSSL 1.0.2+ required)!\n"
  59                   "HTTP/2 is disabled. Use --no-http2 to silence this warning.",
  60                   file=sys.stderr)
  61 
  62         if options.server_replay:
  63             self.start_server_playback(
  64                 self._readflow(options.server_replay),
  65                 options.kill, options.rheaders,
  66                 not options.keepserving,
  67                 options.nopop,
  68                 options.replay_ignore_params,
  69                 options.replay_ignore_content,
  70                 options.replay_ignore_payload_params,
  71                 options.replay_ignore_host
  72             )
  73 
  74         if options.client_replay:
  75             self.start_client_playback(
  76                 self._readflow(options.client_replay),
  77                 not options.keepserving
  78             )
  79 
  80         if options.rfile:
  81             try:
  82                 self.load_flows_file(options.rfile)
  83             except exceptions.FlowReadException as v:
  84                 self.add_log("Flow file corrupted.", "error")
  85                 raise DumpError(v)
  86 
  87         if self.options.app:
  88             self.start_app(self.options.app_host, self.options.app_port)
  89 
  90     def _readflow(self, paths):
  91         """
  92         Utitility function that reads a list of flows
  93         or raises a DumpError if that fails.
  94         """
  95         try:
  96             return flow.read_flows_from_paths(paths)
  97         except exceptions.FlowReadException as e:
  98             raise DumpError(str(e))
  99 
  100     def add_log(self, e, level="info"):
  101         if level == "error":
  102             self.has_errored = True
  103         if self.options.verbosity >= utils.log_tier(level):
  104             click.secho(
  105                 e,
  106                 file=self.options.tfile,
  107                 fg="red" if level == "error" else None,
  108                 dim=(level == "debug"),
  109                 err=(level == "error")
  110             )
  111 
  112     @controller.handler
  113     def request(self, f):
  114         f = super(DumpMaster, self).request(f)
  115         if f:
  116             self.state.delete_flow(f)
  117         return f
  118 
  119     def run(self):  # pragma: no cover
  120         if self.options.rfile and not self.options.keepserving:
  121             return
  122         super(DumpMaster, self).run()
  123
  [end of mitmproxy/dump.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/mitmproxy/dump.py b/mitmproxy/dump.py
  --- a/mitmproxy/dump.py
  +++ b/mitmproxy/dump.py
  @@ -118,5 +118,6 @@
   
       def run(self):  # pragma: no cover
           if self.options.rfile and not self.options.keepserving:
  +            self.addons.done()
               return
           super(DumpMaster, self).run()
  
verification_info: {"golden_diff": "diff --git a/mitmproxy/dump.py b/mitmproxy/dump.py\n--- a/mitmproxy/dump.py\n+++ b/mitmproxy/dump.py\n@@ -118,5 +118,6 @@\n \n     def run(self):  # pragma: no cover\n         if self.options.rfile and not self.options.keepserving:\n+            self.addons.done()\n             return\n         super(DumpMaster, self).run()\n", "issue": "Scripts: \"done\" hook is not executed.\n##### Steps to reproduce the problem:\n1. `touch foo`\n2. `mitmdump -r foo -s examples\\stub.py`\n##### What is the expected behavior?\n\n```\nstart\nconfigure\ndone\n```\n##### What went wrong?\n\n```\nstart\nconfigure\n```\n##### Any other comments? What have you tried so far?\n\nSomewhat related: Rename it to `stop` ?\n\n---\n\nMitmproxy Version: master\nOperating System: Win10 x64\n\n", "before_files": [{"content": "from __future__ import absolute_import, print_function, division\n\nimport sys\n\nfrom typing import Optional  # noqa\nimport typing  # noqa\n\nimport click\n\nfrom mitmproxy import controller\nfrom mitmproxy import exceptions\nfrom mitmproxy import flow\nfrom mitmproxy import builtins\nfrom mitmproxy import utils\nfrom mitmproxy import options\nfrom mitmproxy.builtins import dumper\nfrom netlib import tcp\n\n\nclass DumpError(Exception):\n    pass\n\n\nclass Options(options.Options):\n    def __init__(\n            self,\n            keepserving=False,  # type: bool\n            filtstr=None,  # type: Optional[str]\n            flow_detail=1,  # type: int\n            tfile=None,  # type: Optional[typing.io.TextIO]\n            **kwargs\n    ):\n        self.filtstr = filtstr\n        self.flow_detail = flow_detail\n        self.keepserving = keepserving\n        self.tfile = tfile\n        super(Options, self).__init__(**kwargs)\n\n\nclass DumpMaster(flow.FlowMaster):\n\n    def __init__(self, server, options):\n        flow.FlowMaster.__init__(self, options, server, flow.State())\n        self.has_errored = False\n        self.addons.add(options, *builtins.default_addons())\n        self.addons.add(options, dumper.Dumper())\n        # This line is just for type hinting\n        self.options = self.options  # type: Options\n        self.replay_ignore_params = options.replay_ignore_params\n        self.replay_ignore_content = options.replay_ignore_content\n        self.replay_ignore_host = options.replay_ignore_host\n        self.refresh_server_playback = options.refresh_server_playback\n        self.replay_ignore_payload_params = options.replay_ignore_payload_params\n\n        self.set_stream_large_bodies(options.stream_large_bodies)\n\n        if self.server and self.options.http2 and not tcp.HAS_ALPN:  # pragma: no cover\n            print(\"ALPN support missing (OpenSSL 1.0.2+ required)!\\n\"\n                  \"HTTP/2 is disabled. Use --no-http2 to silence this warning.\",\n                  file=sys.stderr)\n\n        if options.server_replay:\n            self.start_server_playback(\n                self._readflow(options.server_replay),\n                options.kill, options.rheaders,\n                not options.keepserving,\n                options.nopop,\n                options.replay_ignore_params,\n                options.replay_ignore_content,\n                options.replay_ignore_payload_params,\n                options.replay_ignore_host\n            )\n\n        if options.client_replay:\n            self.start_client_playback(\n                self._readflow(options.client_replay),\n                not options.keepserving\n            )\n\n        if options.rfile:\n            try:\n                self.load_flows_file(options.rfile)\n            except exceptions.FlowReadException as v:\n                self.add_log(\"Flow file corrupted.\", \"error\")\n                raise DumpError(v)\n\n        if self.options.app:\n            self.start_app(self.options.app_host, self.options.app_port)\n\n    def _readflow(self, paths):\n        \"\"\"\n        Utitility function that reads a list of flows\n        or raises a DumpError if that fails.\n        \"\"\"\n        try:\n            return flow.read_flows_from_paths(paths)\n        except exceptions.FlowReadException as e:\n            raise DumpError(str(e))\n\n    def add_log(self, e, level=\"info\"):\n        if level == \"error\":\n            self.has_errored = True\n        if self.options.verbosity >= utils.log_tier(level):\n            click.secho(\n                e,\n                file=self.options.tfile,\n                fg=\"red\" if level == \"error\" else None,\n                dim=(level == \"debug\"),\n                err=(level == \"error\")\n            )\n\n    @controller.handler\n    def request(self, f):\n        f = super(DumpMaster, self).request(f)\n        if f:\n            self.state.delete_flow(f)\n        return f\n\n    def run(self):  # pragma: no cover\n        if self.options.rfile and not self.options.keepserving:\n            return\n        super(DumpMaster, self).run()\n", "path": "mitmproxy/dump.py"}]}