We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN 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


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mitmproxy/dump.py`
Content:
```
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 FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

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()

{"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"}], "after_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            self.addons.done()\n            return\n        super(DumpMaster, self).run()\n", "path": "mitmproxy/dump.py"}]}