Ejemplo n.º 1
0
    def __parse_qdisc(device):
        qdisc_parser = TcQdiscParser()
        command = "tc qdisc show dev {:s}".format(device)
        qdisk_show_runner = SubprocessRunner(command)
        qdisk_show_runner.run()

        return qdisc_parser.parse(qdisk_show_runner.stdout)
Ejemplo n.º 2
0
    def test_config_file(self, tmpdir, device_option, overwrite, expected):

        p = tmpdir.join("tcconfig.json")
        config = "{" + '"{:s}"'.format(device_option) + ": {" + """
        "outgoing": {
            "network=192.168.0.10/32, port=8080": {
                "delay": "10.0",
                "loss": "0.01",
                "rate": "250K",
                "delay-distro": "2.0"
            },
            "network=0.0.0.0/0": {}
        },
        "incoming": {
            "network=192.168.10.0/24": {
                "corrupt": "0.02",
                "rate": "1500K"
            },
            "network=0.0.0.0/0": {}
        }
    }
}
"""
        p.write(config)

        SubprocessRunner("tcdel --device " + device_option).run()
        command = " ".join(["tcset -f ", str(p), overwrite])
        assert SubprocessRunner(command).run() == expected

        runner = SubprocessRunner("tcshow --device " + device_option)
        runner.run()
        assert json.loads(runner.stdout) == json.loads(config)

        SubprocessRunner("tcdel --device " + device_option).run()
Ejemplo n.º 3
0
    def __get_ifb_from_device(self):
        filter_parser = TcFilterParser()
        command = "tc filter show dev {:s} root".format(self.device)
        filter_runner = SubprocessRunner(command)
        filter_runner.run()

        return filter_parser.parse_incoming_device(filter_runner.stdout)
Ejemplo n.º 4
0
    def execute(cls, package_name):
        cache_file_path = cls.cache_mgr.get_pkg_cache_filepath(package_name, "pip_show")

        if cls.cache_mgr.is_cache_available(cache_file_path):
            logger.debug("load pip show cache from {}".format(cache_file_path))

            with cache_file_path.open() as f:
                return PipShow(f.read())

        proc_runner = SubprocessRunner(["pip", "show", package_name])

        try:
            proc_runner.run(check=True)
        except CalledProcessError as e:
            logger.error(
                "failed to fetch '{}' package info: require an installed PyPI package name".format(
                    package_name
                )
            )
            sys.exit(e.returncode)

        logger.debug("write pip show cache to {}".format(cache_file_path))

        pip_show = proc_runner.stdout
        with cache_file_path.open(mode="w") as f:
            f.write(pip_show)

        return PipShow(pip_show)
Ejemplo n.º 5
0
    def test_normal_single_icmp_timestamp(self):
        count = 1
        dest = "localhost"
        runner = SubprocessRunner([
            sys.executable,
            "-m",
            "pingparsing",
            dest,
            "-c",
            count,
            "--icmp-reply",
            "--timestamp",
            "epoch",
        ])
        runner.run()

        print_result(stdout=runner.stdout, stderr=runner.stderr)

        assert runner.returncode == 0

        parsed_result = json.loads(runner.stdout)

        assert parsed_result[dest]["packet_transmit"] == count
        assert parsed_result[dest]["rtt_max"] > 0

        icmp_replies = parsed_result[dest]["icmp_replies"]
        assert icmp_replies
        assert icmp_replies[0]["timestamp"]
Ejemplo n.º 6
0
    def test_normal_empty(self, device_value):
        if device_value is None:
            pytest.skip("device option is null")

        for tc_target in [device_value, "--device {}".format(device_value)]:
            delete_all_rules(tc_target)

            runner = SubprocessRunner(" ".join([Tc.Command.TCSHOW, tc_target]))
            expected = ("{" + '"{:s}"'.format(device_value) + ": {" + """
                        "outgoing": {
                        },
                        "incoming": {
                        }
                    }
                }""")

            print(runner.command_str)
            runner.run()

            print_test_result(expected=expected,
                              actual=runner.stdout,
                              error=runner.stderr)
            assert runner.returncode == 0
            assert json.loads(runner.stdout) == json.loads(expected)

            # smoe test for --color option
            runner = SubprocessRunner(" ".join(
                [Tc.Command.TCSHOW, tc_target, "--color"]))
            assert runner.run() == 0, runner.stderr
