Skip to content

WIP: add type hints #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified LICENSE
100755 → 100644
Empty file.
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

dependencies:
pip install -r requirements.txt

dependencies-dev:
pip install -r requirements-dev.txt

mypy:
python -m mypy --strict --exclude build .

test:
python -m pytest .

.PHONY: dependencies dependencies-dev mypy test
Empty file modified README.md
100755 → 100644
Empty file.
Empty file modified challtools/__init__.py
100755 → 100644
Empty file.
Empty file modified challtools/challenge.schema.json
100755 → 100644
Empty file.
83 changes: 46 additions & 37 deletions challtools/cli.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,43 +1,51 @@
# PYTHON_ARGCOMPLETE_OK
import sys
import time
import argparse
import os
import uuid
import hashlib
import json
import os
import pkg_resources
import shutil
import sys
import time
import urllib.parse
import json
import uuid
from pathlib import Path
import pkg_resources
from typing import List, Optional, Callable, Dict, Any

import argcomplete
import docker
import requests
import yaml
import docker
import argcomplete
from .validator import ConfigValidator, is_url

from .constants import *
from .utils import (
_copytree,
build_chall,
build_docker_images,
create_docker_name,
CriticalException,
process_messages,
load_ctf_config,
load_config,
get_ctf_config_path,
get_valid_config,
discover_challenges,
format_user_service,
generate_compose,
get_ctf_config_path,
get_docker_client,
create_docker_name,
build_docker_images,
build_chall,
get_valid_config,
load_config,
load_ctf_config,
process_messages,
start_chall,
start_solution,
validate_solution_output,
format_user_service,
generate_compose,
_copytree,
)
from .constants import *
from .validator import ConfigValidator, is_url

class CliArguments(argparse.Namespace):
def __init__(self) -> None:
self.somearg: str
self.func: Callable

def main(passed_args=None):

def main(passed_args: Optional[List[str]] = None) -> int:
parser = argparse.ArgumentParser(
prog="challtools",
description="A tool for managing CTF challenges and challenge repositories using the OpenChallSpec",
Expand Down Expand Up @@ -165,19 +173,20 @@ def main(passed_args=None):

argcomplete.autocomplete(parser, always_complete_options=False)

args = parser.parse_args(passed_args)
args = parser.parse_args(passed_args, namespace=CliArguments)

if not getattr(args, "func", None):
parser.print_usage()
return 1
else:
try:
exit(args.func(args))
return args.func(args)
except CriticalException as e:
print(CRITICAL + e.args[0] + CLEAR)
exit(1)
return 1


def allchalls(args):
def allchalls(args: CliArguments) -> int:
parser = args.subparsers.choices.get(args.command[0])

if not parser:
Expand Down Expand Up @@ -210,7 +219,7 @@ def allchalls(args):
return int(failed)


def validate(args):
def validate(args: CliArguments) -> int:

config = load_config()

Expand Down Expand Up @@ -260,7 +269,7 @@ def validate(args):
return 0


def build(args):
def build(args: CliArguments) -> int:
config = get_valid_config()

if build_chall(config):
Expand All @@ -271,7 +280,7 @@ def build(args):
return 0


def start(args):
def start(args: CliArguments) -> int:
config = get_valid_config()

if args.build and build_chall(config):
Expand Down Expand Up @@ -322,7 +331,7 @@ def start(args):
return 1


def solve(args): # TODO add support for solve script
def solve(args: CliArguments) -> int: # TODO add support for solve script
config = get_valid_config()

if not config["solution_image"]:
Expand Down Expand Up @@ -370,7 +379,7 @@ def solve(args): # TODO add support for solve script
return 0


def compose(args):
def compose(args: CliArguments) -> int:
if args.all:
configs = [
(path, get_valid_config(path, cd=False)) for path in discover_challenges()
Expand All @@ -390,7 +399,7 @@ def compose(args):
return 0


def ensureid(args):
def ensureid(args: CliArguments) -> int:
path = Path(".")
if (path / "challenge.yml").exists():
path = path / "challenge.yml"
Expand All @@ -413,7 +422,7 @@ def ensureid(args):
if highest_level == 5:
print(
"\n".join(
process_messages([m for m in messages if m["level"] == 5])[
process_messages([m for m in messages if m.level == 5])[
"message_strings"
]
)
Expand Down Expand Up @@ -457,7 +466,7 @@ def ensureid(args):
return 0


def push(args):
def push(args: CliArguments) -> int:
config = get_valid_config()
ctf_config = load_ctf_config()

Expand Down Expand Up @@ -629,7 +638,7 @@ def push(args):
return 0


def init(args):
def init(args: CliArguments) -> int:

if args.list:
for template_path in Path(
Expand Down Expand Up @@ -687,7 +696,7 @@ def init(args):
return 0


def templateCompleter(**kwargs):
def templateCompleter(**kwargs: Dict[str, Any]) -> List[str]:
return [
path.name
for path in Path(
Expand All @@ -696,7 +705,7 @@ def templateCompleter(**kwargs):
]


def spoilerfree(args):
def spoilerfree(args: CliArguments) -> int:
config = get_valid_config()

print(f"\033[1;97m{config['title']}{CLEAR}")
Expand Down
Empty file modified challtools/codes.yml
100755 → 100644
Empty file.
Empty file modified challtools/constants.py
100755 → 100644
Empty file.
3 changes: 2 additions & 1 deletion challtools/templates/flask/container/server.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from flask import Flask
from flask.typing import ResponseReturnValue

app = Flask(__name__)


@app.route("/")
def index():
def index() -> ResponseReturnValue:
return "Template challenge running!"


Expand Down
Loading