Ejemplo n.º 7
0
    def __get_ifb_from_device(self):
        filter_parser = TcFilterParser()
        command = "tc filter show dev {:s} root".format(self.device)
        filter_runner = SubprocessRunner(command)
        filter_runner.run()

        return filter_parser.parse_incoming_device(filter_runner.stdout)
Ejemplo n.º 8
0
    def __parse_qdisc(device):
        qdisc_parser = TcQdiscParser()
        command = "tc qdisc show dev {:s}".format(device)
        qdisk_show_runner = SubprocessRunner(command)
        qdisk_show_runner.run()

        return qdisc_parser.parse(qdisk_show_runner.stdout)
    def test_stderr(self, capsys, command, ignore_stderr_regexp, out_regexp,
                    expected):
        from loguru import logger

        import subprocrunner

        logger.remove()
        logger.add(sys.stderr, level="DEBUG")
        logger.enable("test")
        subprocrunner.set_logger(True)

        runner = SubprocessRunner(command,
                                  ignore_stderr_regexp=ignore_stderr_regexp)
        runner.run()

        assert is_null_string(runner.stdout.strip())
        assert is_not_null_string(runner.stderr.strip())
        assert runner.returncode != 0

        out, err = capsys.readouterr()
        print("[sys stdout]\n{}\n".format(out))
        print("[sys stderr]\n{}\n".format(err))
        print("[proc stdout]\n{}\n".format(runner.stdout))
        print("[proc stderr]\n{}\n".format(runner.stderr))

        actual = out_regexp.search(err) is not None
        assert actual == expected
Ejemplo n.º 10
0
    def __get_ifb_from_device(self):
        filter_runner = SubprocessRunner("tc filter show dev {:s} root".format(
            self.device),
                                         dry_run=False)
        filter_runner.run()

        return TcFilterParser(self.__ip_version).parse_incoming_device(
            filter_runner.stdout)
Ejemplo n.º 11
0
    def test_normal(self, tmpdir):
        runner = SubprocessRunner(["pingparsing"])
        runner.run(input=DEBIAN_SUCCESS_0.value)

        print_result(stdout=runner.stdout, stderr=runner.stderr)

        assert runner.returncode == 0
        assert json.loads(runner.stdout) == DEBIAN_SUCCESS_0.expected
Ejemplo n.º 12
0
    def test_normal(self, device_option):
        if device_option is None:
            pytest.skip("device option is null")

        SubprocessRunner("tcdel --device " + device_option).run()

        command = " ".join([
            "tcset",
            "--device", device_option,
            "--delay", "10",
            "--delay-distro", "2",
            "--loss", "0.01",
            "--rate", "0.25M",
            "--network", "192.168.0.10",
            "--port", "8080",
        ])
        assert SubprocessRunner(command).run() == 0

        command = " ".join([
            "tcset",
            "--device", device_option,
            "--delay", "1",
            "--loss", "0.02",
            "--rate", "500K",
            "--direction", "incoming",
        ])
        assert SubprocessRunner(command).run() == 0

        command = " ".join([
            "tcshow",
            "--device", device_option,
        ])
        runner = SubprocessRunner(command)
        runner.run()

        expected = "{" + '"{:s}"'.format(device_option) + ": {" + """
        "outgoing": {
            "network=192.168.0.10/32, port=8080": {
                "delay": "10.0",
                "loss": "0.01",
                "rate": "250K",
                "delay-distro": "2.0"
            },
            "network=0.0.0.0/0": {}
        },
        "incoming": {
            "network=0.0.0.0/0": {
                "delay": "1.0",
                "loss": "0.02",
                "rate": "500K"
            }
        }
    }
}"""

        assert json.loads(runner.stdout) == json.loads(expected)

        SubprocessRunner("tcdel --device " + device_option).run()
Ejemplo n.º 13
0
    def test_normal_single(self, tmpdir):
        runner = SubprocessRunner("pingparsing")
        runner.run(input=DEBIAN_SUCCESS_0.value)

        print("[stdout]\n{}".format(runner.stdout))
        print("[stderr]\n{}".format(runner.stderr))

        assert runner.returncode == 0
        assert json.loads(runner.stdout) == DEBIAN_SUCCESS_0.expected
    def test_stdout(self, command, expected):
        runner = SubprocessRunner(command)
        runner.run()

        assert runner.command == command
        assert isinstance(runner.command_str, str)
        assert runner.returncode == 0
        assert runner.stdout.strip() == expected
        assert is_null_string(runner.stderr)
    def test_stderr_check(self, command, ignore_stderr_regexp, expected):
        runner = SubprocessRunner(command,
                                  ignore_stderr_regexp=ignore_stderr_regexp)

        if ignore_stderr_regexp:
            runner.run(check=True)
        else:
            with pytest.raises(expected):
                runner.run(check=True)
Ejemplo n.º 16
0
def runner_helper(command):
    proc_runner = SubprocessRunner(command)
    proc_runner.run()

    print("{}\n{}\n".format(proc_runner.command_str, proc_runner.stderr),
          file=sys.stderr)

    assert proc_runner.returncode == 0

    return proc_runner
    def test_unicode(self, monkeypatch):
        def monkey_communicate(input=None):
            return ("", "'dummy' は、内部コマンドまたは外部コマンド、"
                    "操作可能なプログラムまたはバッチ ファイルとして認識されていません")

        monkeypatch.setattr(subprocess.Popen, "communicate",
                            monkey_communicate)

        runner = SubprocessRunner(list_command)
        runner.run()
Ejemplo n.º 18
0
    def test_smoke(self, format):
        runner = SubprocessRunner(
            [sys.executable, "-m", "envinfopy", "--format", format, "pathvalidate", "envinfopy"]
        )
        runner.run()

        print(runner.stdout)

        assert runner.returncode == 0
        assert RE_VERSION.search(runner.stdout)
        assert re.search("envinfopy", runner.stdout, re.MULTILINE)
Ejemplo n.º 19
0
    def test_config_file_smoke(self, tmpdir, device_value, overwrite):
        if device_value is None:
            pytest.skip("device option is null")

        p = tmpdir.join("tcconfig.json")
        config = ("{" + '"{:s}"'.format(device_value) + ": {" + """
        "outgoing": {
            "dst-network=192.168.0.10/32, dst-port=8080, protocol=ip": {
                "filter_id": "800::800",
                "delay": "10.0ms",
                "loss": "0.01%",
                "rate": "250Kbps",
                "delay-distro": "2.0ms"
            },
            "src-port=1234, protocol=ip": {
                "filter_id": "800::801",
                "delay": "50.0ms",
                "rate": "1Gbps"
            }
        },
        "incoming": {
            "dst-network=192.168.10.0/24, protocol=ip": {
                "filter_id": "800::800",
                "corrupt": "0.02%",
                "rate": "1500Kbps"
            }
        }
    }
}
""")
        print("[config]\n{}\n".format(config))
        p.write(config)

        for device_option in [
                device_value, "--device {}".format(device_value)
        ]:
            execute_tcdel(device_value)
            command = " ".join(
                [Tc.Command.TCSET,
                 str(p), "--import-setting", overwrite])
            SubprocessRunner(command).run()

            runner = SubprocessRunner("{:s} {:s}".format(
                Tc.Command.TCSHOW, device_option))
            runner.run()

            print_test_result(expected=config,
                              actual=runner.stdout,
                              error=runner.stderr)

            assert json.loads(runner.stdout) == json.loads(config)

            execute_tcdel(device_value)
    def test_normal(self, monkeypatch, command, dry_run, expected):
        r = SubprocessRunner(command, dry_run=dry_run)
        r.run()

        if not dry_run:
            print(r.stderr, file=sys.stderr)

        assert r.returncode in expected

        monkeypatch.setattr("subprocrunner._logger._logger.logger",
                            NullLogger())
        r.run()
Ejemplo n.º 21
0
def update_help():
    for command in ["tcset", "tcdel", "tcshow"]:
        runner = SubprocessRunner("{:s} -h".format(command))
        runner.run(env=dict(os.environ, LC_ALL="C.UTF-8"))
        help_file_path = "pages/usage/{command:s}/{command:s}_help_output.txt".format(
            command=command)

        print(help_file_path)

        with open(help_file_path, "w") as f:
            f.write("::\n\n")
            f.write(indent(runner.stdout, "    "))
Ejemplo n.º 22
0
def main():
    proc = SubprocessRunner(["pingparsing", "-h"])
    proc.run(env=dict(os.environ, LC_ALL="C.UTF-8"))
    help_file_path = "pages/usage/cli_help.txt"

    print(help_file_path)

    with open(help_file_path, "w") as f:
        f.write("CLI help\n")
        f.write("--------------------------------------------\n")
        f.write("::\n\n")
        f.write(indent(proc.stdout, "    "))
Ejemplo n.º 23
0
    def test_config_file_smoke(self, tmpdir, device_value, overwrite):
        if device_value is None:
            pytest.skip("device option is null")

        p = tmpdir.join("tcconfig.json")
        config = "{" + '"{:s}"'.format(device_value) + ": {" + """
        "outgoing": {
            "dst-network=192.168.0.10/32, dst-port=8080, protocol=ip": {
                "filter_id": "800::800",
                "delay": "10.0ms",
                "loss": 0.01,
                "rate": "250K",
                "delay-distro": "2.0ms"
            },
            "src-port=1234, protocol=ip": {
                "filter_id": "800::801",
                "delay": "50.0ms",
                "rate": "1G"
            }
        },
        "incoming": {
            "dst-network=192.168.10.0/24, protocol=ip": {
                "filter_id": "800::800",
                "corrupt": 0.02,
                "rate": "1500K"
            }
        }
    }
}
"""
        print("[config]\n{}\n".format(config))
        p.write(config)

        device_option = "--device {:s}".format(device_value)

        execute_tcdel(device_value)
        command = " ".join(
            ["{:s} -f ".format(Tc.Command.TCSET),
             str(p), overwrite])
        SubprocessRunner(command).run()

        runner = SubprocessRunner("{:s} {:s}".format(Tc.Command.TCSHOW,
                                                     device_option))
        runner.run()

        print("[expected]\n{}\n".format(config))
        print("[actual]\n{}\n".format(runner.stdout))
        print("[stderr]\n{}".format(runner.stderr))

        assert json.loads(runner.stdout) == json.loads(config)

        execute_tcdel(device_value)
Ejemplo n.º 24
0
    def test_normal_single(self, tmpdir):
        tmp_ping_file = tmpdir.join("ping_deb.txt")
        tmp_ping_file.write(DEBIAN_SUCCESS_0.value)
        tmp_ping_path = str(tmp_ping_file)

        runner = SubprocessRunner(["pingparsing", tmp_ping_path])
        runner.run()

        print_result(stdout=runner.stdout, stderr=runner.stderr)

        assert runner.returncode == 0
        assert json.loads(
            runner.stdout)[tmp_ping_path] == DEBIAN_SUCCESS_0.expected
Ejemplo n.º 25
0
    def test_normal_single(self, tmpdir):
        tmp_ping_file = tmpdir.join("ping_deb.txt")
        tmp_ping_file.write(DEBIAN_SUCCESS_0.value)
        tmp_ping_path = str(tmp_ping_file)

        runner = SubprocessRunner("pingparsing {}".format(tmp_ping_path))
        runner.run()

        print("[stdout]\n{}".format(runner.stdout))
        print("[stderr]\n{}".format(runner.stderr))

        assert runner.returncode == 0
        assert json.loads(
            runner.stdout)[tmp_ping_path] == DEBIAN_SUCCESS_0.expected
Ejemplo n.º 26
0
    def test_normal_multi(self):
        count = 1
        dest_list = ["google.com", "twitter.com"]
        runner = SubprocessRunner(["pingparsing"] + dest_list + ["-c", count])
        runner.run()

        print_result(stdout=runner.stdout, stderr=runner.stderr)

        assert runner.returncode == 0

        parsed_result = json.loads(runner.stdout)
        for dest in dest_list:
            assert parsed_result[dest]["packet_transmit"] == count
            assert parsed_result[dest]["rtt_max"] > 0
Ejemplo n.º 27
0
    def test_normal_single(self):
        count = 1
        dest = "localhost"
        runner = SubprocessRunner(["pingparsing", dest, "-c", count])
        runner.run()

        print_result(stdout=runner.stdout, stderr=runner.stderr)

        assert runner.returncode == 0

        parsed_result = json.loads(runner.stdout)

        assert parsed_result[dest]["packet_transmit"] == count
        assert parsed_result[dest]["rtt_max"] > 0
Ejemplo n.º 28
0
    def test_normal_w_option(self, tmpdir):
        expected = dedent("""\
            {
                "destination": "google.com",
                "packet_transmit": 3,
                "packet_receive": 3,
                "packet_loss_count": 0,
                "packet_loss_rate": 0.0,
                "rtt_min": 48.832,
                "rtt_avg": 54.309,
                "rtt_max": 64.334,
                "rtt_mdev": 7.098,
                "packet_duplicate_count": 0,
                "packet_duplicate_rate": 0.0,
                "icmp_replies": [
                    {
                        "timestamp": null,
                        "icmp_seq": 1,
                        "ttl": 50,
                        "time": 64.3,
                        "duplicate": false
                    },
                    {
                        "timestamp": null,
                        "icmp_seq": 2,
                        "ttl": 50,
                        "time": 49.7,
                        "duplicate": false
                    },
                    {
                        "timestamp": null,
                        "icmp_seq": 3,
                        "ttl": 50,
                        "time": 48.8,
                        "duplicate": false
                    }
                ]
            }
            """)
        runner = SubprocessRunner(["pingparsing", "-", "--icmp-reply"])
        runner.run(input=UBUNTU_SUCCESS_2.value)

        print_result(stdout=runner.stdout,
                     stderr=runner.stderr,
                     expected=expected)

        assert runner.returncode == 0
        assert json.loads(runner.stdout) == json.loads(expected)
Ejemplo n.º 29
0
    def test_normal_empty(self, device_value, colorize_option):
        if device_value is None:
            pytest.skip("device option is null")

        for tc_target in [device_value, "--device {}".format(device_value)]:
            execute_tcdel(tc_target)

            runner = SubprocessRunner(" ".join([Tc.Command.TCSHOW, tc_target, colorize_option]))

            expected = (
                "{"
                + '"{:s}"'.format(device_value)
                + ": {"
                + """
                        "outgoing": {
                        },
                        "incoming": {
                        }
                    }
                }"""
            )
            print_test_result(expected=expected, actual=runner.stdout, error=runner.stderr)

            assert runner.run() == 0
            assert json.loads(runner.stdout) == json.loads(expected)
Ejemplo n.º 30
0
    def test_normal_single(self):
        count = 1
        dest = "localhost"
        runner = SubprocessRunner("pingparsing {:s} -c {:d}".format(
            dest, count))
        runner.run()

        print("[stdout]\n{}".format(runner.stdout))
        print("[stderr]\n{}".format(runner.stderr))

        assert runner.returncode == 0

        parsed_result = json.loads(runner.stdout)

        assert parsed_result[dest]["packet_transmit"] == count
        assert parsed_result[dest]["rtt_max"] > 0
Ejemplo n.º 31
0
    def test_normal_multi(self):
        count = 1
        dest_list = ["google.com", "twitter.com"]
        runner = SubprocessRunner("pingparsing {:s} -c {:d}".format(
            " ".join(dest_list), count))
        runner.run()

        print("[stdout]\n{}".format(runner.stdout))
        print("[stderr]\n{}".format(runner.stderr))

        assert runner.returncode == 0

        parsed_result = json.loads(runner.stdout)
        for dest in dest_list:
            assert parsed_result[dest]["packet_transmit"] == count
            assert parsed_result[dest]["rtt_max"] > 0
Ejemplo n.º 32
0
    async def execute_cmds(self,
                           cmds: List[str],
                           dir: str,
                           show_output: bool = False) -> None:
        if len(cmds) > 0:
            if self.check_exec():
                os.chdir(dir)

                for cmd in cmds:
                    execute_tf = SubprocessRunner(cmd)
                    exec = execute_tf.run()
                    execute_tf.command

                    if exec == 0:
                        out = execute_tf.stdout
                        self.save_output(out, self.output_dir,
                                         self.output_file)
                    else:
                        out = execute_tf.stderr
                        self.save_output(out, self.output_dir,
                                         self.output_file)
                        raise TerraformExceptions(
                            self.utils.message(dir, err=True, result=out))
                if show_output:
                    self.utils.message(dir, result=out)
        else:
            raise TerraformExceptions("There are no any commands in the list")
        return
Ejemplo n.º 33
0
    def clear(cls):
        if not cls.enable:
            return

        for mangle in cls.parse():
            proc = SubprocessRunner(mangle.to_delete_command())
            if proc.run() != 0:
                raise RuntimeError(str(proc.stderr))
Ejemplo n.º 34
0
    def clear(cls):
        if not cls.enable:
            return

        for mangle in cls.parse():
            proc = SubprocessRunner(mangle.to_delete_command())
            if proc.run() != 0:
                raise RuntimeError(str(proc.stderr))
Ejemplo n.º 35
0
    def test_config_file_smoke(self, tmpdir, device_value, overwrite):
        if device_value is None:
            pytest.skip("device option is null")

        p = tmpdir.join("tcconfig.json")
        config = "{" + '"{:s}"'.format(device_value) + ": {" + """
        "outgoing": {
            "network=192.168.0.10/32, dst-port=8080, protocol=ip": {
                "delay": "10.0",
                "loss": "0.01",
                "rate": "250K",
                "delay-distro": "2.0"
            },
            "network=0.0.0.0/0, src-port=1234, protocol=ip": {
                "delay": "50.0",
                "rate": "1G"
            }
        },
        "incoming": {
            "network=192.168.10.0/24, protocol=ip": {
                "corrupt": "0.02",
                "rate": "1500K"
            }
        }
    }
}
"""
        p.write(config)

        device_option = "--device {:s}".format(device_value)

        SubprocessRunner("tcdel {:s}".format(device_option)).run()
        command = " ".join(["tcset -f ", str(p), overwrite])
        SubprocessRunner(command).run()

        runner = SubprocessRunner("tcshow {:s}".format(device_option))
        runner.run()

        print("[expected]\n{}\n".format(config))
        print("[actual]\n{}\n".format(runner.stdout))
        print("[stderr]\n{}".format(runner.stderr))

        assert json.loads(runner.stdout) == json.loads(config)

        SubprocessRunner("tcdel {:s}".format(device_option)).run()
Ejemplo n.º 36
0
    def __get_filter(self, device):
        if dataproperty.is_empty_string(device):
            return {}

        # parse filter ---
        filter_parser = TcFilterParser()
        command = "tc filter show dev {:s}".format(device)
        filter_show_runner = SubprocessRunner(command)
        filter_show_runner.run()

        filter_table = {}
        for filter_param in filter_parser.parse_filter(filter_show_runner.stdout):
            filter_key = self.__get_filter_key(filter_param)
            filter_table[filter_key] = {}
            if self.__qdisc_param.get("parent") in (filter_param.get("flowid"), filter_param.get("classid")):
                work_qdisc_param = dict(self.__qdisc_param)
                del work_qdisc_param["parent"]
                filter_table[filter_key] = work_qdisc_param

        return filter_table
Ejemplo n.º 37
0
    def __run(command, regexp, message):
        proc = SubprocessRunner(command, regexp)
        if proc.run() == 0:
            return 0

        match = regexp.search(proc.stderr)
        if match is None:
            return proc.returncode

        logger.notice(message)

        return proc.returncode
Ejemplo n.º 38
0
#!/usr/bin/env python
# encoding: utf-8

from __future__ import print_function, unicode_literals

import os
from textwrap import indent

from subprocrunner import SubprocessRunner


proc = SubprocessRunner(["pingparsing", "-h"])
proc.run(env=dict(os.environ, LC_ALL="C.UTF-8"))
help_file_path = "pages/usage/cli_help.txt"

print(help_file_path)

with open(help_file_path, "w") as f:
    f.write("CLI help\n")
    f.write("--------------------------------------------\n")
    f.write("::\n\n")
    f.write(indent(proc.stdout, "    "))
Ejemplo n.º 39
0
    def get_iptables(cls):
        proc = SubprocessRunner("iptables -t mangle --line-numbers -L")
        if proc.run() != 0:
            raise RuntimeError(str(proc.stderr))

        return proc.stdout
Ejemplo n.º 40
0
"""
.. codeauthor:: Tsuyoshi Hombashi <*****@*****.**>
"""

from __future__ import print_function, unicode_literals

import os
from textwrap import dedent, indent

from subprocrunner import SubprocessRunner


env = dict(os.environ, LC_ALL="C.UTF-8")

proc = SubprocessRunner("sqlitebiter -h")
proc.run(env=env)
help_file_path = "pages/usage/help.txt"
print(help_file_path)

with open(help_file_path, "w") as f:
    f.write(
        dedent(
            """\
        ::

        """
        )
    )

    f.write(indent(proc.stdout, "    "))